Abstract out has_back_edge fn
This commit is contained in:
parent
009beb00bc
commit
8d99b0fc8d
1 changed files with 28 additions and 23 deletions
|
@ -1,7 +1,7 @@
|
||||||
use crate::MirPass;
|
use crate::MirPass;
|
||||||
|
|
||||||
use rustc_middle::mir::{
|
use rustc_middle::mir::{
|
||||||
BasicBlock, BasicBlockData, Body, Statement, StatementKind, TerminatorKind,
|
BasicBlock, BasicBlockData, BasicBlocks, Body, Statement, StatementKind, TerminatorKind,
|
||||||
};
|
};
|
||||||
use rustc_middle::ty::TyCtxt;
|
use rustc_middle::ty::TyCtxt;
|
||||||
|
|
||||||
|
@ -10,23 +10,14 @@ pub struct CtfeLimit;
|
||||||
impl<'tcx> MirPass<'tcx> for CtfeLimit {
|
impl<'tcx> MirPass<'tcx> for CtfeLimit {
|
||||||
#[instrument(skip(self, _tcx, body))]
|
#[instrument(skip(self, _tcx, body))]
|
||||||
fn run_pass(&self, _tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
fn run_pass(&self, _tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||||
let doms = body.basic_blocks.dominators();
|
let indices: Vec<BasicBlock> = body
|
||||||
let indices: Vec<BasicBlock> =
|
.basic_blocks
|
||||||
body.basic_blocks
|
|
||||||
.iter_enumerated()
|
.iter_enumerated()
|
||||||
.filter_map(|(node, node_data)| {
|
.filter_map(|(node, node_data)| {
|
||||||
if matches!(node_data.terminator().kind, TerminatorKind::Call { .. }) ||
|
if matches!(node_data.terminator().kind, TerminatorKind::Call { .. })
|
||||||
// Back edges in a CFG indicate loops
|
// Back edges in a CFG indicate loops
|
||||||
body.basic_blocks.iter_enumerated().any(|(potential_dom, _)| {
|
|| has_back_edge(&body.basic_blocks, node, &node_data)
|
||||||
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)
|
Some(node)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -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<'_>) {
|
fn insert_counter(basic_block_data: &mut BasicBlockData<'_>) {
|
||||||
basic_block_data.statements.push(Statement {
|
basic_block_data.statements.push(Statement {
|
||||||
source_info: basic_block_data.terminator().source_info,
|
source_info: basic_block_data.terminator().source_info,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue