@@ -25,6 +25,22 @@ const INDENT: &'static str = " ";
25
25
/// Alignment for lining up comments following MIR statements
26
26
const ALIGN : usize = 40 ;
27
27
28
+ /// An indication of where we are in the control flow graph. Used for printing
29
+ /// extra information in `dump_mir`
30
+ pub enum PassWhere {
31
+ /// We have not started dumping the control flow graph, but we are about to.
32
+ BeforeCFG ,
33
+
34
+ /// We just finished dumping the control flow graph. This is right before EOF
35
+ AfterCFG ,
36
+
37
+ /// We are about to start dumping the given basic block.
38
+ BeforeBlock ( BasicBlock ) ,
39
+
40
+ /// We are just about to dumpt the given statement or terminator.
41
+ InCFG ( Location ) ,
42
+ }
43
+
28
44
/// If the session is properly configured, dumps a human-readable
29
45
/// representation of the mir into:
30
46
///
@@ -39,12 +55,16 @@ const ALIGN: usize = 40;
39
55
/// - `substring1&substring2,...` -- `&`-separated list of substrings
40
56
/// that can appear in the pass-name or the `item_path_str` for the given
41
57
/// node-id. If any one of the substrings match, the data is dumped out.
42
- pub fn dump_mir < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
43
- pass_num : Option < ( MirSuite , MirPassIndex ) > ,
44
- pass_name : & str ,
45
- disambiguator : & Display ,
46
- source : MirSource ,
47
- mir : & Mir < ' tcx > ) {
58
+ pub fn dump_mir < ' a , ' tcx , F > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
59
+ pass_num : Option < ( MirSuite , MirPassIndex ) > ,
60
+ pass_name : & str ,
61
+ disambiguator : & Display ,
62
+ source : MirSource ,
63
+ mir : & Mir < ' tcx > ,
64
+ extra_data : F )
65
+ where
66
+ F : FnMut ( PassWhere , & mut Write ) -> io:: Result < ( ) >
67
+ {
48
68
if !dump_enabled ( tcx, pass_name, source) {
49
69
return ;
50
70
}
@@ -53,12 +73,7 @@ pub fn dump_mir<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
53
73
tcx. item_path_str ( tcx. hir . local_def_id ( source. item_id ( ) ) )
54
74
} ) ;
55
75
dump_matched_mir_node ( tcx, pass_num, pass_name, & node_path,
56
- disambiguator, source, mir) ;
57
- for ( index, promoted_mir) in mir. promoted . iter_enumerated ( ) {
58
- let promoted_source = MirSource :: Promoted ( source. item_id ( ) , index) ;
59
- dump_matched_mir_node ( tcx, pass_num, pass_name, & node_path, disambiguator,
60
- promoted_source, promoted_mir) ;
61
- }
76
+ disambiguator, source, mir, extra_data) ;
62
77
}
63
78
64
79
pub fn dump_enabled < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
@@ -85,13 +100,17 @@ pub fn dump_enabled<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
85
100
// `item_path_str()` would otherwise trigger `type_of`, and this can
86
101
// run while we are already attempting to evaluate `type_of`.
87
102
88
- fn dump_matched_mir_node < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
89
- pass_num : Option < ( MirSuite , MirPassIndex ) > ,
90
- pass_name : & str ,
91
- node_path : & str ,
92
- disambiguator : & Display ,
93
- source : MirSource ,
94
- mir : & Mir < ' tcx > ) {
103
+ fn dump_matched_mir_node < ' a , ' tcx , F > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
104
+ pass_num : Option < ( MirSuite , MirPassIndex ) > ,
105
+ pass_name : & str ,
106
+ node_path : & str ,
107
+ disambiguator : & Display ,
108
+ source : MirSource ,
109
+ mir : & Mir < ' tcx > ,
110
+ mut extra_data : F )
111
+ where
112
+ F : FnMut ( PassWhere , & mut Write ) -> io:: Result < ( ) >
113
+ {
95
114
let promotion_id = match source {
96
115
MirSource :: Promoted ( _, id) => format ! ( "-{:?}" , id) ,
97
116
MirSource :: GeneratorDrop ( _) => format ! ( "-drop" ) ,
@@ -125,7 +144,9 @@ fn dump_matched_mir_node<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
125
144
writeln ! ( file, "// generator_layout = {:?}" , layout) ?;
126
145
}
127
146
writeln ! ( file, "" ) ?;
128
- write_mir_fn ( tcx, source, mir, & mut file) ?;
147
+ extra_data ( PassWhere :: BeforeCFG , & mut file) ?;
148
+ write_mir_fn ( tcx, source, mir, & mut extra_data, & mut file) ?;
149
+ extra_data ( PassWhere :: AfterCFG , & mut file) ?;
129
150
Ok ( ( ) )
130
151
} ) ;
131
152
}
@@ -152,24 +173,29 @@ pub fn write_mir_pretty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
152
173
153
174
let id = tcx. hir . as_local_node_id ( def_id) . unwrap ( ) ;
154
175
let src = MirSource :: from_node ( tcx, id) ;
155
- write_mir_fn ( tcx, src, mir, w) ?;
176
+ write_mir_fn ( tcx, src, mir, & mut |_ , _| Ok ( ( ) ) , w) ?;
156
177
157
178
for ( i, mir) in mir. promoted . iter_enumerated ( ) {
158
179
writeln ! ( w, "" ) ?;
159
- write_mir_fn ( tcx, MirSource :: Promoted ( id, i) , mir, w) ?;
180
+ write_mir_fn ( tcx, MirSource :: Promoted ( id, i) , mir, & mut |_ , _| Ok ( ( ) ) , w) ?;
160
181
}
161
182
}
162
183
Ok ( ( ) )
163
184
}
164
185
165
- pub fn write_mir_fn < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
166
- src : MirSource ,
167
- mir : & Mir < ' tcx > ,
168
- w : & mut Write )
169
- -> io:: Result < ( ) > {
186
+ pub fn write_mir_fn < ' a , ' tcx , F > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
187
+ src : MirSource ,
188
+ mir : & Mir < ' tcx > ,
189
+ extra_data : & mut F ,
190
+ w : & mut Write )
191
+ -> io:: Result < ( ) >
192
+ where
193
+ F : FnMut ( PassWhere , & mut Write ) -> io:: Result < ( ) >
194
+ {
170
195
write_mir_intro ( tcx, src, mir, w) ?;
171
196
for block in mir. basic_blocks ( ) . indices ( ) {
172
- write_basic_block ( tcx, block, mir, w) ?;
197
+ extra_data ( PassWhere :: BeforeBlock ( block) , w) ?;
198
+ write_basic_block ( tcx, block, mir, extra_data, w) ?;
173
199
if block. index ( ) + 1 != mir. basic_blocks ( ) . len ( ) {
174
200
writeln ! ( w, "" ) ?;
175
201
}
@@ -180,11 +206,15 @@ pub fn write_mir_fn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
180
206
}
181
207
182
208
/// Write out a human-readable textual representation for the given basic block.
183
- pub fn write_basic_block ( tcx : TyCtxt ,
184
- block : BasicBlock ,
185
- mir : & Mir ,
186
- w : & mut Write )
187
- -> io:: Result < ( ) > {
209
+ pub fn write_basic_block < F > ( tcx : TyCtxt ,
210
+ block : BasicBlock ,
211
+ mir : & Mir ,
212
+ extra_data : & mut F ,
213
+ w : & mut Write )
214
+ -> io:: Result < ( ) >
215
+ where
216
+ F : FnMut ( PassWhere , & mut Write ) -> io:: Result < ( ) >
217
+ {
188
218
let data = & mir[ block] ;
189
219
190
220
// Basic block label at the top.
@@ -195,6 +225,7 @@ pub fn write_basic_block(tcx: TyCtxt,
195
225
// List of statements in the middle.
196
226
let mut current_location = Location { block : block, statement_index : 0 } ;
197
227
for statement in & data. statements {
228
+ extra_data ( PassWhere :: InCFG ( current_location) , w) ?;
198
229
let indented_mir = format ! ( "{0}{0}{1:?};" , INDENT , statement) ;
199
230
writeln ! ( w, "{0:1$} // {2}" ,
200
231
indented_mir,
@@ -205,6 +236,7 @@ pub fn write_basic_block(tcx: TyCtxt,
205
236
}
206
237
207
238
// Terminator at the bottom.
239
+ extra_data ( PassWhere :: InCFG ( current_location) , w) ?;
208
240
let indented_terminator = format ! ( "{0}{0}{1:?};" , INDENT , data. terminator( ) . kind) ;
209
241
writeln ! ( w, "{0:1$} // {2}" ,
210
242
indented_terminator,
0 commit comments