1
1
#![ deny( rustc:: untranslatable_diagnostic) ]
2
2
#![ deny( rustc:: diagnostic_outside_of_impl) ]
3
+ use rustc_data_structures:: fx:: FxHashSet ;
3
4
use rustc_data_structures:: fx:: FxIndexSet ;
4
5
use rustc_index:: bit_set:: SparseBitMatrix ;
5
6
use rustc_index:: interval:: IntervalSet ;
@@ -125,8 +126,15 @@ pub(crate) struct LivenessValues {
125
126
/// The map from locations to points.
126
127
elements : Rc < RegionValueElements > ,
127
128
129
+ /// Which regions are live. This is exclusive with the fine-grained tracking in `points`, and
130
+ /// currently only used for validating promoteds (which don't care about more precise tracking).
131
+ live_regions : Option < FxHashSet < RegionVid > > ,
132
+
128
133
/// For each region: the points where it is live.
129
- points : SparseIntervalMatrix < RegionVid , PointIndex > ,
134
+ ///
135
+ /// This is not initialized for promoteds, because we don't care *where* within a promoted a
136
+ /// region is live, only that it is.
137
+ points : Option < SparseIntervalMatrix < RegionVid , PointIndex > > ,
130
138
131
139
/// When using `-Zpolonius=next`, for each point: the loans flowing into the live regions at
132
140
/// that point.
@@ -155,24 +163,52 @@ impl LiveLoans {
155
163
156
164
impl LivenessValues {
157
165
/// Create an empty map of regions to locations where they're live.
158
- pub ( crate ) fn new ( elements : Rc < RegionValueElements > ) -> Self {
166
+ pub ( crate ) fn with_specific_points ( elements : Rc < RegionValueElements > ) -> Self {
159
167
LivenessValues {
160
- points : SparseIntervalMatrix :: new ( elements. num_points ) ,
168
+ live_regions : None ,
169
+ points : Some ( SparseIntervalMatrix :: new ( elements. num_points ) ) ,
170
+ elements,
171
+ loans : None ,
172
+ }
173
+ }
174
+
175
+ /// Create an empty map of regions to locations where they're live.
176
+ ///
177
+ /// Unlike `with_specific_points`, does not track exact locations where something is live, only
178
+ /// which regions are live.
179
+ pub ( crate ) fn without_specific_points ( elements : Rc < RegionValueElements > ) -> Self {
180
+ LivenessValues {
181
+ live_regions : Some ( Default :: default ( ) ) ,
182
+ points : None ,
161
183
elements,
162
184
loans : None ,
163
185
}
164
186
}
165
187
166
188
/// 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 ( )
189
+ pub ( crate ) fn regions ( & self ) -> impl Iterator < Item = RegionVid > + ' _ {
190
+ self . points . as_ref ( ) . expect ( "use with_specific_points" ) . rows ( )
191
+ }
192
+
193
+ /// Iterate through each region that has a value in this set.
194
+ // We are passing query instability implications to the caller.
195
+ #[ rustc_lint_query_instability]
196
+ #[ allow( rustc:: potential_query_instability) ]
197
+ pub ( crate ) fn live_regions_unordered ( & self ) -> impl Iterator < Item = RegionVid > + ' _ {
198
+ self . live_regions . as_ref ( ) . unwrap ( ) . iter ( ) . copied ( )
169
199
}
170
200
171
201
/// Records `region` as being live at the given `location`.
172
202
pub ( crate ) fn add_location ( & mut self , region : RegionVid , location : Location ) {
173
- debug ! ( "LivenessValues::add_location(region={:?}, location={:?})" , region, location) ;
174
203
let point = self . elements . point_from_location ( location) ;
175
- self . points . insert ( region, point) ;
204
+ debug ! ( "LivenessValues::add_location(region={:?}, location={:?})" , region, location) ;
205
+ if let Some ( points) = & mut self . points {
206
+ points. insert ( region, point) ;
207
+ } else {
208
+ if self . elements . point_in_range ( point) {
209
+ self . live_regions . as_mut ( ) . unwrap ( ) . insert ( region) ;
210
+ }
211
+ }
176
212
177
213
// When available, record the loans flowing into this region as live at the given point.
178
214
if let Some ( loans) = self . loans . as_mut ( ) {
@@ -185,7 +221,13 @@ impl LivenessValues {
185
221
/// Records `region` as being live at all the given `points`.
186
222
pub ( crate ) fn add_points ( & mut self , region : RegionVid , points : & IntervalSet < PointIndex > ) {
187
223
debug ! ( "LivenessValues::add_points(region={:?}, points={:?})" , region, points) ;
188
- self . points . union_row ( region, points) ;
224
+ if let Some ( this) = & mut self . points {
225
+ this. union_row ( region, points) ;
226
+ } else {
227
+ if points. iter ( ) . any ( |point| self . elements . point_in_range ( point) ) {
228
+ self . live_regions . as_mut ( ) . unwrap ( ) . insert ( region) ;
229
+ }
230
+ }
189
231
190
232
// When available, record the loans flowing into this region as live at the given points.
191
233
if let Some ( loans) = self . loans . as_mut ( ) {
@@ -201,23 +243,33 @@ impl LivenessValues {
201
243
202
244
/// Records `region` as being live at all the control-flow points.
203
245
pub ( crate ) fn add_all_points ( & mut self , region : RegionVid ) {
204
- self . points . insert_all_into_row ( region) ;
246
+ if let Some ( points) = & mut self . points {
247
+ points. insert_all_into_row ( region) ;
248
+ } else {
249
+ self . live_regions . as_mut ( ) . unwrap ( ) . insert ( region) ;
250
+ }
205
251
}
206
252
207
253
/// Returns whether `region` is marked live at the given `location`.
208
254
pub ( crate ) fn is_live_at ( & self , region : RegionVid , location : Location ) -> bool {
209
255
let point = self . elements . point_from_location ( location) ;
210
- self . points . row ( region) . is_some_and ( |r| r. contains ( point) )
211
- }
212
-
213
- /// Returns whether `region` is marked live at any location.
214
- pub ( crate ) fn is_live_anywhere ( & self , region : RegionVid ) -> bool {
215
- self . live_points ( region) . next ( ) . is_some ( )
256
+ if let Some ( points) = & self . points {
257
+ points. row ( region) . is_some_and ( |r| r. contains ( point) )
258
+ } else {
259
+ unreachable ! (
260
+ "Should be using LivenessValues::with_specific_points to ask whether live at a location"
261
+ )
262
+ }
216
263
}
217
264
218
265
/// Returns an iterator of all the points where `region` is live.
219
266
fn live_points ( & self , region : RegionVid ) -> impl Iterator < Item = PointIndex > + ' _ {
220
- self . points
267
+ let Some ( points) = & self . points else {
268
+ unreachable ! (
269
+ "Should be using LivenessValues::with_specific_points to ask whether live at a location"
270
+ )
271
+ } ;
272
+ points
221
273
. row ( region)
222
274
. into_iter ( )
223
275
. flat_map ( |set| set. iter ( ) )
@@ -372,7 +424,10 @@ impl<N: Idx> RegionValues<N> {
372
424
/// elements for the region `from` from `values` and add them to
373
425
/// the region `to` in `self`.
374
426
pub ( crate ) fn merge_liveness ( & mut self , to : N , from : RegionVid , values : & LivenessValues ) {
375
- if let Some ( set) = values. points . row ( from) {
427
+ let Some ( value_points) = & values. points else {
428
+ panic ! ( "LivenessValues must track specific points for use in merge_liveness" ) ;
429
+ } ;
430
+ if let Some ( set) = value_points. row ( from) {
376
431
self . points . union_row ( to, set) ;
377
432
}
378
433
}
0 commit comments