@@ -201,11 +201,12 @@ struct Formatter<'mir, 'tcx, A>
201
201
where
202
202
A : Analysis < ' tcx > ,
203
203
{
204
+ body : & ' mir Body < ' tcx > ,
204
205
// The `RefCell` is used because `<Formatter as Labeller>::node_label`
205
- // takes `&self`, but it needs to modify the cursor . This is also the
206
+ // takes `&self`, but it needs to modify the results . This is also the
206
207
// reason for the `Formatter`/`BlockFormatter` split; `BlockFormatter` has
207
208
// the operations that involve the mutation, i.e. within the `borrow_mut`.
208
- cursor : RefCell < ResultsCursor < ' mir , ' tcx , A > > ,
209
+ results : RefCell < & ' mir mut Results < ' tcx , A > > ,
209
210
style : OutputStyle ,
210
211
reachable : DenseBitSet < BasicBlock > ,
211
212
}
@@ -220,11 +221,7 @@ where
220
221
style : OutputStyle ,
221
222
) -> Self {
222
223
let reachable = traversal:: reachable_as_bitset ( body) ;
223
- Formatter { cursor : results. as_results_cursor ( body) . into ( ) , style, reachable }
224
- }
225
-
226
- fn body ( & self ) -> & ' mir Body < ' tcx > {
227
- self . cursor . borrow ( ) . body ( )
224
+ Formatter { body, results : results. into ( ) , style, reachable }
228
225
}
229
226
}
230
227
@@ -253,7 +250,7 @@ where
253
250
type Edge = CfgEdge ;
254
251
255
252
fn graph_id ( & self ) -> dot:: Id < ' _ > {
256
- let name = graphviz_safe_def_name ( self . body ( ) . source . def_id ( ) ) ;
253
+ let name = graphviz_safe_def_name ( self . body . source . def_id ( ) ) ;
257
254
dot:: Id :: new ( format ! ( "graph_for_def_id_{name}" ) ) . unwrap ( )
258
255
}
259
256
@@ -262,10 +259,16 @@ where
262
259
}
263
260
264
261
fn node_label ( & self , block : & Self :: Node ) -> dot:: LabelText < ' _ > {
265
- let mut cursor = self . cursor . borrow_mut ( ) ;
266
- let mut fmt =
267
- BlockFormatter { cursor : & mut cursor, style : self . style , bg : Background :: Light } ;
268
- let label = fmt. write_node_label ( * block) . unwrap ( ) ;
262
+ let mut results = self . results . borrow_mut ( ) ;
263
+
264
+ let diffs = StateDiffCollector :: run ( self . body , * block, * results, self . style ) ;
265
+
266
+ let mut fmt = BlockFormatter {
267
+ cursor : results. as_results_cursor ( self . body ) ,
268
+ style : self . style ,
269
+ bg : Background :: Light ,
270
+ } ;
271
+ let label = fmt. write_node_label ( * block, diffs) . unwrap ( ) ;
269
272
270
273
dot:: LabelText :: html ( String :: from_utf8 ( label) . unwrap ( ) )
271
274
}
@@ -275,7 +278,7 @@ where
275
278
}
276
279
277
280
fn edge_label ( & self , e : & Self :: Edge ) -> dot:: LabelText < ' _ > {
278
- let label = & self . body ( ) [ e. source ] . terminator ( ) . kind . fmt_successor_labels ( ) [ e. index ] ;
281
+ let label = & self . body [ e. source ] . terminator ( ) . kind . fmt_successor_labels ( ) [ e. index ] ;
279
282
dot:: LabelText :: label ( label. clone ( ) )
280
283
}
281
284
}
@@ -288,7 +291,7 @@ where
288
291
type Edge = CfgEdge ;
289
292
290
293
fn nodes ( & self ) -> dot:: Nodes < ' _ , Self :: Node > {
291
- self . body ( )
294
+ self . body
292
295
. basic_blocks
293
296
. indices ( )
294
297
. filter ( |& idx| self . reachable . contains ( idx) )
@@ -297,10 +300,10 @@ where
297
300
}
298
301
299
302
fn edges ( & self ) -> dot:: Edges < ' _ , Self :: Edge > {
300
- let body = self . body ( ) ;
301
- body . basic_blocks
303
+ self . body
304
+ . basic_blocks
302
305
. indices ( )
303
- . flat_map ( |bb| dataflow_successors ( body, bb) )
306
+ . flat_map ( |bb| dataflow_successors ( self . body , bb) )
304
307
. collect :: < Vec < _ > > ( )
305
308
. into ( )
306
309
}
@@ -310,20 +313,20 @@ where
310
313
}
311
314
312
315
fn target ( & self , edge : & Self :: Edge ) -> Self :: Node {
313
- self . body ( ) [ edge. source ] . terminator ( ) . successors ( ) . nth ( edge. index ) . unwrap ( )
316
+ self . body [ edge. source ] . terminator ( ) . successors ( ) . nth ( edge. index ) . unwrap ( )
314
317
}
315
318
}
316
319
317
- struct BlockFormatter < ' a , ' mir , ' tcx , A >
320
+ struct BlockFormatter < ' mir , ' tcx , A >
318
321
where
319
322
A : Analysis < ' tcx > ,
320
323
{
321
- cursor : & ' a mut ResultsCursor < ' mir , ' tcx , A > ,
324
+ cursor : ResultsCursor < ' mir , ' tcx , A > ,
322
325
bg : Background ,
323
326
style : OutputStyle ,
324
327
}
325
328
326
- impl < ' tcx , A > BlockFormatter < ' _ , ' _ , ' tcx , A >
329
+ impl < ' tcx , A > BlockFormatter < ' _ , ' tcx , A >
327
330
where
328
331
A : Analysis < ' tcx > ,
329
332
A :: Domain : DebugWithContext < A > ,
@@ -336,7 +339,11 @@ where
336
339
bg
337
340
}
338
341
339
- fn write_node_label ( & mut self , block : BasicBlock ) -> io:: Result < Vec < u8 > > {
342
+ fn write_node_label (
343
+ & mut self ,
344
+ block : BasicBlock ,
345
+ diffs : StateDiffCollector < A :: Domain > ,
346
+ ) -> io:: Result < Vec < u8 > > {
340
347
use std:: io:: Write ;
341
348
342
349
// Sample output:
@@ -392,7 +399,7 @@ where
392
399
self . write_row_with_full_state ( w, "" , "(on start)" ) ?;
393
400
394
401
// D + E: Statement and terminator transfer functions
395
- self . write_statements_and_terminator ( w, block) ?;
402
+ self . write_statements_and_terminator ( w, block, diffs ) ?;
396
403
397
404
// F: State at end of block
398
405
@@ -575,14 +582,8 @@ where
575
582
& mut self ,
576
583
w : & mut impl io:: Write ,
577
584
block : BasicBlock ,
585
+ diffs : StateDiffCollector < A :: Domain > ,
578
586
) -> io:: Result < ( ) > {
579
- let diffs = StateDiffCollector :: run (
580
- self . cursor . body ( ) ,
581
- block,
582
- self . cursor . mut_results ( ) ,
583
- self . style ,
584
- ) ;
585
-
586
587
let mut diffs_before = diffs. before . map ( |v| v. into_iter ( ) ) ;
587
588
let mut diffs_after = diffs. after . into_iter ( ) ;
588
589
@@ -709,7 +710,7 @@ impl<D> StateDiffCollector<D> {
709
710
}
710
711
}
711
712
712
- impl < ' tcx , A > ResultsVisitor < ' _ , ' tcx , A > for StateDiffCollector < A :: Domain >
713
+ impl < ' tcx , A > ResultsVisitor < ' tcx , A > for StateDiffCollector < A :: Domain >
713
714
where
714
715
A : Analysis < ' tcx > ,
715
716
A :: Domain : DebugWithContext < A > ,
0 commit comments