diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2018-08-22 07:41:59 -0400 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2018-08-27 13:57:55 -0400 |
| commit | 09feec6d5c2e928c0f154d6ada902334e59acf77 (patch) | |
| tree | 0f68973478bc3e4af2dcde1d0cae74ec4f361d8e | |
| parent | 7eec37b2f94206f40f554266e26f2441a266285a (diff) | |
| download | rust-09feec6d5c2e928c0f154d6ada902334e59acf77.tar.gz rust-09feec6d5c2e928c0f154d6ada902334e59acf77.zip | |
make `to_location` O(1)
| -rw-r--r-- | src/librustc_mir/borrow_check/nll/region_infer/values.rs | 65 |
1 files changed, 23 insertions, 42 deletions
diff --git a/src/librustc_mir/borrow_check/nll/region_infer/values.rs b/src/librustc_mir/borrow_check/nll/region_infer/values.rs index 554338c3e00..ae5d5790673 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/values.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/values.rs @@ -21,14 +21,9 @@ crate struct RegionValueElements { /// For each basic block, how many points are contained within? statements_before_block: IndexVec<BasicBlock, usize>, - /// Map backward from each point into to one of two possible values: - /// - /// - `None`: if this point index represents a Location with non-zero index - /// - `Some(bb)`: if this point index represents a Location with zero index - /// - /// NB. It may be better to just map back to a full `Location`. We - /// should probably try that. - basic_block_heads: IndexVec<PointIndex, Option<BasicBlock>>, + /// Map backward from each point to the basic block that it + /// belongs to. + basic_blocks: IndexVec<PointIndex, BasicBlock>, num_points: usize, } @@ -51,16 +46,14 @@ impl RegionValueElements { ); debug!("RegionValueElements: num_points={:#?}", num_points); - let mut basic_block_heads: IndexVec<PointIndex, Option<BasicBlock>> = - (0..num_points).map(|_| None).collect(); - for (bb, &first_point) in statements_before_block.iter_enumerated() { - let first_point = PointIndex::new(first_point); - basic_block_heads[first_point] = Some(bb); + let mut basic_blocks = IndexVec::with_capacity(num_points); + for (bb, bb_data) in mir.basic_blocks().iter_enumerated() { + basic_blocks.extend((0 .. bb_data.statements.len() + 1).map(|_| bb)); } Self { statements_before_block, - basic_block_heads, + basic_blocks, num_points, } } @@ -86,22 +79,13 @@ impl RegionValueElements { PointIndex::new(start_index) } - /// Converts a `PointIndex` back to a location. O(N) where N is - /// the number of blocks; could be faster if we ever cared. + /// Converts a `PointIndex` back to a location. O(1). crate fn to_location(&self, index: PointIndex) -> Location { assert!(index.index() < self.num_points); - - let mut statement_index = 0; - - for opt_bb in self.basic_block_heads.raw[..= index.index()].iter().rev() { - if let &Some(block) = opt_bb { - return Location { block, statement_index }; - } - - statement_index += 1; - } - - bug!("did not find basic block as expected for index = {:?}", index) + let block = self.basic_blocks[index]; + let start_index = self.statements_before_block[block]; + let statement_index = index.index() - start_index; + Location { block, statement_index } } /// Sometimes we get point-indices back from bitsets that may be @@ -119,23 +103,20 @@ impl RegionValueElements { index: PointIndex, stack: &mut Vec<PointIndex>, ) { - match self.basic_block_heads[index] { + let Location { block, statement_index } = self.to_location(index); + if statement_index == 0 { // If this is a basic block head, then the predecessors are // the the terminators of other basic blocks - Some(bb_head) => { - stack.extend( - mir - .predecessors_for(bb_head) - .iter() - .map(|&pred_bb| mir.terminator_loc(pred_bb)) - .map(|pred_loc| self.point_from_location(pred_loc)), - ); - } - + stack.extend( + mir + .predecessors_for(block) + .iter() + .map(|&pred_bb| mir.terminator_loc(pred_bb)) + .map(|pred_loc| self.point_from_location(pred_loc)), + ); + } else { // Otherwise, the pred is just the previous statement - None => { - stack.push(PointIndex::new(index.index() - 1)); - } + stack.push(PointIndex::new(index.index() - 1)); } } } |
