add update mode to reset and reuse

This commit is contained in:
Folkert 2021-11-28 14:13:02 +01:00
parent 1241d5ccbd
commit 0bdda2506c
8 changed files with 40 additions and 21 deletions

View file

@ -757,8 +757,8 @@ where
self.set_last_seen(*sym, stmt, &owning_symbol); self.set_last_seen(*sym, stmt, &owning_symbol);
} }
} }
Expr::Reset(sym) => { Expr::Reset { symbol, .. } => {
self.set_last_seen(*sym, stmt, &owning_symbol); self.set_last_seen(*symbol, stmt, &owning_symbol);
} }
Expr::EmptyArray => {} Expr::EmptyArray => {}
Expr::RuntimeErrorFunction(_) => {} Expr::RuntimeErrorFunction(_) => {}

View file

@ -1108,7 +1108,7 @@ pub fn build_exp_expr<'a, 'ctx, 'env>(
.. ..
} => build_tag(env, scope, union_layout, *tag_id, arguments, None, parent), } => build_tag(env, scope, union_layout, *tag_id, arguments, None, parent),
Reset(symbol) => { Reset { symbol, .. } => {
let (tag_ptr, layout) = load_symbol_and_layout(scope, symbol); let (tag_ptr, layout) = load_symbol_and_layout(scope, symbol);
let tag_ptr = tag_ptr.into_pointer_value(); let tag_ptr = tag_ptr.into_pointer_value();

View file

@ -2100,6 +2100,7 @@ fn update<'a>(
MadeSpecializations { MadeSpecializations {
module_id, module_id,
mut ident_ids, mut ident_ids,
mut update_mode_ids,
subs, subs,
procedures, procedures,
external_specializations_requested, external_specializations_requested,
@ -2126,6 +2127,7 @@ fn update<'a>(
arena, arena,
module_id, module_id,
&mut ident_ids, &mut ident_ids,
&mut update_mode_ids,
&mut state.procedures, &mut state.procedures,
); );

View file

@ -1626,7 +1626,7 @@ fn expr_spec<'a>(
} }
_ => unreachable!("empty array does not have a list layout"), _ => unreachable!("empty array does not have a list layout"),
}, },
Reset(symbol) => { Reset { symbol, .. } => {
let type_id = layout_spec(builder, layout)?; let type_id = layout_spec(builder, layout)?;
let value_id = env.symbols[symbol]; let value_id = env.symbols[symbol];

View file

@ -726,7 +726,7 @@ impl<'a> BorrowInfState<'a> {
// the function must take it as an owned parameter // the function must take it as an owned parameter
self.own_args_if_param(xs); self.own_args_if_param(xs);
} }
Reset(x) => { Reset { symbol: x, .. } => {
self.own_var(z); self.own_var(z);
self.own_var(*x); self.own_var(*x);
} }

View file

@ -110,7 +110,7 @@ pub fn occurring_variables_expr(expr: &Expr<'_>, result: &mut MutSet<Symbol>) {
result.extend(arguments.iter().copied()); result.extend(arguments.iter().copied());
result.insert(*symbol); result.insert(*symbol);
} }
Reset(x) => { Reset { symbol: x, .. } => {
result.insert(*x); result.insert(*x);
} }
@ -761,7 +761,7 @@ impl<'a> Context<'a> {
self.arena.alloc(Stmt::Let(z, v, l, b)) self.arena.alloc(Stmt::Let(z, v, l, b))
} }
EmptyArray | Literal(_) | Reset(_) | RuntimeErrorFunction(_) => { EmptyArray | Literal(_) | Reset { .. } | RuntimeErrorFunction(_) => {
// EmptyArray is always stack-allocated // EmptyArray is always stack-allocated
// function pointers are persistent // function pointers are persistent
self.arena.alloc(Stmt::Let(z, v, l, b)) self.arena.alloc(Stmt::Let(z, v, l, b))
@ -779,7 +779,7 @@ impl<'a> Context<'a> {
// must this value be consumed? // must this value be consumed?
let consume = consume_expr(&self.vars, expr); let consume = consume_expr(&self.vars, expr);
let reset = matches!(expr, Expr::Reset(_)); let reset = matches!(expr, Expr::Reset { .. });
self.update_var_info_help(symbol, layout, persistent, consume, reset) self.update_var_info_help(symbol, layout, persistent, consume, reset)
} }

View file

@ -31,7 +31,7 @@ pub const PRETTY_PRINT_IR_SYMBOLS: bool = false;
static_assertions::assert_eq_size!([u8; 4 * 8], Literal); static_assertions::assert_eq_size!([u8; 4 * 8], Literal);
#[cfg(not(target_arch = "aarch64"))] #[cfg(not(target_arch = "aarch64"))]
static_assertions::assert_eq_size!([u8; 3 * 8], Literal); static_assertions::assert_eq_size!([u8; 3 * 8], Literal);
static_assertions::assert_eq_size!([u8; 10 * 8], Expr); static_assertions::assert_eq_size!([u8; 11 * 8], Expr);
#[cfg(not(target_arch = "aarch64"))] #[cfg(not(target_arch = "aarch64"))]
static_assertions::assert_eq_size!([u8; 19 * 8], Stmt); static_assertions::assert_eq_size!([u8; 19 * 8], Stmt);
#[cfg(target_arch = "aarch64")] #[cfg(target_arch = "aarch64")]
@ -318,11 +318,17 @@ impl<'a> Proc<'a> {
arena: &'a Bump, arena: &'a Bump,
home: ModuleId, home: ModuleId,
ident_ids: &'i mut IdentIds, ident_ids: &'i mut IdentIds,
update_mode_ids: &'i mut UpdateModeIds,
procs: &mut MutMap<(Symbol, ProcLayout<'a>), Proc<'a>>, procs: &mut MutMap<(Symbol, ProcLayout<'a>), Proc<'a>>,
) { ) {
for (_, proc) in procs.iter_mut() { for (_, proc) in procs.iter_mut() {
let new_proc = let new_proc = crate::reset_reuse::insert_reset_reuse(
crate::reset_reuse::insert_reset_reuse(arena, home, ident_ids, proc.clone()); arena,
home,
ident_ids,
update_mode_ids,
proc.clone(),
);
*proc = new_proc; *proc = new_proc;
} }
} }
@ -1306,7 +1312,7 @@ impl UpdateModeIds {
Self { next: 0 } Self { next: 0 }
} }
fn next_id(&mut self) -> UpdateModeId { pub fn next_id(&mut self) -> UpdateModeId {
let id = UpdateModeId { id: self.next }; let id = UpdateModeId { id: self.next };
self.next += 1; self.next += 1;
id id
@ -1401,15 +1407,17 @@ pub enum Expr<'a> {
Reuse { Reuse {
symbol: Symbol, symbol: Symbol,
update_tag_id: bool, update_tag_id: bool,
// update_mode: UpdateModeId, update_mode: UpdateModeId,
// normal Tag fields // normal Tag fields
tag_layout: UnionLayout<'a>, tag_layout: UnionLayout<'a>,
tag_name: TagName, tag_name: TagName,
tag_id: TagIdIntType, tag_id: TagIdIntType,
arguments: &'a [Symbol], arguments: &'a [Symbol],
}, },
// Reset { symbol: Symbol, update_mode: UpdateModeId, }, Reset {
Reset(Symbol), symbol: Symbol,
update_mode: UpdateModeId,
},
RuntimeErrorFunction(&'a str), RuntimeErrorFunction(&'a str),
} }
@ -1525,7 +1533,7 @@ impl<'a> Expr<'a> {
.append(alloc.space()) .append(alloc.space())
.append(alloc.intersperse(it, " ")) .append(alloc.intersperse(it, " "))
} }
Reset(symbol) => alloc.text("Reset ").append(symbol_to_doc(alloc, *symbol)), Reset { symbol, .. } => alloc.text("Reset ").append(symbol_to_doc(alloc, *symbol)),
Struct(args) => { Struct(args) => {
let it = args.iter().map(|s| symbol_to_doc(alloc, *s)); let it = args.iter().map(|s| symbol_to_doc(alloc, *s));
@ -5728,7 +5736,7 @@ fn substitute_in_expr<'a>(
} }
} }
Reuse { .. } | Reset(_) => unreachable!("reset/reuse have not been introduced yet"), Reuse { .. } | Reset { .. } => unreachable!("reset/reuse have not been introduced yet"),
Struct(args) => { Struct(args) => {
let mut did_change = false; let mut did_change = false;

View file

@ -1,5 +1,5 @@
use crate::inc_dec::{collect_stmt, occurring_variables_expr, JPLiveVarMap, LiveVarSet}; use crate::inc_dec::{collect_stmt, occurring_variables_expr, JPLiveVarMap, LiveVarSet};
use crate::ir::{BranchInfo, Call, Expr, ListLiteralElement, Proc, Stmt}; use crate::ir::{BranchInfo, Call, Expr, ListLiteralElement, Proc, Stmt, UpdateModeIds};
use crate::layout::{Layout, TagIdIntType, UnionLayout}; use crate::layout::{Layout, TagIdIntType, UnionLayout};
use bumpalo::collections::Vec; use bumpalo::collections::Vec;
use bumpalo::Bump; use bumpalo::Bump;
@ -10,12 +10,14 @@ pub fn insert_reset_reuse<'a, 'i>(
arena: &'a Bump, arena: &'a Bump,
home: ModuleId, home: ModuleId,
ident_ids: &'i mut IdentIds, ident_ids: &'i mut IdentIds,
update_mode_ids: &'i mut UpdateModeIds,
mut proc: Proc<'a>, mut proc: Proc<'a>,
) -> Proc<'a> { ) -> Proc<'a> {
let mut env = Env { let mut env = Env {
arena, arena,
home, home,
ident_ids, ident_ids,
update_mode_ids,
jp_live_vars: Default::default(), jp_live_vars: Default::default(),
}; };
@ -50,6 +52,7 @@ struct Env<'a, 'i> {
/// required for creating new `Symbol`s /// required for creating new `Symbol`s
home: ModuleId, home: ModuleId,
ident_ids: &'i mut IdentIds, ident_ids: &'i mut IdentIds,
update_mode_ids: &'i mut UpdateModeIds,
jp_live_vars: JPLiveVarMap, jp_live_vars: JPLiveVarMap,
} }
@ -82,10 +85,12 @@ fn function_s<'a, 'i>(
} if may_reuse(*tag_layout, *tag_id, c) => { } if may_reuse(*tag_layout, *tag_id, c) => {
// for now, always overwrite the tag ID just to be sure // for now, always overwrite the tag ID just to be sure
let update_tag_id = true; let update_tag_id = true;
let update_mode = env.update_mode_ids.next_id();
let new_expr = Expr::Reuse { let new_expr = Expr::Reuse {
symbol: w, symbol: w,
update_tag_id, update_tag_id,
update_mode,
tag_layout: *tag_layout, tag_layout: *tag_layout,
tag_id: *tag_id, tag_id: *tag_id,
tag_name: tag_name.clone(), tag_name: tag_name.clone(),
@ -216,12 +221,16 @@ fn insert_reset<'a>(
| Array { .. } | Array { .. }
| EmptyArray | EmptyArray
| Reuse { .. } | Reuse { .. }
| Reset(_) | Reset { .. }
| RuntimeErrorFunction(_) => break, | RuntimeErrorFunction(_) => break,
} }
} }
let reset_expr = Expr::Reset(x); let update_mode = env.update_mode_ids.next_id();
let reset_expr = Expr::Reset {
symbol: x,
update_mode,
};
let layout = Layout::Union(union_layout); let layout = Layout::Union(union_layout);
@ -584,7 +593,7 @@ fn has_live_var_expr<'a>(expr: &'a Expr<'a>, needle: Symbol) -> bool {
Expr::Reuse { Expr::Reuse {
symbol, arguments, .. symbol, arguments, ..
} => needle == *symbol || arguments.iter().any(|s| *s == needle), } => needle == *symbol || arguments.iter().any(|s| *s == needle),
Expr::Reset(symbol) => needle == *symbol, Expr::Reset { symbol, .. } => needle == *symbol,
Expr::RuntimeErrorFunction(_) => false, Expr::RuntimeErrorFunction(_) => false,
} }
} }