about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJubilee <workingjubilee@gmail.com>2025-03-04 19:37:01 -0800
committerGitHub <noreply@github.com>2025-03-04 19:37:01 -0800
commit81a4349e73bcec82cbd7cbeda7dca337fddab92d (patch)
tree7ac69ef038811b4132f82e9fc5d13cedbd66baa6
parentb3d7c1483da2172644b15a923ffb001960e8feb1 (diff)
parentfe6cf341479c91ef90d8c809aea70193ed42036a (diff)
downloadrust-81a4349e73bcec82cbd7cbeda7dca337fddab92d.tar.gz
rust-81a4349e73bcec82cbd7cbeda7dca337fddab92d.zip
Rollup merge of #137923 - scottmcm:fix-postorder-size-hint, r=tmiasko
Simplify `<Postorder as Iterator>::size_hint`

The current version is sometimes malformed (cc #137919); let's see if we can get away with a loose but trivially-correct one.
-rw-r--r--compiler/rustc_middle/src/mir/traversal.rs37
1 files changed, 11 insertions, 26 deletions
diff --git a/compiler/rustc_middle/src/mir/traversal.rs b/compiler/rustc_middle/src/mir/traversal.rs
index 5950ac295af..9308570d89d 100644
--- a/compiler/rustc_middle/src/mir/traversal.rs
+++ b/compiler/rustc_middle/src/mir/traversal.rs
@@ -23,19 +23,13 @@ pub struct Preorder<'a, 'tcx> {
     body: &'a Body<'tcx>,
     visited: DenseBitSet<BasicBlock>,
     worklist: Vec<BasicBlock>,
-    root_is_start_block: bool,
 }
 
 impl<'a, 'tcx> Preorder<'a, 'tcx> {
     pub fn new(body: &'a Body<'tcx>, root: BasicBlock) -> Preorder<'a, 'tcx> {
         let worklist = vec![root];
 
-        Preorder {
-            body,
-            visited: DenseBitSet::new_empty(body.basic_blocks.len()),
-            worklist,
-            root_is_start_block: root == START_BLOCK,
-        }
+        Preorder { body, visited: DenseBitSet::new_empty(body.basic_blocks.len()), worklist }
     }
 }
 
@@ -71,15 +65,11 @@ impl<'a, 'tcx> Iterator for Preorder<'a, 'tcx> {
     }
 
     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();
+        // The worklist might be only things already visited.
+        let lower = 0;
 
-        let lower = if self.root_is_start_block {
-            // We will visit all remaining blocks exactly once.
-            upper
-        } else {
-            self.worklist.len()
-        };
+        // This is extremely loose, but it's not worth a popcnt loop to do better.
+        let upper = self.body.basic_blocks.len();
 
         (lower, Some(upper))
     }
@@ -108,7 +98,6 @@ pub struct Postorder<'a, 'tcx> {
     basic_blocks: &'a IndexSlice<BasicBlock, BasicBlockData<'tcx>>,
     visited: DenseBitSet<BasicBlock>,
     visit_stack: Vec<(BasicBlock, Successors<'a>)>,
-    root_is_start_block: bool,
     /// A non-empty `extra` allows for a precise calculation of the successors.
     extra: Option<(TyCtxt<'tcx>, Instance<'tcx>)>,
 }
@@ -123,7 +112,6 @@ impl<'a, 'tcx> Postorder<'a, 'tcx> {
             basic_blocks,
             visited: DenseBitSet::new_empty(basic_blocks.len()),
             visit_stack: Vec::new(),
-            root_is_start_block: root == START_BLOCK,
             extra,
         };
 
@@ -211,16 +199,13 @@ impl<'tcx> Iterator for Postorder<'_, 'tcx> {
     }
 
     fn size_hint(&self) -> (usize, Option<usize>) {
-        // All the blocks, minus the number of blocks we've visited.
-        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.
-            upper
-        } else {
-            self.visit_stack.len()
-        };
+        // These bounds are not at all tight, but that's fine.
+        // It's not worth a popcnt loop in `DenseBitSet` to improve the upper,
+        // and in mono-reachable we can't be precise anyway.
+        // Leaning on amortized growth is fine.
 
+        let lower = self.visit_stack.len();
+        let upper = self.basic_blocks.len();
         (lower, Some(upper))
     }
 }