about summary refs log tree commit diff
path: root/compiler/rustc_middle/src/mir/traversal.rs
diff options
context:
space:
mode:
authorTomasz Miąsko <tomasz.miasko@gmail.com>2022-07-04 00:00:00 +0000
committerTomasz Miąsko <tomasz.miasko@gmail.com>2022-07-07 08:11:49 +0200
commitc9dd1d9983b9a08159c2e3c86071d1a5ef7ebb20 (patch)
tree821f63c3785e5599f0252939c2289414b947d530 /compiler/rustc_middle/src/mir/traversal.rs
parentfac8fa56726f7a5b2d4880a4719c5f99beec8328 (diff)
downloadrust-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.rs31
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())
     }
 }