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::entity::{EntityRef, EntityVec, PerEntity};
|
||||||
use crate::frontend::parse_body;
|
use crate::frontend::parse_body;
|
||||||
use crate::ir::SourceLoc;
|
use crate::ir::SourceLoc;
|
||||||
|
use crate::passes::Fuel;
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[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 {
|
match self {
|
||||||
FuncDecl::Body(_, _, body) => {
|
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);
|
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::resolve_aliases::run(self);
|
||||||
crate::passes::ssa::run(self, &cfg);
|
crate::passes::ssa::run(self, &cfg);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,3 +7,18 @@ pub mod maxssa;
|
||||||
pub mod resolve_aliases;
|
pub mod resolve_aliases;
|
||||||
pub mod ssa;
|
pub mod ssa;
|
||||||
pub mod trace;
|
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::interp::{const_eval, ConstVal};
|
||||||
use crate::ir::*;
|
use crate::ir::*;
|
||||||
use crate::passes::dom_pass::{dom_pass, DomtreePass};
|
use crate::passes::dom_pass::{dom_pass, DomtreePass};
|
||||||
|
use crate::passes::Fuel;
|
||||||
use crate::scoped_map::ScopedMap;
|
use crate::scoped_map::ScopedMap;
|
||||||
use crate::Operator;
|
use crate::Operator;
|
||||||
|
|
||||||
pub fn gvn(body: &mut FunctionBody, cfg: &CFGInfo) {
|
pub fn gvn(body: &mut FunctionBody, cfg: &CFGInfo, fuel: &mut Fuel) {
|
||||||
dom_pass::<GVNPass>(body, cfg, &mut GVNPass::default());
|
dom_pass::<GVNPass<'_>>(
|
||||||
|
body,
|
||||||
|
cfg,
|
||||||
|
&mut GVNPass {
|
||||||
|
map: ScopedMap::default(),
|
||||||
|
fuel,
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default)]
|
#[derive(Debug)]
|
||||||
struct GVNPass {
|
struct GVNPass<'a> {
|
||||||
map: ScopedMap<ValueDef, Value>,
|
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) {
|
fn enter(&mut self, block: Block, body: &mut FunctionBody) {
|
||||||
self.map.push_level();
|
self.map.push_level();
|
||||||
self.optimize(block, body);
|
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) {
|
fn optimize(&mut self, block: Block, body: &mut FunctionBody) {
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
while i < body.blocks[block].insts.len() {
|
while i < body.blocks[block].insts.len() {
|
||||||
|
if !self.fuel.consume() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let inst = body.blocks[block].insts[i];
|
let inst = body.blocks[block].insts[i];
|
||||||
i += 1;
|
i += 1;
|
||||||
if value_is_pure(inst, body) {
|
if value_is_pure(inst, body) {
|
||||||
|
|
Loading…
Reference in a new issue