Fuel mechanism to help debug opts

This commit is contained in:
Chris Fallin 2023-02-25 11:31:49 -08:00
parent 9031e74abd
commit f81b5bfbe9
3 changed files with 39 additions and 10 deletions

View file

@ -3,6 +3,7 @@ use crate::cfg::CFGInfo;
use crate::entity::{EntityRef, EntityVec, PerEntity};
use crate::frontend::parse_body;
use crate::ir::SourceLoc;
use crate::passes::Fuel;
use anyhow::Result;
#[derive(Clone, Debug)]
@ -32,10 +33,10 @@ impl<'a> FuncDecl<'a> {
}
}
pub fn optimize(&mut self) {
pub fn optimize(&mut self, fuel: &mut Fuel) {
match self {
FuncDecl::Body(_, _, body) => {
body.optimize();
body.optimize(fuel);
}
_ => {}
}
@ -131,9 +132,9 @@ impl FunctionBody {
}
}
pub fn optimize(&mut self) {
pub fn optimize(&mut self, fuel: &mut Fuel) {
let cfg = crate::cfg::CFGInfo::new(self);
crate::passes::basic_opt::gvn(self, &cfg);
crate::passes::basic_opt::gvn(self, &cfg, fuel);
crate::passes::resolve_aliases::run(self);
crate::passes::ssa::run(self, &cfg);
}

View file

@ -7,3 +7,18 @@ pub mod maxssa;
pub mod resolve_aliases;
pub mod ssa;
pub mod trace;
#[derive(Clone, Debug)]
pub struct Fuel {
pub remaining: u64,
}
impl Fuel {
pub fn consume(&mut self) -> bool {
if self.remaining == 0 {
false
} else {
self.remaining -= 1;
true
}
}
}

View file

@ -4,19 +4,28 @@ use crate::cfg::CFGInfo;
use crate::interp::{const_eval, ConstVal};
use crate::ir::*;
use crate::passes::dom_pass::{dom_pass, DomtreePass};
use crate::passes::Fuel;
use crate::scoped_map::ScopedMap;
use crate::Operator;
pub fn gvn(body: &mut FunctionBody, cfg: &CFGInfo) {
dom_pass::<GVNPass>(body, cfg, &mut GVNPass::default());
pub fn gvn(body: &mut FunctionBody, cfg: &CFGInfo, fuel: &mut Fuel) {
dom_pass::<GVNPass<'_>>(
body,
cfg,
&mut GVNPass {
map: ScopedMap::default(),
fuel,
},
);
}
#[derive(Clone, Debug, Default)]
struct GVNPass {
#[derive(Debug)]
struct GVNPass<'a> {
map: ScopedMap<ValueDef, Value>,
fuel: &'a mut Fuel,
}
impl DomtreePass for GVNPass {
impl<'a> DomtreePass for GVNPass<'a> {
fn enter(&mut self, block: Block, body: &mut FunctionBody) {
self.map.push_level();
self.optimize(block, body);
@ -34,10 +43,14 @@ fn value_is_pure(value: Value, body: &FunctionBody) -> bool {
}
}
impl GVNPass {
impl<'a> GVNPass<'a> {
fn optimize(&mut self, block: Block, body: &mut FunctionBody) {
let mut i = 0;
while i < body.blocks[block].insts.len() {
if !self.fuel.consume() {
return;
}
let inst = body.blocks[block].insts[i];
i += 1;
if value_is_pure(inst, body) {