@@ -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