62
62
//! - `reader`: the `LiveNode` ID of some node which will read the value
63
63
//! that `V` holds on entry to `N`. Formally: a node `M` such
64
64
//! that there exists a path `P` from `N` to `M` where `P` does not
65
- //! write `V`. If the `reader` is `invalid_node() `, then the current
65
+ //! write `V`. If the `reader` is `INVALID_NODE `, then the current
66
66
//! value will never be read (the variable is dead, essentially).
67
67
//!
68
68
//! - `writer`: the `LiveNode` ID of some node which will write the
69
69
//! variable `V` and which is reachable from `N`. Formally: a node `M`
70
70
//! such that there exists a path `P` from `N` to `M` and `M` writes
71
- //! `V`. If the `writer` is `invalid_node() `, then there is no writer
71
+ //! `V`. If the `writer` is `INVALID_NODE `, then there is no writer
72
72
//! of `V` that follows `N`.
73
73
//!
74
74
//! - `used`: a boolean value indicating whether `V` is *used*. We
@@ -92,6 +92,7 @@ use rustc_hir::def::*;
92
92
use rustc_hir:: def_id:: LocalDefId ;
93
93
use rustc_hir:: intravisit:: { self , FnKind , NestedVisitorMap , Visitor } ;
94
94
use rustc_hir:: { Expr , HirId , HirIdMap , HirIdSet , Node } ;
95
+ use rustc_index:: vec:: IndexVec ;
95
96
use rustc_middle:: hir:: map:: Map ;
96
97
use rustc_middle:: ty:: query:: Providers ;
97
98
use rustc_middle:: ty:: { self , TyCtxt } ;
@@ -100,26 +101,20 @@ use rustc_span::symbol::{kw, sym, Symbol};
100
101
use rustc_span:: Span ;
101
102
102
103
use std:: collections:: VecDeque ;
103
- use std:: fmt;
104
104
use std:: io;
105
105
use std:: io:: prelude:: * ;
106
106
use std:: rc:: Rc ;
107
107
108
- #[ derive( Copy , Clone , PartialEq ) ]
109
- struct Variable ( u32 ) ;
110
-
111
- #[ derive( Copy , Clone , PartialEq ) ]
112
- struct LiveNode ( u32 ) ;
113
-
114
- impl Variable {
115
- fn get ( & self ) -> usize {
116
- self . 0 as usize
108
+ rustc_index:: newtype_index! {
109
+ pub struct Variable {
110
+ DEBUG_FORMAT = "v({})" ,
117
111
}
118
112
}
119
113
120
- impl LiveNode {
121
- fn get ( & self ) -> usize {
122
- self . 0 as usize
114
+ rustc_index:: newtype_index! {
115
+ pub struct LiveNode {
116
+ DEBUG_FORMAT = "ln({})" ,
117
+ const INVALID_NODE = LiveNode :: MAX_AS_U32 ,
123
118
}
124
119
}
125
120
@@ -183,18 +178,6 @@ pub fn provide(providers: &mut Providers) {
183
178
* providers = Providers { check_mod_liveness, ..* providers } ;
184
179
}
185
180
186
- impl fmt:: Debug for LiveNode {
187
- fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
188
- write ! ( f, "ln({})" , self . get( ) )
189
- }
190
- }
191
-
192
- impl fmt:: Debug for Variable {
193
- fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
194
- write ! ( f, "v({})" , self . get( ) )
195
- }
196
- }
197
-
198
181
// ______________________________________________________________________
199
182
// Creating ir_maps
200
183
//
@@ -218,15 +201,11 @@ impl fmt::Debug for Variable {
218
201
// assignment. And so forth.
219
202
220
203
impl LiveNode {
221
- fn is_valid ( & self ) -> bool {
222
- self . 0 != u32 :: MAX
204
+ fn is_valid ( self ) -> bool {
205
+ self != INVALID_NODE
223
206
}
224
207
}
225
208
226
- fn invalid_node ( ) -> LiveNode {
227
- LiveNode ( u32:: MAX )
228
- }
229
-
230
209
struct CaptureInfo {
231
210
ln : LiveNode ,
232
211
var_hid : HirId ,
@@ -252,8 +231,8 @@ struct IrMaps<'tcx> {
252
231
live_node_map : HirIdMap < LiveNode > ,
253
232
variable_map : HirIdMap < Variable > ,
254
233
capture_info_map : HirIdMap < Rc < Vec < CaptureInfo > > > ,
255
- var_kinds : Vec < VarKind > ,
256
- lnks : Vec < LiveNodeKind > ,
234
+ var_kinds : IndexVec < Variable , VarKind > ,
235
+ lnks : IndexVec < LiveNode , LiveNodeKind > ,
257
236
}
258
237
259
238
impl IrMaps < ' tcx > {
@@ -264,14 +243,13 @@ impl IrMaps<'tcx> {
264
243
live_node_map : HirIdMap :: default ( ) ,
265
244
variable_map : HirIdMap :: default ( ) ,
266
245
capture_info_map : Default :: default ( ) ,
267
- var_kinds : Vec :: new ( ) ,
268
- lnks : Vec :: new ( ) ,
246
+ var_kinds : IndexVec :: new ( ) ,
247
+ lnks : IndexVec :: new ( ) ,
269
248
}
270
249
}
271
250
272
251
fn add_live_node ( & mut self , lnk : LiveNodeKind ) -> LiveNode {
273
- let ln = LiveNode ( self . lnks . len ( ) as u32 ) ;
274
- self . lnks . push ( lnk) ;
252
+ let ln = self . lnks . push ( lnk) ;
275
253
276
254
debug ! ( "{:?} is of kind {}" , ln, live_node_kind_to_string( lnk, self . tcx) ) ;
277
255
@@ -286,8 +264,7 @@ impl IrMaps<'tcx> {
286
264
}
287
265
288
266
fn add_variable ( & mut self , vk : VarKind ) -> Variable {
289
- let v = Variable ( self . var_kinds . len ( ) as u32 ) ;
290
- self . var_kinds . push ( vk) ;
267
+ let v = self . var_kinds . push ( vk) ;
291
268
292
269
match vk {
293
270
Local ( LocalInfo { id : node_id, .. } ) | Param ( node_id, _) | Upvar ( node_id, _) => {
@@ -310,13 +287,13 @@ impl IrMaps<'tcx> {
310
287
}
311
288
312
289
fn variable_name ( & self , var : Variable ) -> Symbol {
313
- match self . var_kinds [ var. get ( ) ] {
290
+ match self . var_kinds [ var] {
314
291
Local ( LocalInfo { name, .. } ) | Param ( _, name) | Upvar ( _, name) => name,
315
292
}
316
293
}
317
294
318
295
fn variable_is_shorthand ( & self , var : Variable ) -> bool {
319
- match self . var_kinds [ var. get ( ) ] {
296
+ match self . var_kinds [ var] {
320
297
Local ( LocalInfo { is_shorthand, .. } ) => is_shorthand,
321
298
Param ( ..) | Upvar ( ..) => false ,
322
299
}
@@ -327,7 +304,7 @@ impl IrMaps<'tcx> {
327
304
}
328
305
329
306
fn lnk ( & self , ln : LiveNode ) -> LiveNodeKind {
330
- self . lnks [ ln. get ( ) ]
307
+ self . lnks [ ln]
331
308
}
332
309
}
333
310
@@ -556,10 +533,10 @@ struct RWUTable {
556
533
unpacked_rwus : Vec < RWU > ,
557
534
}
558
535
559
- // A constant representing `RWU { reader: invalid_node() ; writer: invalid_node() ; used: false }`.
536
+ // A constant representing `RWU { reader: INVALID_NODE ; writer: INVALID_NODE ; used: false }`.
560
537
const INV_INV_FALSE : u32 = u32:: MAX ;
561
538
562
- // A constant representing `RWU { reader: invalid_node() ; writer: invalid_node() ; used: true }`.
539
+ // A constant representing `RWU { reader: INVALID_NODE ; writer: INVALID_NODE ; used: true }`.
563
540
const INV_INV_TRUE : u32 = u32:: MAX - 1 ;
564
541
565
542
impl RWUTable {
@@ -570,24 +547,24 @@ impl RWUTable {
570
547
fn get ( & self , idx : usize ) -> RWU {
571
548
let packed_rwu = self . packed_rwus [ idx] ;
572
549
match packed_rwu {
573
- INV_INV_FALSE => RWU { reader : invalid_node ( ) , writer : invalid_node ( ) , used : false } ,
574
- INV_INV_TRUE => RWU { reader : invalid_node ( ) , writer : invalid_node ( ) , used : true } ,
550
+ INV_INV_FALSE => RWU { reader : INVALID_NODE , writer : INVALID_NODE , used : false } ,
551
+ INV_INV_TRUE => RWU { reader : INVALID_NODE , writer : INVALID_NODE , used : true } ,
575
552
_ => self . unpacked_rwus [ packed_rwu as usize ] ,
576
553
}
577
554
}
578
555
579
556
fn get_reader ( & self , idx : usize ) -> LiveNode {
580
557
let packed_rwu = self . packed_rwus [ idx] ;
581
558
match packed_rwu {
582
- INV_INV_FALSE | INV_INV_TRUE => invalid_node ( ) ,
559
+ INV_INV_FALSE | INV_INV_TRUE => INVALID_NODE ,
583
560
_ => self . unpacked_rwus [ packed_rwu as usize ] . reader ,
584
561
}
585
562
}
586
563
587
564
fn get_writer ( & self , idx : usize ) -> LiveNode {
588
565
let packed_rwu = self . packed_rwus [ idx] ;
589
566
match packed_rwu {
590
- INV_INV_FALSE | INV_INV_TRUE => invalid_node ( ) ,
567
+ INV_INV_FALSE | INV_INV_TRUE => INVALID_NODE ,
591
568
_ => self . unpacked_rwus [ packed_rwu as usize ] . writer ,
592
569
}
593
570
}
@@ -607,7 +584,7 @@ impl RWUTable {
607
584
}
608
585
609
586
fn assign_unpacked ( & mut self , idx : usize , rwu : RWU ) {
610
- if rwu. reader == invalid_node ( ) && rwu. writer == invalid_node ( ) {
587
+ if rwu. reader == INVALID_NODE && rwu. writer == INVALID_NODE {
611
588
// When we overwrite an indexing entry in `self.packed_rwus` with
612
589
// `INV_INV_{TRUE,FALSE}` we don't remove the corresponding entry
613
590
// from `self.unpacked_rwus`; it's not worth the effort, and we
@@ -634,7 +611,7 @@ struct Liveness<'a, 'tcx> {
634
611
ir : & ' a mut IrMaps < ' tcx > ,
635
612
typeck_results : & ' a ty:: TypeckResults < ' tcx > ,
636
613
param_env : ty:: ParamEnv < ' tcx > ,
637
- successors : Vec < LiveNode > ,
614
+ successors : IndexVec < LiveNode , LiveNode > ,
638
615
rwu_table : RWUTable ,
639
616
640
617
/// A live node representing a point of execution before closure entry &
@@ -667,7 +644,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
667
644
ir,
668
645
typeck_results,
669
646
param_env,
670
- successors : vec ! [ invalid_node ( ) ; num_live_nodes] ,
647
+ successors : IndexVec :: from_elem_n ( INVALID_NODE , num_live_nodes) ,
671
648
rwu_table : RWUTable :: new ( num_live_nodes * num_vars) ,
672
649
closure_ln,
673
650
exit_ln,
@@ -708,7 +685,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
708
685
}
709
686
710
687
fn idx ( & self , ln : LiveNode , var : Variable ) -> usize {
711
- ln. get ( ) * self . ir . var_kinds . len ( ) + var. get ( )
688
+ ln. index ( ) * self . ir . var_kinds . len ( ) + var. index ( )
712
689
}
713
690
714
691
fn live_on_entry ( & self , ln : LiveNode , var : Variable ) -> Option < LiveNodeKind > {
@@ -719,7 +696,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
719
696
720
697
// Is this variable live on entry to any of its successor nodes?
721
698
fn live_on_exit ( & self , ln : LiveNode , var : Variable ) -> Option < LiveNodeKind > {
722
- let successor = self . successors [ ln. get ( ) ] ;
699
+ let successor = self . successors [ ln] ;
723
700
self . live_on_entry ( successor, var)
724
701
}
725
702
@@ -735,16 +712,16 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
735
712
}
736
713
737
714
fn assigned_on_exit ( & self , ln : LiveNode , var : Variable ) -> Option < LiveNodeKind > {
738
- let successor = self . successors [ ln. get ( ) ] ;
715
+ let successor = self . successors [ ln] ;
739
716
self . assigned_on_entry ( successor, var)
740
717
}
741
718
742
719
fn indices2 < F > ( & mut self , ln : LiveNode , succ_ln : LiveNode , mut op : F )
743
720
where
744
721
F : FnMut ( & mut Liveness < ' a , ' tcx > , usize , usize ) ,
745
722
{
746
- let node_base_idx = self . idx ( ln, Variable ( 0 ) ) ;
747
- let succ_base_idx = self . idx ( succ_ln, Variable ( 0 ) ) ;
723
+ let node_base_idx = self . idx ( ln, Variable :: from ( 0u32 ) ) ;
724
+ let succ_base_idx = self . idx ( succ_ln, Variable :: from ( 0u32 ) ) ;
748
725
for var_idx in 0 ..self . ir . var_kinds . len ( ) {
749
726
op ( self , node_base_idx + var_idx, succ_base_idx + var_idx) ;
750
727
}
@@ -754,11 +731,11 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
754
731
where
755
732
F : FnMut ( usize ) -> bool ,
756
733
{
757
- let node_base_idx = self . idx ( ln, Variable ( 0 ) ) ;
734
+ let node_base_idx = self . idx ( ln, Variable :: from ( 0u32 ) ) ;
758
735
for var_idx in 0 ..self . ir . var_kinds . len ( ) {
759
736
let idx = node_base_idx + var_idx;
760
737
if test ( idx) {
761
- write ! ( wr, " {:?}" , Variable ( var_idx as u32 ) ) ?;
738
+ write ! ( wr, " {:?}" , Variable :: from ( var_idx) ) ?;
762
739
}
763
740
}
764
741
Ok ( ( ) )
@@ -769,14 +746,14 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
769
746
let mut wr = Vec :: new ( ) ;
770
747
{
771
748
let wr = & mut wr as & mut dyn Write ;
772
- write ! ( wr, "[ln( {:?}) of kind {:?} reads" , ln. get ( ) , self . ir. lnk( ln) ) ;
749
+ write ! ( wr, "[{:?} of kind {:?} reads" , ln, self . ir. lnk( ln) ) ;
773
750
self . write_vars ( wr, ln, |idx| self . rwu_table . get_reader ( idx) . is_valid ( ) ) ;
774
751
write ! ( wr, " writes" ) ;
775
752
self . write_vars ( wr, ln, |idx| self . rwu_table . get_writer ( idx) . is_valid ( ) ) ;
776
753
write ! ( wr, " uses" ) ;
777
754
self . write_vars ( wr, ln, |idx| self . rwu_table . get_used ( idx) ) ;
778
755
779
- write ! ( wr, " precedes {:?}]" , self . successors[ ln. get ( ) ] ) ;
756
+ write ! ( wr, " precedes {:?}]" , self . successors[ ln] ) ;
780
757
}
781
758
String :: from_utf8 ( wr) . unwrap ( )
782
759
}
@@ -787,7 +764,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
787
764
"^^ liveness computation results for body {} (entry={:?})" ,
788
765
{
789
766
for ln_idx in 0 ..self . ir. lnks. len( ) {
790
- debug!( "{:?}" , self . ln_str( LiveNode ( ln_idx as u32 ) ) ) ;
767
+ debug!( "{:?}" , self . ln_str( LiveNode :: from ( ln_idx) ) ) ;
791
768
}
792
769
hir_id
793
770
} ,
@@ -796,7 +773,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
796
773
}
797
774
798
775
fn init_empty ( & mut self , ln : LiveNode , succ_ln : LiveNode ) {
799
- self . successors [ ln. get ( ) ] = succ_ln;
776
+ self . successors [ ln] = succ_ln;
800
777
801
778
// It is not necessary to initialize the RWUs here because they are all
802
779
// set to INV_INV_FALSE when they are created, and the sets only grow
@@ -805,7 +782,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
805
782
806
783
fn init_from_succ ( & mut self , ln : LiveNode , succ_ln : LiveNode ) {
807
784
// more efficient version of init_empty() / merge_from_succ()
808
- self . successors [ ln. get ( ) ] = succ_ln;
785
+ self . successors [ ln] = succ_ln;
809
786
810
787
self . indices2 ( ln, succ_ln, |this, idx, succ_idx| {
811
788
this. rwu_table . copy_packed ( idx, succ_idx) ;
@@ -878,7 +855,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
878
855
let mut rwu = self . rwu_table . get ( idx) ;
879
856
880
857
if ( acc & ACC_WRITE ) != 0 {
881
- rwu. reader = invalid_node ( ) ;
858
+ rwu. reader = INVALID_NODE ;
882
859
rwu. writer = ln;
883
860
}
884
861
0 commit comments