From 5860e78ce9b5926de2d856d2dc8e4f3790584b81 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Mon, 20 Jan 2020 15:15:37 -0800 Subject: [PATCH] Skip caching block transfer functions for acyclic MIR --- src/librustc_mir/dataflow/generic/engine.rs | 24 ++++++++++++--------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/librustc_mir/dataflow/generic/engine.rs b/src/librustc_mir/dataflow/generic/engine.rs index 718c1e9ae20..b81f0adc201 100644 --- a/src/librustc_mir/dataflow/generic/engine.rs +++ b/src/librustc_mir/dataflow/generic/engine.rs @@ -44,15 +44,20 @@ where def_id: DefId, analysis: A, ) -> 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 mut trans_for_block = 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() { let trans = &mut trans_for_block[block]; @@ -62,11 +67,10 @@ where analysis.statement_effect(trans, statement, loc); } - if let Some(terminator) = &block_data.terminator { - let loc = Location { block, statement_index: block_data.statements.len() }; - analysis.before_terminator_effect(trans, terminator, loc); - analysis.terminator_effect(trans, terminator, loc); - } + let terminator = block_data.terminator(); + let loc = Location { block, statement_index: block_data.statements.len() }; + analysis.before_terminator_effect(trans, terminator, loc); + analysis.terminator_effect(trans, terminator, loc); } Self::new(tcx, body, def_id, analysis, Some(trans_for_block))