diff --git a/compiler/rustc_mir_transform/src/ctfe_limit.rs b/compiler/rustc_mir_transform/src/ctfe_limit.rs index 462be8afaaf..1ff8b792dca 100644 --- a/compiler/rustc_mir_transform/src/ctfe_limit.rs +++ b/compiler/rustc_mir_transform/src/ctfe_limit.rs @@ -1,7 +1,7 @@ use crate::MirPass; use rustc_middle::mir::{ - BasicBlock, BasicBlockData, Body, Statement, StatementKind, TerminatorKind, + BasicBlock, BasicBlockData, BasicBlocks, Body, Statement, StatementKind, TerminatorKind, }; use rustc_middle::ty::TyCtxt; @@ -10,29 +10,20 @@ pub struct CtfeLimit; impl<'tcx> MirPass<'tcx> for CtfeLimit { #[instrument(skip(self, _tcx, body))] fn run_pass(&self, _tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - let doms = body.basic_blocks.dominators(); - let indices: Vec = - body.basic_blocks - .iter_enumerated() - .filter_map(|(node, node_data)| { - if matches!(node_data.terminator().kind, TerminatorKind::Call { .. }) || + let indices: Vec = body + .basic_blocks + .iter_enumerated() + .filter_map(|(node, node_data)| { + if matches!(node_data.terminator().kind, TerminatorKind::Call { .. }) // Back edges in a CFG indicate loops - body.basic_blocks.iter_enumerated().any(|(potential_dom, _)| { - doms.is_reachable(potential_dom) - && doms.is_reachable(node) - && doms.is_dominated_by(node, potential_dom) - && node_data - .terminator() - .successors() - .into_iter() - .any(|succ| succ == potential_dom) - }) { - Some(node) - } else { - None - } - }) - .collect(); + || has_back_edge(&body.basic_blocks, node, &node_data) + { + Some(node) + } else { + None + } + }) + .collect(); for index in indices { insert_counter( body.basic_blocks_mut() @@ -43,6 +34,20 @@ impl<'tcx> MirPass<'tcx> for CtfeLimit { } } +fn has_back_edge( + basic_blocks: &BasicBlocks<'_>, + node: BasicBlock, + node_data: &BasicBlockData<'_>, +) -> bool { + let doms = basic_blocks.dominators(); + basic_blocks.indices().any(|potential_dom| { + doms.is_reachable(potential_dom) + && doms.is_reachable(node) + && doms.is_dominated_by(node, potential_dom) + && node_data.terminator().successors().into_iter().any(|succ| succ == potential_dom) + }) +} + fn insert_counter(basic_block_data: &mut BasicBlockData<'_>) { basic_block_data.statements.push(Statement { source_info: basic_block_data.terminator().source_info,