@@ -19,15 +19,15 @@ use rustc::mir::{ClosureOutlivesRequirement, ClosureRegionRequirements, Location
19
19
use rustc:: ty:: { self , RegionVid } ;
20
20
use rustc_data_structures:: indexed_vec:: IndexVec ;
21
21
use 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 ;
25
22
use std:: fmt;
23
+ use std:: rc:: Rc ;
26
24
use syntax_pos:: Span ;
27
25
28
26
mod annotation;
29
27
mod dump_mir;
30
28
mod graphviz;
29
+ mod values;
30
+ use self :: values:: { RegionValueElements , RegionValues } ;
31
31
32
32
pub struct RegionInferenceContext < ' tcx > {
33
33
/// Contains the definition for every region variable. Region
@@ -36,27 +36,22 @@ pub struct RegionInferenceContext<'tcx> {
36
36
/// from as well as its final inferred value.
37
37
definitions : IndexVec < RegionVid , RegionDefinition < ' tcx > > ,
38
38
39
+ /// Maps from points/universal-regions to a `RegionElementIndex`.
40
+ elements : Rc < RegionValueElements > ,
41
+
39
42
/// The liveness constraints added to each region. For most
40
43
/// regions, these start out empty and steadily grow, though for
41
44
/// each universally quantified region R they start out containing
42
45
/// 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 ,
47
47
48
48
/// The final inferred values of the inference variables; `None`
49
49
/// until `solve` is invoked.
50
- inferred_values : Option < BitMatrix > ,
50
+ inferred_values : Option < RegionValues > ,
51
51
52
52
/// The constraints we have accumulated and used during solving.
53
53
constraints : Vec < Constraint > ,
54
54
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
-
60
55
/// Information about the universally quantified regions in scope
61
56
/// on this function and their (known) relations to one another.
62
57
universal_regions : UniversalRegions < ' tcx > ,
@@ -112,19 +107,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
112
107
let num_region_variables = var_origins. len ( ) ;
113
108
let num_universal_regions = universal_regions. len ( ) ;
114
109
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) ) ;
128
111
129
112
// Create a RegionDefinition for each inference variable.
130
113
let definitions = var_origins
@@ -134,13 +117,10 @@ impl<'tcx> RegionInferenceContext<'tcx> {
134
117
135
118
let mut result = Self {
136
119
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) ,
141
122
inferred_values : None ,
142
123
constraints : Vec :: new ( ) ,
143
- point_indices,
144
124
universal_regions,
145
125
} ;
146
126
@@ -186,14 +166,12 @@ impl<'tcx> RegionInferenceContext<'tcx> {
186
166
self . definitions [ variable] . is_universal = true ;
187
167
188
168
// 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) ;
192
171
}
193
172
194
173
// 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) ;
197
175
}
198
176
}
199
177
@@ -217,32 +195,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
217
195
let inferred_values = self . inferred_values
218
196
. as_ref ( )
219
197
. 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)
246
199
}
247
200
248
201
/// Returns access to the value of `r` for debugging purposes.
@@ -251,43 +204,24 @@ impl<'tcx> RegionInferenceContext<'tcx> {
251
204
. as_ref ( )
252
205
. expect ( "region values not yet inferred" ) ;
253
206
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)
281
208
}
282
209
283
210
/// 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.
284
214
pub ( super ) fn add_live_point ( & mut self , v : RegionVid , point : Location ) -> bool {
285
215
debug ! ( "add_live_point({:?}, {:?})" , v, point) ;
286
216
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
+ }
291
225
}
292
226
293
227
/// Indicates that the region variable `sup` must outlive `sub` is live at the point `point`.
@@ -386,16 +320,12 @@ impl<'tcx> RegionInferenceContext<'tcx> {
386
320
outlives_requirements : & mut Vec < ClosureOutlivesRequirement > ,
387
321
) {
388
322
let inferred_values = self . inferred_values . as_ref ( ) . unwrap ( ) ;
389
- let longer_value = inferred_values. iter ( longer_fr. index ( ) ) ;
390
323
391
324
debug ! ( "check_universal_region(fr={:?})" , longer_fr) ;
392
325
393
326
// Find every region `o` such that `fr: o`
394
327
// (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) {
399
329
// If it is known that `fr: o`, carry on.
400
330
if self . universal_regions . outlives ( longer_fr, shorter_fr) {
401
331
continue ;
@@ -512,20 +442,22 @@ impl<'tcx> RegionInferenceContext<'tcx> {
512
442
513
443
fn copy (
514
444
& self ,
515
- inferred_values : & mut BitMatrix ,
445
+ inferred_values : & mut RegionValues ,
516
446
mir : & Mir < ' tcx > ,
517
447
from_region : RegionVid ,
518
448
to_region : RegionVid ,
519
- start_point : Location ,
449
+ constraint_point : Location ,
520
450
) -> bool {
521
451
let mut changed = false ;
522
452
523
453
let mut stack = vec ! [ ] ;
524
454
let mut visited = FxHashSet ( ) ;
525
455
526
- stack. push ( start_point ) ;
456
+ stack. push ( constraint_point ) ;
527
457
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) {
529
461
debug ! ( " not in from-region" ) ;
530
462
continue ;
531
463
}
@@ -535,8 +467,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
535
467
continue ;
536
468
}
537
469
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 ;
540
472
541
473
let block_data = & mir[ p. block ] ;
542
474
let successor_points = if p. statement_index < block_data. statements . len ( ) {
@@ -564,13 +496,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
564
496
// If we reach the END point in the graph, then copy
565
497
// over any skolemized end points in the `from_region`
566
498
// 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) ;
574
501
} else {
575
502
stack. extend ( successor_points) ;
576
503
}
0 commit comments