remove aliased symbols after definition

This commit is contained in:
Folkert 2021-01-29 15:49:59 +01:00
parent 4bd9d417d1
commit b5cfb12a3b

View file

@ -125,6 +125,7 @@ pub struct Env<'a, 'i> {
pub deferred: Deferred<'a>, pub deferred: Deferred<'a>,
} }
#[derive(Debug)]
pub struct Deferred<'a> { pub struct Deferred<'a> {
pub inc_dec_map: LinkedHashMap<Symbol, i64>, pub inc_dec_map: LinkedHashMap<Symbol, i64>,
pub assignments: Vec<'a, (Symbol, Expr<'a>, Layout<'a>)>, pub assignments: Vec<'a, (Symbol, Expr<'a>, Layout<'a>)>,
@ -284,7 +285,7 @@ fn can_push_inc_through(stmt: &Stmt) -> bool {
match stmt { match stmt {
Let(_, expr, _, _) => { Let(_, expr, _, _) => {
// we can always delay an increment/decrement until after a field access // we can always delay an increment/decrement until after a field access
matches!(expr, Expr::AccessAtIndex { .. }) matches!(expr, Expr::AccessAtIndex { .. } | Expr::Literal(_))
} }
Refcounting(ModifyRc::Inc(_, _), _) => true, Refcounting(ModifyRc::Inc(_, _), _) => true,
@ -325,6 +326,8 @@ pub fn expand_and_cancel<'a>(env: &mut Env<'a, '_>, stmt: &'a Stmt<'a>) -> &'a S
env.layout_map.insert(symbol, layout.clone()); env.layout_map.insert(symbol, layout.clone());
let new_cont;
if let Expr::AccessAtIndex { if let Expr::AccessAtIndex {
structure, index, .. structure, index, ..
} = expr } = expr
@ -335,10 +338,18 @@ pub fn expand_and_cancel<'a>(env: &mut Env<'a, '_>, stmt: &'a Stmt<'a>) -> &'a S
.or_insert_with(MutMap::default); .or_insert_with(MutMap::default);
entry.insert(*index, symbol); entry.insert(*index, symbol);
new_cont = expand_and_cancel(env, cont);
// make sure to remove the alias, so other branches don't use it by accident
env.alias_map
.get_mut(structure)
.and_then(|map| map.remove(index));
} else {
new_cont = expand_and_cancel(env, cont);
} }
let cont = expand_and_cancel(env, cont); let stmt = Let(symbol, expr.clone(), layout.clone(), new_cont);
let stmt = Let(symbol, expr.clone(), layout.clone(), cont);
&*env.arena.alloc(stmt) &*env.arena.alloc(stmt)
} }