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_middle/src/mir/traversal.rs | |
| parent | 5ba6db1b648d93fbbab4ae0466e40db682fa45fc (diff) | |
| download | rust-0ea5dc506f50cf8e2732c715878ecf09ea0db480.tar.gz rust-0ea5dc506f50cf8e2732c715878ecf09ea0db480.zip | |
Don't alloca for unused locals
Diffstat (limited to 'compiler/rustc_middle/src/mir/traversal.rs')
| -rw-r--r-- | compiler/rustc_middle/src/mir/traversal.rs | 95 |
1 files changed, 87 insertions, 8 deletions
diff --git a/compiler/rustc_middle/src/mir/traversal.rs b/compiler/rustc_middle/src/mir/traversal.rs index 245e9096bad..1d55a38f30b 100644 --- a/compiler/rustc_middle/src/mir/traversal.rs +++ b/compiler/rustc_middle/src/mir/traversal.rs @@ -1,4 +1,5 @@ use super::*; +use crate::mir::visit::Visitor; /// Preorder traversal of a graph. /// @@ -232,6 +233,90 @@ pub fn postorder<'a, 'tcx>( reverse_postorder(body).rev() } +struct UsedLocals(BitSet<Local>); + +impl<'tcx> Visitor<'tcx> for UsedLocals { + fn visit_local( + &mut self, + local: Local, + _ctx: crate::mir::visit::PlaceContext, + _location: Location, + ) { + self.0.insert(local); + } +} + +struct MonoReachablePostorder<'a, 'tcx> { + basic_blocks: &'a IndexSlice<BasicBlock, BasicBlockData<'tcx>>, + visited: BitSet<BasicBlock>, + visit_stack: Vec<(BasicBlock, Successors<'a>)>, + locals: UsedLocals, + tcx: TyCtxt<'tcx>, + instance: Instance<'tcx>, +} + +impl<'a, 'tcx> MonoReachablePostorder<'a, 'tcx> { + fn new( + body: &'a Body<'tcx>, + tcx: TyCtxt<'tcx>, + instance: Instance<'tcx>, + ) -> MonoReachablePostorder<'a, 'tcx> { + let basic_blocks = &body.basic_blocks; + let mut po = MonoReachablePostorder { + basic_blocks, + visited: BitSet::new_empty(basic_blocks.len()), + visit_stack: Vec::new(), + locals: UsedLocals(BitSet::new_empty(body.local_decls.len())), + tcx, + instance, + }; + + po.visit(START_BLOCK); + po.traverse_successor(); + po + } + + fn visit(&mut self, bb: BasicBlock) { + if !self.visited.insert(bb) { + return; + } + let data = &self.basic_blocks[bb]; + self.locals.visit_basic_block_data(bb, data); + let successors = data.mono_successors(self.tcx, self.instance); + self.visit_stack.push((bb, successors)); + } + + fn traverse_successor(&mut self) { + while let Some(bb) = self.visit_stack.last_mut().and_then(|(_, iter)| iter.next_back()) { + self.visit(bb); + } + } +} + +impl<'tcx> Iterator for MonoReachablePostorder<'_, 'tcx> { + type Item = BasicBlock; + + fn next(&mut self) -> Option<BasicBlock> { + let (bb, _) = self.visit_stack.pop()?; + self.traverse_successor(); + Some(bb) + } +} + +pub fn mono_reachable_reverse_postorder<'a, 'tcx>( + body: &'a Body<'tcx>, + tcx: TyCtxt<'tcx>, + instance: Instance<'tcx>, +) -> (Vec<BasicBlock>, BitSet<Local>) { + let mut iter = MonoReachablePostorder::new(body, tcx, instance); + let mut items = Vec::with_capacity(body.basic_blocks.len()); + while let Some(block) = iter.next() { + items.push(block); + } + items.reverse(); + (items, iter.locals.0) +} + /// Returns an iterator over all basic blocks reachable from the `START_BLOCK` in no particular /// order. /// @@ -358,14 +443,8 @@ impl<'a, 'tcx> Iterator for MonoReachable<'a, 'tcx> { let data = &self.body[idx]; - if let Some((bits, targets)) = - Body::try_const_mono_switchint(self.tcx, self.instance, data) - { - let target = targets.target_for_value(bits); - self.add_work([target]); - } else { - self.add_work(data.terminator().successors()); - } + let targets = data.mono_successors(self.tcx, self.instance); + self.add_work(targets); return Some((idx, data)); } |
