Skip to content

Commit a173a82

Browse files
committed
Auto merge of #48602 - eddyb:get-in-line, r=<try>
rustc_mir: always run the inlining pass. **DO NOT MERGE**: there are still issues around debuginfo and maybe even misoptimizations. As suggested by @pcwalton, maybe it's time to test the overhead / wins from turning MIR inlining on.
2 parents affe297 + f1878ff commit a173a82

File tree

15 files changed

+109
-61
lines changed

15 files changed

+109
-61
lines changed

src/librustc_metadata/creader.rs

+1
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,7 @@ impl<'a> CrateLoader<'a> {
248248
cnum_map: RefCell::new(cnum_map),
249249
cnum,
250250
codemap_import_info: RefCell::new(vec![]),
251+
last_filemap_index: Cell::new(0),
251252
attribute_cache: RefCell::new([Vec::new(), Vec::new()]),
252253
dep_kind: Cell::new(dep_kind),
253254
source: cstore::CrateSource {

src/librustc_metadata/cstore.rs

+2
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ pub struct CrateMetadata {
6767
pub cnum_map: RefCell<CrateNumMap>,
6868
pub cnum: CrateNum,
6969
pub codemap_import_info: RefCell<Vec<ImportedFileMap>>,
70+
// Cache the last used filemap for translating spans as an optimization.
71+
pub last_filemap_index: Cell<usize>,
7072
pub attribute_cache: RefCell<[Vec<Option<Rc<[ast::Attribute]>>>; 2]>,
7173

7274
pub root: schema::CrateRoot,

src/librustc_metadata/cstore_impl.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ macro_rules! provide {
6767

6868
let $cdata = $tcx.crate_data_as_rc_any($def_id.krate);
6969
let $cdata = $cdata.downcast_ref::<cstore::CrateMetadata>()
70-
.expect("CrateStore crated ata is not a CrateMetadata");
70+
.expect("CrateStore crate data is not a CrateMetadata");
7171
$compute
7272
})*
7373

src/librustc_metadata/decoder.rs

+59-41
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ use std::cell::Ref;
3333
use std::collections::BTreeMap;
3434
use std::io;
3535
use std::mem;
36+
use std::ops::RangeInclusive;
3637
use std::rc::Rc;
3738
use std::u32;
3839

@@ -50,9 +51,6 @@ pub struct DecodeContext<'a, 'tcx: 'a> {
5051
sess: Option<&'a Session>,
5152
tcx: Option<TyCtxt<'a, 'tcx, 'tcx>>,
5253

53-
// Cache the last used filemap for translating spans as an optimization.
54-
last_filemap_index: usize,
55-
5654
lazy_state: LazyState,
5755
}
5856

@@ -70,7 +68,7 @@ pub trait Metadata<'a, 'tcx>: Copy {
7068
cdata: self.cdata(),
7169
sess: self.sess().or(tcx.map(|tcx| tcx.sess)),
7270
tcx,
73-
last_filemap_index: 0,
71+
7472
lazy_state: LazyState::NoNode,
7573
}
7674
}
@@ -270,63 +268,46 @@ impl<'a, 'tcx> SpecializedDecoder<DefIndex> for DecodeContext<'a, 'tcx> {
270268

271269
impl<'a, 'tcx> SpecializedDecoder<Span> for DecodeContext<'a, 'tcx> {
272270
fn specialized_decode(&mut self) -> Result<Span, Self::Error> {
273-
let tag = u8::decode(self)?;
271+
let cnum_tag = u32::decode(self)?;
274272

275-
if tag == TAG_INVALID_SPAN {
273+
if cnum_tag == TAG_INVALID_SPAN_CNUM {
276274
return Ok(DUMMY_SP)
277275
}
278276

279-
debug_assert_eq!(tag, TAG_VALID_SPAN);
277+
let original_cnum = CrateNum::from_u32(cnum_tag - TAG_VALID_SPAN_CNUM_START);
278+
let cnum = self.map_encoded_cnum_to_current(original_cnum);
280279

281280
let lo = BytePos::decode(self)?;
282281
let len = BytePos::decode(self)?;
283-
let hi = lo + len;
284282

285283
let sess = if let Some(sess) = self.sess {
286284
sess
287285
} else {
288286
bug!("Cannot decode Span without Session.")
289287
};
290288

291-
let imported_filemaps = self.cdata().imported_filemaps(&sess.codemap());
292-
let filemap = {
293-
// Optimize for the case that most spans within a translated item
294-
// originate from the same filemap.
295-
let last_filemap = &imported_filemaps[self.last_filemap_index];
296-
297-
if lo >= last_filemap.original_start_pos &&
298-
lo <= last_filemap.original_end_pos {
299-
last_filemap
300-
} else {
301-
let mut a = 0;
302-
let mut b = imported_filemaps.len();
303-
304-
while b - a > 1 {
305-
let m = (a + b) / 2;
306-
if imported_filemaps[m].original_start_pos > lo {
307-
b = m;
308-
} else {
309-
a = m;
310-
}
311-
}
312-
313-
self.last_filemap_index = a;
314-
&imported_filemaps[a]
315-
}
289+
let span_cdata_rc_any;
290+
let span_cdata = if original_cnum == LOCAL_CRATE {
291+
self.cdata()
292+
} else {
293+
// FIXME(eddyb) this requires the `tcx` which isn't always available.
294+
// However, currently only MIR inlining can end up producing such
295+
// cross-crate spans, and decoding MIR always provides a `tcx`.
296+
span_cdata_rc_any = self.tcx().crate_data_as_rc_any(cnum);
297+
span_cdata_rc_any.downcast_ref::<CrateMetadata>()
298+
.expect("CrateStore crate data is not a CrateMetadata")
316299
};
317300

318-
// Make sure our binary search above is correct.
319-
debug_assert!(lo >= filemap.original_start_pos &&
320-
lo <= filemap.original_end_pos);
301+
let filemap = span_cdata.imported_filemap_containing(&sess.codemap(), lo, |filemap| {
302+
filemap.original_start_pos..=filemap.original_end_pos
303+
});
321304

322305
// Make sure we correctly filtered out invalid spans during encoding
323-
debug_assert!(hi >= filemap.original_start_pos &&
324-
hi <= filemap.original_end_pos);
306+
debug_assert!(lo + len >= filemap.original_start_pos &&
307+
lo + len <= filemap.original_end_pos);
325308

326309
let lo = (lo + filemap.translated_filemap.start_pos) - filemap.original_start_pos;
327-
let hi = (hi + filemap.translated_filemap.start_pos) - filemap.original_start_pos;
328-
329-
Ok(Span::new(lo, hi, NO_EXPANSION))
310+
Ok(Span::new(lo, lo + len, NO_EXPANSION))
330311
}
331312
}
332313

@@ -1169,4 +1150,41 @@ impl<'a, 'tcx> CrateMetadata {
11691150
*self.codemap_import_info.borrow_mut() = imported_filemaps;
11701151
self.codemap_import_info.borrow()
11711152
}
1153+
1154+
pub fn imported_filemap_containing<F>(&'a self,
1155+
local_codemap: &codemap::CodeMap,
1156+
pos: BytePos,
1157+
range_of: F)
1158+
-> Ref<'a, cstore::ImportedFileMap>
1159+
where F: Fn(&cstore::ImportedFileMap) -> RangeInclusive<BytePos>
1160+
{
1161+
Ref::map(self.imported_filemaps(local_codemap), |imported_filemaps| {
1162+
// Optimize for the case that most spans within a translated item
1163+
// originate from the same filemap.
1164+
let last_filemap = &imported_filemaps[self.last_filemap_index.get()];
1165+
if range_of(last_filemap).contains(pos) {
1166+
last_filemap
1167+
} else {
1168+
let mut a = 0;
1169+
let mut b = imported_filemaps.len();
1170+
1171+
while b - a > 1 {
1172+
let m = (a + b) / 2;
1173+
if range_of(&imported_filemaps[m]).start > pos {
1174+
b = m;
1175+
} else {
1176+
a = m;
1177+
}
1178+
}
1179+
1180+
self.last_filemap_index.set(a);
1181+
let filemap = &imported_filemaps[a];
1182+
1183+
// Make sure our binary search above is correct.
1184+
debug_assert!(range_of(filemap).contains(pos));
1185+
1186+
filemap
1187+
}
1188+
})
1189+
}
11721190
}

src/librustc_metadata/encoder.rs

+23-4
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
use cstore::CrateMetadata;
1112
use index::Index;
1213
use index_builder::{FromId, IndexBuilder, Untracked};
1314
use isolated_encoder::IsolatedEncoder;
@@ -147,7 +148,7 @@ impl<'a, 'tcx> SpecializedEncoder<DefIndex> for EncodeContext<'a, 'tcx> {
147148
impl<'a, 'tcx> SpecializedEncoder<Span> for EncodeContext<'a, 'tcx> {
148149
fn specialized_encode(&mut self, span: &Span) -> Result<(), Self::Error> {
149150
if *span == DUMMY_SP {
150-
return TAG_INVALID_SPAN.encode(self)
151+
return TAG_INVALID_SPAN_CNUM.encode(self)
151152
}
152153

153154
let span = span.data();
@@ -164,11 +165,29 @@ impl<'a, 'tcx> SpecializedEncoder<Span> for EncodeContext<'a, 'tcx> {
164165
if !self.filemap_cache.contains(span.hi) {
165166
// Unfortunately, macro expansion still sometimes generates Spans
166167
// that malformed in this way.
167-
return TAG_INVALID_SPAN.encode(self)
168+
return TAG_INVALID_SPAN_CNUM.encode(self)
168169
}
169170

170-
TAG_VALID_SPAN.encode(self)?;
171-
span.lo.encode(self)?;
171+
let cnum = CrateNum::from_u32(self.filemap_cache.crate_of_origin);
172+
let cnum_tag = TAG_VALID_SPAN_CNUM_START + cnum.as_u32();
173+
cnum_tag.encode(self)?;
174+
let original_lo = if cnum == LOCAL_CRATE {
175+
span.lo
176+
} else {
177+
// Imported spans were adjusted when they were decoded, so
178+
// they have to be translated back into their crate of origin.
179+
let codemap = self.tcx.sess.codemap();
180+
let span_cdata_rc_any = self.tcx.crate_data_as_rc_any(cnum);
181+
let span_cdata = span_cdata_rc_any.downcast_ref::<CrateMetadata>()
182+
.expect("CrateStore crate data is not a CrateMetadata");
183+
// FIXME(eddyb) It'd be easier to just put `original_{start,end}_pos`
184+
// in `syntax_pos::FileMap` instead of `ImportedFileMap`.
185+
let filemap = span_cdata.imported_filemap_containing(&codemap, span.lo, |filemap| {
186+
filemap.translated_filemap.start_pos..=filemap.translated_filemap.end_pos
187+
});
188+
(span.lo + filemap.original_start_pos) - filemap.translated_filemap.start_pos
189+
};
190+
original_lo.encode(self)?;
172191

173192
// Encode length which is usually less than span.hi and profits more
174193
// from the variable-length integer encoding that we use.

src/librustc_metadata/lib.rs

+3
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,12 @@
1717
#![feature(conservative_impl_trait)]
1818
#![feature(fs_read_write)]
1919
#![feature(i128_type)]
20+
#![feature(inclusive_range)]
21+
#![feature(inclusive_range_syntax)]
2022
#![feature(libc)]
2123
#![feature(proc_macro_internals)]
2224
#![feature(quote)]
25+
#![feature(range_contains)]
2326
#![feature(rustc_diagnostic_macros)]
2427
#![feature(specialization)]
2528
#![feature(rustc_private)]

src/librustc_metadata/schema.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -521,5 +521,5 @@ pub struct GeneratorData<'tcx> {
521521
impl_stable_hash_for!(struct GeneratorData<'tcx> { layout });
522522

523523
// Tags used for encoding Spans:
524-
pub const TAG_VALID_SPAN: u8 = 0;
525-
pub const TAG_INVALID_SPAN: u8 = 1;
524+
pub const TAG_INVALID_SPAN_CNUM: u32 = 0;
525+
pub const TAG_VALID_SPAN_CNUM_START: u32 = 1;

src/librustc_mir/transform/inline.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,7 @@ impl MirPass for Inline {
5252
tcx: TyCtxt<'a, 'tcx, 'tcx>,
5353
source: MirSource,
5454
mir: &mut Mir<'tcx>) {
55-
if tcx.sess.opts.debugging_opts.mir_opt_level >= 2 {
56-
Inliner { tcx, source }.run_pass(mir);
57-
}
55+
Inliner { tcx, source }.run_pass(mir);
5856
}
5957
}
6058

src/test/codegen/internalize-closures.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,13 @@
1010

1111
// compile-flags: -C no-prepopulate-passes
1212

13+
#![feature(stmt_expr_attributes)]
14+
1315
pub fn main() {
1416

1517
// We want to make sure that closures get 'internal' linkage instead of
1618
// 'weak_odr' when they are not shared between codegen units
1719
// CHECK: define internal {{.*}}_ZN20internalize_closures4main{{.*}}$u7b$$u7b$closure$u7d$$u7d$
18-
let c = |x:i32| { x + 1 };
20+
let c = #[inline(never)] |x:i32| { x + 1 };
1921
let _ = c(1);
2022
}

src/test/codegen/remap_path_prefix/aux_mod.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
// ignore-test: this is not a test
1212

13-
#[inline]
14-
pub fn some_aux_mod_function() -> i32 {
15-
1234
13+
#[inline(never)]
14+
pub fn some_aux_mod_function<T>() -> usize {
15+
::std::mem::size_of::<T>()
1616
}

src/test/codegen/remap_path_prefix/auxiliary/remap_path_prefix_aux.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
// compile-flags: -g -Zremap-path-prefix-from={{cwd}} -Zremap-path-prefix-to=/the/aux-cwd -Zremap-path-prefix-from={{src-base}}/remap_path_prefix/auxiliary -Zremap-path-prefix-to=/the/aux-src
1414

15-
#[inline]
16-
pub fn some_aux_function() -> i32 {
17-
1234
15+
#[inline(never)]
16+
pub fn some_aux_function<T>() -> usize {
17+
std::mem::size_of::<T>()
1818
}

src/test/codegen/remap_path_prefix/main.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@ include!("aux_mod.rs");
2626
pub static FILE_PATH: &'static str = file!();
2727

2828
fn main() {
29-
remap_path_prefix_aux::some_aux_function();
30-
aux_mod::some_aux_mod_function();
31-
some_aux_mod_function();
29+
remap_path_prefix_aux::some_aux_function::<()>();
30+
aux_mod::some_aux_mod_function::<()>();
31+
some_aux_mod_function::<()>();
3232
}
3333

3434
// Here we check that local debuginfo is mapped correctly.

src/test/compile-fail/issue-22638.rs

+1
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ impl C {
5757
struct D (Box<A>);
5858

5959
impl D {
60+
#[inline(never)]
6061
pub fn matches<F: Fn()>(&self, f: &F) {
6162
//~^ ERROR reached the type-length limit while instantiating `D::matches::<[closure
6263
let &D(ref a) = self;

src/test/compile-fail/type_length_limit.rs

+3
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ link! { F, G }
3030

3131
pub struct G;
3232

33+
#[inline(never)]
34+
fn drop<T>(_: T) {}
35+
3336
fn main() {
3437
drop::<Option<A>>(None);
3538
}

src/test/debuginfo/associated-types.rs

+1
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ fn assoc_return_value<T: TraitWithAssocType>(arg: T) -> T::Type {
125125
return arg.get_value();
126126
}
127127

128+
#[inline(never)]
128129
fn assoc_tuple<T: TraitWithAssocType>(arg: (T, T::Type)) {
129130
zzz(); // #break
130131
}

0 commit comments

Comments
 (0)