Skip to content

Commit 701f211

Browse files
committed
Give inlining bonuses to things that optimize out
1 parent 916e0d2 commit 701f211

File tree

1 file changed

+44
-8
lines changed

1 file changed

+44
-8
lines changed

compiler/rustc_mir_transform/src/cost_checker.rs

+44-8
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ const INSTR_COST: usize = 5;
66
const CALL_PENALTY: usize = 25;
77
const LANDINGPAD_PENALTY: usize = 50;
88
const RESUME_PENALTY: usize = 45;
9+
const LARGE_SWITCH_PENALTY: usize = 20;
10+
const CONST_SWITCH_BONUS: usize = 30;
911

1012
/// Verify that the callee body is compatible with the caller.
1113
#[derive(Clone)]
@@ -42,13 +44,30 @@ impl<'b, 'tcx> CostChecker<'b, 'tcx> {
4244
}
4345

4446
impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> {
45-
fn visit_statement(&mut self, statement: &Statement<'tcx>, _: Location) {
46-
// Don't count StorageLive/StorageDead in the inlining cost.
47+
fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) {
48+
// Most costs are in rvalues and terminators, not in statements.
4749
match statement.kind {
48-
StatementKind::StorageLive(_)
49-
| StatementKind::StorageDead(_)
50-
| StatementKind::Deinit(_)
51-
| StatementKind::Nop => {}
50+
StatementKind::Intrinsic(ref ndi) => {
51+
self.penalty += match **ndi {
52+
NonDivergingIntrinsic::Assume(..) => INSTR_COST,
53+
NonDivergingIntrinsic::CopyNonOverlapping(..) => CALL_PENALTY,
54+
};
55+
}
56+
_ => self.super_statement(statement, location),
57+
}
58+
}
59+
60+
fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, _location: Location) {
61+
match rvalue {
62+
Rvalue::NullaryOp(NullOp::UbChecks, ..) if !self.tcx.sess.ub_checks() => {
63+
// If this is in optimized MIR it's because it's used later,
64+
// so if we don't need UB checks this session, give a bonus
65+
// here to offset the cost of the call later.
66+
self.bonus += CALL_PENALTY;
67+
}
68+
// These are essentially constants that didn't end up in an Operand,
69+
// so treat them as also being free.
70+
Rvalue::NullaryOp(..) => {}
5271
_ => self.penalty += INSTR_COST,
5372
}
5473
}
@@ -82,8 +101,25 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> {
82101
self.penalty += LANDINGPAD_PENALTY;
83102
}
84103
}
85-
TerminatorKind::Assert { unwind, .. } => {
86-
self.penalty += CALL_PENALTY;
104+
TerminatorKind::SwitchInt { ref discr, ref targets } => {
105+
if discr.constant().is_some() {
106+
// Not only will this become a `Goto`, but likely other
107+
// things will be removable as unreachable.
108+
self.bonus += CONST_SWITCH_BONUS;
109+
} else if targets.all_targets().len() > 3 {
110+
// More than false/true/unreachable gets extra cost.
111+
self.penalty += LARGE_SWITCH_PENALTY;
112+
} else {
113+
self.penalty += INSTR_COST;
114+
}
115+
}
116+
TerminatorKind::Assert { unwind, ref msg, .. } => {
117+
self.penalty +=
118+
if msg.is_optional_overflow_check() && !self.tcx.sess.overflow_checks() {
119+
INSTR_COST
120+
} else {
121+
CALL_PENALTY
122+
};
87123
if let UnwindAction::Cleanup(_) = unwind {
88124
self.penalty += LANDINGPAD_PENALTY;
89125
}

0 commit comments

Comments
 (0)