Skip to content

Commit bea062f

Browse files
committed
slightly broken inlining
1 parent a0c290f commit bea062f

File tree

8 files changed

+70
-17
lines changed

8 files changed

+70
-17
lines changed

library/core/src/iter/range.rs

+3-15
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::char;
22
use crate::convert::TryFrom;
33
use crate::mem;
4-
use crate::ops::{self, Add, Sub, Try};
4+
use crate::ops::{self, Try};
55

66
use super::{FusedIterator, TrustedLen};
77

@@ -201,24 +201,12 @@ macro_rules! step_identical_methods {
201201

202202
#[inline]
203203
fn forward(start: Self, n: usize) -> Self {
204-
// In debug builds, trigger a panic on overflow.
205-
// This should optimize completely out in release builds.
206-
if Self::forward_checked(start, n).is_none() {
207-
let _ = Add::add(Self::MAX, 1);
208-
}
209-
// Do wrapping math to allow e.g. `Step::forward(-128i8, 255)`.
210-
start.wrapping_add(n as Self)
204+
start + (n as Self)
211205
}
212206

213207
#[inline]
214208
fn backward(start: Self, n: usize) -> Self {
215-
// In debug builds, trigger a panic on overflow.
216-
// This should optimize completely out in release builds.
217-
if Self::backward_checked(start, n).is_none() {
218-
let _ = Sub::sub(Self::MIN, 1);
219-
}
220-
// Do wrapping math to allow e.g. `Step::backward(127i8, 255)`.
221-
start.wrapping_sub(n as Self)
209+
start - (n as Self)
222210
}
223211
};
224212
}

src/librustc_metadata/rmeta/decoder.rs

+9
Original file line numberDiff line numberDiff line change
@@ -1139,6 +1139,15 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
11391139
}
11401140
}
11411141

1142+
fn get_is_trivial_mir(&self, tcx: TyCtxt<'tcx>, id: DefIndex) -> bool {
1143+
self.root
1144+
.tables
1145+
.is_trivial_mir
1146+
.get(self, id)
1147+
.filter(|_| !self.is_proc_macro(id))
1148+
.map_or(false, |v| v.decode((self, tcx)))
1149+
}
1150+
11421151
fn get_optimized_mir(&self, tcx: TyCtxt<'tcx>, id: DefIndex) -> Body<'tcx> {
11431152
self.root
11441153
.tables

src/librustc_metadata/rmeta/decoder/cstore_impl.rs

+1
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ provide! { <'tcx> tcx, def_id, other, cdata,
111111
bug!("coerce_unsized_info: `{:?}` is missing its info", def_id);
112112
})
113113
}
114+
is_trivial_mir => { *tcx.arena.alloc(cdata.get_is_trivial_mir(tcx, def_id.index)) }
114115
optimized_mir => { tcx.arena.alloc(cdata.get_optimized_mir(tcx, def_id.index)) }
115116
promoted_mir => { tcx.arena.alloc(cdata.get_promoted_mir(tcx, def_id.index)) }
116117
unused_generic_params => { cdata.get_unused_generic_params(def_id.index) }

src/librustc_metadata/rmeta/encoder.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1125,6 +1125,7 @@ impl EncodeContext<'a, 'tcx> {
11251125
fn encode_optimized_mir(&mut self, def_id: LocalDefId) {
11261126
debug!("EntryBuilder::encode_mir({:?})", def_id);
11271127
if self.tcx.mir_keys(LOCAL_CRATE).contains(&def_id) {
1128+
record!(self.tables.is_trivial_mir[def_id.to_def_id()] <- self.tcx.is_trivial_mir(def_id));
11281129
record!(self.tables.mir[def_id.to_def_id()] <- self.tcx.optimized_mir(def_id));
11291130

11301131
let unused = self.tcx.unused_generic_params(def_id);

src/librustc_metadata/rmeta/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,7 @@ define_tables! {
283283
// Also, as an optimization, a missing entry indicates an empty `&[]`.
284284
inferred_outlives: Table<DefIndex, Lazy!(&'tcx [(ty::Predicate<'tcx>, Span)])>,
285285
super_predicates: Table<DefIndex, Lazy!(ty::GenericPredicates<'tcx>)>,
286+
is_trivial_mir: Table<DefIndex, Lazy<bool>>,
286287
mir: Table<DefIndex, Lazy!(mir::Body<'tcx>)>,
287288
promoted_mir: Table<DefIndex, Lazy!(IndexVec<mir::Promoted, mir::Body<'tcx>>)>,
288289
unused_generic_params: Table<DefIndex, Lazy<FiniteBitSet<u32>>>,

src/librustc_middle/query/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,10 @@ rustc_queries! {
260260
}
261261
}
262262

263+
query is_trivial_mir(key: DefId) -> bool {
264+
desc { |tcx| "checking if MIR for `{}` is trivial", tcx.def_path_str(key) }
265+
}
266+
263267
/// MIR after our optimization passes have run. This is MIR that is ready
264268
/// for codegen. This is also the only query that can fetch non-local MIR, at present.
265269
query optimized_mir(key: DefId) -> &'tcx mir::Body<'tcx> {

src/librustc_mir/transform/inline.rs

+48-2
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ struct CallSite<'tcx> {
3838

3939
impl<'tcx> MirPass<'tcx> for Inline {
4040
fn run_pass(&self, tcx: TyCtxt<'tcx>, source: MirSource<'tcx>, body: &mut Body<'tcx>) {
41-
if tcx.sess.opts.debugging_opts.mir_opt_level >= 2 {
41+
if tcx.sess.opts.debugging_opts.mir_opt_level >= 1 {
4242
if tcx.sess.opts.debugging_opts.instrument_coverage {
4343
// The current implementation of source code coverage injects code region counters
4444
// into the MIR, and assumes a 1-to-1 correspondence between MIR and source-code-
@@ -100,7 +100,12 @@ impl Inliner<'tcx> {
100100
continue;
101101
}
102102

103-
let callee_body = if let Some(callee_def_id) = callsite.callee.as_local() {
103+
let callee_body = if self.tcx.is_trivial_mir(callsite.callee) {
104+
self.tcx.optimized_mir(callsite.callee)
105+
} else if self.tcx.sess.opts.debugging_opts.mir_opt_level < 2 {
106+
// Only inline trivial functions by default.
107+
continue;
108+
} else if let Some(callee_def_id) = callsite.callee.as_local() {
104109
let callee_hir_id = self.tcx.hir().as_local_hir_id(callee_def_id);
105110
let self_hir_id =
106111
self.tcx.hir().as_local_hir_id(self.source.def_id().expect_local());
@@ -802,3 +807,44 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> {
802807
*scope = self.scope_map[*scope];
803808
}
804809
}
810+
811+
struct FunctionCallFinder {
812+
found: bool,
813+
}
814+
815+
impl FunctionCallFinder {
816+
fn new() -> Self {
817+
FunctionCallFinder { found: false }
818+
}
819+
}
820+
821+
impl<'tcx> Visitor<'tcx> for FunctionCallFinder {
822+
fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, _location: Location) {
823+
if let TerminatorKind::Call { .. } = terminator.kind {
824+
self.found = true;
825+
}
826+
}
827+
}
828+
829+
pub fn is_trivial_mir(tcx: TyCtxt<'tcx>, did: DefId) -> bool {
830+
debug!("is_trivial_mir({:?})", did);
831+
if tcx.is_constructor(did) {
832+
debug!("is_trivial_mir = true (constructor)");
833+
return true;
834+
}
835+
836+
if let Some(did) = did.as_local() {
837+
let body = tcx
838+
.mir_drops_elaborated_and_const_checked(ty::WithOptConstParam::unknown(did))
839+
.borrow();
840+
let mut finder = FunctionCallFinder::new();
841+
finder.visit_body(&body);
842+
debug!("is_trivial_mir = {}", !finder.found);
843+
!finder.found
844+
} else {
845+
// This branch is only taken if no `optimized_mir` is available for
846+
// an extern crate, as `is_trivial_mir` has otherwise been encoded.
847+
debug!("is_trivial_mir = false (no MIR available)");
848+
false
849+
}
850+
}

src/librustc_mir/transform/mod.rs

+3
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ pub(crate) fn provide(providers: &mut Providers) {
6161
},
6262
mir_validated,
6363
mir_drops_elaborated_and_const_checked,
64+
is_trivial_mir: inline::is_trivial_mir,
6465
optimized_mir,
6566
optimized_mir_of_const_arg,
6667
is_mir_available,
@@ -510,6 +511,8 @@ fn inner_optimized_mir(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>)
510511
return shim::build_adt_ctor(tcx, def.did.to_def_id());
511512
}
512513

514+
// `is_trivial_mir` uses `mir_drops_elaborated_and_const_checked` so run that first.
515+
tcx.ensure().is_trivial_mir(def.did.to_def_id());
513516
let mut body = tcx.mir_drops_elaborated_and_const_checked(def).steal();
514517
run_optimization_passes(tcx, &mut body, def.did, None);
515518

0 commit comments

Comments
 (0)