From 047779d981ad71d68c1891be7ff6ac8f94f053f2 Mon Sep 17 00:00:00 2001 From: Folkert Date: Fri, 28 Jun 2024 15:44:04 +0200 Subject: [PATCH] WIP infer join points too --- crates/compiler/alias_analysis/src/lib.rs | 5 +- crates/compiler/mono/src/borrow.rs | 159 +++++++++++++----- crates/compiler/mono/src/inc_dec.rs | 14 +- crates/compiler/test_gen/src/helpers/llvm.rs | 3 +- ...lambda_set_productive_nullable_wrapped.txt | 13 +- .../encode_derived_nested_record_string.txt | 4 - ...encode_derived_record_one_field_string.txt | 2 - ...ncode_derived_record_two_field_strings.txt | 2 - .../encode_derived_tag_one_field_string.txt | 2 - ...encode_derived_tag_two_payloads_string.txt | 2 - .../generated/inspect_derived_dict.txt | 11 -- .../inspect_derived_tag_one_field_string.txt | 2 - ...nspect_derived_tag_two_payloads_string.txt | 2 - .../test_mono/generated/quicksort_help.txt | 3 - ...not_duplicate_identical_concrete_types.txt | 2 - ...types_without_unification_of_unifiable.txt | 4 - crates/glue/src/RustGlue.roc | 1 + crates/valgrind/src/lib.rs | 19 +++ 18 files changed, 156 insertions(+), 94 deletions(-) diff --git a/crates/compiler/alias_analysis/src/lib.rs b/crates/compiler/alias_analysis/src/lib.rs index 88eeadc7e5..2c20582296 100644 --- a/crates/compiler/alias_analysis/src/lib.rs +++ b/crates/compiler/alias_analysis/src/lib.rs @@ -349,8 +349,9 @@ where } match opt_level { - OptLevel::Development | OptLevel::Normal => morphic_lib::solve_trivial(program), - OptLevel::Optimize | OptLevel::Size => morphic_lib::solve(program), + // OptLevel::Development | OptLevel::Normal => morphic_lib::solve_trivial(program), + // OptLevel::Optimize | OptLevel::Size => morphic_lib::solve(program), + _ => morphic_lib::solve_trivial(program), } } diff --git a/crates/compiler/mono/src/borrow.rs b/crates/compiler/mono/src/borrow.rs index 1da0e3c2ba..d059085d32 100644 --- a/crates/compiler/mono/src/borrow.rs +++ b/crates/compiler/mono/src/borrow.rs @@ -1,11 +1,13 @@ -use bumpalo::{collections::Vec, Bump}; +use bumpalo::{ + collections::{CollectIn, Vec}, + Bump, +}; use roc_collections::{MutMap, ReferenceMatrix}; -use roc_error_macros::todo_lambda_erasure; use roc_module::symbol::Symbol; use crate::{ inc_dec::Ownership, - ir::{Call, CallType, Expr, Proc, ProcLayout, Stmt}, + ir::{Call, CallType, Expr, JoinPointId, Param, Proc, ProcLayout, Stmt}, layout::{Builtin, InLayout, LayoutInterner, LayoutRepr, Niche}, }; @@ -46,15 +48,19 @@ impl BorrowSignature { } } - fn set(&mut self, index: usize, ownership: Ownership) { + fn set(&mut self, index: usize, ownership: Ownership) -> bool { assert!(index < self.len()); + let modified = self.get(index) != Some(&ownership); + let mask = 1 << (index + 8); match ownership { Ownership::Owned => self.0 |= mask, Ownership::Borrowed => self.0 &= !mask, } + + modified } pub fn iter(&self) -> impl Iterator + '_ { @@ -76,27 +82,35 @@ impl std::ops::Index for BorrowSignature { } } -pub(crate) type BorrowSignatures<'a> = MutMap<(Symbol, ProcLayout<'a>), BorrowSignature>; +pub(crate) struct BorrowSignatures<'a> { + pub(crate) procs: MutMap<(Symbol, ProcLayout<'a>), BorrowSignature>, +} pub(crate) fn infer_borrow_signatures<'a, 'b: 'a>( arena: &'a Bump, interner: &impl LayoutInterner<'a>, procs: &'b MutMap<(Symbol, ProcLayout<'a>), Proc<'a>>, ) -> BorrowSignatures<'a> { - let mut borrow_signatures: BorrowSignatures = procs - .iter() - .map(|(_key, proc)| { - let mut signature = BorrowSignature::new(proc.args.len()); + let mut borrow_signatures: BorrowSignatures = BorrowSignatures { + procs: procs + .iter() + .map(|(_key, proc)| { + let mut signature = BorrowSignature::new(proc.args.len()); - let key = (proc.name.name(), proc.proc_layout(arena)); + let key = (proc.name.name(), proc.proc_layout(arena)); - for (i, in_layout) in key.1.arguments.iter().enumerate() { - signature.set(i, layout_to_ownership(*in_layout, interner)); - } + for (i, in_layout) in key.1.arguments.iter().enumerate() { + signature.set(i, layout_to_ownership(*in_layout, interner)); + } - (key, signature) - }) - .collect(); + (key, signature) + }) + .collect(), + }; + + let mut join_points: Vec<_> = std::iter::repeat_with(MutMap::default) + .take(procs.len()) + .collect_in(arena); // next we first partition the functions into strongly connected components, then do a // topological sort on these components, finally run the fix-point borrow analysis on each @@ -105,6 +119,9 @@ pub(crate) fn infer_borrow_signatures<'a, 'b: 'a>( let matrix = construct_reference_matrix(arena, procs); let sccs = matrix.strongly_connected_components_all(); + let mut join_point_stack = Vec::new_in(arena); + let mut proc_join_points = MutMap::default(); + for (group, _) in sccs.groups() { // This is a fixed-point analysis // @@ -121,22 +138,38 @@ pub(crate) fn infer_borrow_signatures<'a, 'b: 'a>( let (_, proc) = procs.iter().nth(index).unwrap(); let key = (proc.name.name(), proc.proc_layout(arena)); + std::mem::swap(&mut proc_join_points, &mut join_points[index]); + if proc.args.is_empty() { continue; } let mut state = State { args: proc.args, - borrow_signature: *borrow_signatures.get(&key).unwrap(), + borrow_signature: *borrow_signatures.procs.get(&key).unwrap(), + join_point_stack, + join_points: proc_join_points, + modified: false, }; - state.inspect_stmt(&mut borrow_signatures, &proc.body); + state.inspect_stmt(interner, &mut borrow_signatures, &proc.body); - let Some(old) = borrow_signatures.insert(key, state.borrow_signature) else { + let Some(old) = borrow_signatures.procs.insert(key, state.borrow_signature) else { unreachable!("key should be present"); }; - modified |= old != state.borrow_signature + // TODO I think this should use state.modified, but that loops infinitely currently + // also maybe a change in join point signature is always immediately reflected in a + // change in proc signature, in which case using the join point changes may not + // have any effect. + modified |= old != state.borrow_signature; + + proc_join_points = state.join_points; + + std::mem::swap(&mut proc_join_points, &mut join_points[index]); + + join_point_stack = state.join_point_stack; + join_point_stack.clear(); } if !modified { @@ -156,7 +189,7 @@ fn infer_borrow_signature<'a>( proc: &'a Proc<'a>, ) -> BorrowSignature { let mut state = State::new(arena, interner, borrow_signatures, proc); - state.inspect_stmt(borrow_signatures, &proc.body); + state.inspect_stmt(interner, borrow_signatures, &proc.body); state.borrow_signature } @@ -165,6 +198,9 @@ struct State<'a> { /// for which borrow inference might decide to pass as borrowed args: &'a [(InLayout<'a>, Symbol)], borrow_signature: BorrowSignature, + join_point_stack: Vec<'a, (JoinPointId, &'a [Param<'a>])>, + join_points: MutMap, + modified: bool, } fn layout_to_ownership<'a>( @@ -172,7 +208,8 @@ fn layout_to_ownership<'a>( interner: &impl LayoutInterner<'a>, ) -> Ownership { match interner.get_repr(in_layout) { - LayoutRepr::Builtin(Builtin::Str | Builtin::List(_)) => Ownership::Borrowed, + LayoutRepr::Builtin(Builtin::Str) => Ownership::Borrowed, + LayoutRepr::Builtin(Builtin::List(_)) => Ownership::Borrowed, LayoutRepr::LambdaSet(inner) => { layout_to_ownership(inner.runtime_representation(), interner) } @@ -190,7 +227,7 @@ impl<'a> State<'a> { let key = (proc.name.name(), proc.proc_layout(arena)); // initialize the borrow signature based on the layout if first time - let borrow_signature = borrow_signatures.entry(key).or_insert_with(|| { + let borrow_signature = borrow_signatures.procs.entry(key).or_insert_with(|| { let mut borrow_signature = BorrowSignature::new(proc.args.len()); for (i, in_layout) in key.1.arguments.iter().enumerate() { @@ -203,6 +240,9 @@ impl<'a> State<'a> { Self { args: proc.args, borrow_signature: *borrow_signature, + join_point_stack: Vec::new_in(arena), + join_points: MutMap::default(), + modified: false, } } @@ -211,15 +251,30 @@ impl<'a> State<'a> { /// Currently argument symbols participate if `layout_to_ownership` returns `Borrowed` for their layout. fn mark_owned(&mut self, symbol: Symbol) { if let Some(index) = self.args.iter().position(|(_, s)| *s == symbol) { - self.borrow_signature.set(index, Ownership::Owned); + self.modified |= self.borrow_signature.set(index, Ownership::Owned); + } + + for (id, params) in &self.join_point_stack { + if let Some(index) = params.iter().position(|p| p.symbol == symbol) { + self.modified |= self + .join_points + .get_mut(id) + .unwrap() + .set(index, Ownership::Owned); + } } } - fn inspect_stmt(&mut self, borrow_signatures: &mut BorrowSignatures<'a>, stmt: &'a Stmt<'a>) { + fn inspect_stmt( + &mut self, + interner: &impl LayoutInterner<'a>, + borrow_signatures: &mut BorrowSignatures<'a>, + stmt: &'a Stmt<'a>, + ) { match stmt { Stmt::Let(_, expr, _, stmt) => { self.inspect_expr(borrow_signatures, expr); - self.inspect_stmt(borrow_signatures, stmt); + self.inspect_stmt(interner, borrow_signatures, stmt); } Stmt::Switch { branches, @@ -227,9 +282,9 @@ impl<'a> State<'a> { .. } => { for (_, _, stmt) in branches.iter() { - self.inspect_stmt(borrow_signatures, stmt); + self.inspect_stmt(interner, borrow_signatures, stmt); } - self.inspect_stmt(borrow_signatures, default_branch.1); + self.inspect_stmt(interner, borrow_signatures, default_branch.1); } Stmt::Ret(s) => { // to return a value we must own it @@ -239,20 +294,47 @@ impl<'a> State<'a> { Stmt::Refcounting(_, _) => unreachable!("not inserted yet"), Stmt::Expect { remainder, .. } | Stmt::ExpectFx { remainder, .. } => { // based on my reading of inc_dec.rs, expect borrows the symbols - self.inspect_stmt(borrow_signatures, remainder); + self.inspect_stmt(interner, borrow_signatures, remainder); } Stmt::Dbg { remainder, .. } => { // based on my reading of inc_dec.rs, expect borrows the symbol - self.inspect_stmt(borrow_signatures, remainder); + self.inspect_stmt(interner, borrow_signatures, remainder); } Stmt::Join { - body, remainder, .. + id, + parameters, + body, + remainder, } => { - self.inspect_stmt(borrow_signatures, body); - self.inspect_stmt(borrow_signatures, remainder); + self.join_points.entry(*id).or_insert_with(|| { + let mut signature = BorrowSignature::new(parameters.len()); + + for (i, param) in parameters.iter().enumerate() { + signature.set(i, layout_to_ownership(param.layout, interner)); + } + + signature + }); + self.join_point_stack.push((*id, parameters)); + self.inspect_stmt(interner, borrow_signatures, body); + self.join_point_stack.pop().unwrap(); + self.inspect_stmt(interner, borrow_signatures, remainder); } - Stmt::Jump(_, _) | Stmt::Crash(_, _) => { /* not relevant for ownership */ } + Stmt::Jump(id, arguments) => { + let borrow_signature = match self.join_points.get(id) { + Some(s) => *s, + None => unreachable!("no borrow signature for join point {id:?} layout"), + }; + + for (argument, ownership) in arguments.iter().zip(borrow_signature.iter()) { + if let Ownership::Owned = ownership { + self.mark_owned(*argument); + } + } + } + + Stmt::Crash(_, _) => { /* not relevant for ownership */ } } } @@ -281,10 +363,11 @@ impl<'a> State<'a> { niche: Niche::NONE, }; - let borrow_signature = match borrow_signatures.get(&(name.name(), proc_layout)) { - Some(s) => s, - None => unreachable!("no borrow signature for {name:?} layout"), - }; + let borrow_signature = + match borrow_signatures.procs.get(&(name.name(), proc_layout)) { + Some(s) => s, + None => unreachable!("no borrow signature for {name:?} layout"), + }; for (argument, ownership) in arguments.iter().zip(borrow_signature.iter()) { if let Ownership::Owned = ownership { diff --git a/crates/compiler/mono/src/inc_dec.rs b/crates/compiler/mono/src/inc_dec.rs index ce9ce65ea4..0c06d5fa83 100644 --- a/crates/compiler/mono/src/inc_dec.rs +++ b/crates/compiler/mono/src/inc_dec.rs @@ -38,7 +38,7 @@ pub fn insert_inc_dec_operations<'a>( let borrow_signatures = crate::borrow::infer_borrow_signatures(arena, layout_interner, ps); let borrow_signatures = arena.alloc(borrow_signatures); - // for ((s, _), sig) in borrow_signatures.iter() { + // for ((s, _), sig) in borrow_signatures.procs.iter() { // dbg!((s, sig)); // } @@ -58,10 +58,8 @@ pub fn insert_inc_dec_operations<'a>( } } -/** -Enum indicating whether a symbol should be reference counted or not. -This includes layouts that themselves can be stack allocated but that contain a heap allocated item. -*/ +/// Enum indicating whether a symbol should be reference counted or not. +/// This includes layouts that themselves can be stack allocated but that contain a heap allocated item. #[derive(Copy, Clone)] enum VarRcType { ReferenceCounted, @@ -435,6 +433,7 @@ fn insert_inc_dec_operations_proc<'a>( // Add all arguments to the environment (if they are reference counted) let borrow_signature = borrow_signatures + .procs .get(&(proc.name.name(), proc.proc_layout(arena))) .unwrap(); for ((_, symbol), ownership) in proc.args.iter().zip(borrow_signature.iter()) { @@ -1008,10 +1007,6 @@ fn insert_refcount_operations_binding<'a>( ret_layout, .. } => { - // let new_let = new_let!(stmt); - // - // inc_owned!(arguments.iter().copied(), new_let) - let proc_layout = ProcLayout { arguments: arg_layouts, result: ret_layout, @@ -1020,6 +1015,7 @@ fn insert_refcount_operations_binding<'a>( let borrow_signature = match environment .borrow_signatures + .procs .get(&(name.name(), proc_layout)) { Some(s) => s, diff --git a/crates/compiler/test_gen/src/helpers/llvm.rs b/crates/compiler/test_gen/src/helpers/llvm.rs index c65af4c149..809900431d 100644 --- a/crates/compiler/test_gen/src/helpers/llvm.rs +++ b/crates/compiler/test_gen/src/helpers/llvm.rs @@ -29,7 +29,8 @@ const TEST_WRAPPER_NAME: &str = "test_wrapper"; #[allow(dead_code)] pub const OPT_LEVEL: OptLevel = if cfg!(debug_assertions) { - OptLevel::Normal + // OptLevel::Normal + OptLevel::Optimize } else { OptLevel::Optimize }; diff --git a/crates/compiler/test_mono/generated/compose_recursive_lambda_set_productive_nullable_wrapped.txt b/crates/compiler/test_mono/generated/compose_recursive_lambda_set_productive_nullable_wrapped.txt index a3a7026fcd..d1441b7f9b 100644 --- a/crates/compiler/test_mono/generated/compose_recursive_lambda_set_productive_nullable_wrapped.txt +++ b/crates/compiler/test_mono/generated/compose_recursive_lambda_set_productive_nullable_wrapped.txt @@ -51,7 +51,7 @@ procedure Test.11 (#Derived_gen.10, #Derived_gen.11): joinpoint Test.27 Test.12 #Attr.12: let Test.34 : Int1 = UnionAtIndex (Id 2) (Index 1) #Attr.12; let Test.33 : [, C *self Int1, C *self Int1] = UnionAtIndex (Id 2) (Index 0) #Attr.12; - joinpoint #Derived_gen.16: + joinpoint #Derived_gen.14: joinpoint Test.31 Test.29: let Test.30 : U8 = GetTagId Test.33; switch Test.30: @@ -78,16 +78,15 @@ procedure Test.11 (#Derived_gen.10, #Derived_gen.11): jump Test.31 Test.32; in - let #Derived_gen.17 : Int1 = lowlevel RefCountIsUnique #Attr.12; - if #Derived_gen.17 then + let #Derived_gen.15 : Int1 = lowlevel RefCountIsUnique #Attr.12; + if #Derived_gen.15 then free #Attr.12; - jump #Derived_gen.16; + jump #Derived_gen.14; else inc Test.33; decref #Attr.12; - jump #Derived_gen.16; + jump #Derived_gen.14; in - inc #Derived_gen.10; jump Test.27 #Derived_gen.10 #Derived_gen.11; procedure Test.2 (Test.13): @@ -144,7 +143,6 @@ procedure Test.9 (Test.10, #Attr.12): default: let Test.41 : Str = CallByName Test.11 Test.10 Test.42; - dec Test.10; jump Test.40 Test.41; in @@ -180,6 +178,5 @@ procedure Test.0 (): default: let Test.17 : Str = CallByName Test.11 Test.18 Test.16; - dec Test.18; ret Test.17; diff --git a/crates/compiler/test_mono/generated/encode_derived_nested_record_string.txt b/crates/compiler/test_mono/generated/encode_derived_nested_record_string.txt index 72503bc54b..e00e5541b9 100644 --- a/crates/compiler/test_mono/generated/encode_derived_nested_record_string.txt +++ b/crates/compiler/test_mono/generated/encode_derived_nested_record_string.txt @@ -128,7 +128,6 @@ procedure List.92 (#Derived_gen.29, #Derived_gen.30, #Derived_gen.31, #Derived_g ret List.164; in inc #Derived_gen.29; - inc #Derived_gen.30; jump List.603 #Derived_gen.29 #Derived_gen.30 #Derived_gen.31 #Derived_gen.32 #Derived_gen.33; procedure List.92 (#Derived_gen.37, #Derived_gen.38, #Derived_gen.39, #Derived_gen.40, #Derived_gen.41): @@ -146,7 +145,6 @@ procedure List.92 (#Derived_gen.37, #Derived_gen.38, #Derived_gen.39, #Derived_g ret List.164; in inc #Derived_gen.37; - inc #Derived_gen.38; jump List.577 #Derived_gen.37 #Derived_gen.38 #Derived_gen.39 #Derived_gen.40 #Derived_gen.41; procedure Num.127 (#Attr.2): @@ -235,7 +233,6 @@ procedure Test.67 (Test.68, Test.262, Test.66): let Test.69 : List U8 = CallByName Test.3 Test.68 Test.290 Test.291; let Test.265 : {} = Struct {}; let Test.264 : List U8 = CallByName List.18 Test.66 Test.69 Test.265; - dec Test.69; ret Test.264; procedure Test.67 (Test.68, Test.262, Test.66): @@ -244,7 +241,6 @@ procedure Test.67 (Test.68, Test.262, Test.66): let Test.69 : List U8 = CallByName Test.3 Test.68 Test.322 Test.323; let Test.297 : {} = Struct {}; let Test.296 : List U8 = CallByName List.18 Test.66 Test.69 Test.297; - dec Test.69; ret Test.296; procedure Test.70 (Test.71, Test.266): diff --git a/crates/compiler/test_mono/generated/encode_derived_record_one_field_string.txt b/crates/compiler/test_mono/generated/encode_derived_record_one_field_string.txt index f0353f48e3..bbba25e90b 100644 --- a/crates/compiler/test_mono/generated/encode_derived_record_one_field_string.txt +++ b/crates/compiler/test_mono/generated/encode_derived_record_one_field_string.txt @@ -85,7 +85,6 @@ procedure List.92 (#Derived_gen.13, #Derived_gen.14, #Derived_gen.15, #Derived_g dec List.163; ret List.164; in - inc #Derived_gen.14; inc #Derived_gen.13; jump List.577 #Derived_gen.13 #Derived_gen.14 #Derived_gen.15 #Derived_gen.16 #Derived_gen.17; @@ -171,7 +170,6 @@ procedure Test.67 (Test.68, Test.261, Test.66): let Test.69 : List U8 = CallByName Test.3 Test.68 Test.289 Test.290; let Test.264 : {} = Struct {}; let Test.263 : List U8 = CallByName List.18 Test.66 Test.69 Test.264; - dec Test.69; ret Test.263; procedure Test.70 (Test.71, Test.265): diff --git a/crates/compiler/test_mono/generated/encode_derived_record_two_field_strings.txt b/crates/compiler/test_mono/generated/encode_derived_record_two_field_strings.txt index 447d77bc41..aae93c839f 100644 --- a/crates/compiler/test_mono/generated/encode_derived_record_two_field_strings.txt +++ b/crates/compiler/test_mono/generated/encode_derived_record_two_field_strings.txt @@ -93,7 +93,6 @@ procedure List.92 (#Derived_gen.17, #Derived_gen.18, #Derived_gen.19, #Derived_g ret List.164; in inc #Derived_gen.17; - inc #Derived_gen.18; jump List.577 #Derived_gen.17 #Derived_gen.18 #Derived_gen.19 #Derived_gen.20 #Derived_gen.21; procedure Num.127 (#Attr.2): @@ -178,7 +177,6 @@ procedure Test.67 (Test.68, Test.262, Test.66): let Test.69 : List U8 = CallByName Test.3 Test.68 Test.290 Test.291; let Test.265 : {} = Struct {}; let Test.264 : List U8 = CallByName List.18 Test.66 Test.69 Test.265; - dec Test.69; ret Test.264; procedure Test.70 (Test.71, Test.266): diff --git a/crates/compiler/test_mono/generated/encode_derived_tag_one_field_string.txt b/crates/compiler/test_mono/generated/encode_derived_tag_one_field_string.txt index 7943b1b0c5..0a0bcc07c3 100644 --- a/crates/compiler/test_mono/generated/encode_derived_tag_one_field_string.txt +++ b/crates/compiler/test_mono/generated/encode_derived_tag_one_field_string.txt @@ -90,7 +90,6 @@ procedure List.92 (#Derived_gen.13, #Derived_gen.14, #Derived_gen.15, #Derived_g dec List.163; ret List.164; in - inc #Derived_gen.14; inc #Derived_gen.13; jump List.577 #Derived_gen.13 #Derived_gen.14 #Derived_gen.15 #Derived_gen.16 #Derived_gen.17; @@ -192,7 +191,6 @@ procedure Test.60 (Test.61, Test.266, #Attr.12): let Test.62 : List U8 = CallByName Test.3 Test.61 Test.274 Test.275; let Test.268 : List U8 = CallByName List.18 Test.58 Test.62 Test.59; dec Test.58; - dec Test.62; ret Test.268; procedure Test.63 (Test.64, Test.65, Test.59): diff --git a/crates/compiler/test_mono/generated/encode_derived_tag_two_payloads_string.txt b/crates/compiler/test_mono/generated/encode_derived_tag_two_payloads_string.txt index 0e5ab79b26..6e6237e121 100644 --- a/crates/compiler/test_mono/generated/encode_derived_tag_two_payloads_string.txt +++ b/crates/compiler/test_mono/generated/encode_derived_tag_two_payloads_string.txt @@ -93,7 +93,6 @@ procedure List.92 (#Derived_gen.14, #Derived_gen.15, #Derived_gen.16, #Derived_g dec List.163; ret List.164; in - inc #Derived_gen.15; inc #Derived_gen.14; jump List.577 #Derived_gen.14 #Derived_gen.15 #Derived_gen.16 #Derived_gen.17 #Derived_gen.18; @@ -195,7 +194,6 @@ procedure Test.60 (Test.61, Test.267, #Attr.12): let Test.62 : List U8 = CallByName Test.3 Test.61 Test.275 Test.276; let Test.269 : List U8 = CallByName List.18 Test.58 Test.62 Test.59; dec Test.58; - dec Test.62; ret Test.269; procedure Test.63 (Test.64, Test.65, Test.59): diff --git a/crates/compiler/test_mono/generated/inspect_derived_dict.txt b/crates/compiler/test_mono/generated/inspect_derived_dict.txt index 02f44ebb71..aac6e67eb9 100644 --- a/crates/compiler/test_mono/generated/inspect_derived_dict.txt +++ b/crates/compiler/test_mono/generated/inspect_derived_dict.txt @@ -141,7 +141,6 @@ procedure Dict.38 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2, #Derived_gen. let Dict.766 : U32 = CallByName Num.131 Dict.236; let Dict.752 : {U32, U32} = Struct {Dict.766, Dict.224}; let Dict.237 : List {U32, U32} = CallByName Dict.67 Dict.221 Dict.752 Dict.223; - dec Dict.221; let Dict.751 : {List {U32, U32}, List {Str, I64}, U64, Float32, U8} = Struct {Dict.237, Dict.235, Dict.227, Dict.228, Dict.229}; ret Dict.751; else @@ -150,8 +149,6 @@ procedure Dict.38 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2, #Derived_gen. let Dict.239 : U32 = CallByName Dict.48 Dict.224; jump Dict.736 Dict.221 Dict.222 Dict.238 Dict.239 Dict.225 Dict.226 Dict.227 Dict.228 Dict.229; in - inc #Derived_gen.0; - inc #Derived_gen.1; inc #Derived_gen.4; jump Dict.736 #Derived_gen.0 #Derived_gen.1 #Derived_gen.2 #Derived_gen.3 #Derived_gen.4 #Derived_gen.5 #Derived_gen.6 #Derived_gen.7 #Derived_gen.8; @@ -232,7 +229,6 @@ procedure Dict.59 (Dict.719): let Dict.381 : List {U32, U32} = StructAtIndex 0 Dict.855; let Dict.382 : U64 = StructAtIndex 1 Dict.855; let Dict.383 : List {U32, U32} = CallByName Dict.64 Dict.381 Dict.376 Dict.380; - dec Dict.381; let Dict.837 : {List {U32, U32}, List {Str, I64}, U64, Float32, U8} = Struct {Dict.383, Dict.376, Dict.382, Dict.378, Dict.380}; ret Dict.837; else @@ -324,7 +320,6 @@ procedure Dict.67 (#Derived_gen.28, #Derived_gen.29, #Derived_gen.30): let Dict.754 : List {U32, U32} = CallByName List.3 Dict.414 Dict.416 Dict.415; ret Dict.754; in - inc #Derived_gen.28; jump Dict.753 #Derived_gen.28 #Derived_gen.29 #Derived_gen.30; procedure Dict.68 (Dict.419, Dict.420): @@ -422,8 +417,6 @@ procedure Dict.8 (Dict.210, Dict.211, Dict.212): let Dict.219 : U32 = CallByName Dict.70 Dict.218; let Dict.220 : U64 = CallByName Dict.71 Dict.218 Dict.217; let Dict.735 : {List {U32, U32}, List {Str, I64}, U64, Float32, U8} = CallByName Dict.38 Dict.213 Dict.214 Dict.220 Dict.219 Dict.211 Dict.212 Dict.215 Dict.216 Dict.217; - dec Dict.214; - dec Dict.213; dec Dict.211; ret Dict.735; in @@ -900,7 +893,6 @@ procedure Inspect.60 (Inspect.298): procedure List.11 (List.138, List.139): let List.636 : List {U32, U32} = CallByName List.68 List.139; let List.635 : List {U32, U32} = CallByName List.90 List.138 List.139 List.636; - dec List.636; ret List.635; procedure List.18 (List.160, List.161, List.162): @@ -1011,7 +1003,6 @@ procedure List.90 (#Derived_gen.33, #Derived_gen.34, #Derived_gen.35): else ret List.142; in - inc #Derived_gen.35; jump List.625 #Derived_gen.33 #Derived_gen.34 #Derived_gen.35; procedure List.92 (#Derived_gen.50, #Derived_gen.51, #Derived_gen.52, #Derived_gen.53, #Derived_gen.54): @@ -1055,7 +1046,6 @@ procedure List.93 (#Derived_gen.23, #Derived_gen.24, #Derived_gen.25, #Derived_g let List.622 : {Str, I64} = CallByName List.66 List.172 List.175; inc List.622; let List.177 : List {U32, U32} = CallByName Dict.398 List.173 List.622 List.175 List.174; - dec List.173; let List.621 : U64 = 1i64; let List.620 : U64 = CallByName Num.51 List.175 List.621; jump List.616 List.172 List.177 List.174 List.620 List.176; @@ -1063,7 +1053,6 @@ procedure List.93 (#Derived_gen.23, #Derived_gen.24, #Derived_gen.25, #Derived_g dec List.172; ret List.173; in - inc #Derived_gen.24; inc #Derived_gen.23; jump List.616 #Derived_gen.23 #Derived_gen.24 #Derived_gen.25 #Derived_gen.26 #Derived_gen.27; diff --git a/crates/compiler/test_mono/generated/inspect_derived_tag_one_field_string.txt b/crates/compiler/test_mono/generated/inspect_derived_tag_one_field_string.txt index 25ed85325b..90534657ea 100644 --- a/crates/compiler/test_mono/generated/inspect_derived_tag_one_field_string.txt +++ b/crates/compiler/test_mono/generated/inspect_derived_tag_one_field_string.txt @@ -34,7 +34,6 @@ procedure Inspect.202 (Inspect.203, #Attr.12): let Inspect.321 : Str = CallByName Inspect.59 Inspect.333 Inspect.335; dec Inspect.335; let Inspect.317 : Str = CallByName Inspect.204 Inspect.321 Inspect.336; - dec Inspect.321; dec Inspect.336; let Inspect.318 : Str = ")"; let Inspect.316 : Str = CallByName Inspect.59 Inspect.317 Inspect.318; @@ -168,7 +167,6 @@ procedure List.92 (#Derived_gen.10, #Derived_gen.11, #Derived_gen.12, #Derived_g dec List.163; ret List.164; in - inc #Derived_gen.11; inc #Derived_gen.10; jump List.577 #Derived_gen.10 #Derived_gen.11 #Derived_gen.12 #Derived_gen.13 #Derived_gen.14; diff --git a/crates/compiler/test_mono/generated/inspect_derived_tag_two_payloads_string.txt b/crates/compiler/test_mono/generated/inspect_derived_tag_two_payloads_string.txt index 3cb2ba051c..76d50019de 100644 --- a/crates/compiler/test_mono/generated/inspect_derived_tag_two_payloads_string.txt +++ b/crates/compiler/test_mono/generated/inspect_derived_tag_two_payloads_string.txt @@ -37,7 +37,6 @@ procedure Inspect.202 (Inspect.203, #Attr.12): let Inspect.321 : Str = CallByName Inspect.59 Inspect.333 Inspect.335; dec Inspect.335; let Inspect.317 : Str = CallByName Inspect.204 Inspect.321 Inspect.336; - dec Inspect.321; dec Inspect.336; let Inspect.318 : Str = ")"; let Inspect.316 : Str = CallByName Inspect.59 Inspect.317 Inspect.318; @@ -171,7 +170,6 @@ procedure List.92 (#Derived_gen.13, #Derived_gen.14, #Derived_gen.15, #Derived_g dec List.163; ret List.164; in - inc #Derived_gen.14; inc #Derived_gen.13; jump List.577 #Derived_gen.13 #Derived_gen.14 #Derived_gen.15 #Derived_gen.16 #Derived_gen.17; diff --git a/crates/compiler/test_mono/generated/quicksort_help.txt b/crates/compiler/test_mono/generated/quicksort_help.txt index 98989a534c..26912208f7 100644 --- a/crates/compiler/test_mono/generated/quicksort_help.txt +++ b/crates/compiler/test_mono/generated/quicksort_help.txt @@ -23,14 +23,12 @@ procedure Test.1 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2): let Test.20 : I64 = 1i64; let Test.19 : I64 = CallByName Num.20 Test.5 Test.20; let Test.16 : List I64 = CallByName Test.1 Test.6 Test.3 Test.19; - dec Test.6; let Test.18 : I64 = 1i64; let Test.17 : I64 = CallByName Num.19 Test.5 Test.18; jump Test.12 Test.16 Test.17 Test.4; else ret Test.2; in - inc #Derived_gen.0; jump Test.12 #Derived_gen.0 #Derived_gen.1 #Derived_gen.2; procedure Test.0 (): @@ -38,5 +36,4 @@ procedure Test.0 (): let Test.10 : I64 = 0i64; let Test.11 : I64 = 0i64; let Test.8 : List I64 = CallByName Test.1 Test.9 Test.10 Test.11; - dec Test.9; ret Test.8; diff --git a/crates/compiler/test_mono/generated/unspecialized_lambda_set_unification_does_not_duplicate_identical_concrete_types.txt b/crates/compiler/test_mono/generated/unspecialized_lambda_set_unification_does_not_duplicate_identical_concrete_types.txt index 38ea3dd06d..f0887e0a1c 100644 --- a/crates/compiler/test_mono/generated/unspecialized_lambda_set_unification_does_not_duplicate_identical_concrete_types.txt +++ b/crates/compiler/test_mono/generated/unspecialized_lambda_set_unification_does_not_duplicate_identical_concrete_types.txt @@ -80,7 +80,6 @@ procedure List.92 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2, #Derived_gen. ret List.164; in inc #Derived_gen.0; - inc #Derived_gen.1; jump List.577 #Derived_gen.0 #Derived_gen.1 #Derived_gen.2 #Derived_gen.3 #Derived_gen.4; procedure Num.127 (#Attr.2): @@ -196,7 +195,6 @@ procedure Test.63 (Test.64, Test.276, #Attr.12): let Test.65 : List U8 = CallByName Test.4 Test.64 Test.284 Test.285; let Test.278 : List U8 = CallByName List.18 Test.61 Test.65 Test.62; dec Test.61; - dec Test.65; ret Test.278; procedure Test.66 (Test.67, Test.68, Test.62): diff --git a/crates/compiler/test_mono/generated/unspecialized_lambda_set_unification_keeps_all_concrete_types_without_unification_of_unifiable.txt b/crates/compiler/test_mono/generated/unspecialized_lambda_set_unification_keeps_all_concrete_types_without_unification_of_unifiable.txt index 941ff04c3f..7f8440dd32 100644 --- a/crates/compiler/test_mono/generated/unspecialized_lambda_set_unification_keeps_all_concrete_types_without_unification_of_unifiable.txt +++ b/crates/compiler/test_mono/generated/unspecialized_lambda_set_unification_keeps_all_concrete_types_without_unification_of_unifiable.txt @@ -156,7 +156,6 @@ procedure List.92 (#Derived_gen.29, #Derived_gen.30, #Derived_gen.31, #Derived_g ret List.164; in inc #Derived_gen.29; - inc #Derived_gen.30; jump List.577 #Derived_gen.29 #Derived_gen.30 #Derived_gen.31 #Derived_gen.32 #Derived_gen.33; procedure List.92 (#Derived_gen.52, #Derived_gen.53, #Derived_gen.54, #Derived_gen.55, #Derived_gen.56): @@ -173,7 +172,6 @@ procedure List.92 (#Derived_gen.52, #Derived_gen.53, #Derived_gen.54, #Derived_g dec List.163; ret List.164; in - inc #Derived_gen.53; inc #Derived_gen.52; jump List.604 #Derived_gen.52 #Derived_gen.53 #Derived_gen.54 #Derived_gen.55 #Derived_gen.56; @@ -323,7 +321,6 @@ procedure Test.63 (Test.64, Test.279, #Attr.12): let Test.65 : List U8 = CallByName Test.4 Test.64 Test.331 Test.332; let Test.325 : List U8 = CallByName List.18 Test.61 Test.65 Test.62; dec Test.61; - dec Test.65; ret Test.325; procedure Test.63 (Test.64, Test.279, #Attr.12): @@ -334,7 +331,6 @@ procedure Test.63 (Test.64, Test.279, #Attr.12): let Test.65 : List U8 = CallByName Test.4 Test.64 Test.287 Test.288; let Test.281 : List U8 = CallByName List.18 Test.61 Test.65 Test.62; dec Test.61; - dec Test.65; ret Test.281; procedure Test.66 (Test.67, Test.68, Test.62): diff --git a/crates/glue/src/RustGlue.roc b/crates/glue/src/RustGlue.roc index 01b58fdd03..d40bd35e74 100644 --- a/crates/glue/src/RustGlue.roc +++ b/crates/glue/src/RustGlue.roc @@ -1286,6 +1286,7 @@ writeIndents = \buf, indents -> |> Str.concat indent |> writeIndents (indents - 1) +writeTagImpls : Str, List { name : Str, payload : [Some TypeId, None] }, Str, U64, (Str, [Some TypeId, None] -> Str) -> Str writeTagImpls = \buf, tags, discriminantName, indents, f -> buf |> writeIndents indents diff --git a/crates/valgrind/src/lib.rs b/crates/valgrind/src/lib.rs index 5bff7e6059..3266f26a38 100644 --- a/crates/valgrind/src/lib.rs +++ b/crates/valgrind/src/lib.rs @@ -566,3 +566,22 @@ fn freeing_boxes() { "# )); } + +#[test] +fn joinpoint_that_owns() { + valgrind_test(indoc!( + r#" + ( + writeIndents = \buf, indents -> + if indents <= 0 then + buf + else + buf + |> Str.concat " " + |> writeIndents (indents - 1) + + List.walk [{}, {}] "" \accum, {} -> accum |> writeIndents 4 + ) + "# + )); +}