Skip to content

Commit f98c04d

Browse files
committed
Don't alloca for unused locals
1 parent 5601d14 commit f98c04d

File tree

3 files changed

+28
-6
lines changed

3 files changed

+28
-6
lines changed

compiler/rustc_codegen_cranelift/src/base.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,8 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
299299
.generic_activity("codegen prelude")
300300
.run(|| crate::abi::codegen_fn_prelude(fx, start_block));
301301

302-
let reachable_blocks = traversal::mono_reachable_as_bitset(fx.mir, fx.tcx, fx.instance);
302+
let (reachable_blocks, _reachable_locals) =
303+
traversal::mono_reachable_as_bitset(fx.mir, fx.tcx, fx.instance);
303304

304305
for (bb, bb_data) in fx.mir.basic_blocks.iter_enumerated() {
305306
let block = fx.get_block(bb);

compiler/rustc_codegen_ssa/src/mir/mod.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,9 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
192192
})
193193
.collect();
194194

195+
let (reachable_blocks, reachable_locals) =
196+
traversal::mono_reachable_as_bitset(mir, cx.tcx(), instance);
197+
195198
let mut fx = FunctionCx {
196199
instance,
197200
mir,
@@ -218,7 +221,8 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
218221

219222
fx.per_local_var_debug_info = fx.compute_per_local_var_debug_info(&mut start_bx);
220223

221-
let memory_locals = analyze::non_ssa_locals(&fx);
224+
let mut memory_locals = analyze::non_ssa_locals(&fx);
225+
memory_locals.intersect(&reachable_locals);
222226

223227
// Allocate variable and temp allocas
224228
let local_values = {
@@ -277,8 +281,6 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
277281
// So drop the builder of `start_llbb` to avoid having two at the same time.
278282
drop(start_bx);
279283

280-
let reachable_blocks = traversal::mono_reachable_as_bitset(mir, cx.tcx(), instance);
281-
282284
// Codegen the body of each block using reverse postorder
283285
for (bb, _) in traversal::reverse_postorder(mir) {
284286
if reachable_blocks.contains(bb) {

compiler/rustc_middle/src/mir/traversal.rs

+21-2
Original file line numberDiff line numberDiff line change
@@ -303,10 +303,10 @@ pub fn mono_reachable_as_bitset<'a, 'tcx>(
303303
body: &'a Body<'tcx>,
304304
tcx: TyCtxt<'tcx>,
305305
instance: Instance<'tcx>,
306-
) -> BitSet<BasicBlock> {
306+
) -> (BitSet<BasicBlock>, BitSet<Local>) {
307307
let mut iter = mono_reachable(body, tcx, instance);
308308
while let Some(_) = iter.next() {}
309-
iter.visited
309+
(iter.visited, iter.locals)
310310
}
311311

312312
pub struct MonoReachable<'a, 'tcx> {
@@ -318,6 +318,23 @@ pub struct MonoReachable<'a, 'tcx> {
318318
// store ours in a BitSet and thus save allocations because BitSet has a small size
319319
// optimization.
320320
worklist: BitSet<BasicBlock>,
321+
locals: BitSet<Local>,
322+
}
323+
324+
struct UsedLocals<'a> {
325+
locals: &'a mut BitSet<Local>,
326+
}
327+
328+
use crate::mir::visit::Visitor;
329+
impl<'a, 'tcx> Visitor<'tcx> for UsedLocals<'a> {
330+
fn visit_local(
331+
&mut self,
332+
local: Local,
333+
_ctx: crate::mir::visit::PlaceContext,
334+
_location: Location,
335+
) {
336+
self.locals.insert(local);
337+
}
321338
}
322339

323340
impl<'a, 'tcx> MonoReachable<'a, 'tcx> {
@@ -334,6 +351,7 @@ impl<'a, 'tcx> MonoReachable<'a, 'tcx> {
334351
instance,
335352
visited: BitSet::new_empty(body.basic_blocks.len()),
336353
worklist,
354+
locals: BitSet::new_empty(body.local_decls.len()),
337355
}
338356
}
339357

@@ -357,6 +375,7 @@ impl<'a, 'tcx> Iterator for MonoReachable<'a, 'tcx> {
357375
}
358376

359377
let data = &self.body[idx];
378+
UsedLocals { locals: &mut self.locals }.visit_basic_block_data(idx, data);
360379

361380
if let Some((bits, targets)) =
362381
Body::try_const_mono_switchint(self.tcx, self.instance, data)

0 commit comments

Comments
 (0)