@@ -19,15 +19,15 @@ use rustc::mir::{ClosureOutlivesRequirement, ClosureRegionRequirements, Location
1919use rustc:: ty:: { self , RegionVid } ;
2020use rustc_data_structures:: indexed_vec:: IndexVec ;
2121use rustc_data_structures:: fx:: FxHashSet ;
22- use rustc_data_structures:: bitvec:: BitMatrix ;
23- use rustc_data_structures:: indexed_vec:: Idx ;
24- use std:: collections:: BTreeMap ;
2522use std:: fmt;
23+ use std:: rc:: Rc ;
2624use syntax_pos:: Span ;
2725
2826mod annotation;
2927mod dump_mir;
3028mod graphviz;
29+ mod values;
30+ use self :: values:: { RegionValueElements , RegionValues } ;
3131
3232pub struct RegionInferenceContext < ' tcx > {
3333 /// Contains the definition for every region variable. Region
@@ -36,27 +36,22 @@ pub struct RegionInferenceContext<'tcx> {
3636 /// from as well as its final inferred value.
3737 definitions : IndexVec < RegionVid , RegionDefinition < ' tcx > > ,
3838
39+ /// Maps from points/universal-regions to a `RegionElementIndex`.
40+ elements : Rc < RegionValueElements > ,
41+
3942 /// The liveness constraints added to each region. For most
4043 /// regions, these start out empty and steadily grow, though for
4144 /// each universally quantified region R they start out containing
4245 /// the entire CFG and `end(R)`.
43- ///
44- /// In this `BitMatrix` representation, the rows are the region
45- /// variables and the columns are the free regions and MIR locations.
46- liveness_constraints : BitMatrix ,
46+ liveness_constraints : RegionValues ,
4747
4848 /// The final inferred values of the inference variables; `None`
4949 /// until `solve` is invoked.
50- inferred_values : Option < BitMatrix > ,
50+ inferred_values : Option < RegionValues > ,
5151
5252 /// The constraints we have accumulated and used during solving.
5353 constraints : Vec < Constraint > ,
5454
55- /// A map from each MIR Location to its column index in
56- /// `liveness_constraints`/`inferred_values`. (The first N columns are
57- /// the free regions.)
58- point_indices : BTreeMap < Location , usize > ,
59-
6055 /// Information about the universally quantified regions in scope
6156 /// on this function and their (known) relations to one another.
6257 universal_regions : UniversalRegions < ' tcx > ,
@@ -112,19 +107,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
112107 let num_region_variables = var_origins. len ( ) ;
113108 let num_universal_regions = universal_regions. len ( ) ;
114109
115- let mut num_points = 0 ;
116- let mut point_indices = BTreeMap :: new ( ) ;
117-
118- for ( block, block_data) in mir. basic_blocks ( ) . iter_enumerated ( ) {
119- for statement_index in 0 ..block_data. statements . len ( ) + 1 {
120- let location = Location {
121- block,
122- statement_index,
123- } ;
124- point_indices. insert ( location, num_universal_regions + num_points) ;
125- num_points += 1 ;
126- }
127- }
110+ let elements = & Rc :: new ( RegionValueElements :: new ( mir, num_universal_regions) ) ;
128111
129112 // Create a RegionDefinition for each inference variable.
130113 let definitions = var_origins
@@ -134,13 +117,10 @@ impl<'tcx> RegionInferenceContext<'tcx> {
134117
135118 let mut result = Self {
136119 definitions,
137- liveness_constraints : BitMatrix :: new (
138- num_region_variables,
139- num_universal_regions + num_points,
140- ) ,
120+ elements : elements. clone ( ) ,
121+ liveness_constraints : RegionValues :: new ( elements, num_region_variables) ,
141122 inferred_values : None ,
142123 constraints : Vec :: new ( ) ,
143- point_indices,
144124 universal_regions,
145125 } ;
146126
@@ -186,14 +166,12 @@ impl<'tcx> RegionInferenceContext<'tcx> {
186166 self . definitions [ variable] . is_universal = true ;
187167
188168 // Add all nodes in the CFG to liveness constraints
189- for ( _location, point_index) in & self . point_indices {
190- self . liveness_constraints
191- . add ( variable. index ( ) , * point_index) ;
169+ for point_index in self . elements . all_point_indices ( ) {
170+ self . liveness_constraints . add ( variable, point_index) ;
192171 }
193172
194173 // Add `end(X)` into the set for X.
195- self . liveness_constraints
196- . add ( variable. index ( ) , variable. index ( ) ) ;
174+ self . liveness_constraints . add ( variable, variable) ;
197175 }
198176 }
199177
@@ -217,32 +195,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
217195 let inferred_values = self . inferred_values
218196 . as_ref ( )
219197 . expect ( "region values not yet inferred" ) ;
220- self . region_contains_point_in_matrix ( inferred_values, r, p)
221- }
222-
223- /// True if given region `r` contains the point `p`, when
224- /// evaluated in the set of region values `matrix`.
225- fn region_contains_point_in_matrix (
226- & self ,
227- matrix : & BitMatrix ,
228- r : RegionVid ,
229- p : Location ,
230- ) -> bool {
231- let point_index = self . point_indices
232- . get ( & p)
233- . expect ( "point index should be known" ) ;
234- matrix. contains ( r. index ( ) , * point_index)
235- }
236-
237- /// True if given region `r` contains the `end(s)`, when
238- /// evaluated in the set of region values `matrix`.
239- fn region_contains_region_in_matrix (
240- & self ,
241- matrix : & BitMatrix ,
242- r : RegionVid ,
243- s : RegionVid ,
244- ) -> bool {
245- matrix. contains ( r. index ( ) , s. index ( ) )
198+ inferred_values. contains ( r, p)
246199 }
247200
248201 /// Returns access to the value of `r` for debugging purposes.
@@ -251,43 +204,24 @@ impl<'tcx> RegionInferenceContext<'tcx> {
251204 . as_ref ( )
252205 . expect ( "region values not yet inferred" ) ;
253206
254- self . region_value_str_from_matrix ( inferred_values, r)
255- }
256-
257- fn region_value_str_from_matrix ( & self ,
258- matrix : & BitMatrix ,
259- r : RegionVid ) -> String {
260- let mut result = String :: new ( ) ;
261- result. push_str ( "{" ) ;
262- let mut sep = "" ;
263-
264- for & point in self . point_indices . keys ( ) {
265- if self . region_contains_point_in_matrix ( matrix, r, point) {
266- result. push_str ( & format ! ( "{}{:?}" , sep, point) ) ;
267- sep = ", " ;
268- }
269- }
270-
271- for fr in ( 0 ..self . universal_regions . len ( ) ) . map ( RegionVid :: new) {
272- if self . region_contains_region_in_matrix ( matrix, r, fr) {
273- result. push_str ( & format ! ( "{}{:?}" , sep, fr) ) ;
274- sep = ", " ;
275- }
276- }
277-
278- result. push_str ( "}" ) ;
279-
280- result
207+ inferred_values. region_value_str ( r)
281208 }
282209
283210 /// Indicates that the region variable `v` is live at the point `point`.
211+ ///
212+ /// Returns `true` if this constraint is new and `false` is the
213+ /// constraint was already present.
284214 pub ( super ) fn add_live_point ( & mut self , v : RegionVid , point : Location ) -> bool {
285215 debug ! ( "add_live_point({:?}, {:?})" , v, point) ;
286216 assert ! ( self . inferred_values. is_none( ) , "values already inferred" ) ;
287- let point_index = self . point_indices
288- . get ( & point)
289- . expect ( "point index should be known" ) ;
290- self . liveness_constraints . add ( v. index ( ) , * point_index)
217+ debug ! ( "add_live_point: @{:?}" , point) ;
218+
219+ let element = self . elements . index ( point) ;
220+ if self . liveness_constraints . add ( v, element) {
221+ true
222+ } else {
223+ false
224+ }
291225 }
292226
293227 /// Indicates that the region variable `sup` must outlive `sub` is live at the point `point`.
@@ -386,16 +320,12 @@ impl<'tcx> RegionInferenceContext<'tcx> {
386320 outlives_requirements : & mut Vec < ClosureOutlivesRequirement > ,
387321 ) {
388322 let inferred_values = self . inferred_values . as_ref ( ) . unwrap ( ) ;
389- let longer_value = inferred_values. iter ( longer_fr. index ( ) ) ;
390323
391324 debug ! ( "check_universal_region(fr={:?})" , longer_fr) ;
392325
393326 // Find every region `o` such that `fr: o`
394327 // (because `fr` includes `end(o)`).
395- let shorter_frs = longer_value
396- . take_while ( |& i| i < self . universal_regions . len ( ) )
397- . map ( RegionVid :: new) ;
398- for shorter_fr in shorter_frs {
328+ for shorter_fr in inferred_values. universal_regions_outlived_by ( longer_fr) {
399329 // If it is known that `fr: o`, carry on.
400330 if self . universal_regions . outlives ( longer_fr, shorter_fr) {
401331 continue ;
@@ -512,20 +442,22 @@ impl<'tcx> RegionInferenceContext<'tcx> {
512442
513443 fn copy (
514444 & self ,
515- inferred_values : & mut BitMatrix ,
445+ inferred_values : & mut RegionValues ,
516446 mir : & Mir < ' tcx > ,
517447 from_region : RegionVid ,
518448 to_region : RegionVid ,
519- start_point : Location ,
449+ constraint_point : Location ,
520450 ) -> bool {
521451 let mut changed = false ;
522452
523453 let mut stack = vec ! [ ] ;
524454 let mut visited = FxHashSet ( ) ;
525455
526- stack. push ( start_point ) ;
456+ stack. push ( constraint_point ) ;
527457 while let Some ( p) = stack. pop ( ) {
528- if !self . region_contains_point_in_matrix ( inferred_values, from_region, p) {
458+ let point_index = self . elements . index ( p) ;
459+
460+ if !inferred_values. contains ( from_region, point_index) {
529461 debug ! ( " not in from-region" ) ;
530462 continue ;
531463 }
@@ -535,8 +467,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
535467 continue ;
536468 }
537469
538- let point_index = self . point_indices . get ( & p ) . unwrap ( ) ;
539- changed |= inferred_values . add ( to_region . index ( ) , * point_index ) ;
470+ let new = inferred_values . add ( to_region , point_index ) ;
471+ changed |= new ;
540472
541473 let block_data = & mir[ p. block ] ;
542474 let successor_points = if p. statement_index < block_data. statements . len ( ) {
@@ -564,13 +496,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
564496 // If we reach the END point in the graph, then copy
565497 // over any skolemized end points in the `from_region`
566498 // and make sure they are included in the `to_region`.
567- let universal_region_indices = inferred_values
568- . iter ( from_region. index ( ) )
569- . take_while ( |& i| i < self . universal_regions . len ( ) )
570- . collect :: < Vec < _ > > ( ) ;
571- for fr in & universal_region_indices {
572- changed |= inferred_values. add ( to_region. index ( ) , * fr) ;
573- }
499+ changed |=
500+ inferred_values. add_universal_regions_outlived_by ( from_region, to_region) ;
574501 } else {
575502 stack. extend ( successor_points) ;
576503 }
0 commit comments