@@ -8,6 +8,7 @@ use rustc_index::Idx;
8
8
use rustc_index:: IndexVec ;
9
9
use rustc_middle:: mir:: { BasicBlock , Body , Location } ;
10
10
use rustc_middle:: ty:: { self , RegionVid } ;
11
+ use std:: collections:: BTreeSet ;
11
12
use std:: fmt:: Debug ;
12
13
use std:: rc:: Rc ;
13
14
@@ -125,8 +126,13 @@ pub(crate) struct LivenessValues {
125
126
/// The map from locations to points.
126
127
elements : Rc < RegionValueElements > ,
127
128
129
+ live_regions : BTreeSet < RegionVid > ,
130
+
128
131
/// For each region: the points where it is live.
129
- points : SparseIntervalMatrix < RegionVid , PointIndex > ,
132
+ ///
133
+ /// This is not initialized for promoteds, because we don't care *where* within a promoted a
134
+ /// region is live, only that it is.
135
+ points : Option < SparseIntervalMatrix < RegionVid , PointIndex > > ,
130
136
131
137
/// When using `-Zpolonius=next`, for each point: the loans flowing into the live regions at
132
138
/// that point.
@@ -155,24 +161,38 @@ impl LiveLoans {
155
161
156
162
impl LivenessValues {
157
163
/// Create an empty map of regions to locations where they're live.
158
- pub ( crate ) fn new ( elements : Rc < RegionValueElements > ) -> Self {
164
+ pub ( crate ) fn with_specific_points ( elements : Rc < RegionValueElements > ) -> Self {
159
165
LivenessValues {
160
- points : SparseIntervalMatrix :: new ( elements. num_points ) ,
166
+ live_regions : BTreeSet :: new ( ) ,
167
+ points : Some ( SparseIntervalMatrix :: new ( elements. num_points ) ) ,
161
168
elements,
162
169
loans : None ,
163
170
}
164
171
}
165
172
173
+ /// Create an empty map of regions to locations where they're live.
174
+ ///
175
+ /// Unlike `with_specific_points`, does not track exact locations where something is live, only
176
+ /// which regions are live.
177
+ pub ( crate ) fn without_specific_points ( elements : Rc < RegionValueElements > ) -> Self {
178
+ LivenessValues { live_regions : BTreeSet :: new ( ) , points : None , elements, loans : None }
179
+ }
180
+
166
181
/// Iterate through each region that has a value in this set.
167
- pub ( crate ) fn regions ( & self ) -> impl Iterator < Item = RegionVid > {
168
- self . points . rows ( )
182
+ pub ( crate ) fn regions ( & self ) -> impl Iterator < Item = RegionVid > + ' _ {
183
+ self . live_regions . iter ( ) . copied ( )
169
184
}
170
185
171
186
/// Records `region` as being live at the given `location`.
172
187
pub ( crate ) fn add_location ( & mut self , region : RegionVid , location : Location ) {
173
- debug ! ( "LivenessValues::add_location(region={:?}, location={:?})" , region, location) ;
174
188
let point = self . elements . point_from_location ( location) ;
175
- self . points . insert ( region, point) ;
189
+ debug ! ( "LivenessValues::add_location(region={:?}, location={:?})" , region, location) ;
190
+ if self . elements . point_in_range ( point) {
191
+ self . live_regions . insert ( region) ;
192
+ }
193
+ if let Some ( points) = & mut self . points {
194
+ points. insert ( region, point) ;
195
+ }
176
196
177
197
// When available, record the loans flowing into this region as live at the given point.
178
198
if let Some ( loans) = self . loans . as_mut ( ) {
@@ -185,7 +205,12 @@ impl LivenessValues {
185
205
/// Records `region` as being live at all the given `points`.
186
206
pub ( crate ) fn add_points ( & mut self , region : RegionVid , points : & IntervalSet < PointIndex > ) {
187
207
debug ! ( "LivenessValues::add_points(region={:?}, points={:?})" , region, points) ;
188
- self . points . union_row ( region, points) ;
208
+ if points. iter ( ) . any ( |point| self . elements . point_in_range ( point) ) {
209
+ self . live_regions . insert ( region) ;
210
+ }
211
+ if let Some ( this) = & mut self . points {
212
+ this. union_row ( region, points) ;
213
+ }
189
214
190
215
// When available, record the loans flowing into this region as live at the given points.
191
216
if let Some ( loans) = self . loans . as_mut ( ) {
@@ -201,23 +226,37 @@ impl LivenessValues {
201
226
202
227
/// Records `region` as being live at all the control-flow points.
203
228
pub ( crate ) fn add_all_points ( & mut self , region : RegionVid ) {
204
- self . points . insert_all_into_row ( region) ;
229
+ if let Some ( points) = & mut self . points {
230
+ points. insert_all_into_row ( region) ;
231
+ }
232
+ self . live_regions . insert ( region) ;
205
233
}
206
234
207
235
/// Returns whether `region` is marked live at the given `location`.
208
236
pub ( crate ) fn is_live_at ( & self , region : RegionVid , location : Location ) -> bool {
209
237
let point = self . elements . point_from_location ( location) ;
210
- self . points . row ( region) . is_some_and ( |r| r. contains ( point) )
238
+ if let Some ( points) = & self . points {
239
+ points. row ( region) . is_some_and ( |r| r. contains ( point) )
240
+ } else {
241
+ unreachable ! (
242
+ "Should be using LivenessValues::with_specific_points to ask whether live at a location"
243
+ )
244
+ }
211
245
}
212
246
213
247
/// Returns whether `region` is marked live at any location.
214
248
pub ( crate ) fn is_live_anywhere ( & self , region : RegionVid ) -> bool {
215
- self . live_points ( region ) . next ( ) . is_some ( )
249
+ self . live_regions . contains ( & region )
216
250
}
217
251
218
252
/// Returns an iterator of all the points where `region` is live.
219
253
fn live_points ( & self , region : RegionVid ) -> impl Iterator < Item = PointIndex > + ' _ {
220
- self . points
254
+ let Some ( points) = & self . points else {
255
+ unreachable ! (
256
+ "Should be using LivenessValues::with_specific_points to ask whether live at a location"
257
+ )
258
+ } ;
259
+ points
221
260
. row ( region)
222
261
. into_iter ( )
223
262
. flat_map ( |set| set. iter ( ) )
@@ -372,7 +411,10 @@ impl<N: Idx> RegionValues<N> {
372
411
/// elements for the region `from` from `values` and add them to
373
412
/// the region `to` in `self`.
374
413
pub ( crate ) fn merge_liveness ( & mut self , to : N , from : RegionVid , values : & LivenessValues ) {
375
- if let Some ( set) = values. points . row ( from) {
414
+ let Some ( value_points) = & values. points else {
415
+ panic ! ( "LivenessValues must track specific points for use in merge_liveness" ) ;
416
+ } ;
417
+ if let Some ( set) = value_points. row ( from) {
376
418
self . points . union_row ( to, set) ;
377
419
}
378
420
}
0 commit comments