Don't alloca for unused locals

This commit is contained in:
Ben Kimock
2024-08-19 19:04:43 -04:00
parent 5ba6db1b64
commit 0ea5dc506f
7 changed files with 156 additions and 26 deletions

View File

@@ -192,6 +192,9 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
})
.collect();
let (traversal_order, reachable_locals) =
traversal::mono_reachable_reverse_postorder(mir, cx.tcx(), instance);
let mut fx = FunctionCx {
instance,
mir,
@@ -218,7 +221,7 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
fx.per_local_var_debug_info = fx.compute_per_local_var_debug_info(&mut start_bx);
let memory_locals = analyze::non_ssa_locals(&fx);
let memory_locals = analyze::non_ssa_locals(&fx, &traversal_order, &reachable_locals);
// Allocate variable and temp allocas
let local_values = {
@@ -277,17 +280,14 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
// So drop the builder of `start_llbb` to avoid having two at the same time.
drop(start_bx);
let reachable_blocks = traversal::mono_reachable_as_bitset(mir, cx.tcx(), instance);
// Codegen the body of each block using reverse postorder
for (bb, _) in traversal::reverse_postorder(mir) {
if reachable_blocks.contains(bb) {
fx.codegen_block(bb);
} else {
// We want to skip this block, because it's not reachable. But we still create
// the block so terminators in other blocks can reference it.
fx.codegen_block_as_unreachable(bb);
}
let mut unreached_blocks = BitSet::new_filled(mir.basic_blocks.len());
// Codegen the body of each reachable block using our reverse postorder list.
for bb in traversal_order {
fx.codegen_block(bb);
unreached_blocks.remove(bb);
}
for bb in unreached_blocks.iter() {
fx.codegen_block_as_unreachable(bb);
}
}