@@ -21,14 +21,9 @@ crate struct RegionValueElements {
21
21
/// For each basic block, how many points are contained within?
22
22
statements_before_block : IndexVec < BasicBlock , usize > ,
23
23
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 > ,
32
27
33
28
num_points : usize ,
34
29
}
@@ -51,16 +46,14 @@ impl RegionValueElements {
51
46
) ;
52
47
debug ! ( "RegionValueElements: num_points={:#?}" , num_points) ;
53
48
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) ) ;
59
52
}
60
53
61
54
Self {
62
55
statements_before_block,
63
- basic_block_heads ,
56
+ basic_blocks ,
64
57
num_points,
65
58
}
66
59
}
@@ -86,22 +79,13 @@ impl RegionValueElements {
86
79
PointIndex :: new ( start_index)
87
80
}
88
81
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).
91
83
crate fn to_location ( & self , index : PointIndex ) -> Location {
92
84
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 }
105
89
}
106
90
107
91
/// Sometimes we get point-indices back from bitsets that may be
@@ -119,23 +103,20 @@ impl RegionValueElements {
119
103
index : PointIndex ,
120
104
stack : & mut Vec < PointIndex > ,
121
105
) {
122
- match self . basic_block_heads [ index] {
106
+ let Location { block, statement_index } = self . to_location ( index) ;
107
+ if statement_index == 0 {
123
108
// If this is a basic block head, then the predecessors are
124
109
// 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 {
135
118
// 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 ) ) ;
139
120
}
140
121
}
141
122
}
0 commit comments