Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 6ee42d5

Browse files
committedMar 4, 2025
Auto merge of rust-lang#137923 - scottmcm:fix-postorder-size-hint, r=<try>
Simplify `<Postorder as Iterator>::size_hint` The current version is sometimes malformed (cc rust-lang#137919); let's see if we can get away with a loose but trivially-correct one.
2 parents 2010bba + fe6cf34 commit 6ee42d5

File tree

1 file changed

+11
-26
lines changed

1 file changed

+11
-26
lines changed
 

‎compiler/rustc_middle/src/mir/traversal.rs

+11-26
Original file line numberDiff line numberDiff line change
@@ -23,19 +23,13 @@ pub struct Preorder<'a, 'tcx> {
2323
body: &'a Body<'tcx>,
2424
visited: DenseBitSet<BasicBlock>,
2525
worklist: Vec<BasicBlock>,
26-
root_is_start_block: bool,
2726
}
2827

2928
impl<'a, 'tcx> Preorder<'a, 'tcx> {
3029
pub fn new(body: &'a Body<'tcx>, root: BasicBlock) -> Preorder<'a, 'tcx> {
3130
let worklist = vec![root];
3231

33-
Preorder {
34-
body,
35-
visited: DenseBitSet::new_empty(body.basic_blocks.len()),
36-
worklist,
37-
root_is_start_block: root == START_BLOCK,
38-
}
32+
Preorder { body, visited: DenseBitSet::new_empty(body.basic_blocks.len()), worklist }
3933
}
4034
}
4135

@@ -71,15 +65,11 @@ impl<'a, 'tcx> Iterator for Preorder<'a, 'tcx> {
7165
}
7266

7367
fn size_hint(&self) -> (usize, Option<usize>) {
74-
// All the blocks, minus the number of blocks we've visited.
75-
let upper = self.body.basic_blocks.len() - self.visited.count();
68+
// The worklist might be only things already visited.
69+
let lower = 0;
7670

77-
let lower = if self.root_is_start_block {
78-
// We will visit all remaining blocks exactly once.
79-
upper
80-
} else {
81-
self.worklist.len()
82-
};
71+
// This is extremely loose, but it's not worth a popcnt loop to do better.
72+
let upper = self.body.basic_blocks.len();
8373

8474
(lower, Some(upper))
8575
}
@@ -108,7 +98,6 @@ pub struct Postorder<'a, 'tcx> {
10898
basic_blocks: &'a IndexSlice<BasicBlock, BasicBlockData<'tcx>>,
10999
visited: DenseBitSet<BasicBlock>,
110100
visit_stack: Vec<(BasicBlock, Successors<'a>)>,
111-
root_is_start_block: bool,
112101
/// A non-empty `extra` allows for a precise calculation of the successors.
113102
extra: Option<(TyCtxt<'tcx>, Instance<'tcx>)>,
114103
}
@@ -123,7 +112,6 @@ impl<'a, 'tcx> Postorder<'a, 'tcx> {
123112
basic_blocks,
124113
visited: DenseBitSet::new_empty(basic_blocks.len()),
125114
visit_stack: Vec::new(),
126-
root_is_start_block: root == START_BLOCK,
127115
extra,
128116
};
129117

@@ -211,16 +199,13 @@ impl<'tcx> Iterator for Postorder<'_, 'tcx> {
211199
}
212200

213201
fn size_hint(&self) -> (usize, Option<usize>) {
214-
// All the blocks, minus the number of blocks we've visited.
215-
let upper = self.basic_blocks.len() - self.visited.count();
216-
217-
let lower = if self.root_is_start_block {
218-
// We will visit all remaining blocks exactly once.
219-
upper
220-
} else {
221-
self.visit_stack.len()
222-
};
202+
// These bounds are not at all tight, but that's fine.
203+
// It's not worth a popcnt loop in `DenseBitSet` to improve the upper,
204+
// and in mono-reachable we can't be precise anyway.
205+
// Leaning on amortized growth is fine.
223206

207+
let lower = self.visit_stack.len();
208+
let upper = self.basic_blocks.len();
224209
(lower, Some(upper))
225210
}
226211
}

0 commit comments

Comments
 (0)
Failed to load comments.