mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-26 13:29:12 +00:00
start resetref
This commit is contained in:
parent
61efec6fe2
commit
d4ed6f7778
13 changed files with 214 additions and 18 deletions
|
@ -707,7 +707,7 @@ impl<'a> BorrowInfState<'a> {
|
|||
self.if_is_owned_then_own(z, *x);
|
||||
}
|
||||
|
||||
Reset { symbol: x, .. } => {
|
||||
Reset { symbol: x, .. } | ResetRef { symbol: x, .. } => {
|
||||
self.own_var(z);
|
||||
self.own_var(*x);
|
||||
}
|
||||
|
|
|
@ -31,6 +31,8 @@ pub enum HelperOp {
|
|||
Dec,
|
||||
DecRef(JoinPointId),
|
||||
Reset,
|
||||
// TODO update all usages
|
||||
ResetRef,
|
||||
Eq,
|
||||
}
|
||||
|
||||
|
@ -272,7 +274,7 @@ impl<'a> CodeGenHelp<'a> {
|
|||
let arg = self.replace_rec_ptr(ctx, layout_interner, layout);
|
||||
match ctx.op {
|
||||
Dec | DecRef(_) => (LAYOUT_UNIT, self.arena.alloc([arg])),
|
||||
Reset => (layout, self.arena.alloc([layout])),
|
||||
Reset | ResetRef => (layout, self.arena.alloc([layout])),
|
||||
Inc => (LAYOUT_UNIT, self.arena.alloc([arg, self.layout_isize])),
|
||||
Eq => (LAYOUT_BOOL, self.arena.alloc([arg, arg])),
|
||||
}
|
||||
|
@ -346,7 +348,7 @@ impl<'a> CodeGenHelp<'a> {
|
|||
Symbol::ARG_1,
|
||||
),
|
||||
),
|
||||
Reset => (
|
||||
Reset | ResetRef => (
|
||||
layout,
|
||||
refcount::refcount_reset_proc_body(
|
||||
self,
|
||||
|
@ -370,7 +372,7 @@ impl<'a> CodeGenHelp<'a> {
|
|||
let inc_amount = (self.layout_isize, ARG_2);
|
||||
self.arena.alloc([roc_value, inc_amount])
|
||||
}
|
||||
Dec | DecRef(_) | Reset => self.arena.alloc([roc_value]),
|
||||
Dec | DecRef(_) | Reset | ResetRef => self.arena.alloc([roc_value]),
|
||||
Eq => self.arena.alloc([roc_value, (layout, ARG_2)]),
|
||||
}
|
||||
};
|
||||
|
@ -421,6 +423,7 @@ impl<'a> CodeGenHelp<'a> {
|
|||
niche: Niche::NONE,
|
||||
},
|
||||
HelperOp::DecRef(_) => unreachable!("No generated Proc for DecRef"),
|
||||
HelperOp::ResetRef => unreachable!("No generated Proc for ResetRef"),
|
||||
HelperOp::Eq => ProcLayout {
|
||||
arguments: self.arena.alloc([layout, layout]),
|
||||
result: LAYOUT_BOOL,
|
||||
|
|
|
@ -464,6 +464,10 @@ impl<'a, 'r> Ctx<'a, 'r> {
|
|||
&Expr::Reset {
|
||||
symbol,
|
||||
update_mode: _,
|
||||
}
|
||||
| &Expr::ResetRef {
|
||||
symbol,
|
||||
update_mode: _,
|
||||
} => {
|
||||
self.check_sym_exists(symbol);
|
||||
None
|
||||
|
|
|
@ -310,7 +310,14 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
|
|||
update_mode_id: update_mode_ids.next_id(),
|
||||
};
|
||||
environment.push_reuse_token(&layout_clone, reuse_token);
|
||||
Some((layout_clone, *symbol, reuse_token))
|
||||
|
||||
let dec_ref = match rc {
|
||||
ModifyRc::Dec(_) => false,
|
||||
ModifyRc::DecRef(_) => true,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
Some((layout_clone, *symbol, reuse_token, dec_ref))
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
|
@ -328,7 +335,7 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
|
|||
);
|
||||
|
||||
// If we inserted a reuse token, we need to insert a reset reuse operation if the reuse token is consumed.
|
||||
if let Some((layout, symbol, reuse_token)) = reuse_pair {
|
||||
if let Some((layout, symbol, reuse_token, dec_ref)) = reuse_pair {
|
||||
let stack_reuse_token = environment.peek_reuse_token(&layout);
|
||||
|
||||
match stack_reuse_token {
|
||||
|
@ -340,9 +347,17 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
|
|||
_ => {
|
||||
// The token we inserted is no longer on the stack, it must have been consumed.
|
||||
// So we need to insert a reset operation.
|
||||
let reset_expr = Expr::Reset {
|
||||
symbol,
|
||||
update_mode: reuse_token.update_mode_id,
|
||||
let reset_expr = match dec_ref {
|
||||
// A decref will be replaced by a resetref.
|
||||
true => Expr::ResetRef {
|
||||
symbol,
|
||||
update_mode: reuse_token.update_mode_id,
|
||||
},
|
||||
// And a dec will be replaced by a reset.
|
||||
false => Expr::Reset {
|
||||
symbol,
|
||||
update_mode: reuse_token.update_mode_id,
|
||||
},
|
||||
};
|
||||
|
||||
// If we generate a reuse token, we no longer want to use the drop statement anymore. So we just return the reset expression.
|
||||
|
|
|
@ -205,7 +205,7 @@ pub fn occurring_variables_expr(expr: &Expr<'_>, result: &mut MutSet<Symbol>) {
|
|||
result.extend(arguments.iter().copied());
|
||||
result.insert(*symbol);
|
||||
}
|
||||
Reset { symbol: x, .. } => {
|
||||
Reset { symbol: x, .. } | ResetRef { symbol: x, .. } => {
|
||||
result.insert(*x);
|
||||
}
|
||||
|
||||
|
@ -945,7 +945,7 @@ impl<'a, 'i> Context<'a, 'i> {
|
|||
self.arena.alloc(Stmt::Let(z, v, l, b))
|
||||
}
|
||||
|
||||
EmptyArray | Literal(_) | Reset { .. } | RuntimeErrorFunction(_) => {
|
||||
EmptyArray | Literal(_) | Reset { .. } | ResetRef { .. } | RuntimeErrorFunction(_) => {
|
||||
// EmptyArray is always stack-allocated function pointers are persistent
|
||||
self.arena.alloc(Stmt::Let(z, v, l, b))
|
||||
}
|
||||
|
|
|
@ -1935,6 +1935,13 @@ pub enum Expr<'a> {
|
|||
update_mode: UpdateModeId,
|
||||
},
|
||||
|
||||
// Just like Reset, but does not recursively decrement the children.
|
||||
// Used in reuse analysis to replace a decref with a resetRef to avoid decrementing when the dec ref didn't.
|
||||
ResetRef {
|
||||
symbol: Symbol,
|
||||
update_mode: UpdateModeId,
|
||||
},
|
||||
|
||||
RuntimeErrorFunction(&'a str),
|
||||
}
|
||||
|
||||
|
@ -2057,7 +2064,13 @@ impl<'a> Expr<'a> {
|
|||
"Reset {{ symbol: {:?}, id: {} }}",
|
||||
symbol, update_mode.id
|
||||
)),
|
||||
|
||||
ResetRef {
|
||||
symbol,
|
||||
update_mode,
|
||||
} => alloc.text(format!(
|
||||
"ResetRef {{ symbol: {:?}, id: {} }}",
|
||||
symbol, update_mode.id
|
||||
)),
|
||||
Struct(args) => {
|
||||
let it = args.iter().map(|s| symbol_to_doc(alloc, *s, pretty));
|
||||
|
||||
|
@ -7187,7 +7200,9 @@ fn substitute_in_expr<'a>(
|
|||
}
|
||||
}
|
||||
|
||||
Reuse { .. } | Reset { .. } => unreachable!("reset/reuse have not been introduced yet"),
|
||||
Reuse { .. } | Reset { .. } | ResetRef { .. } => {
|
||||
unreachable!("reset/resetref/reuse have not been introduced yet")
|
||||
}
|
||||
|
||||
Struct(args) => {
|
||||
let mut did_change = false;
|
||||
|
|
|
@ -427,8 +427,8 @@ impl VariableUsage {
|
|||
borrowed: MutSet::default(),
|
||||
}
|
||||
}
|
||||
Expr::Reuse { .. } | Expr::Reset { .. } => {
|
||||
unreachable!("Reset and reuse should not exist at this point")
|
||||
Expr::Reuse { .. } | Expr::Reset { .. } | Expr::ResetRef { .. } => {
|
||||
unreachable!("Reset(ref) and reuse should not exist at this point")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -326,6 +326,7 @@ fn insert_reset<'a>(
|
|||
| EmptyArray
|
||||
| Reuse { .. }
|
||||
| Reset { .. }
|
||||
| ResetRef { .. }
|
||||
| RuntimeErrorFunction(_) => break,
|
||||
}
|
||||
}
|
||||
|
@ -862,7 +863,7 @@ fn has_live_var_expr<'a>(expr: &'a Expr<'a>, needle: Symbol) -> bool {
|
|||
Expr::Reuse {
|
||||
symbol, arguments, ..
|
||||
} => needle == *symbol || arguments.iter().any(|s| *s == needle),
|
||||
Expr::Reset { symbol, .. } => needle == *symbol,
|
||||
Expr::Reset { symbol, .. } | Expr::ResetRef { symbol, .. } => needle == *symbol,
|
||||
Expr::ExprBox { symbol, .. } => needle == *symbol,
|
||||
Expr::ExprUnbox { symbol, .. } => needle == *symbol,
|
||||
Expr::RuntimeErrorFunction(_) => false,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue