diff options
| author | Ben Kimock <kimockb@gmail.com> | 2024-08-19 19:04:43 -0400 |
|---|---|---|
| committer | Ben Kimock <kimockb@gmail.com> | 2024-09-21 01:06:59 -0400 |
| commit | 0ea5dc506f50cf8e2732c715878ecf09ea0db480 (patch) | |
| tree | fbd70826c455558345b87f836adff155fae93cc9 /compiler/rustc_codegen_ssa/src | |
| parent | 5ba6db1b648d93fbbab4ae0466e40db682fa45fc (diff) | |
| download | rust-0ea5dc506f50cf8e2732c715878ecf09ea0db480.tar.gz rust-0ea5dc506f50cf8e2732c715878ecf09ea0db480.zip | |
Don't alloca for unused locals
Diffstat (limited to 'compiler/rustc_codegen_ssa/src')
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/mir/analyze.rs | 12 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/mir/mod.rs | 24 |
2 files changed, 21 insertions, 15 deletions
diff --git a/compiler/rustc_codegen_ssa/src/mir/analyze.rs b/compiler/rustc_codegen_ssa/src/mir/analyze.rs index f13c46e8bef..4e4bffd8b89 100644 --- a/compiler/rustc_codegen_ssa/src/mir/analyze.rs +++ b/compiler/rustc_codegen_ssa/src/mir/analyze.rs @@ -15,13 +15,18 @@ use crate::traits::*; pub(crate) fn non_ssa_locals<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( fx: &FunctionCx<'a, 'tcx, Bx>, + traversal_order: &[mir::BasicBlock], + reachable_locals: &BitSet<mir::Local>, ) -> BitSet<mir::Local> { let mir = fx.mir; let dominators = mir.basic_blocks.dominators(); let locals = mir .local_decls - .iter() - .map(|decl| { + .iter_enumerated() + .map(|(local, decl)| { + if !reachable_locals.contains(local) { + return LocalKind::Unused; + } let ty = fx.monomorphize(decl.ty); let layout = fx.cx.spanned_layout_of(ty, decl.source_info.span); if layout.is_zst() { @@ -44,7 +49,8 @@ pub(crate) fn non_ssa_locals<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( // If there exists a local definition that dominates all uses of that local, // the definition should be visited first. Traverse blocks in an order that // is a topological sort of dominance partial order. - for (bb, data) in traversal::reverse_postorder(mir) { + for bb in traversal_order.iter().copied() { + let data = &mir.basic_blocks[bb]; analyzer.visit_basic_block_data(bb, data); } diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs index 61e9b9bd774..6b36e730267 100644 --- a/compiler/rustc_codegen_ssa/src/mir/mod.rs +++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs @@ -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); } } |
