Avoid MIR bloat in inlining
In 126578 we ended up with more binary size increases than expected. This change attempts to avoid inlining large things into small things, to avoid that kind of increase, in cases when top-down inlining will still be able to do that inlining later.
This commit is contained in:
parent
c3774be741
commit
23c8ed14c9
18 changed files with 387 additions and 847 deletions
|
@ -31,6 +31,37 @@ impl<'b, 'tcx> CostChecker<'b, 'tcx> {
|
|||
CostChecker { tcx, param_env, callee_body, instance, penalty: 0, bonus: 0 }
|
||||
}
|
||||
|
||||
/// Add function-level costs not well-represented by the block-level costs.
|
||||
///
|
||||
/// Needed because the `CostChecker` is used sometimes for just blocks,
|
||||
/// and even the full `Inline` doesn't call `visit_body`, so there's nowhere
|
||||
/// to put this logic in the visitor.
|
||||
pub fn add_function_level_costs(&mut self) {
|
||||
fn is_call_like(bbd: &BasicBlockData<'_>) -> bool {
|
||||
use TerminatorKind::*;
|
||||
match bbd.terminator().kind {
|
||||
Call { .. } | Drop { .. } | Assert { .. } | InlineAsm { .. } => true,
|
||||
|
||||
Goto { .. }
|
||||
| SwitchInt { .. }
|
||||
| UnwindResume
|
||||
| UnwindTerminate(_)
|
||||
| Return
|
||||
| Unreachable => false,
|
||||
|
||||
Yield { .. } | CoroutineDrop | FalseEdge { .. } | FalseUnwind { .. } => {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If the only has one Call (or similar), inlining isn't increasing the total
|
||||
// number of calls, so give extra encouragement to inlining that.
|
||||
if self.callee_body.basic_blocks.iter().filter(|bbd| is_call_like(bbd)).count() == 1 {
|
||||
self.bonus += CALL_PENALTY;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cost(&self) -> usize {
|
||||
usize::saturating_sub(self.penalty, self.bonus)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue