Clean up CtfeLimit MirPass
This commit is contained in:
parent
360db516cc
commit
026a67377f
3 changed files with 72 additions and 78 deletions
|
@ -1,92 +1,49 @@
|
||||||
use crate::MirPass;
|
use crate::MirPass;
|
||||||
|
|
||||||
use rustc_middle::mir::{BasicBlock, Body, Statement, StatementKind, TerminatorKind};
|
use rustc_middle::mir::{BasicBlockData, Body, Statement, StatementKind, TerminatorKind};
|
||||||
use rustc_middle::ty::TyCtxt;
|
use rustc_middle::ty::TyCtxt;
|
||||||
|
|
||||||
use tracing::{info, instrument};
|
|
||||||
|
|
||||||
pub struct CtfeLimit;
|
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 doms = body.basic_blocks.dominators();
|
||||||
//info!("Got body with {} basic blocks: {:#?}", body.basic_blocks.len(), body.basic_blocks);
|
let mut indices = Vec::new();
|
||||||
//info!("With doms: {doms:?}");
|
for (node, node_data) in body.basic_blocks.iter_enumerated() {
|
||||||
|
if let TerminatorKind::Call { .. } = node_data.terminator().kind {
|
||||||
/*
|
indices.push(node);
|
||||||
for (index, basic_block) in body.basic_blocks.iter().enumerate() {
|
continue;
|
||||||
info!("bb{index}: {basic_block:#?}")
|
}
|
||||||
}*/
|
// Back edges in a CFG indicate loops
|
||||||
for (index, basic_block) in body.basic_blocks.iter().enumerate() {
|
for (potential_dom, _) in body.basic_blocks.iter_enumerated() {
|
||||||
info!(
|
if doms.is_reachable(potential_dom)
|
||||||
"bb{index} -> successors = {:?}",
|
&& doms.is_reachable(node)
|
||||||
basic_block.terminator().successors().collect::<Vec<BasicBlock>>()
|
&& doms.is_dominated_by(node, potential_dom)
|
||||||
|
&& node_data
|
||||||
|
.terminator()
|
||||||
|
.successors()
|
||||||
|
.into_iter()
|
||||||
|
.any(|succ| succ == potential_dom)
|
||||||
|
{
|
||||||
|
indices.push(node);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for index in indices {
|
||||||
|
insert_counter(
|
||||||
|
body.basic_blocks_mut()
|
||||||
|
.get_mut(index)
|
||||||
|
.expect("basic_blocks index {index} should exist"),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
for (index, basic_block) in body.basic_blocks.iter().enumerate() {
|
|
||||||
info!("bb{index} -> unwind = {:?}", basic_block.terminator().unwind())
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut dominators = Vec::new();
|
|
||||||
for idom in 0..body.basic_blocks.len() {
|
|
||||||
let mut nodes = Vec::new();
|
|
||||||
for inode in 0..body.basic_blocks.len() {
|
|
||||||
let dom = BasicBlock::from_usize(idom);
|
|
||||||
let node = BasicBlock::from_usize(inode);
|
|
||||||
if doms.is_reachable(dom)
|
|
||||||
&& doms.is_reachable(node)
|
|
||||||
&& doms.is_dominated_by(node, dom)
|
|
||||||
{
|
|
||||||
//info!("{idom} dominates {inode}");
|
|
||||||
nodes.push(true);
|
|
||||||
} else {
|
|
||||||
nodes.push(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dominators.push(nodes);
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
for idom in 0..body.basic_blocks.len() {
|
|
||||||
print!("{idom} | dom | ");
|
|
||||||
for inode in 0..body.basic_blocks.len() {
|
|
||||||
if dominators[idom][inode] {
|
|
||||||
print!("{inode} | ");
|
|
||||||
} else {
|
|
||||||
print!(" | ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
print!("\n");
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
for (index, basic_block) in body.basic_blocks_mut().iter_mut().enumerate() {
|
|
||||||
// info!("bb{index}: {basic_block:#?}");
|
|
||||||
//info!("bb{index} -> successors = {:?}", basic_block.terminator().successors().collect::<Vec<BasicBlock>>());
|
|
||||||
let is_back_edge_or_fn_call = 'label: {
|
|
||||||
match basic_block.terminator().kind {
|
|
||||||
TerminatorKind::Call { .. } => {
|
|
||||||
break 'label true;
|
|
||||||
}
|
|
||||||
_ => (),
|
|
||||||
}
|
|
||||||
for successor in basic_block.terminator().successors() {
|
|
||||||
let s_index = successor.as_usize();
|
|
||||||
if dominators[s_index][index] {
|
|
||||||
info!("{s_index} to {index} is a loop");
|
|
||||||
break 'label true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
false
|
|
||||||
};
|
|
||||||
if is_back_edge_or_fn_call {
|
|
||||||
basic_block.statements.push(Statement {
|
|
||||||
source_info: basic_block.terminator().source_info,
|
|
||||||
kind: StatementKind::ConstEvalCounter,
|
|
||||||
});
|
|
||||||
info!("New basic block statements vector: {:?}", basic_block.statements);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
info!("With doms: {doms:?}");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn insert_counter(basic_block_data: &mut BasicBlockData<'_>) {
|
||||||
|
basic_block_data.statements.push(Statement {
|
||||||
|
source_info: basic_block_data.terminator().source_info,
|
||||||
|
kind: StatementKind::ConstEvalCounter,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
33
src/test/ui/consts/const-eval/stable-metric/ctfe-fn-call.rs
Normal file
33
src/test/ui/consts/const-eval/stable-metric/ctfe-fn-call.rs
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
// check-pass
|
||||||
|
|
||||||
|
const fn foo() {}
|
||||||
|
|
||||||
|
const fn call_foo() -> u32 {
|
||||||
|
foo();
|
||||||
|
foo();
|
||||||
|
foo();
|
||||||
|
foo();
|
||||||
|
foo();
|
||||||
|
foo();
|
||||||
|
foo();
|
||||||
|
foo();
|
||||||
|
foo();
|
||||||
|
foo();
|
||||||
|
foo();
|
||||||
|
foo();
|
||||||
|
foo();
|
||||||
|
foo();
|
||||||
|
foo();
|
||||||
|
foo();
|
||||||
|
foo();
|
||||||
|
foo();
|
||||||
|
foo();
|
||||||
|
foo();
|
||||||
|
0
|
||||||
|
}
|
||||||
|
|
||||||
|
const X: u32 = call_foo();
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
println!("{X}");
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
warning: Const eval counter limit (20) has been crossed
|
||||||
|
|
||||||
|
warning: 1 warning emitted
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue