11#![ deny( rustc:: untranslatable_diagnostic) ]
22#![ deny( rustc:: diagnostic_outside_of_impl) ]
3+ use rustc_data_structures:: fx:: FxHashSet ;
34use rustc_data_structures:: fx:: FxIndexSet ;
45use rustc_index:: bit_set:: SparseBitMatrix ;
56use rustc_index:: interval:: IntervalSet ;
@@ -41,8 +42,15 @@ pub(crate) struct LivenessValues {
4142 /// The map from locations to points.
4243 elements : Rc < DenseLocationMap > ,
4344
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+
4449 /// 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 > > ,
4654
4755 /// When using `-Zpolonius=next`, for each point: the loans flowing into the live regions at
4856 /// that point.
@@ -71,24 +79,52 @@ impl LiveLoans {
7179
7280impl LivenessValues {
7381 /// 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 {
7583 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 ,
7799 elements,
78100 loans : None ,
79101 }
80102 }
81103
82104 /// 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 ( )
85115 }
86116
87117 /// Records `region` as being live at the given `location`.
88118 pub ( crate ) fn add_location ( & mut self , region : RegionVid , location : Location ) {
89- debug ! ( "LivenessValues::add_location(region={:?}, location={:?})" , region, location) ;
90119 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+ }
92128
93129 // When available, record the loans flowing into this region as live at the given point.
94130 if let Some ( loans) = self . loans . as_mut ( ) {
@@ -101,7 +137,13 @@ impl LivenessValues {
101137 /// Records `region` as being live at all the given `points`.
102138 pub ( crate ) fn add_points ( & mut self , region : RegionVid , points : & IntervalSet < PointIndex > ) {
103139 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+ }
105147
106148 // When available, record the loans flowing into this region as live at the given points.
107149 if let Some ( loans) = self . loans . as_mut ( ) {
@@ -117,23 +159,33 @@ impl LivenessValues {
117159
118160 /// Records `region` as being live at all the control-flow points.
119161 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+ }
121167 }
122168
123169 /// Returns whether `region` is marked live at the given `location`.
124170 pub ( crate ) fn is_live_at ( & self , region : RegionVid , location : Location ) -> bool {
125171 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+ }
132179 }
133180
134181 /// Returns an iterator of all the points where `region` is live.
135182 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
137189 . row ( region)
138190 . into_iter ( )
139191 . flat_map ( |set| set. iter ( ) )
@@ -288,7 +340,10 @@ impl<N: Idx> RegionValues<N> {
288340 /// elements for the region `from` from `values` and add them to
289341 /// the region `to` in `self`.
290342 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) {
292347 self . points . union_row ( to, set) ;
293348 }
294349 }
0 commit comments