1
Fork 0

Auto merge of #110705 - saethlin:ignore-locals-cost, r=cjgillot

Remove the size of locals heuristic in MIR inlining

This heuristic doesn't necessarily correlate to complexity of the MIR Body. In particular, a lot of straight-line code in MIR tends to never reuse a local, even though any optimizer would effectively reuse the storage or just put everything in registers. So it doesn't even necessarily make sense that this would be a stack size heuristic.

So... what happens if we just delete the heuristic? The benchmark suite improves significantly. Less heuristics better?

r? `@cjgillot`
This commit is contained in:
bors 2023-04-23 15:41:45 +00:00
commit 915aa06700
5 changed files with 450 additions and 82 deletions

View file

@ -26,8 +26,6 @@ const CALL_PENALTY: usize = 25;
const LANDINGPAD_PENALTY: usize = 50;
const RESUME_PENALTY: usize = 45;
const UNKNOWN_SIZE_COST: usize = 10;
const TOP_DOWN_DEPTH_LIMIT: usize = 5;
pub struct Inline;
@ -464,12 +462,6 @@ impl<'tcx> Inliner<'tcx> {
}
}
// Count up the cost of local variables and temps, if we know the size
// use that, otherwise we use a moderately-large dummy cost.
for v in callee_body.vars_and_temps_iter() {
checker.visit_local_decl(v, &callee_body.local_decls[v]);
}
// Abort if type validation found anything fishy.
checker.validation?;
@ -764,14 +756,6 @@ impl<'tcx> Inliner<'tcx> {
}
}
fn type_size_of<'tcx>(
tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
ty: Ty<'tcx>,
) -> Option<u64> {
tcx.layout_of(param_env.and(ty)).ok().map(|layout| layout.size.bytes())
}
/// Verify that the callee body is compatible with the caller.
///
/// This visitor mostly computes the inlining cost,
@ -845,24 +829,6 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> {
self.super_terminator(terminator, location);
}
/// Count up the cost of local variables and temps, if we know the size
/// use that, otherwise we use a moderately-large dummy cost.
fn visit_local_decl(&mut self, local: Local, local_decl: &LocalDecl<'tcx>) {
let tcx = self.tcx;
let ptr_size = tcx.data_layout.pointer_size.bytes();
let ty = self.instance.subst_mir(tcx, &local_decl.ty);
// Cost of the var is the size in machine-words, if we know
// it.
if let Some(size) = type_size_of(tcx, self.param_env, ty) {
self.cost += ((size + ptr_size - 1) / ptr_size) as usize;
} else {
self.cost += UNKNOWN_SIZE_COST;
}
self.super_local_decl(local, local_decl)
}
/// This method duplicates code from MIR validation in an attempt to detect type mismatches due
/// to normalization failure.
fn visit_projection_elem(