Skip to content

Commit 09feec6

Browse files
committed
make to_location O(1)
1 parent 7eec37b commit 09feec6

File tree

1 file changed

+23
-42
lines changed
  • src/librustc_mir/borrow_check/nll/region_infer

1 file changed

+23
-42
lines changed

src/librustc_mir/borrow_check/nll/region_infer/values.rs

+23-42
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,9 @@ crate struct RegionValueElements {
2121
/// For each basic block, how many points are contained within?
2222
statements_before_block: IndexVec<BasicBlock, usize>,
2323

24-
/// Map backward from each point into to one of two possible values:
25-
///
26-
/// - `None`: if this point index represents a Location with non-zero index
27-
/// - `Some(bb)`: if this point index represents a Location with zero index
28-
///
29-
/// NB. It may be better to just map back to a full `Location`. We
30-
/// should probably try that.
31-
basic_block_heads: IndexVec<PointIndex, Option<BasicBlock>>,
24+
/// Map backward from each point to the basic block that it
25+
/// belongs to.
26+
basic_blocks: IndexVec<PointIndex, BasicBlock>,
3227

3328
num_points: usize,
3429
}
@@ -51,16 +46,14 @@ impl RegionValueElements {
5146
);
5247
debug!("RegionValueElements: num_points={:#?}", num_points);
5348

54-
let mut basic_block_heads: IndexVec<PointIndex, Option<BasicBlock>> =
55-
(0..num_points).map(|_| None).collect();
56-
for (bb, &first_point) in statements_before_block.iter_enumerated() {
57-
let first_point = PointIndex::new(first_point);
58-
basic_block_heads[first_point] = Some(bb);
49+
let mut basic_blocks = IndexVec::with_capacity(num_points);
50+
for (bb, bb_data) in mir.basic_blocks().iter_enumerated() {
51+
basic_blocks.extend((0 .. bb_data.statements.len() + 1).map(|_| bb));
5952
}
6053

6154
Self {
6255
statements_before_block,
63-
basic_block_heads,
56+
basic_blocks,
6457
num_points,
6558
}
6659
}
@@ -86,22 +79,13 @@ impl RegionValueElements {
8679
PointIndex::new(start_index)
8780
}
8881

89-
/// Converts a `PointIndex` back to a location. O(N) where N is
90-
/// the number of blocks; could be faster if we ever cared.
82+
/// Converts a `PointIndex` back to a location. O(1).
9183
crate fn to_location(&self, index: PointIndex) -> Location {
9284
assert!(index.index() < self.num_points);
93-
94-
let mut statement_index = 0;
95-
96-
for opt_bb in self.basic_block_heads.raw[..= index.index()].iter().rev() {
97-
if let &Some(block) = opt_bb {
98-
return Location { block, statement_index };
99-
}
100-
101-
statement_index += 1;
102-
}
103-
104-
bug!("did not find basic block as expected for index = {:?}", index)
85+
let block = self.basic_blocks[index];
86+
let start_index = self.statements_before_block[block];
87+
let statement_index = index.index() - start_index;
88+
Location { block, statement_index }
10589
}
10690

10791
/// Sometimes we get point-indices back from bitsets that may be
@@ -119,23 +103,20 @@ impl RegionValueElements {
119103
index: PointIndex,
120104
stack: &mut Vec<PointIndex>,
121105
) {
122-
match self.basic_block_heads[index] {
106+
let Location { block, statement_index } = self.to_location(index);
107+
if statement_index == 0 {
123108
// If this is a basic block head, then the predecessors are
124109
// the the terminators of other basic blocks
125-
Some(bb_head) => {
126-
stack.extend(
127-
mir
128-
.predecessors_for(bb_head)
129-
.iter()
130-
.map(|&pred_bb| mir.terminator_loc(pred_bb))
131-
.map(|pred_loc| self.point_from_location(pred_loc)),
132-
);
133-
}
134-
110+
stack.extend(
111+
mir
112+
.predecessors_for(block)
113+
.iter()
114+
.map(|&pred_bb| mir.terminator_loc(pred_bb))
115+
.map(|pred_loc| self.point_from_location(pred_loc)),
116+
);
117+
} else {
135118
// Otherwise, the pred is just the previous statement
136-
None => {
137-
stack.push(PointIndex::new(index.index() - 1));
138-
}
119+
stack.push(PointIndex::new(index.index() - 1));
139120
}
140121
}
141122
}

0 commit comments

Comments
 (0)