Improve efficiency of has_back_edge(...)
This commit is contained in:
parent
7618163a1c
commit
1bbd655888
2 changed files with 18 additions and 10 deletions
|
@ -2,8 +2,9 @@
|
|||
//! (thus indicating there is a loop in the CFG), or whose terminator is a function call.
|
||||
use crate::MirPass;
|
||||
|
||||
use rustc_data_structures::graph::dominators::Dominators;
|
||||
use rustc_middle::mir::{
|
||||
BasicBlock, BasicBlockData, BasicBlocks, Body, Statement, StatementKind, TerminatorKind,
|
||||
BasicBlock, BasicBlockData, Body, Statement, StatementKind, TerminatorKind,
|
||||
};
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
|
||||
|
@ -12,13 +13,14 @@ 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<BasicBlock> = 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
|
||||
|| has_back_edge(&body.basic_blocks, node, &node_data)
|
||||
|| has_back_edge(&doms, node, &node_data)
|
||||
{
|
||||
Some(node)
|
||||
} else {
|
||||
|
@ -37,17 +39,16 @@ impl<'tcx> MirPass<'tcx> for CtfeLimit {
|
|||
}
|
||||
|
||||
fn has_back_edge(
|
||||
basic_blocks: &BasicBlocks<'_>,
|
||||
doms: &Dominators<BasicBlock>,
|
||||
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)
|
||||
})
|
||||
if !doms.is_reachable(node) {
|
||||
return false;
|
||||
}
|
||||
// Check if any of the dominators of the node are also the node's successor.
|
||||
doms.dominators(node)
|
||||
.any(|dom| node_data.terminator().successors().into_iter().any(|succ| succ == dom))
|
||||
}
|
||||
|
||||
fn insert_counter(basic_block_data: &mut BasicBlockData<'_>) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue