@@ -44,15 +44,20 @@ where
44
44
def_id : DefId ,
45
45
analysis : A ,
46
46
) -> Self {
47
+ // If there are no back-edges in the control-flow graph, we only ever need to apply the
48
+ // transfer function for each block exactly once (assuming that we process blocks in RPO).
49
+ //
50
+ // In this case, there's no need to compute the block transfer functions ahead of time.
51
+ if !body. is_cfg_cyclic ( ) {
52
+ return Self :: new ( tcx, body, def_id, analysis, None ) ;
53
+ }
54
+
55
+ // Otherwise, compute and store the cumulative transfer function for each block.
56
+
47
57
let bits_per_block = analysis. bits_per_block ( body) ;
48
58
let mut trans_for_block =
49
59
IndexVec :: from_elem ( GenKillSet :: identity ( bits_per_block) , body. basic_blocks ( ) ) ;
50
60
51
- // Compute cumulative block transfer functions.
52
- //
53
- // FIXME: we may want to skip this if the MIR is acyclic, since we will never access a
54
- // block transfer function more than once.
55
-
56
61
for ( block, block_data) in body. basic_blocks ( ) . iter_enumerated ( ) {
57
62
let trans = & mut trans_for_block[ block] ;
58
63
@@ -62,11 +67,10 @@ where
62
67
analysis. statement_effect ( trans, statement, loc) ;
63
68
}
64
69
65
- if let Some ( terminator) = & block_data. terminator {
66
- let loc = Location { block, statement_index : block_data. statements . len ( ) } ;
67
- analysis. before_terminator_effect ( trans, terminator, loc) ;
68
- analysis. terminator_effect ( trans, terminator, loc) ;
69
- }
70
+ let terminator = block_data. terminator ( ) ;
71
+ let loc = Location { block, statement_index : block_data. statements . len ( ) } ;
72
+ analysis. before_terminator_effect ( trans, terminator, loc) ;
73
+ analysis. terminator_effect ( trans, terminator, loc) ;
70
74
}
71
75
72
76
Self :: new ( tcx, body, def_id, analysis, Some ( trans_for_block) )
0 commit comments