@@ -105,6 +105,8 @@ use std::io;
105105use std:: io:: prelude:: * ;
106106use std:: rc:: Rc ;
107107
108+ mod rwu_table;
109+
108110rustc_index:: newtype_index! {
109111 pub struct Variable {
110112 DEBUG_FORMAT = "v({})" ,
@@ -468,149 +470,6 @@ impl<'tcx> Visitor<'tcx> for IrMaps<'tcx> {
468470// Actually we compute just a bit more than just liveness, but we use
469471// the same basic propagation framework in all cases.
470472
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-
614473const ACC_READ : u32 = 1 ;
615474const ACC_WRITE : u32 = 2 ;
616475const ACC_USE : u32 = 4 ;
@@ -623,7 +482,7 @@ struct Liveness<'a, 'tcx> {
623482 upvars : Option < & ' tcx FxIndexMap < hir:: HirId , hir:: Upvar > > ,
624483 closure_captures : Option < & ' tcx FxIndexMap < hir:: HirId , ty:: UpvarId > > ,
625484 successors : IndexVec < LiveNode , Option < LiveNode > > ,
626- rwu_table : RWUTable ,
485+ rwu_table : rwu_table :: RWUTable ,
627486
628487 /// A live node representing a point of execution before closure entry &
629488 /// after closure exit. Used to calculate liveness of captured variables
@@ -661,7 +520,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
661520 upvars,
662521 closure_captures,
663522 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) ,
665524 closure_ln,
666525 exit_ln,
667526 break_ln : Default :: default ( ) ,
@@ -796,7 +655,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
796655 // this) so we just clear out all the data.
797656 fn define ( & mut self , writer : LiveNode , var : Variable ) {
798657 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 } ) ;
800659 debug ! ( "{:?} defines {:?}: {}" , writer, var, self . ln_str( writer) ) ;
801660 }
802661
0 commit comments