Fuel mechanism to help debug opts
This commit is contained in:
parent
9031e74abd
commit
f81b5bfbe9
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in a new issue