very basic const propagation possible

This commit is contained in:
nora 2022-04-16 23:14:33 +02:00
parent 80b1b0e3f6
commit 9db60ac38d
6 changed files with 45 additions and 15 deletions

View file

@ -86,7 +86,7 @@ where
if let Some(DumpKind::Mir) = config.dump { if let Some(DumpKind::Mir) = config.dump {
let mir_alloc = Bump::new(); let mir_alloc = Bump::new();
let mir = mir::optimized_mir(&mir_alloc, &optimized_hir); let mir = mir::optimized_mir(&mir_alloc, &optimized_hir);
println!("{mir:#?}"); //println!("{mir:#?}");
} }
let cg_alloc = Bump::new(); let cg_alloc = Bump::new();

View file

@ -16,6 +16,7 @@ fn main() {
tracing_subscriber::fmt() tracing_subscriber::fmt()
.with_env_filter(tracing_subscriber::filter::EnvFilter::from_default_env()) .with_env_filter(tracing_subscriber::filter::EnvFilter::from_default_env())
.without_time()
.init(); .init();
let src = fs::read_to_string(&args.file).unwrap_or_else(|err| { let src = fs::read_to_string(&args.file).unwrap_or_else(|err| {

View file

@ -54,10 +54,10 @@ enum StmtKind<'mir> {
SetN(u8, Store), SetN(u8, Store),
} }
#[tracing::instrument] #[tracing::instrument(skip(alloc, hir))]
pub fn optimized_mir<'mir>(alloc: &'mir Bump, hir: &Hir<'_>) -> Mir<'mir> { pub fn optimized_mir<'mir>(alloc: &'mir Bump, hir: &Hir<'_>) -> Mir<'mir> {
let mut mir = hir_to_mir(alloc, hir); let mut mir = hir_to_mir(alloc, hir);
opts::pass_get_state_info(alloc, &mut mir); opts::passes(alloc, &mut mir);
mir mir
} }

View file

@ -1,4 +1,5 @@
use bumpalo::Bump; use bumpalo::Bump;
use tracing::info;
use crate::mir::{ use crate::mir::{
state::{CellState, MemoryState, MemoryStateChange}, state::{CellState, MemoryState, MemoryStateChange},
@ -6,13 +7,19 @@ use crate::mir::{
}; };
/// this pass fills out as much state info for all statements as possible /// this pass fills out as much state info for all statements as possible
#[tracing::instrument] #[tracing::instrument(skip(alloc, mir))]
pub fn passes<'mir>(alloc: &'mir Bump, mir: &mut Mir<'mir>) {
pass_get_state_info(alloc, mir);
pass_const_propagation(mir);
}
/// this pass fills out as much state info for all statements as possible
#[tracing::instrument(skip(alloc, mir))]
pub fn pass_get_state_info<'mir>(alloc: &'mir Bump, mir: &mut Mir<'mir>) { pub fn pass_get_state_info<'mir>(alloc: &'mir Bump, mir: &mut Mir<'mir>) {
let empty_state = MemoryState::empty(alloc); let empty_state = MemoryState::empty(alloc);
pass_get_state_info_inner(alloc, mir, empty_state); pass_get_state_info_inner(alloc, mir, empty_state);
} }
#[tracing::instrument] #[tracing::instrument(skip(alloc, mir))]
fn pass_get_state_info_inner<'mir>( fn pass_get_state_info_inner<'mir>(
alloc: &'mir Bump, alloc: &'mir Bump,
mir: &mut Mir<'mir>, mir: &mut Mir<'mir>,
@ -85,5 +92,28 @@ fn pass_get_state_info_inner<'mir>(
} }
} }
#[tracing::instrument] #[tracing::instrument(skip(mir))]
fn pass_const_propagation(mir: &mut Mir<'_>) {} fn pass_const_propagation(mir: &mut Mir<'_>) {
pass_const_propagation_inner(mir)
}
fn pass_const_propagation_inner(mir: &mut Mir<'_>) {
for stmt in &mut mir.stmts {
match &mut stmt.kind {
StmtKind::Out => {
let state = stmt.state.state_for_offset(0);
info!(?state, "We got the state of the output 😳😳😳");
// we could now insert a `SetN` before the `Out`, to mark the previous store
// as dead.
}
StmtKind::Loop(body) => {
let state = stmt.state.state_for_offset(0);
info!(?state, "We got the state of the output 😳😳😳");
// we could now insert a `SetN` before the `Out`, to mark the previous store
// as dead.
pass_const_propagation_inner(body);
}
_ => {}
}
}
}

View file

@ -38,7 +38,7 @@ impl<'mir> MemoryState<'mir> {
}))) })))
} }
pub fn state_for_offset(&self, offset: i32) -> &'mir CellState { pub fn state_for_offset(&self, offset: i32) -> CellState {
self.0.borrow().state_for_offset(offset) self.0.borrow().state_for_offset(offset)
} }
} }
@ -60,26 +60,25 @@ pub struct MemoryStateInner<'mir> {
} }
impl<'mir> MemoryStateInner<'mir> { impl<'mir> MemoryStateInner<'mir> {
pub fn state_for_offset(&self, offset: i32) -> &'mir CellState { pub fn state_for_offset(&self, offset: i32) -> CellState {
let mut offset = offset; let mut offset = offset;
for delta in &self.deltas { for delta in &self.deltas {
match delta { match delta {
MemoryStateChange::Change { MemoryStateChange::Change {
offset: write_offset, offset: write_offset,
new_state, new_state,
} if *write_offset == offset => { } if *write_offset == offset => return new_state.clone(),
return new_state;
}
MemoryStateChange::Move(change) => offset -= change, MemoryStateChange::Move(change) => offset -= change,
// we may not access the forbidden knowledge // we may not access the forbidden knowledge
MemoryStateChange::Forget => return &CellState::Unknown, MemoryStateChange::Forget => return CellState::Unknown,
_ => {} _ => {}
} }
} }
self.prev self.prev
.as_ref()
.map(|state| state.state_for_offset(offset)) .map(|state| state.state_for_offset(offset))
.unwrap_or(&CellState::Unknown) .unwrap_or(CellState::Unknown)
} }
} }

View file

@ -1 +1 @@
+>. [-]+>[-]<<>.