@@ -19,7 +19,6 @@ use rustc_data_structures::graph::implementation::{
19
19
Direction , Graph , NodeIndex , INCOMING , OUTGOING ,
20
20
} ;
21
21
use rustc_hir:: def_id:: DefId ;
22
- use rustc_index:: bit_set:: BitSet ;
23
22
use rustc_index:: vec:: { Idx , IndexVec } ;
24
23
use rustc_span:: Span ;
25
24
use std:: fmt;
@@ -297,23 +296,19 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
297
296
}
298
297
299
298
fn expansion ( & self , var_values : & mut LexicalRegionResolutions < ' tcx > ) {
300
- let mut changed = false ;
301
- let mut constraints = Vec :: new ( ) ;
299
+ let mut constraints = IndexVec :: from_elem_n ( Vec :: new ( ) , var_values . values . len ( ) ) ;
300
+ let mut changes = Vec :: new ( ) ;
302
301
for constraint in self . data . constraints . keys ( ) {
303
- let ( a_region, b_vid, b_data) = match * constraint {
302
+ let ( a_vid , a_region, b_vid, b_data) = match * constraint {
304
303
Constraint :: RegSubVar ( a_region, b_vid) => {
305
304
let b_data = var_values. value_mut ( b_vid) ;
306
- ( a_region, b_vid, b_data)
305
+ ( None , a_region, b_vid, b_data)
307
306
}
308
307
Constraint :: VarSubVar ( a_vid, b_vid) => match * var_values. value ( a_vid) {
309
308
VarValue :: ErrorValue => continue ,
310
309
VarValue :: Value ( a_region) => {
311
310
let b_data = var_values. value_mut ( b_vid) ;
312
- match * b_data {
313
- VarValue :: Value ( ReStatic ) | VarValue :: ErrorValue => ( ) ,
314
- _ => constraints. push ( ( a_vid, b_vid) ) ,
315
- }
316
- ( a_region, b_vid, b_data)
311
+ ( Some ( a_vid) , a_region, b_vid, b_data)
317
312
}
318
313
} ,
319
314
Constraint :: RegSubReg ( ..) | Constraint :: VarSubReg ( ..) => {
@@ -322,56 +317,38 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
322
317
continue ;
323
318
}
324
319
} ;
325
- let edge_changed = self . expand_node ( a_region, b_vid, b_data) ;
326
- if edge_changed {
327
- changed = true
320
+ if self . expand_node ( a_region, b_vid, b_data) {
321
+ changes. push ( b_vid) ;
328
322
}
329
- }
330
-
331
- let mut process_constraint = |a_vid, b_vid| {
332
- let ( a_region, b_data, retain) = match * var_values. value ( a_vid) {
333
- VarValue :: ErrorValue => return ( false , false ) ,
334
- VarValue :: Value ( a_region) => {
335
- let b_data = var_values. value_mut ( b_vid) ;
336
- let retain = match * b_data {
337
- VarValue :: Value ( ReStatic ) | VarValue :: ErrorValue => false ,
338
- _ => true ,
339
- } ;
340
- ( a_region, b_data, retain)
323
+ if let Some ( a_vid) = a_vid {
324
+ match * b_data {
325
+ VarValue :: Value ( ReStatic ) | VarValue :: ErrorValue => ( ) ,
326
+ _ => {
327
+ constraints[ a_vid] . push ( ( a_vid, b_vid) ) ;
328
+ constraints[ b_vid] . push ( ( a_vid, b_vid) ) ;
329
+ }
341
330
}
342
- } ;
343
- let changed = self . expand_node ( a_region, b_vid, b_data) ;
344
- ( changed, retain)
345
- } ;
331
+ }
332
+ }
346
333
347
- // Using bitsets to track the remaining elements is faster than using a
348
- // `Vec` by itself (which requires removing elements, which requires
349
- // element shuffling, which is slow).
350
- let mut live_indices: BitSet < usize > = BitSet :: new_filled ( constraints. len ( ) ) ;
351
- let mut killed_indices: BitSet < usize > = BitSet :: new_empty ( constraints. len ( ) ) ;
352
- while changed {
353
- changed = false ;
354
- for index in live_indices. iter ( ) {
355
- let ( a_vid, b_vid) = constraints[ index] ;
356
- let ( edge_changed, retain) = process_constraint ( a_vid, b_vid) ;
357
- if edge_changed {
358
- changed = true
334
+ while let Some ( vid) = changes. pop ( ) {
335
+ constraints[ vid] . retain ( |& ( a_vid, b_vid) | {
336
+ let a_region = match * var_values. value ( a_vid) {
337
+ VarValue :: ErrorValue => return false ,
338
+ VarValue :: Value ( a_region) => a_region,
339
+ } ;
340
+ let b_data = var_values. value_mut ( b_vid) ;
341
+ if self . expand_node ( a_region, b_vid, b_data) {
342
+ changes. push ( b_vid) ;
359
343
}
360
- if !retain {
361
- let changed = killed_indices . insert ( index ) ;
362
- debug_assert ! ( changed ) ;
344
+ match * b_data {
345
+ VarValue :: Value ( ReStatic ) | VarValue :: ErrorValue => false ,
346
+ _ => true ,
363
347
}
364
- }
365
- live_indices. subtract ( & killed_indices) ;
366
-
367
- // We could clear `killed_indices` here, but we don't need to and
368
- // it's cheaper not to.
348
+ } ) ;
369
349
}
370
350
}
371
351
372
- // This function is very hot in some workloads. There's a single callsite
373
- // so always inlining is ok even though it's large.
374
- #[ inline( always) ]
375
352
fn expand_node (
376
353
& self ,
377
354
a_region : Region < ' tcx > ,
0 commit comments