@@ -105,6 +105,8 @@ use std::io;
105
105
use std:: io:: prelude:: * ;
106
106
use std:: rc:: Rc ;
107
107
108
+ mod rwu_table;
109
+
108
110
rustc_index:: newtype_index! {
109
111
pub struct Variable {
110
112
DEBUG_FORMAT = "v({})" ,
@@ -468,149 +470,6 @@ impl<'tcx> Visitor<'tcx> for IrMaps<'tcx> {
468
470
// Actually we compute just a bit more than just liveness, but we use
469
471
// the same basic propagation framework in all cases.
470
472
471
- #[ derive( Clone , Copy ) ]
472
- struct RWU {
473
- reader : bool ,
474
- writer : bool ,
475
- used : bool ,
476
- }
477
-
478
- /// Conceptually, this is like a `Vec<Vec<RWU>>`. But the number of
479
- /// RWU`s can get very large, so it uses a more compact representation.
480
- struct RWUTable {
481
- /// Total number of live nodes.
482
- live_nodes : usize ,
483
- /// Total number of variables.
484
- vars : usize ,
485
-
486
- /// A compressed representation of `RWU`s.
487
- ///
488
- /// Each word represents 2 different `RWU`s packed together. Each packed RWU
489
- /// is stored in 4 bits: a reader bit, a writer bit, a used bit and a
490
- /// padding bit.
491
- ///
492
- /// The data for each live node is contiguous and starts at a word boundary,
493
- /// so there might be an unused space left.
494
- words : Vec < u8 > ,
495
- /// Number of words per each live node.
496
- live_node_words : usize ,
497
- }
498
-
499
- impl RWUTable {
500
- const RWU_READER : u8 = 0b0001 ;
501
- const RWU_WRITER : u8 = 0b0010 ;
502
- const RWU_USED : u8 = 0b0100 ;
503
- const RWU_MASK : u8 = 0b1111 ;
504
-
505
- /// Size of packed RWU in bits.
506
- const RWU_BITS : usize = 4 ;
507
- /// Size of a word in bits.
508
- const WORD_BITS : usize = std:: mem:: size_of :: < u8 > ( ) * 8 ;
509
- /// Number of packed RWUs that fit into a single word.
510
- const WORD_RWU_COUNT : usize = Self :: WORD_BITS / Self :: RWU_BITS ;
511
-
512
- fn new ( live_nodes : usize , vars : usize ) -> RWUTable {
513
- let live_node_words = ( vars + Self :: WORD_RWU_COUNT - 1 ) / Self :: WORD_RWU_COUNT ;
514
- Self { live_nodes, vars, live_node_words, words : vec ! [ 0u8 ; live_node_words * live_nodes] }
515
- }
516
-
517
- fn word_and_shift ( & self , ln : LiveNode , var : Variable ) -> ( usize , u32 ) {
518
- assert ! ( ln. index( ) < self . live_nodes) ;
519
- assert ! ( var. index( ) < self . vars) ;
520
-
521
- let var = var. index ( ) ;
522
- let word = var / Self :: WORD_RWU_COUNT ;
523
- let shift = Self :: RWU_BITS * ( var % Self :: WORD_RWU_COUNT ) ;
524
- ( ln. index ( ) * self . live_node_words + word, shift as u32 )
525
- }
526
-
527
- fn pick2_rows_mut ( & mut self , a : LiveNode , b : LiveNode ) -> ( & mut [ u8 ] , & mut [ u8 ] ) {
528
- assert ! ( a. index( ) < self . live_nodes) ;
529
- assert ! ( b. index( ) < self . live_nodes) ;
530
- assert ! ( a != b) ;
531
-
532
- let a_start = a. index ( ) * self . live_node_words ;
533
- let b_start = b. index ( ) * self . live_node_words ;
534
-
535
- unsafe {
536
- let ptr = self . words . as_mut_ptr ( ) ;
537
- (
538
- std:: slice:: from_raw_parts_mut ( ptr. add ( a_start) , self . live_node_words ) ,
539
- std:: slice:: from_raw_parts_mut ( ptr. add ( b_start) , self . live_node_words ) ,
540
- )
541
- }
542
- }
543
-
544
- fn copy ( & mut self , dst : LiveNode , src : LiveNode ) {
545
- if dst == src {
546
- return ;
547
- }
548
-
549
- let ( dst_row, src_row) = self . pick2_rows_mut ( dst, src) ;
550
- dst_row. copy_from_slice ( src_row) ;
551
- }
552
-
553
- /// Sets `dst` to the union of `dst` and `src`, returns true if `dst` was
554
- /// changed.
555
- fn union ( & mut self , dst : LiveNode , src : LiveNode ) -> bool {
556
- if dst == src {
557
- return false ;
558
- }
559
-
560
- let mut changed = false ;
561
- let ( dst_row, src_row) = self . pick2_rows_mut ( dst, src) ;
562
- for ( dst_word, src_word) in dst_row. iter_mut ( ) . zip ( src_row. iter ( ) ) {
563
- let old = * dst_word;
564
- let new = * dst_word | src_word;
565
- * dst_word = new;
566
- changed |= old != new;
567
- }
568
- changed
569
- }
570
-
571
- fn get_reader ( & self , ln : LiveNode , var : Variable ) -> bool {
572
- let ( word, shift) = self . word_and_shift ( ln, var) ;
573
- ( self . words [ word] >> shift) & Self :: RWU_READER != 0
574
- }
575
-
576
- fn get_writer ( & self , ln : LiveNode , var : Variable ) -> bool {
577
- let ( word, shift) = self . word_and_shift ( ln, var) ;
578
- ( self . words [ word] >> shift) & Self :: RWU_WRITER != 0
579
- }
580
-
581
- fn get_used ( & self , ln : LiveNode , var : Variable ) -> bool {
582
- let ( word, shift) = self . word_and_shift ( ln, var) ;
583
- ( self . words [ word] >> shift) & Self :: RWU_USED != 0
584
- }
585
-
586
- fn get ( & self , ln : LiveNode , var : Variable ) -> RWU {
587
- let ( word, shift) = self . word_and_shift ( ln, var) ;
588
- let rwu_packed = self . words [ word] >> shift;
589
- RWU {
590
- reader : rwu_packed & Self :: RWU_READER != 0 ,
591
- writer : rwu_packed & Self :: RWU_WRITER != 0 ,
592
- used : rwu_packed & Self :: RWU_USED != 0 ,
593
- }
594
- }
595
-
596
- fn set ( & mut self , ln : LiveNode , var : Variable , rwu : RWU ) {
597
- let mut packed = 0 ;
598
- if rwu. reader {
599
- packed |= Self :: RWU_READER ;
600
- }
601
- if rwu. writer {
602
- packed |= Self :: RWU_WRITER ;
603
- }
604
- if rwu. used {
605
- packed |= Self :: RWU_USED ;
606
- }
607
-
608
- let ( word, shift) = self . word_and_shift ( ln, var) ;
609
- let word = & mut self . words [ word] ;
610
- * word = ( * word & !( Self :: RWU_MASK << shift) ) | ( packed << shift)
611
- }
612
- }
613
-
614
473
const ACC_READ : u32 = 1 ;
615
474
const ACC_WRITE : u32 = 2 ;
616
475
const ACC_USE : u32 = 4 ;
@@ -623,7 +482,7 @@ struct Liveness<'a, 'tcx> {
623
482
upvars : Option < & ' tcx FxIndexMap < hir:: HirId , hir:: Upvar > > ,
624
483
closure_captures : Option < & ' tcx FxIndexMap < hir:: HirId , ty:: UpvarId > > ,
625
484
successors : IndexVec < LiveNode , Option < LiveNode > > ,
626
- rwu_table : RWUTable ,
485
+ rwu_table : rwu_table :: RWUTable ,
627
486
628
487
/// A live node representing a point of execution before closure entry &
629
488
/// after closure exit. Used to calculate liveness of captured variables
@@ -661,7 +520,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
661
520
upvars,
662
521
closure_captures,
663
522
successors : IndexVec :: from_elem_n ( None , num_live_nodes) ,
664
- rwu_table : RWUTable :: new ( num_live_nodes, num_vars) ,
523
+ rwu_table : rwu_table :: RWUTable :: new ( num_live_nodes, num_vars) ,
665
524
closure_ln,
666
525
exit_ln,
667
526
break_ln : Default :: default ( ) ,
@@ -796,7 +655,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
796
655
// this) so we just clear out all the data.
797
656
fn define ( & mut self , writer : LiveNode , var : Variable ) {
798
657
let used = self . rwu_table . get_used ( writer, var) ;
799
- self . rwu_table . set ( writer, var, RWU { reader : false , writer : false , used } ) ;
658
+ self . rwu_table . set ( writer, var, rwu_table :: RWU { reader : false , writer : false , used } ) ;
800
659
debug ! ( "{:?} defines {:?}: {}" , writer, var, self . ln_str( writer) ) ;
801
660
}
802
661
0 commit comments