@@ -44,15 +44,20 @@ where
4444 def_id : DefId ,
4545 analysis : A ,
4646 ) -> 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+
4757 let bits_per_block = analysis. bits_per_block ( body) ;
4858 let mut trans_for_block =
4959 IndexVec :: from_elem ( GenKillSet :: identity ( bits_per_block) , body. basic_blocks ( ) ) ;
5060
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-
5661 for ( block, block_data) in body. basic_blocks ( ) . iter_enumerated ( ) {
5762 let trans = & mut trans_for_block[ block] ;
5863
@@ -62,11 +67,10 @@ where
6267 analysis. statement_effect ( trans, statement, loc) ;
6368 }
6469
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) ;
7074 }
7175
7276 Self :: new ( tcx, body, def_id, analysis, Some ( trans_for_block) )
0 commit comments