Skip to content

Commit 8841021

Browse files
committed
Always consider inlining for trivial functions
1 parent 2a7c2df commit 8841021

22 files changed

+143
-31
lines changed

compiler/rustc_mir_transform/src/inline.rs

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ use rustc_middle::mir::visit::*;
1010
use rustc_middle::mir::*;
1111
use rustc_middle::ty::TypeVisitableExt;
1212
use rustc_middle::ty::{self, Instance, InstanceDef, ParamEnv, Ty, TyCtxt};
13-
use rustc_session::config::OptLevel;
1413
use rustc_target::abi::FieldIdx;
1514
use rustc_target::spec::abi::Abi;
1615

@@ -47,12 +46,8 @@ impl<'tcx> MirPass<'tcx> for Inline {
4746
}
4847

4948
match sess.mir_opt_level() {
50-
0 | 1 => false,
51-
2 => {
52-
(sess.opts.optimize == OptLevel::Default
53-
|| sess.opts.optimize == OptLevel::Aggressive)
54-
&& sess.opts.incremental == None
55-
}
49+
0 => false,
50+
1 | 2 => sess.opts.incremental.is_none(),
5651
_ => true,
5752
}
5853
}
@@ -471,7 +466,11 @@ impl<'tcx> Inliner<'tcx> {
471466
if callee_body.basic_blocks.len() <= 3 {
472467
threshold += threshold / 4;
473468
}
474-
debug!(" final inline threshold = {}", threshold);
469+
470+
if tcx.sess.mir_opt_level() == 1 {
471+
threshold = 2 * INSTR_COST;
472+
}
473+
debug!("final inline threshold = {}", threshold);
475474

476475
// FIXME: Give a bonus to functions with only a single caller
477476

@@ -481,6 +480,7 @@ impl<'tcx> Inliner<'tcx> {
481480
instance: callsite.callee,
482481
callee_body,
483482
cost: 0,
483+
threshold,
484484
};
485485

486486
// Traverse the MIR manually so we can account for the effects of inlining on the CFG.
@@ -493,6 +493,10 @@ impl<'tcx> Inliner<'tcx> {
493493

494494
let blk = &callee_body.basic_blocks[bb];
495495
checker.visit_basic_block_data(bb, blk);
496+
if callee_attrs.inline != InlineAttr::Always && checker.cost > threshold {
497+
debug!("checker cost exceeded threshold partway through");
498+
return Err("cost above threshold");
499+
}
496500

497501
let term = blk.terminator();
498502
if let TerminatorKind::Drop { ref place, target, unwind, replace: _ } = term.kind {
@@ -805,12 +809,17 @@ struct CostChecker<'b, 'tcx> {
805809
tcx: TyCtxt<'tcx>,
806810
param_env: ParamEnv<'tcx>,
807811
cost: usize,
812+
threshold: usize,
808813
callee_body: &'b Body<'tcx>,
809814
instance: ty::Instance<'tcx>,
810815
}
811816

812817
impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> {
813818
fn visit_statement(&mut self, statement: &Statement<'tcx>, _: Location) {
819+
if self.cost > self.threshold {
820+
return;
821+
}
822+
814823
// Don't count StorageLive/StorageDead in the inlining cost.
815824
match statement.kind {
816825
StatementKind::StorageLive(_)

tests/codegen-units/polymorphization/unused_type_parameters.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// compile-flags:-Zpolymorphize=on -Zprint-mono-items=lazy -Copt-level=1
1+
// compile-flags:-Zpolymorphize=on -Zprint-mono-items=lazy -Copt-level=1 -Zmir-opt-level=0
22

33
#![crate_type = "rlib"]
44

tests/debuginfo/function-names.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Function names are formatted differently in old versions of GDB
22
// min-gdb-version: 10.1
33

4-
// compile-flags:-g
4+
// compile-flags: -g -Zmir-opt-level=0
55

66
// === GDB TESTS ===================================================================================
77

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
2+
// compile-flags: -Copt-level=0 -Zmir-opt-level=1
3+
#![crate_type = "lib"]
4+
5+
// Test that we still inline trivial functions even in a debug build
6+
7+
pub struct Thing {
8+
inner: u8,
9+
}
10+
11+
impl Thing {
12+
#[inline]
13+
pub fn get(&self) -> u8 {
14+
self.inner
15+
}
16+
}
17+
18+
// EMIT_MIR trivial_fn_debug_build.wrapper.Inline.diff
19+
// EMIT_MIR trivial_fn_debug_build.wrapper.PreCodegen.after.mir
20+
pub fn wrapper(t: &Thing) -> u8 {
21+
t.get()
22+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
- // MIR for `wrapper` before Inline
2+
+ // MIR for `wrapper` after Inline
3+
4+
fn wrapper(_1: &Thing) -> u8 {
5+
debug t => _1;
6+
let mut _0: u8;
7+
let mut _2: &Thing;
8+
+ scope 1 (inlined Thing::get) {
9+
+ debug self => _2;
10+
+ }
11+
12+
bb0: {
13+
StorageLive(_2);
14+
_2 = &(*_1);
15+
- _0 = Thing::get(move _2) -> [return: bb1, unwind unreachable];
16+
- }
17+
-
18+
- bb1: {
19+
+ _0 = ((*_2).0: u8);
20+
StorageDead(_2);
21+
return;
22+
}
23+
}
24+
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
- // MIR for `wrapper` before Inline
2+
+ // MIR for `wrapper` after Inline
3+
4+
fn wrapper(_1: &Thing) -> u8 {
5+
debug t => _1;
6+
let mut _0: u8;
7+
let mut _2: &Thing;
8+
+ scope 1 (inlined Thing::get) {
9+
+ debug self => _2;
10+
+ }
11+
12+
bb0: {
13+
StorageLive(_2);
14+
_2 = &(*_1);
15+
- _0 = Thing::get(move _2) -> [return: bb1, unwind continue];
16+
- }
17+
-
18+
- bb1: {
19+
+ _0 = ((*_2).0: u8);
20+
StorageDead(_2);
21+
return;
22+
}
23+
}
24+
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// MIR for `wrapper` after PreCodegen
2+
3+
fn wrapper(_1: &Thing) -> u8 {
4+
debug t => _1;
5+
let mut _0: u8;
6+
scope 1 (inlined Thing::get) {
7+
debug self => _1;
8+
}
9+
10+
bb0: {
11+
_0 = ((*_1).0: u8);
12+
return;
13+
}
14+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// MIR for `wrapper` after PreCodegen
2+
3+
fn wrapper(_1: &Thing) -> u8 {
4+
debug t => _1;
5+
let mut _0: u8;
6+
scope 1 (inlined Thing::get) {
7+
debug self => _1;
8+
}
9+
10+
bb0: {
11+
_0 = ((*_1).0: u8);
12+
return;
13+
}
14+
}

tests/ui-fulldeps/stable-mir/crate-info.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ fn test_stable_mir(_tcx: TyCtxt<'_>) -> ControlFlow<()> {
5959
let foo_bar = get_item(&items, (DefKind::Fn, "foo_bar")).unwrap();
6060
let body = foo_bar.body();
6161
assert_eq!(body.locals.len(), 5);
62-
assert_eq!(body.blocks.len(), 4);
62+
assert_eq!(body.blocks.len(), 3);
6363
let block = &body.blocks[0];
6464
match &block.terminator.kind {
6565
stable_mir::mir::TerminatorKind::Call { .. } => {}

tests/ui/consts/const-eval/index-out-of-bounds-never-type.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// build-fail
2+
// compile-flags: -Zmir-opt-level=0
23

34
// Regression test for #66975
45
#![warn(unconditional_panic)]

0 commit comments

Comments
 (0)