Skip caching block transfer functions for acyclic MIR

This commit is contained in:
Dylan MacKenzie 2020-01-20 15:15:37 -08:00
parent 42d19a4e18
commit 5860e78ce9

View File

@ -44,15 +44,20 @@ where
def_id: DefId, def_id: DefId,
analysis: A, analysis: A,
) -> Self { ) -> Self {
// If there are no back-edges in the control-flow graph, we only ever need to apply the
// transfer function for each block exactly once (assuming that we process blocks in RPO).
//
// In this case, there's no need to compute the block transfer functions ahead of time.
if !body.is_cfg_cyclic() {
return Self::new(tcx, body, def_id, analysis, None);
}
// Otherwise, compute and store the cumulative transfer function for each block.
let bits_per_block = analysis.bits_per_block(body); let bits_per_block = analysis.bits_per_block(body);
let mut trans_for_block = let mut trans_for_block =
IndexVec::from_elem(GenKillSet::identity(bits_per_block), body.basic_blocks()); IndexVec::from_elem(GenKillSet::identity(bits_per_block), body.basic_blocks());
// Compute cumulative block transfer functions.
//
// FIXME: we may want to skip this if the MIR is acyclic, since we will never access a
// block transfer function more than once.
for (block, block_data) in body.basic_blocks().iter_enumerated() { for (block, block_data) in body.basic_blocks().iter_enumerated() {
let trans = &mut trans_for_block[block]; let trans = &mut trans_for_block[block];
@ -62,11 +67,10 @@ where
analysis.statement_effect(trans, statement, loc); analysis.statement_effect(trans, statement, loc);
} }
if let Some(terminator) = &block_data.terminator { let terminator = block_data.terminator();
let loc = Location { block, statement_index: block_data.statements.len() }; let loc = Location { block, statement_index: block_data.statements.len() };
analysis.before_terminator_effect(trans, terminator, loc); analysis.before_terminator_effect(trans, terminator, loc);
analysis.terminator_effect(trans, terminator, loc); analysis.terminator_effect(trans, terminator, loc);
}
} }
Self::new(tcx, body, def_id, analysis, Some(trans_for_block)) Self::new(tcx, body, def_id, analysis, Some(trans_for_block))