diff options
| author | Tomasz Miąsko <tomasz.miasko@gmail.com> | 2022-07-04 00:00:00 +0000 |
|---|---|---|
| committer | Tomasz Miąsko <tomasz.miasko@gmail.com> | 2022-07-07 08:11:49 +0200 |
| commit | c9dd1d9983b9a08159c2e3c86071d1a5ef7ebb20 (patch) | |
| tree | 821f63c3785e5599f0252939c2289414b947d530 /compiler/rustc_middle/src/mir/traversal.rs | |
| parent | fac8fa56726f7a5b2d4880a4719c5f99beec8328 (diff) | |
| download | rust-c9dd1d9983b9a08159c2e3c86071d1a5ef7ebb20.tar.gz rust-c9dd1d9983b9a08159c2e3c86071d1a5ef7ebb20.zip | |
Make MIR basic blocks field public
This makes it possible to mutably borrow different fields of the MIR body without resorting to methods like `basic_blocks_local_decls_mut_and_var_debug_info`. To preserve validity of control flow graph caches in the presence of modifications, a new struct `BasicBlocks` wraps together basic blocks and control flow graph caches. The `BasicBlocks` dereferences to `IndexVec<BasicBlock, BasicBlockData>`. On the other hand a mutable access requires explicit `as_mut()` call.
Diffstat (limited to 'compiler/rustc_middle/src/mir/traversal.rs')
| -rw-r--r-- | compiler/rustc_middle/src/mir/traversal.rs | 31 |
1 files changed, 15 insertions, 16 deletions
diff --git a/compiler/rustc_middle/src/mir/traversal.rs b/compiler/rustc_middle/src/mir/traversal.rs index 30648679dae..627dc32f37e 100644 --- a/compiler/rustc_middle/src/mir/traversal.rs +++ b/compiler/rustc_middle/src/mir/traversal.rs @@ -104,22 +104,25 @@ impl<'a, 'tcx> Iterator for Preorder<'a, 'tcx> { /// /// A Postorder traversal of this graph is `D B C A` or `D C B A` pub struct Postorder<'a, 'tcx> { - body: &'a Body<'tcx>, + basic_blocks: &'a IndexVec<BasicBlock, BasicBlockData<'tcx>>, visited: BitSet<BasicBlock>, visit_stack: Vec<(BasicBlock, Successors<'a>)>, root_is_start_block: bool, } impl<'a, 'tcx> Postorder<'a, 'tcx> { - pub fn new(body: &'a Body<'tcx>, root: BasicBlock) -> Postorder<'a, 'tcx> { + pub fn new( + basic_blocks: &'a IndexVec<BasicBlock, BasicBlockData<'tcx>>, + root: BasicBlock, + ) -> Postorder<'a, 'tcx> { let mut po = Postorder { - body, - visited: BitSet::new_empty(body.basic_blocks().len()), + basic_blocks, + visited: BitSet::new_empty(basic_blocks.len()), visit_stack: Vec::new(), root_is_start_block: root == START_BLOCK, }; - let data = &po.body[root]; + let data = &po.basic_blocks[root]; if let Some(ref term) = data.terminator { po.visited.insert(root); @@ -190,7 +193,7 @@ impl<'a, 'tcx> Postorder<'a, 'tcx> { }; if self.visited.insert(bb) { - if let Some(term) = &self.body[bb].terminator { + if let Some(term) = &self.basic_blocks[bb].terminator { self.visit_stack.push((bb, term.successors())); } } @@ -199,7 +202,7 @@ impl<'a, 'tcx> Postorder<'a, 'tcx> { } pub fn postorder<'a, 'tcx>(body: &'a Body<'tcx>) -> Postorder<'a, 'tcx> { - Postorder::new(body, START_BLOCK) + Postorder::new(&body.basic_blocks, START_BLOCK) } impl<'a, 'tcx> Iterator for Postorder<'a, 'tcx> { @@ -211,12 +214,12 @@ impl<'a, 'tcx> Iterator for Postorder<'a, 'tcx> { self.traverse_successor(); } - next.map(|(bb, _)| (bb, &self.body[bb])) + next.map(|(bb, _)| (bb, &self.basic_blocks[bb])) } fn size_hint(&self) -> (usize, Option<usize>) { // All the blocks, minus the number of blocks we've visited. - let upper = self.body.basic_blocks().len() - self.visited.count(); + let upper = self.basic_blocks.len() - self.visited.count(); let lower = if self.root_is_start_block { // We will visit all remaining blocks exactly once. @@ -263,10 +266,8 @@ pub struct ReversePostorder<'a, 'tcx> { impl<'a, 'tcx> ReversePostorder<'a, 'tcx> { pub fn new(body: &'a Body<'tcx>, root: BasicBlock) -> ReversePostorder<'a, 'tcx> { - let blocks: Vec<_> = Postorder::new(body, root).map(|(bb, _)| bb).collect(); - + let blocks: Vec<_> = Postorder::new(&body.basic_blocks, root).map(|(bb, _)| bb).collect(); let len = blocks.len(); - ReversePostorder { body, blocks, idx: len } } } @@ -334,10 +335,8 @@ impl<'a, 'tcx> Iterator for ReversePostorderIter<'a, 'tcx> { impl<'a, 'tcx> ExactSizeIterator for ReversePostorderIter<'a, 'tcx> {} pub fn reverse_postorder<'a, 'tcx>(body: &'a Body<'tcx>) -> ReversePostorderIter<'a, 'tcx> { - let blocks = body.postorder_cache.compute(body); - + let blocks = body.basic_blocks.postorder(); let len = blocks.len(); - ReversePostorderIter { body, blocks, idx: len } } @@ -360,7 +359,7 @@ impl PostorderCache { /// Returns the `&[BasicBlocks]` represents the postorder graph for this MIR. #[inline] - pub(super) fn compute(&self, body: &Body<'_>) -> &[BasicBlock] { + pub(super) fn compute(&self, body: &IndexVec<BasicBlock, BasicBlockData<'_>>) -> &[BasicBlock] { self.cache.get_or_init(|| Postorder::new(body, START_BLOCK).map(|(bb, _)| bb).collect()) } } |
