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 ;
@@ -41,8 +42,15 @@ pub(crate) struct LivenessValues {
41
42
/// The map from locations to points.
42
43
elements : Rc < DenseLocationMap > ,
43
44
45
+ /// Which regions are live. This is exclusive with the fine-grained tracking in `points`, and
46
+ /// currently only used for validating promoteds (which don't care about more precise tracking).
47
+ live_regions : Option < FxHashSet < RegionVid > > ,
48
+
44
49
/// For each region: the points where it is live.
45
- points : SparseIntervalMatrix < RegionVid , PointIndex > ,
50
+ ///
51
+ /// This is not initialized for promoteds, because we don't care *where* within a promoted a
52
+ /// region is live, only that it is.
53
+ points : Option < SparseIntervalMatrix < RegionVid , PointIndex > > ,
46
54
47
55
/// When using `-Zpolonius=next`, for each point: the loans flowing into the live regions at
48
56
/// that point.
@@ -71,24 +79,52 @@ impl LiveLoans {
71
79
72
80
impl LivenessValues {
73
81
/// Create an empty map of regions to locations where they're live.
74
- pub ( crate ) fn new ( elements : Rc < DenseLocationMap > ) -> Self {
82
+ pub ( crate ) fn with_specific_points ( elements : Rc < DenseLocationMap > ) -> Self {
75
83
LivenessValues {
76
- points : SparseIntervalMatrix :: new ( elements. num_points ( ) ) ,
84
+ live_regions : None ,
85
+ points : Some ( SparseIntervalMatrix :: new ( elements. num_points ( ) ) ) ,
86
+ elements,
87
+ loans : None ,
88
+ }
89
+ }
90
+
91
+ /// Create an empty map of regions to locations where they're live.
92
+ ///
93
+ /// Unlike `with_specific_points`, does not track exact locations where something is live, only
94
+ /// which regions are live.
95
+ pub ( crate ) fn without_specific_points ( elements : Rc < DenseLocationMap > ) -> Self {
96
+ LivenessValues {
97
+ live_regions : Some ( Default :: default ( ) ) ,
98
+ points : None ,
77
99
elements,
78
100
loans : None ,
79
101
}
80
102
}
81
103
82
104
/// Iterate through each region that has a value in this set.
83
- pub ( crate ) fn regions ( & self ) -> impl Iterator < Item = RegionVid > {
84
- self . points . rows ( )
105
+ pub ( crate ) fn regions ( & self ) -> impl Iterator < Item = RegionVid > + ' _ {
106
+ self . points . as_ref ( ) . expect ( "use with_specific_points" ) . rows ( )
107
+ }
108
+
109
+ /// Iterate through each region that has a value in this set.
110
+ // We are passing query instability implications to the caller.
111
+ #[ rustc_lint_query_instability]
112
+ #[ allow( rustc:: potential_query_instability) ]
113
+ pub ( crate ) fn live_regions_unordered ( & self ) -> impl Iterator < Item = RegionVid > + ' _ {
114
+ self . live_regions . as_ref ( ) . unwrap ( ) . iter ( ) . copied ( )
85
115
}
86
116
87
117
/// Records `region` as being live at the given `location`.
88
118
pub ( crate ) fn add_location ( & mut self , region : RegionVid , location : Location ) {
89
- debug ! ( "LivenessValues::add_location(region={:?}, location={:?})" , region, location) ;
90
119
let point = self . elements . point_from_location ( location) ;
91
- self . points . insert ( region, point) ;
120
+ debug ! ( "LivenessValues::add_location(region={:?}, location={:?})" , region, location) ;
121
+ if let Some ( points) = & mut self . points {
122
+ points. insert ( region, point) ;
123
+ } else {
124
+ if self . elements . point_in_range ( point) {
125
+ self . live_regions . as_mut ( ) . unwrap ( ) . insert ( region) ;
126
+ }
127
+ }
92
128
93
129
// When available, record the loans flowing into this region as live at the given point.
94
130
if let Some ( loans) = self . loans . as_mut ( ) {
@@ -101,7 +137,13 @@ impl LivenessValues {
101
137
/// Records `region` as being live at all the given `points`.
102
138
pub ( crate ) fn add_points ( & mut self , region : RegionVid , points : & IntervalSet < PointIndex > ) {
103
139
debug ! ( "LivenessValues::add_points(region={:?}, points={:?})" , region, points) ;
104
- self . points . union_row ( region, points) ;
140
+ if let Some ( this) = & mut self . points {
141
+ this. union_row ( region, points) ;
142
+ } else {
143
+ if points. iter ( ) . any ( |point| self . elements . point_in_range ( point) ) {
144
+ self . live_regions . as_mut ( ) . unwrap ( ) . insert ( region) ;
145
+ }
146
+ }
105
147
106
148
// When available, record the loans flowing into this region as live at the given points.
107
149
if let Some ( loans) = self . loans . as_mut ( ) {
@@ -117,23 +159,33 @@ impl LivenessValues {
117
159
118
160
/// Records `region` as being live at all the control-flow points.
119
161
pub ( crate ) fn add_all_points ( & mut self , region : RegionVid ) {
120
- self . points . insert_all_into_row ( region) ;
162
+ if let Some ( points) = & mut self . points {
163
+ points. insert_all_into_row ( region) ;
164
+ } else {
165
+ self . live_regions . as_mut ( ) . unwrap ( ) . insert ( region) ;
166
+ }
121
167
}
122
168
123
169
/// Returns whether `region` is marked live at the given `location`.
124
170
pub ( crate ) fn is_live_at ( & self , region : RegionVid , location : Location ) -> bool {
125
171
let point = self . elements . point_from_location ( location) ;
126
- self . points . row ( region) . is_some_and ( |r| r. contains ( point) )
127
- }
128
-
129
- /// Returns whether `region` is marked live at any location.
130
- pub ( crate ) fn is_live_anywhere ( & self , region : RegionVid ) -> bool {
131
- self . live_points ( region) . next ( ) . is_some ( )
172
+ if let Some ( points) = & self . points {
173
+ points. row ( region) . is_some_and ( |r| r. contains ( point) )
174
+ } else {
175
+ unreachable ! (
176
+ "Should be using LivenessValues::with_specific_points to ask whether live at a location"
177
+ )
178
+ }
132
179
}
133
180
134
181
/// Returns an iterator of all the points where `region` is live.
135
182
fn live_points ( & self , region : RegionVid ) -> impl Iterator < Item = PointIndex > + ' _ {
136
- self . points
183
+ let Some ( points) = & self . points else {
184
+ unreachable ! (
185
+ "Should be using LivenessValues::with_specific_points to ask whether live at a location"
186
+ )
187
+ } ;
188
+ points
137
189
. row ( region)
138
190
. into_iter ( )
139
191
. flat_map ( |set| set. iter ( ) )
@@ -288,7 +340,10 @@ impl<N: Idx> RegionValues<N> {
288
340
/// elements for the region `from` from `values` and add them to
289
341
/// the region `to` in `self`.
290
342
pub ( crate ) fn merge_liveness ( & mut self , to : N , from : RegionVid , values : & LivenessValues ) {
291
- if let Some ( set) = values. points . row ( from) {
343
+ let Some ( value_points) = & values. points else {
344
+ panic ! ( "LivenessValues must track specific points for use in merge_liveness" ) ;
345
+ } ;
346
+ if let Some ( set) = value_points. row ( from) {
292
347
self . points . union_row ( to, set) ;
293
348
}
294
349
}
0 commit comments