@@ -21,23 +21,73 @@ use std::fs::File;
21
21
use std:: io;
22
22
use std:: io:: prelude:: * ;
23
23
use std:: marker:: PhantomData ;
24
+ use std:: mem;
24
25
use std:: path:: Path ;
25
26
27
+ use super :: super :: gather_moves:: { MoveData } ;
26
28
use super :: super :: MirBorrowckCtxtPreDataflow ;
27
29
use bitslice:: bits_to_string;
30
+ use indexed_set:: { Idx , IdxSet } ;
28
31
use 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
+ }
30
80
31
81
pub trait MirWithFlowState < ' tcx > {
32
- type BD : BitDenotation ;
82
+ type BD : BitDenotation < Ctxt = MoveData < ' tcx > > ;
33
83
fn node_id ( & self ) -> NodeId ;
34
84
fn mir ( & self ) -> & Mir < ' tcx > ;
35
85
fn analysis_ctxt ( & self ) -> & <Self :: BD as BitDenotation >:: Ctxt ;
36
86
fn flow_state ( & self ) -> & DataflowState < Self :: BD > ;
37
87
}
38
88
39
89
impl < ' 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 > >
41
91
{
42
92
type BD = BD ;
43
93
fn node_id ( & self ) -> NodeId { self . node_id }
@@ -46,19 +96,23 @@ impl<'a, 'tcx: 'a, BD> MirWithFlowState<'tcx> for MirBorrowckCtxtPreDataflow<'a,
46
96
fn flow_state ( & self ) -> & DataflowState < Self :: BD > { & self . flow_state . flow_state }
47
97
}
48
98
49
- struct Graph < ' a , ' tcx , MWF : ' a > where MWF : MirWithFlowState < ' tcx > ,
99
+ struct Graph < ' a , ' tcx , MWF : ' a , P > where
100
+ MWF : MirWithFlowState < ' tcx >
50
101
{
51
102
mbcx : & ' a MWF ,
52
- phantom : PhantomData < & ' tcx ( ) >
103
+ phantom : PhantomData < & ' tcx ( ) > ,
104
+ render_idx : P ,
53
105
}
54
106
55
- pub fn print_borrowck_graph_to < ' a , ' tcx , BD > (
107
+ pub fn print_borrowck_graph_to < ' a , ' tcx , BD , P > (
56
108
mbcx : & MirBorrowckCtxtPreDataflow < ' a , ' tcx , BD > ,
57
- path : & Path )
109
+ path : & Path ,
110
+ render_idx : P )
58
111
-> 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
60
114
{
61
- let g = Graph { mbcx : mbcx, phantom : PhantomData } ;
115
+ let g = Graph { mbcx : mbcx, phantom : PhantomData , render_idx : render_idx } ;
62
116
let mut v = Vec :: new ( ) ;
63
117
dot:: render ( & g, & mut v) ?;
64
118
debug ! ( "print_borrowck_graph_to path: {} node_id: {}" ,
@@ -76,8 +130,9 @@ fn outgoing(mir: &Mir, bb: BasicBlock) -> Vec<Edge> {
76
130
( 0 ..succ_len) . map ( |index| Edge { source : bb, index : index} ) . collect ( )
77
131
}
78
132
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 ,
81
136
{
82
137
type Node = Node ;
83
138
type Edge = Edge ;
@@ -136,10 +191,10 @@ impl<'a, 'tcx, MWF> dot::Labeller<'a> for Graph<'a, 'tcx, MWF>
136
191
const BG_FLOWCONTENT : & ' static str = r#"bgcolor="pink""# ;
137
192
const ALIGN_RIGHT : & ' static str = r#"align="right""# ;
138
193
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 < ( ) >
143
198
{
144
199
// This function may emit a sequence of <tr>'s, but it
145
200
// always finishes with an (unfinished)
@@ -171,7 +226,9 @@ impl<'a, 'tcx, MWF> dot::Labeller<'a> for Graph<'a, 'tcx, MWF>
171
226
|w| {
172
227
let ctxt = self . mbcx . analysis_ctxt ( ) ;
173
228
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 ) ;
175
232
chunked_present_left ( w, & entry_interp[ ..] , chunk_size) ?;
176
233
let bits_per_block = flow. sets . bits_per_block ( ) ;
177
234
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>
186
243
|w| {
187
244
let ctxt = self . mbcx . analysis_ctxt ( ) ;
188
245
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 ) ;
191
248
chunked_present_left ( w, & gen_interp[ ..] , chunk_size) ?;
192
249
let bits_per_block = flow. sets . bits_per_block ( ) ;
193
250
{
@@ -245,7 +302,7 @@ impl<'a, 'tcx, MWF> dot::Labeller<'a> for Graph<'a, 'tcx, MWF>
245
302
}
246
303
}
247
304
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 >
249
306
where MWF : MirWithFlowState < ' tcx >
250
307
{
251
308
type Node = Node ;
0 commit comments