Skip to content

Commit 2848a10

Browse files
committed
Enable MIR inlining of very small functions in debug builds
1 parent 5d5edf0 commit 2848a10

26 files changed

+167
-55
lines changed

compiler/rustc_mir_transform/src/inline.rs

Lines changed: 20 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
}
@@ -70,6 +65,14 @@ impl<'tcx> MirPass<'tcx> for Inline {
7065
}
7166

7267
fn inline<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) -> bool {
68+
let has_call = body
69+
.basic_blocks
70+
.iter()
71+
.any(|b| matches!(b.terminator().kind, TerminatorKind::Call { .. }));
72+
if !has_call {
73+
return false;
74+
}
75+
7376
let def_id = body.source.def_id().expect_local();
7477

7578
// Only do inlining into fn bodies.
@@ -475,7 +478,16 @@ impl<'tcx> Inliner<'tcx> {
475478
if callee_body.basic_blocks.len() <= 3 {
476479
threshold += threshold / 4;
477480
}
478-
debug!(" final inline threshold = {}", threshold);
481+
482+
// At MIR opt level 1 we only want to do a tiny bit of inlining.
483+
// 2 * INSTR_COST is the cost of one statement plus a return terminator.
484+
if tcx.sess.mir_opt_level() == 1 {
485+
threshold = 2 * INSTR_COST;
486+
if callee_body.basic_blocks.len() > 1 {
487+
return Err("cost above threshold");
488+
}
489+
}
490+
debug!("final inline threshold = {}", threshold);
479491

480492
// FIXME: Give a bonus to functions with only a single caller
481493

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/coverage-map/status-quo/async.cov-map

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -283,22 +283,19 @@ Number of file 0 mappings: 5
283283
- Code(Zero) at (prev + 2, 1) to (start + 0, 2)
284284

285285
Function name: async::l
286-
Raw bytes (37): 0x[01, 01, 04, 01, 07, 09, 05, 09, 0f, 05, 02, 05, 01, 53, 01, 01, 0c, 02, 02, 0e, 00, 10, 05, 01, 0e, 00, 10, 09, 01, 0e, 00, 10, 0b, 02, 01, 00, 02]
286+
Raw bytes (33): 0x[01, 01, 02, 09, 07, 05, 00, 05, 01, 53, 01, 01, 0c, 00, 02, 0e, 00, 10, 00, 01, 0e, 00, 10, 09, 01, 0e, 00, 10, 03, 02, 01, 00, 02]
287287
Number of files: 1
288288
- file 0 => global file 1
289-
Number of expressions: 4
290-
- expression 0 operands: lhs = Counter(0), rhs = Expression(1, Add)
291-
- expression 1 operands: lhs = Counter(2), rhs = Counter(1)
292-
- expression 2 operands: lhs = Counter(2), rhs = Expression(3, Add)
293-
- expression 3 operands: lhs = Counter(1), rhs = Expression(0, Sub)
289+
Number of expressions: 2
290+
- expression 0 operands: lhs = Counter(2), rhs = Expression(1, Add)
291+
- expression 1 operands: lhs = Counter(1), rhs = Zero
294292
Number of file 0 mappings: 5
295293
- Code(Counter(0)) at (prev + 83, 1) to (start + 1, 12)
296-
- Code(Expression(0, Sub)) at (prev + 2, 14) to (start + 0, 16)
297-
= (c0 - (c2 + c1))
298-
- Code(Counter(1)) at (prev + 1, 14) to (start + 0, 16)
294+
- Code(Zero) at (prev + 2, 14) to (start + 0, 16)
295+
- Code(Zero) at (prev + 1, 14) to (start + 0, 16)
299296
- Code(Counter(2)) at (prev + 1, 14) to (start + 0, 16)
300-
- Code(Expression(2, Add)) at (prev + 2, 1) to (start + 0, 2)
301-
= (c2 + (c1 + (c0 - (c2 + c1))))
297+
- Code(Expression(0, Add)) at (prev + 2, 1) to (start + 0, 2)
298+
= (c2 + (c1 + Zero))
302299

303300
Function name: async::m
304301
Raw bytes (9): 0x[01, 01, 00, 01, 01, 5b, 01, 00, 19]

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/run-make/sepcomp-cci-copies/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,5 @@ include ../tools.mk
88
all:
99
$(RUSTC) cci_lib.rs
1010
$(RUSTC) foo.rs --emit=llvm-ir -C codegen-units=6 \
11-
-Z inline-in-all-cgus
11+
-Z inline-in-all-cgus -Zmir-opt-level=0
1212
[ "$$(cat "$(TMPDIR)"/foo.*.ll | grep -c define\ .*cci_fn)" -eq "2" ]

0 commit comments

Comments
 (0)