mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-28 14:24:45 +00:00
add update mode to reset and reuse
This commit is contained in:
parent
1241d5ccbd
commit
0bdda2506c
8 changed files with 40 additions and 21 deletions
|
@ -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(_) => {}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -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];
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue