From 463f739c0664dd09c56219711cb0a5fb94cee75b Mon Sep 17 00:00:00 2001 From: Folkert Date: Wed, 28 Jun 2023 21:26:19 +0200 Subject: [PATCH 1/5] add reuse info to normal Tag ir constructor --- crates/compiler/alias_analysis/src/lib.rs | 1 + crates/compiler/gen_dev/src/lib.rs | 5 +- crates/compiler/gen_llvm/src/llvm/build.rs | 26 +++++----- crates/compiler/gen_wasm/src/backend.rs | 7 ++- crates/compiler/mono/src/debug/checker.rs | 7 +++ crates/compiler/mono/src/ir.rs | 57 +++++++++++++++++++++- crates/compiler/mono/src/reset_reuse.rs | 3 ++ crates/compiler/mono/src/tail_recursion.rs | 4 ++ 8 files changed, 94 insertions(+), 16 deletions(-) diff --git a/crates/compiler/alias_analysis/src/lib.rs b/crates/compiler/alias_analysis/src/lib.rs index 82c9944c4d7..7aa2cea7852 100644 --- a/crates/compiler/alias_analysis/src/lib.rs +++ b/crates/compiler/alias_analysis/src/lib.rs @@ -1325,6 +1325,7 @@ fn expr_spec<'a>( tag_layout, tag_id, arguments, + reuse: _, } => { let data_id = build_tuple_value(builder, env, block, arguments)?; diff --git a/crates/compiler/gen_dev/src/lib.rs b/crates/compiler/gen_dev/src/lib.rs index f624165de0d..d446038288a 100644 --- a/crates/compiler/gen_dev/src/lib.rs +++ b/crates/compiler/gen_dev/src/lib.rs @@ -838,10 +838,11 @@ trait Backend<'a> { tag_layout, tag_id, arguments, - .. + reuse, } => { self.load_literal_symbols(arguments); - self.tag(sym, arguments, tag_layout, *tag_id, None); + let reuse = reuse.map(|ru| ru.symbol); + self.tag(sym, arguments, tag_layout, *tag_id, reuse); } Expr::ExprBox { symbol: value } => { let element_layout = match self.interner().get_repr(*layout) { diff --git a/crates/compiler/gen_llvm/src/llvm/build.rs b/crates/compiler/gen_llvm/src/llvm/build.rs index 9d14ab0fe2e..d902fa63b08 100644 --- a/crates/compiler/gen_llvm/src/llvm/build.rs +++ b/crates/compiler/gen_llvm/src/llvm/build.rs @@ -1088,17 +1088,21 @@ pub(crate) fn build_exp_expr<'a, 'ctx>( arguments, tag_layout: union_layout, tag_id, - .. - } => build_tag( - env, - layout_interner, - scope, - union_layout, - *tag_id, - arguments, - None, - parent, - ), + reuse, + } => { + let reuse_ptr = reuse.map(|ru| scope.load_symbol(&ru.symbol).into_pointer_value()); + + build_tag( + env, + layout_interner, + scope, + union_layout, + *tag_id, + arguments, + reuse_ptr, + parent, + ) + } ExprBox { symbol } => { let (value, layout) = scope.load_symbol_and_layout(symbol); diff --git a/crates/compiler/gen_wasm/src/backend.rs b/crates/compiler/gen_wasm/src/backend.rs index 557cdbecc2d..b236d5c027f 100644 --- a/crates/compiler/gen_wasm/src/backend.rs +++ b/crates/compiler/gen_wasm/src/backend.rs @@ -1104,8 +1104,11 @@ impl<'a, 'r> WasmBackend<'a, 'r> { tag_layout: union_layout, tag_id, arguments, - .. - } => self.expr_tag(union_layout, *tag_id, arguments, sym, storage, None), + reuse, + } => { + let reuse = reuse.map(|ru| ru.symbol); + self.expr_tag(union_layout, *tag_id, arguments, sym, storage, reuse) + } Expr::GetTagId { structure, diff --git a/crates/compiler/mono/src/debug/checker.rs b/crates/compiler/mono/src/debug/checker.rs index afb0917cf83..9c030a068dc 100644 --- a/crates/compiler/mono/src/debug/checker.rs +++ b/crates/compiler/mono/src/debug/checker.rs @@ -397,11 +397,18 @@ impl<'a, 'r> Ctx<'a, 'r> { tag_layout, tag_id, arguments, + reuse, } => { let interned_layout = self .interner .insert_direct_no_semantic(LayoutRepr::Union(tag_layout)); + + if let Some(reuse_token) = reuse { + self.check_sym_layout(reuse_token.symbol, interned_layout, UseKind::TagReuse); + } + self.check_tag_expr(interned_layout, tag_layout, tag_id, arguments); + Some(interned_layout) } Expr::Struct(syms) => { diff --git a/crates/compiler/mono/src/ir.rs b/crates/compiler/mono/src/ir.rs index c9013e78f12..82c6da4e024 100644 --- a/crates/compiler/mono/src/ir.rs +++ b/crates/compiler/mono/src/ir.rs @@ -1825,6 +1825,13 @@ pub struct HigherOrderLowLevel<'a> { pub passed_function: PassedFunction<'a>, } +#[derive(Clone, Copy, Debug, PartialEq)] +pub struct ReuseToken { + pub symbol: Symbol, + pub update_tag_id: bool, + pub update_mode: UpdateModeId, +} + #[derive(Clone, Debug, PartialEq)] pub enum Expr<'a> { Literal(Literal<'a>), @@ -1836,6 +1843,7 @@ pub enum Expr<'a> { tag_layout: UnionLayout<'a>, tag_id: TagIdIntType, arguments: &'a [Symbol], + reuse: Option, }, Struct(&'a [Symbol]), NullPointer, @@ -1977,7 +1985,10 @@ impl<'a> Expr<'a> { Call(call) => call.to_doc(alloc, pretty), Tag { - tag_id, arguments, .. + tag_id, + arguments, + reuse: None, + .. } => { let doc_tag = alloc .text("TagId(") @@ -1990,6 +2001,30 @@ impl<'a> Expr<'a> { .append(alloc.space()) .append(alloc.intersperse(it, " ")) } + + Tag { + tag_id, + arguments, + reuse: Some(reuse_token), + .. + } => { + let doc_tag = alloc + .text("TagId(") + .append(alloc.text(tag_id.to_string())) + .append(")"); + + let it = arguments.iter().map(|s| symbol_to_doc(alloc, *s, pretty)); + + alloc + .text("Reuse ") + .append(symbol_to_doc(alloc, reuse_token.symbol, pretty)) + .append(alloc.space()) + .append(format!("{:?}", reuse_token.update_mode)) + .append(alloc.space()) + .append(doc_tag) + .append(alloc.space()) + .append(alloc.intersperse(it, " ")) + } NullPointer => alloc.text("NullPointer"), Reuse { symbol, @@ -6005,6 +6040,7 @@ where tag_id, tag_layout: union_layout, arguments: symbols, + reuse: None, }; Stmt::Let(assigned, expr, lambda_set_layout, env.arena.alloc(hole)) @@ -6274,6 +6310,7 @@ fn convert_tag_union<'a>( tag_layout: union_layout, tag_id: tag_id as _, arguments: field_symbols, + reuse: None, }; (tag, union_layout) @@ -6296,6 +6333,7 @@ fn convert_tag_union<'a>( tag_layout: union_layout, tag_id: tag_id as _, arguments: field_symbols, + reuse: None, }; (tag, union_layout) @@ -6320,6 +6358,7 @@ fn convert_tag_union<'a>( tag_layout: union_layout, tag_id: tag_id as _, arguments: field_symbols, + reuse: None, }; (tag, union_layout) @@ -6346,6 +6385,7 @@ fn convert_tag_union<'a>( tag_layout: union_layout, tag_id: tag_id as _, arguments: field_symbols, + reuse: None, }; (tag, union_layout) @@ -6363,6 +6403,7 @@ fn convert_tag_union<'a>( tag_layout: union_layout, tag_id: tag_id as _, arguments: field_symbols, + reuse: None, }; (tag, union_layout) @@ -7532,6 +7573,7 @@ fn substitute_in_expr<'a>( tag_layout, tag_id, arguments: args, + reuse, } => { let mut did_change = false; let new_args = Vec::from_iter_in( @@ -7545,6 +7587,18 @@ fn substitute_in_expr<'a>( arena, ); + let reuse = match *reuse { + Some(mut ru) => match substitute(subs, ru.symbol) { + Some(s) => { + did_change = true; + ru.symbol = s; + Some(ru) + } + None => Some(ru), + }, + None => None, + }; + if did_change { let arguments = new_args.into_bump_slice(); @@ -7552,6 +7606,7 @@ fn substitute_in_expr<'a>( tag_layout: *tag_layout, tag_id: *tag_id, arguments, + reuse, }) } else { None diff --git a/crates/compiler/mono/src/reset_reuse.rs b/crates/compiler/mono/src/reset_reuse.rs index 1fb2b581641..05cb06b8467 100644 --- a/crates/compiler/mono/src/reset_reuse.rs +++ b/crates/compiler/mono/src/reset_reuse.rs @@ -134,7 +134,10 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>( tag_layout, tag_id, arguments, + reuse, } => { + debug_assert!(reuse.is_none()); + // The value of the tag is currently only used in the case of nullable recursive unions. // But for completeness we add every kind of union to the layout_tags. environment.add_symbol_tag(*binding, *tag_id); diff --git a/crates/compiler/mono/src/tail_recursion.rs b/crates/compiler/mono/src/tail_recursion.rs index 46b0684ce2e..a55820c8172 100644 --- a/crates/compiler/mono/src/tail_recursion.rs +++ b/crates/compiler/mono/src/tail_recursion.rs @@ -639,8 +639,11 @@ impl<'a> TrmcEnv<'a> { tag_layout, tag_id, arguments, + reuse, } = expr { + debug_assert!(reuse.is_none()); + let info = ConstructorInfo { tag_layout: *tag_layout, tag_id: *tag_id, @@ -910,6 +913,7 @@ impl<'a> TrmcEnv<'a> { tag_layout: cons_info.tag_layout, tag_id: cons_info.tag_id, arguments: arguments.into_bump_slice(), + reuse: None, }; let let_tag = |next| Stmt::Let(*symbol, tag_expr, *layout, next); From 1daf975391da9178ec8b3f861294b909f8ec0851 Mon Sep 17 00:00:00 2001 From: Folkert Date: Wed, 28 Jun 2023 21:47:36 +0200 Subject: [PATCH 2/5] use Tag instead of Reuse constructor --- crates/compiler/mono/src/reset_reuse.rs | 54 +++++++++++++++---------- 1 file changed, 32 insertions(+), 22 deletions(-) diff --git a/crates/compiler/mono/src/reset_reuse.rs b/crates/compiler/mono/src/reset_reuse.rs index 05cb06b8467..e011302771a 100644 --- a/crates/compiler/mono/src/reset_reuse.rs +++ b/crates/compiler/mono/src/reset_reuse.rs @@ -156,42 +156,52 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>( token: reuse_token, inlayout: layout_info, }) => { - // The reuse token layout is the same, we can use it without casting. + let reuse_token = crate::ir::ReuseToken { + symbol: reuse_token.symbol, + update_mode: reuse_token.update_mode_id, + // for now, always overwrite the tag ID just to be sure + update_tag_id: true, + }; + if layout_info == layout { + // The reuse token layout is the same, we can use it without casting. ( None, - Expr::Reuse { - symbol: reuse_token.symbol, - update_mode: reuse_token.update_mode_id, - // for now, always overwrite the tag ID just to be sure - update_tag_id: true, + Expr::Tag { tag_layout: *tag_layout, tag_id: *tag_id, arguments, + reuse: Some(reuse_token), }, ) - } - // The reuse token has a different layout from the tag, we need to pointercast it before. - else { + } else { + // The reuse token has a different layout from the tag, we need to pointercast it before. let new_symbol = Symbol::new(home, ident_ids.gen_unique()); + + let ptr_cast = move |new_let| { + arena.alloc(Stmt::Let( + new_symbol, + create_ptr_cast(arena, reuse_token.symbol), + *layout, + new_let, + )) + }; + + let reuse_token = crate::ir::ReuseToken { + symbol: new_symbol, + update_mode: reuse_token.update_mode, + // for now, always overwrite the tag ID just to be sure + update_tag_id: true, + }; + ( - Some(move |new_let| { - arena.alloc(Stmt::Let( - new_symbol, - create_ptr_cast(arena, reuse_token.symbol), - *layout, - new_let, - )) - }), - Expr::Reuse { - symbol: new_symbol, - update_mode: reuse_token.update_mode_id, - // for now, always overwrite the tag ID just to be sure - update_tag_id: true, + Some(ptr_cast), + Expr::Tag { tag_layout: *tag_layout, tag_id: *tag_id, arguments, + reuse: Some(reuse_token), }, ) } From f27cb83a025870ebbc15ee7d51edb7053a052323 Mon Sep 17 00:00:00 2001 From: Folkert Date: Wed, 28 Jun 2023 22:02:02 +0200 Subject: [PATCH 3/5] remove Reuse --- crates/compiler/alias_analysis/src/lib.rs | 8 +--- crates/compiler/gen_dev/src/lib.rs | 26 ++++--------- crates/compiler/gen_llvm/src/llvm/build.rs | 20 ---------- crates/compiler/gen_wasm/src/backend.rs | 8 ---- crates/compiler/mono/src/borrow.rs | 27 +++++++++----- crates/compiler/mono/src/debug/checker.rs | 15 -------- .../compiler/mono/src/drop_specialization.rs | 3 -- crates/compiler/mono/src/inc_dec.rs | 2 +- crates/compiler/mono/src/ir.rs | 37 +------------------ crates/compiler/mono/src/reset_reuse.rs | 9 +++-- crates/compiler/mono/src/tail_recursion.rs | 3 -- 11 files changed, 33 insertions(+), 125 deletions(-) diff --git a/crates/compiler/alias_analysis/src/lib.rs b/crates/compiler/alias_analysis/src/lib.rs index 7aa2cea7852..9ded9c3c3db 100644 --- a/crates/compiler/alias_analysis/src/lib.rs +++ b/crates/compiler/alias_analysis/src/lib.rs @@ -1315,13 +1315,7 @@ fn expr_spec<'a>( builder.add_unknown_with(block, &[], pointer_type) } Call(call) => call_spec(builder, interner, env, block, layout, call), - Reuse { - tag_layout, - tag_id, - arguments, - .. - } - | Tag { + Tag { tag_layout, tag_id, arguments, diff --git a/crates/compiler/gen_dev/src/lib.rs b/crates/compiler/gen_dev/src/lib.rs index d446038288a..b4d1464cc95 100644 --- a/crates/compiler/gen_dev/src/lib.rs +++ b/crates/compiler/gen_dev/src/lib.rs @@ -138,7 +138,13 @@ impl<'a> LastSeenMap<'a> { Expr::Call(call) => self.scan_ast_call(call, stmt), - Expr::Tag { arguments, .. } => { + Expr::Tag { + arguments, reuse, .. + } => { + if let Some(ru) = reuse { + self.set_last_seen(ru.symbol, stmt); + } + for sym in *arguments { self.set_last_seen(*sym, stmt); } @@ -173,14 +179,6 @@ impl<'a> LastSeenMap<'a> { } } } - Expr::Reuse { - symbol, arguments, .. - } => { - self.set_last_seen(*symbol, stmt); - for sym in *arguments { - self.set_last_seen(*sym, stmt); - } - } Expr::Reset { symbol, .. } | Expr::ResetRef { symbol, .. } => { self.set_last_seen(*symbol, stmt); } @@ -862,16 +860,6 @@ trait Backend<'a> { Expr::NullPointer => { self.load_literal_i64(sym, 0); } - Expr::Reuse { - tag_layout, - tag_id, - symbol: reused, - arguments, - .. - } => { - self.load_literal_symbols(arguments); - self.tag(sym, arguments, tag_layout, *tag_id, Some(*reused)); - } Expr::Reset { symbol, .. } => { let layout = *self.layout_map().get(symbol).unwrap(); diff --git a/crates/compiler/gen_llvm/src/llvm/build.rs b/crates/compiler/gen_llvm/src/llvm/build.rs index d902fa63b08..67748e4a1ef 100644 --- a/crates/compiler/gen_llvm/src/llvm/build.rs +++ b/crates/compiler/gen_llvm/src/llvm/build.rs @@ -1064,26 +1064,6 @@ pub(crate) fn build_exp_expr<'a, 'ctx>( ) .into(), - Reuse { - arguments, - tag_layout: union_layout, - tag_id, - symbol, - .. - } => { - let reset = scope.load_symbol(symbol).into_pointer_value(); - build_tag( - env, - layout_interner, - scope, - union_layout, - *tag_id, - arguments, - Some(reset), - parent, - ) - } - Tag { arguments, tag_layout: union_layout, diff --git a/crates/compiler/gen_wasm/src/backend.rs b/crates/compiler/gen_wasm/src/backend.rs index b236d5c027f..9472b014f57 100644 --- a/crates/compiler/gen_wasm/src/backend.rs +++ b/crates/compiler/gen_wasm/src/backend.rs @@ -1140,14 +1140,6 @@ impl<'a, 'r> WasmBackend<'a, 'r> { Expr::ExprUnbox { symbol: arg_sym } => self.expr_unbox(sym, *arg_sym), - Expr::Reuse { - tag_layout, - tag_id, - arguments, - symbol: reused, - .. - } => self.expr_tag(tag_layout, *tag_id, arguments, sym, storage, Some(*reused)), - Expr::Reset { symbol: arg, .. } => self.expr_reset(*arg, sym, storage), Expr::ResetRef { symbol: arg, .. } => self.expr_resetref(*arg, sym, storage), diff --git a/crates/compiler/mono/src/borrow.rs b/crates/compiler/mono/src/borrow.rs index dc5ad52fc19..8a95c793216 100644 --- a/crates/compiler/mono/src/borrow.rs +++ b/crates/compiler/mono/src/borrow.rs @@ -680,7 +680,22 @@ impl<'a> BorrowInfState<'a> { // the function must take it as an owned parameter self.own_args_if_param(&xs); } - Tag { arguments: xs, .. } | Struct(xs) => { + + Struct(xs) => { + self.own_var(z); + + // if the used symbol is an argument to the current function, + // the function must take it as an owned parameter + self.own_args_if_param(xs); + } + + Tag { + arguments: xs, + reuse, + .. + } => { + debug_assert!(reuse.is_none()); + self.own_var(z); // if the used symbol is an argument to the current function, @@ -708,15 +723,7 @@ impl<'a> BorrowInfState<'a> { self.own_var(z); self.own_var(*x); } - Reuse { - symbol: x, - arguments: ys, - .. - } => { - self.own_var(z); - self.own_var(*x); - self.own_args_if_param(ys); - } + EmptyArray => { self.own_var(z); } diff --git a/crates/compiler/mono/src/debug/checker.rs b/crates/compiler/mono/src/debug/checker.rs index 9c030a068dc..a1d89874785 100644 --- a/crates/compiler/mono/src/debug/checker.rs +++ b/crates/compiler/mono/src/debug/checker.rs @@ -481,21 +481,6 @@ impl<'a, 'r> Ctx<'a, 'r> { } } }), - &Expr::Reuse { - symbol, - update_tag_id: _, - update_mode: _, - tag_layout, - tag_id: _, - arguments: _, - } => { - let union = self - .interner - .insert_direct_no_semantic(LayoutRepr::Union(tag_layout)); - self.check_sym_layout(symbol, union, UseKind::TagReuse); - // TODO also check update arguments - Some(union) - } &Expr::Reset { symbol, update_mode: _, diff --git a/crates/compiler/mono/src/drop_specialization.rs b/crates/compiler/mono/src/drop_specialization.rs index a4203dec05b..6d976130541 100644 --- a/crates/compiler/mono/src/drop_specialization.rs +++ b/crates/compiler/mono/src/drop_specialization.rs @@ -231,9 +231,6 @@ fn specialize_drops_stmt<'a, 'i>( alloc_let_with_continuation!(environment) } - Expr::Reuse { .. } => { - alloc_let_with_continuation!(environment) - } Expr::Reset { .. } => { // TODO allow to inline this to replace it with resetref alloc_let_with_continuation!(environment) diff --git a/crates/compiler/mono/src/inc_dec.rs b/crates/compiler/mono/src/inc_dec.rs index 960a45bf10e..9b421b77e72 100644 --- a/crates/compiler/mono/src/inc_dec.rs +++ b/crates/compiler/mono/src/inc_dec.rs @@ -1093,7 +1093,7 @@ fn insert_refcount_operations_binding<'a>( } } } - Expr::Reuse { .. } | Expr::Reset { .. } | Expr::ResetRef { .. } => { + Expr::Reset { .. } | Expr::ResetRef { .. } => { unreachable!("Reset(ref) and reuse should not exist at this point") } } diff --git a/crates/compiler/mono/src/ir.rs b/crates/compiler/mono/src/ir.rs index 82c6da4e024..7a135dd3a17 100644 --- a/crates/compiler/mono/src/ir.rs +++ b/crates/compiler/mono/src/ir.rs @@ -1825,7 +1825,7 @@ pub struct HigherOrderLowLevel<'a> { pub passed_function: PassedFunction<'a>, } -#[derive(Clone, Copy, Debug, PartialEq)] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] pub struct ReuseToken { pub symbol: Symbol, pub update_tag_id: bool, @@ -1886,15 +1886,6 @@ pub enum Expr<'a> { symbol: Symbol, }, - Reuse { - symbol: Symbol, - update_tag_id: bool, - update_mode: UpdateModeId, - // normal Tag fields - tag_layout: UnionLayout<'a>, - tag_id: TagIdIntType, - arguments: &'a [Symbol], - }, Reset { symbol: Symbol, update_mode: UpdateModeId, @@ -2026,30 +2017,6 @@ impl<'a> Expr<'a> { .append(alloc.intersperse(it, " ")) } NullPointer => alloc.text("NullPointer"), - Reuse { - symbol, - tag_id, - arguments, - update_mode, - .. - } => { - let doc_tag = alloc - .text("TagId(") - .append(alloc.text(tag_id.to_string())) - .append(")"); - - let it = arguments.iter().map(|s| symbol_to_doc(alloc, *s, pretty)); - - alloc - .text("Reuse ") - .append(symbol_to_doc(alloc, *symbol, pretty)) - .append(alloc.space()) - .append(format!("{:?}", update_mode)) - .append(alloc.space()) - .append(doc_tag) - .append(alloc.space()) - .append(alloc.intersperse(it, " ")) - } Reset { symbol, update_mode, @@ -7615,7 +7582,7 @@ fn substitute_in_expr<'a>( NullPointer => None, - Reuse { .. } | Reset { .. } | ResetRef { .. } => { + Reset { .. } | ResetRef { .. } => { unreachable!("reset/resetref/reuse have not been introduced yet") } diff --git a/crates/compiler/mono/src/reset_reuse.rs b/crates/compiler/mono/src/reset_reuse.rs index e011302771a..a5d5ee48b66 100644 --- a/crates/compiler/mono/src/reset_reuse.rs +++ b/crates/compiler/mono/src/reset_reuse.rs @@ -234,12 +234,13 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>( new_triplets.into_iter().rev().fold( new_continuation, - |new_continuation, (binding, (reused, new_expr), layout)| { + |new_continuation, (binding, (opt_ptr_cast, new_expr), layout)| { let new_let = arena.alloc(Stmt::Let(*binding, new_expr, *layout, new_continuation)); - match reused { - // The layout for the reuse does not match that of the reset, use PtrCast to convert the layout. - Some(wrap) => wrap(new_let), + + // if the layout for the reuse does not match that of the reset, use PtrCast to convert the layout. + match opt_ptr_cast { + Some(ptr_cast) => ptr_cast(new_let), None => new_let, } }, diff --git a/crates/compiler/mono/src/tail_recursion.rs b/crates/compiler/mono/src/tail_recursion.rs index a55820c8172..074843fc7b7 100644 --- a/crates/compiler/mono/src/tail_recursion.rs +++ b/crates/compiler/mono/src/tail_recursion.rs @@ -1102,9 +1102,6 @@ fn expr_contains_symbol(expr: &Expr, needle: Symbol) -> bool { }), Expr::EmptyArray => false, Expr::ExprBox { symbol } | Expr::ExprUnbox { symbol } => needle == *symbol, - Expr::Reuse { - symbol, arguments, .. - } => needle == *symbol || arguments.contains(&needle), Expr::Reset { symbol, .. } | Expr::ResetRef { symbol, .. } => needle == *symbol, Expr::RuntimeErrorFunction(_) => false, } From b29e612a4df799a451ab87267da9afcf7c507552 Mon Sep 17 00:00:00 2001 From: Folkert Date: Wed, 28 Jun 2023 22:08:47 +0200 Subject: [PATCH 4/5] refactor --- crates/compiler/mono/src/reset_reuse.rs | 46 +++++++------------------ 1 file changed, 13 insertions(+), 33 deletions(-) diff --git a/crates/compiler/mono/src/reset_reuse.rs b/crates/compiler/mono/src/reset_reuse.rs index a5d5ee48b66..d51e522fa0b 100644 --- a/crates/compiler/mono/src/reset_reuse.rs +++ b/crates/compiler/mono/src/reset_reuse.rs @@ -9,8 +9,8 @@ use std::hash::Hash; use crate::borrow::Ownership; use crate::ir::{ - BranchInfo, Expr, JoinPointId, ModifyRc, Param, Proc, ProcLayout, Stmt, UpdateModeId, - UpdateModeIds, + BranchInfo, Expr, JoinPointId, ModifyRc, Param, Proc, ProcLayout, ReuseToken, Stmt, + UpdateModeId, UpdateModeIds, }; use crate::layout::{InLayout, LayoutInterner, LayoutRepr, STLayoutInterner, UnionLayout}; @@ -153,16 +153,9 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>( )) { // We have a reuse token for this layout, use it. Some(TokenWithInLayout { - token: reuse_token, + token: mut reuse_token, inlayout: layout_info, }) => { - let reuse_token = crate::ir::ReuseToken { - symbol: reuse_token.symbol, - update_mode: reuse_token.update_mode_id, - // for now, always overwrite the tag ID just to be sure - update_tag_id: true, - }; - if layout_info == layout { // The reuse token layout is the same, we can use it without casting. ( @@ -188,12 +181,8 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>( )) }; - let reuse_token = crate::ir::ReuseToken { - symbol: new_symbol, - update_mode: reuse_token.update_mode, - // for now, always overwrite the tag ID just to be sure - update_tag_id: true, - }; + // we now want to reuse the cast pointer + reuse_token.symbol = new_symbol; ( Some(ptr_cast), @@ -491,7 +480,9 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>( let reuse_token = ReuseToken { symbol: reuse_symbol, - update_mode_id: update_mode_ids.next_id(), + update_mode: update_mode_ids.next_id(), + // for now, always overwrite the tag ID just to be sure + update_tag_id: true, }; let owned_layout = **layout; @@ -553,7 +544,7 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>( // a dec will be replaced by a reset. let reset_expr = Expr::Reset { symbol, - update_mode: reuse_token.update_mode_id, + update_mode: reuse_token.update_mode, }; return arena.alloc(Stmt::Let( @@ -567,7 +558,7 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>( // a decref will be replaced by a resetref. let reset_expr = Expr::ResetRef { symbol, - update_mode: reuse_token.update_mode_id, + update_mode: reuse_token.update_mode, }; return arena.alloc(Stmt::Let( @@ -753,7 +744,9 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>( tokens.iter().map(|token| TokenWithInLayout { token: ReuseToken { symbol: Symbol::new(home, ident_ids.gen_unique()), - update_mode_id: update_mode_ids.next_id(), + update_mode: update_mode_ids.next_id(), + // for now, always overwrite the tag ID just to be sure + update_tag_id: true, }, inlayout: token.inlayout, }), @@ -1140,19 +1133,6 @@ struct TokenLayout { alignment: u32, } -/** -A reuse token is a symbol that is used to reset a layout. -Matches symbols that are pointers. -*/ -#[derive(Clone, Copy, PartialEq, Eq)] -struct ReuseToken { - // The symbol of the reuse token. - symbol: Symbol, - - // Index that can be used later to determine if in place mutation is possible. - update_mode_id: UpdateModeId, -} - /** Combines a reuse token with it's possible layout info. */ From 0308e02ba9406c411d452919f4e53156a895e99e Mon Sep 17 00:00:00 2001 From: Folkert Date: Thu, 29 Jun 2023 18:40:14 +0200 Subject: [PATCH 5/5] update some logic and comments --- crates/compiler/mono/src/inc_dec.rs | 2 +- crates/compiler/mono/src/ir.rs | 2 +- crates/compiler/mono/src/tail_recursion.rs | 7 ++++++- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/crates/compiler/mono/src/inc_dec.rs b/crates/compiler/mono/src/inc_dec.rs index 9b421b77e72..139303dc0cc 100644 --- a/crates/compiler/mono/src/inc_dec.rs +++ b/crates/compiler/mono/src/inc_dec.rs @@ -1094,7 +1094,7 @@ fn insert_refcount_operations_binding<'a>( } } Expr::Reset { .. } | Expr::ResetRef { .. } => { - unreachable!("Reset(ref) and reuse should not exist at this point") + unreachable!("Reset(ref) should not exist at this point") } } } diff --git a/crates/compiler/mono/src/ir.rs b/crates/compiler/mono/src/ir.rs index 7a135dd3a17..8ef7a13e27d 100644 --- a/crates/compiler/mono/src/ir.rs +++ b/crates/compiler/mono/src/ir.rs @@ -7583,7 +7583,7 @@ fn substitute_in_expr<'a>( NullPointer => None, Reset { .. } | ResetRef { .. } => { - unreachable!("reset/resetref/reuse have not been introduced yet") + unreachable!("reset(ref) has not been introduced yet") } Struct(args) => { diff --git a/crates/compiler/mono/src/tail_recursion.rs b/crates/compiler/mono/src/tail_recursion.rs index 074843fc7b7..bb7680a5033 100644 --- a/crates/compiler/mono/src/tail_recursion.rs +++ b/crates/compiler/mono/src/tail_recursion.rs @@ -1089,7 +1089,12 @@ fn expr_contains_symbol(expr: &Expr, needle: Symbol) -> bool { match expr { Expr::Literal(_) => false, Expr::Call(call) => call.arguments.contains(&needle), - Expr::Tag { arguments, .. } => arguments.contains(&needle), + Expr::Tag { + arguments, reuse, .. + } => match reuse { + None => arguments.contains(&needle), + Some(ru) => ru.symbol == needle || arguments.contains(&needle), + }, Expr::Struct(fields) => fields.contains(&needle), Expr::NullPointer => false, Expr::StructAtIndex { structure, .. }