@@ -21,23 +21,73 @@ use std::fs::File;
2121use std:: io;
2222use std:: io:: prelude:: * ;
2323use std:: marker:: PhantomData ;
24+ use std:: mem;
2425use std:: path:: Path ;
2526
27+ use super :: super :: gather_moves:: { MoveData } ;
2628use super :: super :: MirBorrowckCtxtPreDataflow ;
2729use bitslice:: bits_to_string;
30+ use indexed_set:: { Idx , IdxSet } ;
2831use super :: { BitDenotation , DataflowState } ;
29- use super :: { HasMoveData } ;
32+
33+ impl < O : BitDenotation > DataflowState < O > {
34+ fn each_bit < F > ( & self , ctxt : & O :: Ctxt , words : & IdxSet < O :: Idx > , mut f : F )
35+ where F : FnMut ( O :: Idx ) {
36+ //! Helper for iterating over the bits in a bitvector.
37+
38+ let bits_per_block = self . operator . bits_per_block ( ctxt) ;
39+ let usize_bits: usize = mem:: size_of :: < usize > ( ) * 8 ;
40+
41+ for ( word_index, & word) in words. words ( ) . iter ( ) . enumerate ( ) {
42+ if word != 0 {
43+ let base_index = word_index * usize_bits;
44+ for offset in 0 ..usize_bits {
45+ let bit = 1 << offset;
46+ if ( word & bit) != 0 {
47+ // NB: we round up the total number of bits
48+ // that we store in any given bit set so that
49+ // it is an even multiple of usize::BITS. This
50+ // means that there may be some stray bits at
51+ // the end that do not correspond to any
52+ // actual value; that's why we first check
53+ // that we are in range of bits_per_block.
54+ let bit_index = base_index + offset as usize ;
55+ if bit_index >= bits_per_block {
56+ return ;
57+ } else {
58+ f ( O :: Idx :: new ( bit_index) ) ;
59+ }
60+ }
61+ }
62+ }
63+ }
64+ }
65+
66+ pub fn interpret_set < ' c , P > ( & self ,
67+ ctxt : & ' c O :: Ctxt ,
68+ words : & IdxSet < O :: Idx > ,
69+ render_idx : & P )
70+ -> Vec < & ' c Debug >
71+ where P : for < ' b > Fn ( & ' b O :: Ctxt , O :: Idx ) -> & ' b Debug
72+ {
73+ let mut v = Vec :: new ( ) ;
74+ self . each_bit ( ctxt, words, |i| {
75+ v. push ( render_idx ( ctxt, i) ) ;
76+ } ) ;
77+ v
78+ }
79+ }
3080
3181pub trait MirWithFlowState < ' tcx > {
32- type BD : BitDenotation ;
82+ type BD : BitDenotation < Ctxt = MoveData < ' tcx > > ;
3383 fn node_id ( & self ) -> NodeId ;
3484 fn mir ( & self ) -> & Mir < ' tcx > ;
3585 fn analysis_ctxt ( & self ) -> & <Self :: BD as BitDenotation >:: Ctxt ;
3686 fn flow_state ( & self ) -> & DataflowState < Self :: BD > ;
3787}
3888
3989impl < ' a , ' tcx : ' a , BD > MirWithFlowState < ' tcx > for MirBorrowckCtxtPreDataflow < ' a , ' tcx , BD >
40- where ' a , ' tcx : ' a , BD : BitDenotation , BD :: Ctxt : HasMoveData < ' tcx >
90+ where ' a , ' tcx : ' a , BD : BitDenotation < Ctxt = MoveData < ' tcx > >
4191{
4292 type BD = BD ;
4393 fn node_id ( & self ) -> NodeId { self . node_id }
@@ -46,19 +96,23 @@ impl<'a, 'tcx: 'a, BD> MirWithFlowState<'tcx> for MirBorrowckCtxtPreDataflow<'a,
4696 fn flow_state ( & self ) -> & DataflowState < Self :: BD > { & self . flow_state . flow_state }
4797}
4898
49- struct Graph < ' a , ' tcx , MWF : ' a > where MWF : MirWithFlowState < ' tcx > ,
99+ struct Graph < ' a , ' tcx , MWF : ' a , P > where
100+ MWF : MirWithFlowState < ' tcx >
50101{
51102 mbcx : & ' a MWF ,
52- phantom : PhantomData < & ' tcx ( ) >
103+ phantom : PhantomData < & ' tcx ( ) > ,
104+ render_idx : P ,
53105}
54106
55- pub fn print_borrowck_graph_to < ' a , ' tcx , BD > (
107+ pub fn print_borrowck_graph_to < ' a , ' tcx , BD , P > (
56108 mbcx : & MirBorrowckCtxtPreDataflow < ' a , ' tcx , BD > ,
57- path : & Path )
109+ path : & Path ,
110+ render_idx : P )
58111 -> io:: Result < ( ) >
59- where BD : BitDenotation , BD :: Bit : Debug , BD :: Ctxt : HasMoveData < ' tcx > ,
112+ where BD : BitDenotation < Ctxt =MoveData < ' tcx > > , BD :: Bit : Debug ,
113+ P : for < ' b > Fn ( & ' b BD :: Ctxt , BD :: Idx ) -> & ' b Debug
60114{
61- let g = Graph { mbcx : mbcx, phantom : PhantomData } ;
115+ let g = Graph { mbcx : mbcx, phantom : PhantomData , render_idx : render_idx } ;
62116 let mut v = Vec :: new ( ) ;
63117 dot:: render ( & g, & mut v) ?;
64118 debug ! ( "print_borrowck_graph_to path: {} node_id: {}" ,
@@ -76,8 +130,9 @@ fn outgoing(mir: &Mir, bb: BasicBlock) -> Vec<Edge> {
76130 ( 0 ..succ_len) . map ( |index| Edge { source : bb, index : index} ) . collect ( )
77131}
78132
79- impl < ' a , ' tcx , MWF > dot:: Labeller < ' a > for Graph < ' a , ' tcx , MWF >
80- where MWF : MirWithFlowState < ' tcx > , <MWF :: BD as BitDenotation >:: Bit : Debug
133+ impl < ' a , ' tcx , MWF , P > dot:: Labeller < ' a > for Graph < ' a , ' tcx , MWF , P >
134+ where MWF : MirWithFlowState < ' tcx > , <MWF :: BD as BitDenotation >:: Bit : Debug ,
135+ P : for < ' b > Fn ( & ' b <MWF :: BD as BitDenotation >:: Ctxt , <MWF :: BD as BitDenotation >:: Idx ) -> & ' b Debug ,
81136{
82137 type Node = Node ;
83138 type Edge = Edge ;
@@ -136,10 +191,10 @@ impl<'a, 'tcx, MWF> dot::Labeller<'a> for Graph<'a, 'tcx, MWF>
136191 const BG_FLOWCONTENT : & ' static str = r#"bgcolor="pink""# ;
137192 const ALIGN_RIGHT : & ' static str = r#"align="right""# ;
138193 const FACE_MONOSPACE : & ' static str = r#"FACE="Courier""# ;
139- fn chunked_present_left < D : Debug , W : io:: Write > ( w : & mut W ,
140- interpreted : & [ & D ] ,
141- chunk_size : usize )
142- -> io:: Result < ( ) >
194+ fn chunked_present_left < W : io:: Write > ( w : & mut W ,
195+ interpreted : & [ & Debug ] ,
196+ chunk_size : usize )
197+ -> io:: Result < ( ) >
143198 {
144199 // This function may emit a sequence of <tr>'s, but it
145200 // always finishes with an (unfinished)
@@ -171,7 +226,9 @@ impl<'a, 'tcx, MWF> dot::Labeller<'a> for Graph<'a, 'tcx, MWF>
171226 |w| {
172227 let ctxt = self . mbcx . analysis_ctxt ( ) ;
173228 let flow = self . mbcx . flow_state ( ) ;
174- let entry_interp = flow. interpret_set ( ctxt, flow. sets . on_entry_set_for ( i) ) ;
229+ let entry_interp = flow. interpret_set ( ctxt,
230+ flow. sets . on_entry_set_for ( i) ,
231+ & self . render_idx ) ;
175232 chunked_present_left ( w, & entry_interp[ ..] , chunk_size) ?;
176233 let bits_per_block = flow. sets . bits_per_block ( ) ;
177234 let entry = flow. sets . on_entry_set_for ( i) ;
@@ -186,8 +243,8 @@ impl<'a, 'tcx, MWF> dot::Labeller<'a> for Graph<'a, 'tcx, MWF>
186243 |w| {
187244 let ctxt = self . mbcx . analysis_ctxt ( ) ;
188245 let flow = self . mbcx . flow_state ( ) ;
189- let gen_interp = flow. interpret_set ( ctxt, flow. sets . gen_set_for ( i) ) ;
190- let kill_interp = flow. interpret_set ( ctxt, flow. sets . kill_set_for ( i) ) ;
246+ let gen_interp = flow. interpret_set ( ctxt, flow. sets . gen_set_for ( i) , & self . render_idx ) ;
247+ let kill_interp = flow. interpret_set ( ctxt, flow. sets . kill_set_for ( i) , & self . render_idx ) ;
191248 chunked_present_left ( w, & gen_interp[ ..] , chunk_size) ?;
192249 let bits_per_block = flow. sets . bits_per_block ( ) ;
193250 {
@@ -245,7 +302,7 @@ impl<'a, 'tcx, MWF> dot::Labeller<'a> for Graph<'a, 'tcx, MWF>
245302 }
246303}
247304
248- impl < ' a , ' tcx , MWF > dot:: GraphWalk < ' a > for Graph < ' a , ' tcx , MWF >
305+ impl < ' a , ' tcx , MWF , P > dot:: GraphWalk < ' a > for Graph < ' a , ' tcx , MWF , P >
249306 where MWF : MirWithFlowState < ' tcx >
250307{
251308 type Node = Node ;
0 commit comments