From 8d01e81aa77cd33bc650bbf1b1f84cc836838266 Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Wed, 10 Aug 2022 07:41:05 -0700 Subject: [PATCH 01/22] Use tag union/recursive tag union layout function for lambda sets --- crates/compiler/mono/src/layout.rs | 75 ++++++------------------------ 1 file changed, 14 insertions(+), 61 deletions(-) diff --git a/crates/compiler/mono/src/layout.rs b/crates/compiler/mono/src/layout.rs index 6bb280ab18..bfa404aa01 100644 --- a/crates/compiler/mono/src/layout.rs +++ b/crates/compiler/mono/src/layout.rs @@ -1053,7 +1053,7 @@ impl<'a> LambdaSet<'a> { lambdas.sort_by_key(|(sym, _)| *sym); let mut set: Vec<(Symbol, &[Layout])> = Vec::with_capacity_in(lambdas.len(), arena); - let mut set_with_variables: std::vec::Vec<(Symbol, std::vec::Vec)> = + let mut set_with_variables: std::vec::Vec<(&Symbol, &[Variable])> = std::vec::Vec::with_capacity(lambdas.len()); let mut last_function_symbol = None; @@ -1090,7 +1090,7 @@ impl<'a> LambdaSet<'a> { has_duplicate_lambda_names = has_duplicate_lambda_names || is_multimorphic; set.push((*function_symbol, arguments)); - set_with_variables.push((*function_symbol, variables.to_vec())); + set_with_variables.push((function_symbol, variables.as_slice())); last_function_symbol = Some(function_symbol); } @@ -1151,70 +1151,23 @@ impl<'a> LambdaSet<'a> { fn make_representation( arena: &'a Bump, subs: &Subs, - tags: std::vec::Vec<(Symbol, std::vec::Vec)>, + tags: std::vec::Vec<(&Symbol, &[Variable])>, opt_rec_var: Option, target_info: TargetInfo, ) -> Layout<'a> { - if let Some(rec_var) = opt_rec_var { - let tags: std::vec::Vec<_> = tags - .iter() - .map(|(sym, vars)| (sym, vars.as_slice())) - .collect(); - let tags = UnsortedUnionLabels { tags }; - let mut env = Env { - seen: Vec::new_in(arena), - target_info, - arena, - subs, - }; + let union_labels = UnsortedUnionLabels { tags }; + let mut env = Env { + seen: Vec::new_in(arena), + target_info, + arena, + subs, + }; - return layout_from_recursive_union(&mut env, rec_var, &tags) - .expect("unable to create lambda set representation"); - } + match opt_rec_var { + Some(rec_var) => layout_from_recursive_union(&mut env, rec_var, &union_labels) + .expect("unable to create lambda set representation"), - // otherwise, this is a closure with a payload - let variant = union_sorted_tags_help(arena, tags, opt_rec_var, subs, target_info); - - use UnionVariant::*; - match variant { - Never => Layout::VOID, - BoolUnion { .. } => Layout::bool(), - ByteUnion { .. } => Layout::u8(), - Unit | UnitWithArguments => { - // no useful information to store - Layout::UNIT - } - Newtype { - arguments: layouts, .. - } => Layout::struct_no_name_order(layouts.into_bump_slice()), - Wrapped(variant) => { - use WrappedVariant::*; - - match variant { - NonRecursive { - sorted_tag_layouts: tags, - } => { - debug_assert!(tags.len() > 1); - - // if the closed-over value is actually a layout, it should be wrapped in a 1-element record - debug_assert!(matches!(tags[0].0, TagOrClosure::Closure(_))); - - let mut tag_arguments = Vec::with_capacity_in(tags.len(), arena); - - for (_, tag_args) in tags.iter() { - tag_arguments.push(&tag_args[0..]); - } - Layout::Union(UnionLayout::NonRecursive(tag_arguments.into_bump_slice())) - } - - Recursive { .. } - | NullableUnwrapped { .. } - | NullableWrapped { .. } - | NonNullableUnwrapped { .. } => { - internal_error!("Recursive layouts should be produced in an earlier branch") - } - } - } + None => layout_from_union(&mut env, &union_labels), } } From fc4979e2ce6aee3874e96d056bc5ca2bfd9a7606 Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Wed, 10 Aug 2022 09:16:22 -0700 Subject: [PATCH 02/22] Add ClosureCallOptions enum to describe how to switch calling lambda --- crates/compiler/mono/src/ir.rs | 182 +++++-- crates/compiler/mono/src/layout.rs | 83 ++- .../test_mono/generated/closure_in_list.txt | 10 +- .../encode_derived_nested_record_string.txt | 502 +++++++++--------- ...encode_derived_record_one_field_string.txt | 270 +++++----- ...ncode_derived_record_two_field_strings.txt | 278 +++++----- .../generated/encode_derived_string.txt | 32 +- .../encode_derived_tag_one_field_string.txt | 264 ++++----- ...encode_derived_tag_two_payloads_string.txt | 264 ++++----- ...ches_have_captured_function_in_closure.txt | 24 +- ...iche_same_layout_different_constructor.txt | 26 +- .../test_mono/generated/nested_closure.txt | 8 +- .../recursive_call_capturing_function.txt | 19 +- 13 files changed, 1104 insertions(+), 858 deletions(-) diff --git a/crates/compiler/mono/src/ir.rs b/crates/compiler/mono/src/ir.rs index bb9a528084..5438801bce 100644 --- a/crates/compiler/mono/src/ir.rs +++ b/crates/compiler/mono/src/ir.rs @@ -1,8 +1,9 @@ #![allow(clippy::manual_map)] use crate::layout::{ - Builtin, CapturesNiche, ClosureRepresentation, LambdaName, LambdaSet, Layout, LayoutCache, - LayoutProblem, RawFunctionLayout, TagIdIntType, UnionLayout, WrappedVariant, + Builtin, CapturesNiche, ClosureCallOptions, ClosureRepresentation, LambdaName, LambdaSet, + Layout, LayoutCache, LayoutProblem, RawFunctionLayout, TagIdIntType, UnionLayout, + WrappedVariant, }; use bumpalo::collections::{CollectIn, Vec}; use bumpalo::Bump; @@ -3233,13 +3234,41 @@ fn specialize_external<'a>( } } - ClosureRepresentation::Other(layout) => match layout { + ClosureRepresentation::UnwrappedCapture(layout) => { + debug_assert_eq!(captured.len(), 1); + let (captured_symbol, _) = captured[0]; + + let captured_symbol = get_specialized_name(captured_symbol); + + // To avoid substitution, wrap in a struct and immediately unwrap. + // It should be optimized away later on. + let layout_slice = env.arena.alloc([layout]); + let arg_closure_slice = env.arena.alloc([Symbol::ARG_CLOSURE]); + + let wrap = Expr::Struct(arg_closure_slice); + let wrap_sym = env.unique_symbol(); + let hole = env.arena.alloc(Stmt::Let( + wrap_sym, + wrap, + Layout::struct_no_name_order(layout_slice), + env.arena.alloc(specialized_body), + )); + + let unwrap = Expr::StructAtIndex { + index: 0, + field_layouts: layout_slice, + structure: wrap_sym, + }; + specialized_body = Stmt::Let(captured_symbol, unwrap, layout, hole); + } + + ClosureRepresentation::MultiDispatch(layout) => match layout { Layout::Builtin(Builtin::Bool) => { - // just ignore this value + // just ignore this value, since it's not a capture // IDEA don't pass this value in the future } Layout::Builtin(Builtin::Int(IntWidth::U8)) => { - // just ignore this value + // just ignore this value, since it's not a capture // IDEA don't pass this value in the future } other => { @@ -5383,29 +5412,59 @@ where Stmt::Let(assigned, expr, lambda_set_layout, hole) } - ClosureRepresentation::Other(Layout::Builtin(Builtin::Bool)) => { - debug_assert_eq!(symbols.len(), 0); + ClosureRepresentation::UnwrappedCapture(layout) => { + debug_assert_eq!(symbols.len(), 1); - debug_assert_eq!(lambda_set.set.len(), 2); - let tag_id = name.name() != lambda_set.iter_set().next().unwrap().name(); - let expr = Expr::Literal(Literal::Bool(tag_id)); + let mut symbols = symbols; + let (captured_symbol, _) = symbols.next().unwrap(); - Stmt::Let(assigned, expr, lambda_set_layout, hole) + // To avoid substitution, wrap in a struct and immediately unwrap. + // It should be optimized away later on. + let layout_slice = env.arena.alloc([layout]); + let captured_slice = env.arena.alloc([*captured_symbol]); + let wrap = Expr::Struct(captured_slice); + let wrap_sym = env.unique_symbol(); + let hole = env.arena.alloc(Stmt::Let( + wrap_sym, + wrap, + Layout::struct_no_name_order(layout_slice), + hole, + )); + + let unwrap = Expr::StructAtIndex { + index: 0, + field_layouts: layout_slice, + structure: wrap_sym, + }; + Stmt::Let(assigned, unwrap, layout, hole) } - ClosureRepresentation::Other(Layout::Builtin(Builtin::Int(IntWidth::U8))) => { - debug_assert_eq!(symbols.len(), 0); + ClosureRepresentation::MultiDispatch(layout) => match layout { + Layout::Builtin(Builtin::Bool) => { + debug_assert_eq!(symbols.len(), 0); - debug_assert!(lambda_set.set.len() > 2); - let tag_id = lambda_set - .iter_set() - .position(|s| s.name() == name.name()) - .unwrap() as u8; + debug_assert_eq!(lambda_set.set.len(), 2); + let tag_id = name.name() != lambda_set.iter_set().next().unwrap().name(); + let expr = Expr::Literal(Literal::Bool(tag_id)); - let expr = Expr::Literal(Literal::Byte(tag_id)); + Stmt::Let(assigned, expr, lambda_set_layout, hole) + } + Layout::Builtin(Builtin::Int(IntWidth::U8)) => { + debug_assert_eq!(symbols.len(), 0); - Stmt::Let(assigned, expr, lambda_set_layout, hole) - } - _ => unreachable!(), + debug_assert!(lambda_set.set.len() > 2); + let tag_id = lambda_set + .iter_set() + .position(|s| s.name() == name.name()) + .unwrap() as u8; + + let expr = Expr::Literal(Literal::Byte(tag_id)); + + Stmt::Let(assigned, expr, lambda_set_layout, hole) + } + layout => { + internal_error!("Invalid layout for multi-dispatch closure: {:?}", layout) + } + }, }; result @@ -9267,9 +9326,9 @@ fn match_on_lambda_set<'a>( assigned: Symbol, hole: &'a Stmt<'a>, ) -> Stmt<'a> { - match lambda_set.runtime_representation() { - Layout::VOID => empty_lambda_set_error(), - Layout::Union(union_layout) => { + match lambda_set.call_by_name_options() { + ClosureCallOptions::Void => empty_lambda_set_error(), + ClosureCallOptions::Union(union_layout) => { let closure_tag_id_symbol = env.unique_symbol(); let result = union_lambda_set_to_switch( @@ -9299,7 +9358,7 @@ fn match_on_lambda_set<'a>( env.arena.alloc(result), ) } - Layout::Struct { + ClosureCallOptions::Struct { field_layouts, field_order_hash, } => { @@ -9343,15 +9402,22 @@ fn match_on_lambda_set<'a>( hole, ) } - Layout::Builtin(Builtin::Bool) => { - let closure_tag_id_symbol = closure_data_symbol; + ClosureCallOptions::UnwrappedCapture(layout) => { + let function_symbol = lambda_set + .iter_set() + .next() + .expect("no function in lambda set"); - enum_lambda_set_to_switch( - env, - lambda_set.iter_set(), - closure_tag_id_symbol, - Layout::Builtin(Builtin::Bool), + let closure_info = ClosureInfo::Captures { + lambda_set, closure_data_symbol, + closure_data_layout: layout, + }; + + union_lambda_set_branch_help( + env, + function_symbol, + closure_info, argument_symbols, argument_layouts, return_layout, @@ -9359,23 +9425,41 @@ fn match_on_lambda_set<'a>( hole, ) } - Layout::Builtin(Builtin::Int(IntWidth::U8)) => { - let closure_tag_id_symbol = closure_data_symbol; + ClosureCallOptions::MultiDispatch(layout) => match layout { + Layout::Builtin(Builtin::Bool) => { + let closure_tag_id_symbol = closure_data_symbol; - enum_lambda_set_to_switch( - env, - lambda_set.iter_set(), - closure_tag_id_symbol, - Layout::Builtin(Builtin::Int(IntWidth::U8)), - closure_data_symbol, - argument_symbols, - argument_layouts, - return_layout, - assigned, - hole, - ) - } - other => todo!("{:?}", other), + enum_lambda_set_to_switch( + env, + lambda_set.iter_set(), + closure_tag_id_symbol, + Layout::Builtin(Builtin::Bool), + closure_data_symbol, + argument_symbols, + argument_layouts, + return_layout, + assigned, + hole, + ) + } + Layout::Builtin(Builtin::Int(IntWidth::U8)) => { + let closure_tag_id_symbol = closure_data_symbol; + + enum_lambda_set_to_switch( + env, + lambda_set.iter_set(), + closure_tag_id_symbol, + Layout::Builtin(Builtin::Int(IntWidth::U8)), + closure_data_symbol, + argument_symbols, + argument_layouts, + return_layout, + assigned, + hole, + ) + } + other => internal_error!("Unexpected multi-dispatch layout: {:?}", other), + }, } } diff --git a/crates/compiler/mono/src/layout.rs b/crates/compiler/mono/src/layout.rs index bfa404aa01..4039e33425 100644 --- a/crates/compiler/mono/src/layout.rs +++ b/crates/compiler/mono/src/layout.rs @@ -791,20 +791,42 @@ pub struct LambdaSet<'a> { /// representation of the closure *for a particular function* #[derive(Debug)] pub enum ClosureRepresentation<'a> { - /// the closure is represented as a union. Includes the tag ID! + /// The closure is represented as a union. Includes the tag ID! + /// Each variant is a different function, and its payloads are the captures. Union { alphabetic_order_fields: &'a [Layout<'a>], closure_name: Symbol, tag_id: TagIdIntType, union_layout: UnionLayout<'a>, }, - /// The closure is represented as a struct. The layouts are sorted - /// alphabetically by the identifier that is captured. + /// The closure is one function, whose captures are represented as a struct. + /// The layouts are sorted alphabetically by the identifier that is captured. /// /// We MUST sort these according to their stack size before code gen! AlphabeticOrderStruct(&'a [Layout<'a>]), - /// the representation is anything but a union - Other(Layout<'a>), + /// The closure dispatches to multiple functions, but none of them capture anything, so this is + /// a boolean or integer flag. + MultiDispatch(Layout<'a>), + /// The closure is one function that captures a single identifier, whose value is unwrapped. + UnwrappedCapture(Layout<'a>), +} + +/// How the closure should be seen when determining a call-by-name. +#[derive(Debug)] +pub enum ClosureCallOptions<'a> { + /// This is an empty lambda set, dispatching is an error + Void, + /// One of a few capturing functions can be called to + Union(UnionLayout<'a>), + /// The closure is one function, whose captures are represented as a struct. + Struct { + field_layouts: &'a [Layout<'a>], + field_order_hash: FieldOrderHash, + }, + /// The closure dispatches to multiple possible functions, none of which capture. + MultiDispatch(Layout<'a>), + /// The closure is one function that captures a single identifier, whose value is unwrapped. + UnwrappedCapture(Layout<'a>), } impl<'a> LambdaSet<'a> { @@ -923,6 +945,11 @@ impl<'a> LambdaSet<'a> { where F: Fn(Symbol, &[Layout]) -> bool, { + if self.has_unwrapped_capture_repr() { + // Only one function, that captures one identifier. + return ClosureRepresentation::UnwrappedCapture(*self.representation); + } + match self.representation { Layout::Union(union) => { // here we rely on the fact that a union in a closure would be stored in a one-element record. @@ -1004,7 +1031,51 @@ impl<'a> LambdaSet<'a> { ClosureRepresentation::AlphabeticOrderStruct(fields) } - _ => ClosureRepresentation::Other(*self.representation), + layout => { + debug_assert!( + self.has_multi_dispatch_repr(), + "Expected this to be a multi-dispatching closure, but it was something else!" + ); + ClosureRepresentation::MultiDispatch(*layout) + } + } + } + + fn has_unwrapped_capture_repr(&self) -> bool { + self.set.len() == 1 && self.set[0].1.len() == 1 + } + + fn has_multi_dispatch_repr(&self) -> bool { + self.set.len() > 1 && self.set.iter().all(|(_, captures)| captures.is_empty()) + } + + pub fn call_by_name_options(&self) -> ClosureCallOptions<'a> { + if self.has_unwrapped_capture_repr() { + return ClosureCallOptions::UnwrappedCapture(*self.representation); + } + + match self.representation { + Layout::Union(union_layout) => { + if self.representation == &Layout::VOID { + debug_assert!(self.set.is_empty()); + return ClosureCallOptions::Void; + } + ClosureCallOptions::Union(*union_layout) + } + Layout::Struct { + field_layouts, + field_order_hash, + } => { + debug_assert_eq!(self.set.len(), 1); + ClosureCallOptions::Struct { + field_layouts, + field_order_hash: *field_order_hash, + } + } + layout => { + debug_assert!(self.has_multi_dispatch_repr()); + ClosureCallOptions::MultiDispatch(*layout) + } } } diff --git a/crates/compiler/test_mono/generated/closure_in_list.txt b/crates/compiler/test_mono/generated/closure_in_list.txt index 520a8a1808..5545d2e4ba 100644 --- a/crates/compiler/test_mono/generated/closure_in_list.txt +++ b/crates/compiler/test_mono/generated/closure_in_list.txt @@ -4,17 +4,19 @@ procedure List.6 (#Attr.2): procedure Test.1 (Test.5): let Test.2 : I64 = 41i64; - let Test.10 : {I64} = Struct {Test.2}; - let Test.9 : List {I64} = Array [Test.10]; + let Test.10 : I64 = StructAtIndex 0 Test.13; + let Test.13 : {I64} = Struct {Test.2}; + let Test.9 : List I64 = Array [Test.10]; ret Test.9; procedure Test.3 (Test.8, #Attr.12): - let Test.2 : I64 = StructAtIndex 0 #Attr.12; + let Test.2 : I64 = StructAtIndex 0 Test.12; + let Test.12 : {I64} = Struct {#Attr.12}; ret Test.2; procedure Test.0 (): let Test.7 : {} = Struct {}; - let Test.4 : List {I64} = CallByName Test.1 Test.7; + let Test.4 : List I64 = CallByName Test.1 Test.7; let Test.6 : U64 = CallByName List.6 Test.4; dec Test.4; ret Test.6; 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 3404bdc22a..4ad29c4b24 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 @@ -1,36 +1,44 @@ procedure #Derived.0 (#Derived.1): - let #Derived_gen.1 : {Str} = Struct {#Derived.1}; - let #Derived_gen.0 : {Str} = CallByName Encode.22 #Derived_gen.1; + let #Derived_gen.1 : Str = StructAtIndex 0 #Derived_gen.2; + inc #Derived_gen.1; + dec #Derived_gen.2; + let #Derived_gen.2 : {Str} = Struct {#Derived.1}; + let #Derived_gen.0 : Str = CallByName Encode.22 #Derived_gen.1; ret #Derived_gen.0; procedure #Derived.2 (#Derived.3, #Derived.4, #Attr.12): - let #Derived.1 : Str = StructAtIndex 0 #Attr.12; + let #Derived.1 : Str = StructAtIndex 0 #Derived_gen.11; inc #Derived.1; - dec #Attr.12; - let #Derived_gen.7 : Str = "a"; - let #Derived_gen.8 : {Str} = CallByName #Derived.5 #Derived.1; - let #Derived_gen.6 : {Str, {Str}} = Struct {#Derived_gen.7, #Derived_gen.8}; - let #Derived_gen.5 : List {Str, {Str}} = Array [#Derived_gen.6]; - let #Derived_gen.4 : {List {Str, {Str}}} = CallByName Json.20 #Derived_gen.5; - let #Derived_gen.3 : List U8 = CallByName Encode.23 #Derived.3 #Derived_gen.4 #Derived.4; - ret #Derived_gen.3; + dec #Derived_gen.11; + let #Derived_gen.11 : {Str} = Struct {#Attr.12}; + let #Derived_gen.8 : Str = "a"; + let #Derived_gen.9 : Str = CallByName #Derived.5 #Derived.1; + let #Derived_gen.7 : {Str, Str} = Struct {#Derived_gen.8, #Derived_gen.9}; + let #Derived_gen.6 : List {Str, Str} = Array [#Derived_gen.7]; + let #Derived_gen.5 : List {Str, Str} = CallByName Json.20 #Derived_gen.6; + let #Derived_gen.4 : List U8 = CallByName Encode.23 #Derived.3 #Derived_gen.5 #Derived.4; + ret #Derived_gen.4; procedure #Derived.5 (#Derived.6): - let #Derived_gen.15 : {Str} = Struct {#Derived.6}; - let #Derived_gen.14 : {Str} = CallByName Encode.22 #Derived_gen.15; - ret #Derived_gen.14; + let #Derived_gen.17 : Str = StructAtIndex 0 #Derived_gen.18; + inc #Derived_gen.17; + dec #Derived_gen.18; + let #Derived_gen.18 : {Str} = Struct {#Derived.6}; + let #Derived_gen.16 : Str = CallByName Encode.22 #Derived_gen.17; + ret #Derived_gen.16; procedure #Derived.7 (#Derived.8, #Derived.9, #Attr.12): - let #Derived.6 : Str = StructAtIndex 0 #Attr.12; + let #Derived.6 : Str = StructAtIndex 0 #Derived_gen.27; inc #Derived.6; - dec #Attr.12; - let #Derived_gen.21 : Str = "b"; - let #Derived_gen.22 : {Str} = CallByName Json.18 #Derived.6; - let #Derived_gen.20 : {Str, {Str}} = Struct {#Derived_gen.21, #Derived_gen.22}; - let #Derived_gen.19 : List {Str, {Str}} = Array [#Derived_gen.20]; - let #Derived_gen.18 : {List {Str, {Str}}} = CallByName Json.20 #Derived_gen.19; - let #Derived_gen.17 : List U8 = CallByName Encode.23 #Derived.8 #Derived_gen.18 #Derived.9; - ret #Derived_gen.17; + dec #Derived_gen.27; + let #Derived_gen.27 : {Str} = Struct {#Attr.12}; + let #Derived_gen.24 : Str = "b"; + let #Derived_gen.25 : Str = CallByName Json.18 #Derived.6; + let #Derived_gen.23 : {Str, Str} = Struct {#Derived_gen.24, #Derived_gen.25}; + let #Derived_gen.22 : List {Str, Str} = Array [#Derived_gen.23]; + let #Derived_gen.21 : List {Str, Str} = CallByName Json.20 #Derived_gen.22; + let #Derived_gen.20 : List U8 = CallByName Encode.23 #Derived.8 #Derived_gen.21 #Derived.9; + ret #Derived_gen.20; procedure Encode.22 (Encode.93): ret Encode.93; @@ -69,7 +77,7 @@ procedure Encode.23 (Encode.94, Encode.102, Encode.96): procedure Encode.25 (Encode.100, Encode.101): let Encode.104 : List U8 = Array []; - let Encode.105 : {Str} = CallByName #Derived.0 Encode.100; + let Encode.105 : Str = CallByName #Derived.0 Encode.100; let Encode.103 : List U8 = CallByName Encode.23 Encode.104 Encode.105 Encode.101; ret Encode.103; @@ -78,166 +86,181 @@ procedure Json.1 (): ret Json.318; procedure Json.103 (Json.104, Json.321, #Attr.12): - let Json.102 : List {Str, {Str}} = StructAtIndex 0 #Attr.12; + let Json.102 : List {Str, Str} = StructAtIndex 0 Json.356; inc Json.102; - dec #Attr.12; - let Json.354 : I32 = 123i64; - let Json.353 : U8 = CallByName Num.123 Json.354; - let Json.106 : List U8 = CallByName List.4 Json.104 Json.353; - let Json.352 : U64 = CallByName List.6 Json.102; - let Json.329 : {List U8, U64} = Struct {Json.106, Json.352}; - let Json.330 : {} = Struct {}; - let Json.328 : {List U8, U64} = CallByName List.18 Json.102 Json.329 Json.330; + dec Json.356; + let Json.356 : {List {Str, Str}} = Struct {#Attr.12}; + let Json.355 : I32 = 123i64; + let Json.354 : U8 = CallByName Num.123 Json.355; + let Json.106 : List U8 = CallByName List.4 Json.104 Json.354; + let Json.353 : U64 = CallByName List.6 Json.102; + let Json.330 : {List U8, U64} = Struct {Json.106, Json.353}; + let Json.331 : {} = Struct {}; + let Json.329 : {List U8, U64} = CallByName List.18 Json.102 Json.330 Json.331; dec Json.102; - let Json.108 : List U8 = StructAtIndex 0 Json.328; + let Json.108 : List U8 = StructAtIndex 0 Json.329; inc Json.108; - dec Json.328; - let Json.327 : I32 = 125i64; - let Json.326 : U8 = CallByName Num.123 Json.327; - let Json.325 : List U8 = CallByName List.4 Json.108 Json.326; - ret Json.325; + dec Json.329; + let Json.328 : I32 = 125i64; + let Json.327 : U8 = CallByName Num.123 Json.328; + let Json.326 : List U8 = CallByName List.4 Json.108 Json.327; + ret Json.326; procedure Json.103 (Json.104, Json.321, #Attr.12): - let Json.102 : List {Str, {Str}} = StructAtIndex 0 #Attr.12; + let Json.102 : List {Str, Str} = StructAtIndex 0 Json.402; inc Json.102; - dec #Attr.12; - let Json.397 : I32 = 123i64; - let Json.396 : U8 = CallByName Num.123 Json.397; - let Json.106 : List U8 = CallByName List.4 Json.104 Json.396; - let Json.395 : U64 = CallByName List.6 Json.102; - let Json.372 : {List U8, U64} = Struct {Json.106, Json.395}; - let Json.373 : {} = Struct {}; - let Json.371 : {List U8, U64} = CallByName List.18 Json.102 Json.372 Json.373; + dec Json.402; + let Json.402 : {List {Str, Str}} = Struct {#Attr.12}; + let Json.401 : I32 = 123i64; + let Json.400 : U8 = CallByName Num.123 Json.401; + let Json.106 : List U8 = CallByName List.4 Json.104 Json.400; + let Json.399 : U64 = CallByName List.6 Json.102; + let Json.376 : {List U8, U64} = Struct {Json.106, Json.399}; + let Json.377 : {} = Struct {}; + let Json.375 : {List U8, U64} = CallByName List.18 Json.102 Json.376 Json.377; dec Json.102; - let Json.108 : List U8 = StructAtIndex 0 Json.371; + let Json.108 : List U8 = StructAtIndex 0 Json.375; inc Json.108; - dec Json.371; - let Json.370 : I32 = 125i64; - let Json.369 : U8 = CallByName Num.123 Json.370; - let Json.368 : List U8 = CallByName List.4 Json.108 Json.369; - ret Json.368; + dec Json.375; + let Json.374 : I32 = 125i64; + let Json.373 : U8 = CallByName Num.123 Json.374; + let Json.372 : List U8 = CallByName List.4 Json.108 Json.373; + ret Json.372; -procedure Json.105 (Json.323, Json.324): - let Json.111 : Str = StructAtIndex 0 Json.324; +procedure Json.105 (Json.324, Json.325): + let Json.111 : Str = StructAtIndex 0 Json.325; inc Json.111; - let Json.112 : {Str} = StructAtIndex 1 Json.324; + let Json.112 : Str = StructAtIndex 1 Json.325; inc Json.112; - dec Json.324; - let Json.109 : List U8 = StructAtIndex 0 Json.323; + dec Json.325; + let Json.109 : List U8 = StructAtIndex 0 Json.324; inc Json.109; - let Json.110 : U64 = StructAtIndex 1 Json.323; - dec Json.323; - let Json.351 : I32 = 34i64; - let Json.350 : U8 = CallByName Num.123 Json.351; - let Json.348 : List U8 = CallByName List.4 Json.109 Json.350; - let Json.349 : List U8 = CallByName Str.12 Json.111; - let Json.345 : List U8 = CallByName List.8 Json.348 Json.349; - let Json.347 : I32 = 34i64; - let Json.346 : U8 = CallByName Num.123 Json.347; - let Json.342 : List U8 = CallByName List.4 Json.345 Json.346; - let Json.344 : I32 = 58i64; - let Json.343 : U8 = CallByName Num.123 Json.344; - let Json.340 : List U8 = CallByName List.4 Json.342 Json.343; - let Json.341 : {} = Struct {}; - let Json.113 : List U8 = CallByName Encode.23 Json.340 Json.112 Json.341; - joinpoint Json.335 Json.114: - let Json.333 : U64 = 1i64; - let Json.332 : U64 = CallByName Num.20 Json.110 Json.333; - let Json.331 : {List U8, U64} = Struct {Json.114, Json.332}; - ret Json.331; + let Json.110 : U64 = StructAtIndex 1 Json.324; + dec Json.324; + let Json.352 : I32 = 34i64; + let Json.351 : U8 = CallByName Num.123 Json.352; + let Json.349 : List U8 = CallByName List.4 Json.109 Json.351; + let Json.350 : List U8 = CallByName Str.12 Json.111; + let Json.346 : List U8 = CallByName List.8 Json.349 Json.350; + let Json.348 : I32 = 34i64; + let Json.347 : U8 = CallByName Num.123 Json.348; + let Json.343 : List U8 = CallByName List.4 Json.346 Json.347; + let Json.345 : I32 = 58i64; + let Json.344 : U8 = CallByName Num.123 Json.345; + let Json.341 : List U8 = CallByName List.4 Json.343 Json.344; + let Json.342 : {} = Struct {}; + let Json.113 : List U8 = CallByName Encode.23 Json.341 Json.112 Json.342; + joinpoint Json.336 Json.114: + let Json.334 : U64 = 1i64; + let Json.333 : U64 = CallByName Num.20 Json.110 Json.334; + let Json.332 : {List U8, U64} = Struct {Json.114, Json.333}; + ret Json.332; in - let Json.339 : U64 = 1i64; - let Json.336 : Int1 = CallByName Num.24 Json.110 Json.339; - if Json.336 then - let Json.338 : I32 = 44i64; - let Json.337 : U8 = CallByName Num.123 Json.338; - let Json.334 : List U8 = CallByName List.4 Json.113 Json.337; - jump Json.335 Json.334; + let Json.340 : U64 = 1i64; + let Json.337 : Int1 = CallByName Num.24 Json.110 Json.340; + if Json.337 then + let Json.339 : I32 = 44i64; + let Json.338 : U8 = CallByName Num.123 Json.339; + let Json.335 : List U8 = CallByName List.4 Json.113 Json.338; + jump Json.336 Json.335; else - jump Json.335 Json.113; + jump Json.336 Json.113; -procedure Json.105 (Json.323, Json.324): - let Json.111 : Str = StructAtIndex 0 Json.324; +procedure Json.105 (Json.324, Json.325): + let Json.111 : Str = StructAtIndex 0 Json.325; inc Json.111; - let Json.112 : {Str} = StructAtIndex 1 Json.324; + let Json.112 : Str = StructAtIndex 1 Json.325; inc Json.112; - dec Json.324; - let Json.109 : List U8 = StructAtIndex 0 Json.323; + dec Json.325; + let Json.109 : List U8 = StructAtIndex 0 Json.324; inc Json.109; - let Json.110 : U64 = StructAtIndex 1 Json.323; - dec Json.323; + let Json.110 : U64 = StructAtIndex 1 Json.324; + dec Json.324; + let Json.398 : I32 = 34i64; + let Json.397 : U8 = CallByName Num.123 Json.398; + let Json.395 : List U8 = CallByName List.4 Json.109 Json.397; + let Json.396 : List U8 = CallByName Str.12 Json.111; + let Json.392 : List U8 = CallByName List.8 Json.395 Json.396; let Json.394 : I32 = 34i64; let Json.393 : U8 = CallByName Num.123 Json.394; - let Json.391 : List U8 = CallByName List.4 Json.109 Json.393; - let Json.392 : List U8 = CallByName Str.12 Json.111; - let Json.388 : List U8 = CallByName List.8 Json.391 Json.392; - let Json.390 : I32 = 34i64; - let Json.389 : U8 = CallByName Num.123 Json.390; - let Json.385 : List U8 = CallByName List.4 Json.388 Json.389; - let Json.387 : I32 = 58i64; - let Json.386 : U8 = CallByName Num.123 Json.387; - let Json.383 : List U8 = CallByName List.4 Json.385 Json.386; - let Json.384 : {} = Struct {}; - let Json.113 : List U8 = CallByName Encode.23 Json.383 Json.112 Json.384; - joinpoint Json.378 Json.114: - let Json.376 : U64 = 1i64; - let Json.375 : U64 = CallByName Num.20 Json.110 Json.376; - let Json.374 : {List U8, U64} = Struct {Json.114, Json.375}; - ret Json.374; + let Json.389 : List U8 = CallByName List.4 Json.392 Json.393; + let Json.391 : I32 = 58i64; + let Json.390 : U8 = CallByName Num.123 Json.391; + let Json.387 : List U8 = CallByName List.4 Json.389 Json.390; + let Json.388 : {} = Struct {}; + let Json.113 : List U8 = CallByName Encode.23 Json.387 Json.112 Json.388; + joinpoint Json.382 Json.114: + let Json.380 : U64 = 1i64; + let Json.379 : U64 = CallByName Num.20 Json.110 Json.380; + let Json.378 : {List U8, U64} = Struct {Json.114, Json.379}; + ret Json.378; in - let Json.382 : U64 = 1i64; - let Json.379 : Int1 = CallByName Num.24 Json.110 Json.382; - if Json.379 then - let Json.381 : I32 = 44i64; - let Json.380 : U8 = CallByName Num.123 Json.381; - let Json.377 : List U8 = CallByName List.4 Json.113 Json.380; - jump Json.378 Json.377; + let Json.386 : U64 = 1i64; + let Json.383 : Int1 = CallByName Num.24 Json.110 Json.386; + if Json.383 then + let Json.385 : I32 = 44i64; + let Json.384 : U8 = CallByName Num.123 Json.385; + let Json.381 : List U8 = CallByName List.4 Json.113 Json.384; + jump Json.382 Json.381; else - jump Json.378 Json.113; + jump Json.382 Json.113; procedure Json.18 (Json.86): - let Json.365 : {Str} = Struct {Json.86}; - let Json.364 : {Str} = CallByName Encode.22 Json.365; - ret Json.364; + let Json.368 : Str = StructAtIndex 0 Json.370; + inc Json.368; + dec Json.370; + let Json.370 : {Str} = Struct {Json.86}; + let Json.367 : Str = CallByName Encode.22 Json.368; + ret Json.367; procedure Json.20 (Json.102): - let Json.320 : {List {Str, {Str}}} = Struct {Json.102}; - let Json.319 : {List {Str, {Str}}} = CallByName Encode.22 Json.320; + let Json.320 : List {Str, Str} = StructAtIndex 0 Json.322; + inc Json.320; + dec Json.322; + let Json.322 : {List {Str, Str}} = Struct {Json.102}; + let Json.319 : List {Str, Str} = CallByName Encode.22 Json.320; ret Json.319; procedure Json.20 (Json.102): - let Json.362 : {List {Str, {Str}}} = Struct {Json.102}; - let Json.361 : {List {Str, {Str}}} = CallByName Encode.22 Json.362; - ret Json.361; + let Json.364 : List {Str, Str} = StructAtIndex 0 Json.366; + inc Json.364; + dec Json.366; + let Json.366 : {List {Str, Str}} = Struct {Json.102}; + let Json.363 : List {Str, Str} = CallByName Encode.22 Json.364; + ret Json.363; -procedure Json.87 (Json.88, Json.366, #Attr.12): - let Json.86 : Str = StructAtIndex 0 #Attr.12; +procedure Json.87 (Json.88, Json.369, #Attr.12): + let Json.86 : Str = StructAtIndex 0 Json.412; inc Json.86; - dec #Attr.12; - let Json.406 : I32 = 34i64; - let Json.405 : U8 = CallByName Num.123 Json.406; - let Json.403 : List U8 = CallByName List.4 Json.88 Json.405; - let Json.404 : List U8 = CallByName Str.12 Json.86; - let Json.400 : List U8 = CallByName List.8 Json.403 Json.404; - let Json.402 : I32 = 34i64; - let Json.401 : U8 = CallByName Num.123 Json.402; - let Json.399 : List U8 = CallByName List.4 Json.400 Json.401; - ret Json.399; + dec Json.412; + let Json.412 : {Str} = Struct {#Attr.12}; + let Json.411 : I32 = 34i64; + let Json.410 : U8 = CallByName Num.123 Json.411; + let Json.408 : List U8 = CallByName List.4 Json.88 Json.410; + let Json.409 : List U8 = CallByName Str.12 Json.86; + let Json.405 : List U8 = CallByName List.8 Json.408 Json.409; + let Json.407 : I32 = 34i64; + let Json.406 : U8 = CallByName Num.123 Json.407; + let Json.404 : List U8 = CallByName List.4 Json.405 Json.406; + ret Json.404; procedure List.133 (List.134, List.135, #Attr.12): - let List.132 : {} = StructAtIndex 0 #Attr.12; - let List.434 : {List U8, U64} = CallByName Json.105 List.134 List.135; - let List.433 : [C [], C {List U8, U64}] = TagId(1) List.434; - ret List.433; + let List.132 : {} = StructAtIndex 0 List.436; + let List.436 : {{}} = Struct {#Attr.12}; + let List.435 : {List U8, U64} = CallByName Json.105 List.134 List.135; + let List.434 : [C [], C {List U8, U64}] = TagId(1) List.435; + ret List.434; procedure List.133 (List.134, List.135, #Attr.12): - let List.132 : {} = StructAtIndex 0 #Attr.12; - let List.515 : {List U8, U64} = CallByName Json.105 List.134 List.135; - let List.514 : [C [], C {List U8, U64}] = TagId(1) List.515; - ret List.514; + let List.132 : {} = StructAtIndex 0 List.519; + let List.519 : {{}} = Struct {#Attr.12}; + let List.518 : {List U8, U64} = CallByName Json.105 List.134 List.135; + let List.517 : [C [], C {List U8, U64}] = TagId(1) List.518; + ret List.517; procedure List.18 (List.130, List.131, List.132): - let List.411 : {{}} = Struct {List.132}; + let List.411 : {} = StructAtIndex 0 List.412; + let List.412 : {{}} = Struct {List.132}; let List.405 : [C [], C {List U8, U64}] = CallByName List.75 List.130 List.131 List.411; let List.408 : U8 = 1i64; let List.409 : U8 = GetTagId List.405; @@ -254,129 +277,130 @@ procedure List.18 (List.130, List.131, List.132): ret List.407; procedure List.18 (List.130, List.131, List.132): - let List.491 : {{}} = Struct {List.132}; - let List.485 : [C [], C {List U8, U64}] = CallByName List.75 List.130 List.131 List.491; - let List.488 : U8 = 1i64; - let List.489 : U8 = GetTagId List.485; - let List.490 : Int1 = lowlevel Eq List.488 List.489; - if List.490 then - let List.137 : {List U8, U64} = UnionAtIndex (Id 1) (Index 0) List.485; + let List.493 : {} = StructAtIndex 0 List.494; + let List.494 : {{}} = Struct {List.132}; + let List.487 : [C [], C {List U8, U64}] = CallByName List.75 List.130 List.131 List.493; + let List.490 : U8 = 1i64; + let List.491 : U8 = GetTagId List.487; + let List.492 : Int1 = lowlevel Eq List.490 List.491; + if List.492 then + let List.137 : {List U8, U64} = UnionAtIndex (Id 1) (Index 0) List.487; inc List.137; - dec List.485; + dec List.487; ret List.137; else - let List.138 : [] = UnionAtIndex (Id 0) (Index 0) List.485; - dec List.485; - let List.487 : {List U8, U64} = CallByName List.69 List.138; - ret List.487; + let List.138 : [] = UnionAtIndex (Id 0) (Index 0) List.487; + dec List.487; + let List.489 : {List U8, U64} = CallByName List.69 List.138; + ret List.489; procedure List.4 (List.101, List.102): - let List.484 : U64 = 1i64; - let List.483 : List U8 = CallByName List.70 List.101 List.484; - let List.482 : List U8 = CallByName List.71 List.483 List.102; - ret List.482; + let List.486 : U64 = 1i64; + let List.485 : List U8 = CallByName List.70 List.101 List.486; + let List.484 : List U8 = CallByName List.71 List.485 List.102; + ret List.484; procedure List.6 (#Attr.2): let List.385 : U64 = lowlevel ListLen #Attr.2; ret List.385; procedure List.6 (#Attr.2): - let List.413 : U64 = lowlevel ListLen #Attr.2; - ret List.413; + let List.414 : U64 = lowlevel ListLen #Attr.2; + ret List.414; procedure List.6 (#Attr.2): - let List.494 : U64 = lowlevel ListLen #Attr.2; - ret List.494; - -procedure List.66 (#Attr.2, #Attr.3): - let List.432 : {Str, {Str}} = lowlevel ListGetUnsafe #Attr.2 #Attr.3; - ret List.432; - -procedure List.66 (#Attr.2, #Attr.3): - let List.513 : {Str, {Str}} = lowlevel ListGetUnsafe #Attr.2 #Attr.3; - ret List.513; - -procedure List.69 (#Attr.2): - let List.497 : {List U8, U64} = lowlevel Unreachable #Attr.2; + let List.497 : U64 = lowlevel ListLen #Attr.2; ret List.497; +procedure List.66 (#Attr.2, #Attr.3): + let List.433 : {Str, Str} = lowlevel ListGetUnsafe #Attr.2 #Attr.3; + ret List.433; + +procedure List.66 (#Attr.2, #Attr.3): + let List.516 : {Str, Str} = lowlevel ListGetUnsafe #Attr.2 #Attr.3; + ret List.516; + +procedure List.69 (#Attr.2): + let List.500 : {List U8, U64} = lowlevel Unreachable #Attr.2; + ret List.500; + procedure List.70 (#Attr.2, #Attr.3): - let List.496 : List U8 = lowlevel ListReserve #Attr.2 #Attr.3; - ret List.496; + let List.499 : List U8 = lowlevel ListReserve #Attr.2 #Attr.3; + ret List.499; procedure List.71 (#Attr.2, #Attr.3): - let List.495 : List U8 = lowlevel ListAppendUnsafe #Attr.2 #Attr.3; - ret List.495; - -procedure List.75 (List.361, List.362, List.363): - let List.418 : U64 = 0i64; - let List.419 : U64 = CallByName List.6 List.361; - let List.417 : [C [], C {List U8, U64}] = CallByName List.86 List.361 List.362 List.363 List.418 List.419; - ret List.417; - -procedure List.75 (List.361, List.362, List.363): - let List.499 : U64 = 0i64; - let List.500 : U64 = CallByName List.6 List.361; - let List.498 : [C [], C {List U8, U64}] = CallByName List.86 List.361 List.362 List.363 List.499 List.500; + let List.498 : List U8 = lowlevel ListAppendUnsafe #Attr.2 #Attr.3; ret List.498; +procedure List.75 (List.361, List.362, List.363): + let List.419 : U64 = 0i64; + let List.420 : U64 = CallByName List.6 List.361; + let List.418 : [C [], C {List U8, U64}] = CallByName List.86 List.361 List.362 List.363 List.419 List.420; + ret List.418; + +procedure List.75 (List.361, List.362, List.363): + let List.502 : U64 = 0i64; + let List.503 : U64 = CallByName List.6 List.361; + let List.501 : [C [], C {List U8, U64}] = CallByName List.86 List.361 List.362 List.363 List.502 List.503; + ret List.501; + procedure List.8 (#Attr.2, #Attr.3): - let List.493 : List U8 = lowlevel ListConcat #Attr.2 #Attr.3; - ret List.493; + let List.496 : List U8 = lowlevel ListConcat #Attr.2 #Attr.3; + ret List.496; -procedure List.86 (List.448, List.449, List.450, List.451, List.452): - joinpoint List.420 List.364 List.365 List.366 List.367 List.368: - let List.422 : Int1 = CallByName Num.22 List.367 List.368; - if List.422 then - let List.431 : {Str, {Str}} = CallByName List.66 List.364 List.367; - let List.423 : [C [], C {List U8, U64}] = CallByName List.133 List.365 List.431 List.366; - let List.428 : U8 = 1i64; - let List.429 : U8 = GetTagId List.423; - let List.430 : Int1 = lowlevel Eq List.428 List.429; - if List.430 then - let List.369 : {List U8, U64} = UnionAtIndex (Id 1) (Index 0) List.423; +procedure List.86 (List.450, List.451, List.452, List.453, List.454): + joinpoint List.421 List.364 List.365 List.366 List.367 List.368: + let List.423 : Int1 = CallByName Num.22 List.367 List.368; + if List.423 then + let List.432 : {Str, Str} = CallByName List.66 List.364 List.367; + let List.424 : [C [], C {List U8, U64}] = CallByName List.133 List.365 List.432 List.366; + let List.429 : U8 = 1i64; + let List.430 : U8 = GetTagId List.424; + let List.431 : Int1 = lowlevel Eq List.429 List.430; + if List.431 then + let List.369 : {List U8, U64} = UnionAtIndex (Id 1) (Index 0) List.424; inc List.369; - dec List.423; - let List.426 : U64 = 1i64; - let List.425 : U64 = CallByName Num.19 List.367 List.426; - jump List.420 List.364 List.369 List.366 List.425 List.368; + dec List.424; + let List.427 : U64 = 1i64; + let List.426 : U64 = CallByName Num.19 List.367 List.427; + jump List.421 List.364 List.369 List.366 List.426 List.368; else - let List.370 : [] = UnionAtIndex (Id 0) (Index 0) List.423; - dec List.423; - let List.427 : [C [], C {List U8, U64}] = TagId(0) List.370; - ret List.427; + let List.370 : [] = UnionAtIndex (Id 0) (Index 0) List.424; + dec List.424; + let List.428 : [C [], C {List U8, U64}] = TagId(0) List.370; + ret List.428; else - let List.421 : [C [], C {List U8, U64}] = TagId(1) List.365; - ret List.421; + let List.422 : [C [], C {List U8, U64}] = TagId(1) List.365; + ret List.422; in - jump List.420 List.448 List.449 List.450 List.451 List.452; + jump List.421 List.450 List.451 List.452 List.453 List.454; -procedure List.86 (List.529, List.530, List.531, List.532, List.533): - joinpoint List.501 List.364 List.365 List.366 List.367 List.368: - let List.503 : Int1 = CallByName Num.22 List.367 List.368; - if List.503 then - let List.512 : {Str, {Str}} = CallByName List.66 List.364 List.367; - let List.504 : [C [], C {List U8, U64}] = CallByName List.133 List.365 List.512 List.366; - let List.509 : U8 = 1i64; - let List.510 : U8 = GetTagId List.504; - let List.511 : Int1 = lowlevel Eq List.509 List.510; - if List.511 then - let List.369 : {List U8, U64} = UnionAtIndex (Id 1) (Index 0) List.504; +procedure List.86 (List.533, List.534, List.535, List.536, List.537): + joinpoint List.504 List.364 List.365 List.366 List.367 List.368: + let List.506 : Int1 = CallByName Num.22 List.367 List.368; + if List.506 then + let List.515 : {Str, Str} = CallByName List.66 List.364 List.367; + let List.507 : [C [], C {List U8, U64}] = CallByName List.133 List.365 List.515 List.366; + let List.512 : U8 = 1i64; + let List.513 : U8 = GetTagId List.507; + let List.514 : Int1 = lowlevel Eq List.512 List.513; + if List.514 then + let List.369 : {List U8, U64} = UnionAtIndex (Id 1) (Index 0) List.507; inc List.369; - dec List.504; - let List.507 : U64 = 1i64; - let List.506 : U64 = CallByName Num.19 List.367 List.507; - jump List.501 List.364 List.369 List.366 List.506 List.368; + dec List.507; + let List.510 : U64 = 1i64; + let List.509 : U64 = CallByName Num.19 List.367 List.510; + jump List.504 List.364 List.369 List.366 List.509 List.368; else - let List.370 : [] = UnionAtIndex (Id 0) (Index 0) List.504; - dec List.504; - let List.508 : [C [], C {List U8, U64}] = TagId(0) List.370; - ret List.508; + let List.370 : [] = UnionAtIndex (Id 0) (Index 0) List.507; + dec List.507; + let List.511 : [C [], C {List U8, U64}] = TagId(0) List.370; + ret List.511; else - let List.502 : [C [], C {List U8, U64}] = TagId(1) List.365; - ret List.502; + let List.505 : [C [], C {List U8, U64}] = TagId(1) List.365; + ret List.505; in - jump List.501 List.529 List.530 List.531 List.532 List.533; + jump List.504 List.533 List.534 List.535 List.536 List.537; procedure Num.123 (#Attr.2): let Num.283 : U8 = lowlevel NumIntCast #Attr.2; 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 733350c9e4..401305cc93 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 @@ -1,19 +1,23 @@ procedure #Derived.0 (#Derived.1): - let #Derived_gen.1 : {Str} = Struct {#Derived.1}; - let #Derived_gen.0 : {Str} = CallByName Encode.22 #Derived_gen.1; + let #Derived_gen.1 : Str = StructAtIndex 0 #Derived_gen.2; + inc #Derived_gen.1; + dec #Derived_gen.2; + let #Derived_gen.2 : {Str} = Struct {#Derived.1}; + let #Derived_gen.0 : Str = CallByName Encode.22 #Derived_gen.1; ret #Derived_gen.0; procedure #Derived.2 (#Derived.3, #Derived.4, #Attr.12): - let #Derived.1 : Str = StructAtIndex 0 #Attr.12; + let #Derived.1 : Str = StructAtIndex 0 #Derived_gen.11; inc #Derived.1; - dec #Attr.12; - let #Derived_gen.7 : Str = "a"; - let #Derived_gen.8 : {Str} = CallByName Json.18 #Derived.1; - let #Derived_gen.6 : {Str, {Str}} = Struct {#Derived_gen.7, #Derived_gen.8}; - let #Derived_gen.5 : List {Str, {Str}} = Array [#Derived_gen.6]; - let #Derived_gen.4 : {List {Str, {Str}}} = CallByName Json.20 #Derived_gen.5; - let #Derived_gen.3 : List U8 = CallByName Encode.23 #Derived.3 #Derived_gen.4 #Derived.4; - ret #Derived_gen.3; + dec #Derived_gen.11; + let #Derived_gen.11 : {Str} = Struct {#Attr.12}; + let #Derived_gen.8 : Str = "a"; + let #Derived_gen.9 : Str = CallByName Json.18 #Derived.1; + let #Derived_gen.7 : {Str, Str} = Struct {#Derived_gen.8, #Derived_gen.9}; + let #Derived_gen.6 : List {Str, Str} = Array [#Derived_gen.7]; + let #Derived_gen.5 : List {Str, Str} = CallByName Json.20 #Derived_gen.6; + let #Derived_gen.4 : List U8 = CallByName Encode.23 #Derived.3 #Derived_gen.5 #Derived.4; + ret #Derived_gen.4; procedure Encode.22 (Encode.93): ret Encode.93; @@ -38,7 +42,7 @@ procedure Encode.23 (Encode.94, Encode.102, Encode.96): procedure Encode.25 (Encode.100, Encode.101): let Encode.104 : List U8 = Array []; - let Encode.105 : {Str} = CallByName #Derived.0 Encode.100; + let Encode.105 : Str = CallByName #Derived.0 Encode.100; let Encode.103 : List U8 = CallByName Encode.23 Encode.104 Encode.105 Encode.101; ret Encode.103; @@ -47,96 +51,106 @@ procedure Json.1 (): ret Json.318; procedure Json.103 (Json.104, Json.321, #Attr.12): - let Json.102 : List {Str, {Str}} = StructAtIndex 0 #Attr.12; + let Json.102 : List {Str, Str} = StructAtIndex 0 Json.360; inc Json.102; - dec #Attr.12; - let Json.357 : I32 = 123i64; - let Json.356 : U8 = CallByName Num.123 Json.357; - let Json.106 : List U8 = CallByName List.4 Json.104 Json.356; - let Json.355 : U64 = CallByName List.6 Json.102; - let Json.332 : {List U8, U64} = Struct {Json.106, Json.355}; - let Json.333 : {} = Struct {}; - let Json.331 : {List U8, U64} = CallByName List.18 Json.102 Json.332 Json.333; + dec Json.360; + let Json.360 : {List {Str, Str}} = Struct {#Attr.12}; + let Json.359 : I32 = 123i64; + let Json.358 : U8 = CallByName Num.123 Json.359; + let Json.106 : List U8 = CallByName List.4 Json.104 Json.358; + let Json.357 : U64 = CallByName List.6 Json.102; + let Json.334 : {List U8, U64} = Struct {Json.106, Json.357}; + let Json.335 : {} = Struct {}; + let Json.333 : {List U8, U64} = CallByName List.18 Json.102 Json.334 Json.335; dec Json.102; - let Json.108 : List U8 = StructAtIndex 0 Json.331; + let Json.108 : List U8 = StructAtIndex 0 Json.333; inc Json.108; - dec Json.331; - let Json.330 : I32 = 125i64; - let Json.329 : U8 = CallByName Num.123 Json.330; - let Json.328 : List U8 = CallByName List.4 Json.108 Json.329; - ret Json.328; + dec Json.333; + let Json.332 : I32 = 125i64; + let Json.331 : U8 = CallByName Num.123 Json.332; + let Json.330 : List U8 = CallByName List.4 Json.108 Json.331; + ret Json.330; -procedure Json.105 (Json.326, Json.327): - let Json.111 : Str = StructAtIndex 0 Json.327; +procedure Json.105 (Json.328, Json.329): + let Json.111 : Str = StructAtIndex 0 Json.329; inc Json.111; - let Json.112 : {Str} = StructAtIndex 1 Json.327; + let Json.112 : Str = StructAtIndex 1 Json.329; inc Json.112; - dec Json.327; - let Json.109 : List U8 = StructAtIndex 0 Json.326; + dec Json.329; + let Json.109 : List U8 = StructAtIndex 0 Json.328; inc Json.109; - let Json.110 : U64 = StructAtIndex 1 Json.326; - dec Json.326; - let Json.354 : I32 = 34i64; - let Json.353 : U8 = CallByName Num.123 Json.354; - let Json.351 : List U8 = CallByName List.4 Json.109 Json.353; - let Json.352 : List U8 = CallByName Str.12 Json.111; - let Json.348 : List U8 = CallByName List.8 Json.351 Json.352; - let Json.350 : I32 = 34i64; - let Json.349 : U8 = CallByName Num.123 Json.350; - let Json.345 : List U8 = CallByName List.4 Json.348 Json.349; - let Json.347 : I32 = 58i64; - let Json.346 : U8 = CallByName Num.123 Json.347; - let Json.343 : List U8 = CallByName List.4 Json.345 Json.346; - let Json.344 : {} = Struct {}; - let Json.113 : List U8 = CallByName Encode.23 Json.343 Json.112 Json.344; - joinpoint Json.338 Json.114: - let Json.336 : U64 = 1i64; - let Json.335 : U64 = CallByName Num.20 Json.110 Json.336; - let Json.334 : {List U8, U64} = Struct {Json.114, Json.335}; - ret Json.334; + let Json.110 : U64 = StructAtIndex 1 Json.328; + dec Json.328; + let Json.356 : I32 = 34i64; + let Json.355 : U8 = CallByName Num.123 Json.356; + let Json.353 : List U8 = CallByName List.4 Json.109 Json.355; + let Json.354 : List U8 = CallByName Str.12 Json.111; + let Json.350 : List U8 = CallByName List.8 Json.353 Json.354; + let Json.352 : I32 = 34i64; + let Json.351 : U8 = CallByName Num.123 Json.352; + let Json.347 : List U8 = CallByName List.4 Json.350 Json.351; + let Json.349 : I32 = 58i64; + let Json.348 : U8 = CallByName Num.123 Json.349; + let Json.345 : List U8 = CallByName List.4 Json.347 Json.348; + let Json.346 : {} = Struct {}; + let Json.113 : List U8 = CallByName Encode.23 Json.345 Json.112 Json.346; + joinpoint Json.340 Json.114: + let Json.338 : U64 = 1i64; + let Json.337 : U64 = CallByName Num.20 Json.110 Json.338; + let Json.336 : {List U8, U64} = Struct {Json.114, Json.337}; + ret Json.336; in - let Json.342 : U64 = 1i64; - let Json.339 : Int1 = CallByName Num.24 Json.110 Json.342; - if Json.339 then - let Json.341 : I32 = 44i64; - let Json.340 : U8 = CallByName Num.123 Json.341; - let Json.337 : List U8 = CallByName List.4 Json.113 Json.340; - jump Json.338 Json.337; + let Json.344 : U64 = 1i64; + let Json.341 : Int1 = CallByName Num.24 Json.110 Json.344; + if Json.341 then + let Json.343 : I32 = 44i64; + let Json.342 : U8 = CallByName Num.123 Json.343; + let Json.339 : List U8 = CallByName List.4 Json.113 Json.342; + jump Json.340 Json.339; else - jump Json.338 Json.113; + jump Json.340 Json.113; procedure Json.18 (Json.86): - let Json.323 : {Str} = Struct {Json.86}; - let Json.322 : {Str} = CallByName Encode.22 Json.323; - ret Json.322; + let Json.324 : Str = StructAtIndex 0 Json.326; + inc Json.324; + dec Json.326; + let Json.326 : {Str} = Struct {Json.86}; + let Json.323 : Str = CallByName Encode.22 Json.324; + ret Json.323; procedure Json.20 (Json.102): - let Json.320 : {List {Str, {Str}}} = Struct {Json.102}; - let Json.319 : {List {Str, {Str}}} = CallByName Encode.22 Json.320; + let Json.320 : List {Str, Str} = StructAtIndex 0 Json.322; + inc Json.320; + dec Json.322; + let Json.322 : {List {Str, Str}} = Struct {Json.102}; + let Json.319 : List {Str, Str} = CallByName Encode.22 Json.320; ret Json.319; -procedure Json.87 (Json.88, Json.324, #Attr.12): - let Json.86 : Str = StructAtIndex 0 #Attr.12; +procedure Json.87 (Json.88, Json.325, #Attr.12): + let Json.86 : Str = StructAtIndex 0 Json.370; inc Json.86; - dec #Attr.12; - let Json.366 : I32 = 34i64; - let Json.365 : U8 = CallByName Num.123 Json.366; - let Json.363 : List U8 = CallByName List.4 Json.88 Json.365; - let Json.364 : List U8 = CallByName Str.12 Json.86; - let Json.360 : List U8 = CallByName List.8 Json.363 Json.364; - let Json.362 : I32 = 34i64; - let Json.361 : U8 = CallByName Num.123 Json.362; - let Json.359 : List U8 = CallByName List.4 Json.360 Json.361; - ret Json.359; + dec Json.370; + let Json.370 : {Str} = Struct {#Attr.12}; + let Json.369 : I32 = 34i64; + let Json.368 : U8 = CallByName Num.123 Json.369; + let Json.366 : List U8 = CallByName List.4 Json.88 Json.368; + let Json.367 : List U8 = CallByName Str.12 Json.86; + let Json.363 : List U8 = CallByName List.8 Json.366 Json.367; + let Json.365 : I32 = 34i64; + let Json.364 : U8 = CallByName Num.123 Json.365; + let Json.362 : List U8 = CallByName List.4 Json.363 Json.364; + ret Json.362; procedure List.133 (List.134, List.135, #Attr.12): - let List.132 : {} = StructAtIndex 0 #Attr.12; - let List.441 : {List U8, U64} = CallByName Json.105 List.134 List.135; - let List.440 : [C [], C {List U8, U64}] = TagId(1) List.441; - ret List.440; + let List.132 : {} = StructAtIndex 0 List.443; + let List.443 : {{}} = Struct {#Attr.12}; + let List.442 : {List U8, U64} = CallByName Json.105 List.134 List.135; + let List.441 : [C [], C {List U8, U64}] = TagId(1) List.442; + ret List.441; procedure List.18 (List.130, List.131, List.132): - let List.417 : {{}} = Struct {List.132}; + let List.417 : {} = StructAtIndex 0 List.418; + let List.418 : {{}} = Struct {List.132}; let List.411 : [C [], C {List U8, U64}] = CallByName List.75 List.130 List.131 List.417; let List.414 : U8 = 1i64; let List.415 : U8 = GetTagId List.411; @@ -163,61 +177,61 @@ procedure List.6 (#Attr.2): ret List.385; procedure List.6 (#Attr.2): - let List.420 : U64 = lowlevel ListLen #Attr.2; - ret List.420; - -procedure List.66 (#Attr.2, #Attr.3): - let List.439 : {Str, {Str}} = lowlevel ListGetUnsafe #Attr.2 #Attr.3; - ret List.439; - -procedure List.69 (#Attr.2): - let List.423 : {List U8, U64} = lowlevel Unreachable #Attr.2; - ret List.423; - -procedure List.70 (#Attr.2, #Attr.3): - let List.422 : List U8 = lowlevel ListReserve #Attr.2 #Attr.3; - ret List.422; - -procedure List.71 (#Attr.2, #Attr.3): - let List.421 : List U8 = lowlevel ListAppendUnsafe #Attr.2 #Attr.3; + let List.421 : U64 = lowlevel ListLen #Attr.2; ret List.421; -procedure List.75 (List.361, List.362, List.363): - let List.425 : U64 = 0i64; - let List.426 : U64 = CallByName List.6 List.361; - let List.424 : [C [], C {List U8, U64}] = CallByName List.86 List.361 List.362 List.363 List.425 List.426; +procedure List.66 (#Attr.2, #Attr.3): + let List.440 : {Str, Str} = lowlevel ListGetUnsafe #Attr.2 #Attr.3; + ret List.440; + +procedure List.69 (#Attr.2): + let List.424 : {List U8, U64} = lowlevel Unreachable #Attr.2; ret List.424; -procedure List.8 (#Attr.2, #Attr.3): - let List.419 : List U8 = lowlevel ListConcat #Attr.2 #Attr.3; - ret List.419; +procedure List.70 (#Attr.2, #Attr.3): + let List.423 : List U8 = lowlevel ListReserve #Attr.2 #Attr.3; + ret List.423; -procedure List.86 (List.455, List.456, List.457, List.458, List.459): - joinpoint List.427 List.364 List.365 List.366 List.367 List.368: - let List.429 : Int1 = CallByName Num.22 List.367 List.368; - if List.429 then - let List.438 : {Str, {Str}} = CallByName List.66 List.364 List.367; - let List.430 : [C [], C {List U8, U64}] = CallByName List.133 List.365 List.438 List.366; - let List.435 : U8 = 1i64; - let List.436 : U8 = GetTagId List.430; - let List.437 : Int1 = lowlevel Eq List.435 List.436; - if List.437 then - let List.369 : {List U8, U64} = UnionAtIndex (Id 1) (Index 0) List.430; +procedure List.71 (#Attr.2, #Attr.3): + let List.422 : List U8 = lowlevel ListAppendUnsafe #Attr.2 #Attr.3; + ret List.422; + +procedure List.75 (List.361, List.362, List.363): + let List.426 : U64 = 0i64; + let List.427 : U64 = CallByName List.6 List.361; + let List.425 : [C [], C {List U8, U64}] = CallByName List.86 List.361 List.362 List.363 List.426 List.427; + ret List.425; + +procedure List.8 (#Attr.2, #Attr.3): + let List.420 : List U8 = lowlevel ListConcat #Attr.2 #Attr.3; + ret List.420; + +procedure List.86 (List.457, List.458, List.459, List.460, List.461): + joinpoint List.428 List.364 List.365 List.366 List.367 List.368: + let List.430 : Int1 = CallByName Num.22 List.367 List.368; + if List.430 then + let List.439 : {Str, Str} = CallByName List.66 List.364 List.367; + let List.431 : [C [], C {List U8, U64}] = CallByName List.133 List.365 List.439 List.366; + let List.436 : U8 = 1i64; + let List.437 : U8 = GetTagId List.431; + let List.438 : Int1 = lowlevel Eq List.436 List.437; + if List.438 then + let List.369 : {List U8, U64} = UnionAtIndex (Id 1) (Index 0) List.431; inc List.369; - dec List.430; - let List.433 : U64 = 1i64; - let List.432 : U64 = CallByName Num.19 List.367 List.433; - jump List.427 List.364 List.369 List.366 List.432 List.368; + dec List.431; + let List.434 : U64 = 1i64; + let List.433 : U64 = CallByName Num.19 List.367 List.434; + jump List.428 List.364 List.369 List.366 List.433 List.368; else - let List.370 : [] = UnionAtIndex (Id 0) (Index 0) List.430; - dec List.430; - let List.434 : [C [], C {List U8, U64}] = TagId(0) List.370; - ret List.434; + let List.370 : [] = UnionAtIndex (Id 0) (Index 0) List.431; + dec List.431; + let List.435 : [C [], C {List U8, U64}] = TagId(0) List.370; + ret List.435; else - let List.428 : [C [], C {List U8, U64}] = TagId(1) List.365; - ret List.428; + let List.429 : [C [], C {List U8, U64}] = TagId(1) List.365; + ret List.429; in - jump List.427 List.455 List.456 List.457 List.458 List.459; + jump List.428 List.457 List.458 List.459 List.460 List.461; procedure Num.123 (#Attr.2): let Num.264 : U8 = lowlevel NumIntCast #Attr.2; 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 918c446170..ef4b7f9022 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 @@ -1,27 +1,31 @@ procedure #Derived.0 (#Derived.1): - let #Derived_gen.1 : {{Str, Str}} = Struct {#Derived.1}; - let #Derived_gen.0 : {{Str, Str}} = CallByName Encode.22 #Derived_gen.1; + let #Derived_gen.1 : {Str, Str} = StructAtIndex 0 #Derived_gen.2; + inc #Derived_gen.1; + dec #Derived_gen.2; + let #Derived_gen.2 : {{Str, Str}} = Struct {#Derived.1}; + let #Derived_gen.0 : {Str, Str} = CallByName Encode.22 #Derived_gen.1; ret #Derived_gen.0; procedure #Derived.2 (#Derived.3, #Derived.4, #Attr.12): - let #Derived.1 : {Str, Str} = StructAtIndex 0 #Attr.12; + let #Derived.1 : {Str, Str} = StructAtIndex 0 #Derived_gen.15; inc #Derived.1; - dec #Attr.12; - let #Derived_gen.11 : Str = "a"; - let #Derived_gen.13 : Str = StructAtIndex 0 #Derived.1; - inc #Derived_gen.13; - let #Derived_gen.12 : {Str} = CallByName Json.18 #Derived_gen.13; - let #Derived_gen.6 : {Str, {Str}} = Struct {#Derived_gen.11, #Derived_gen.12}; - let #Derived_gen.8 : Str = "b"; - let #Derived_gen.10 : Str = StructAtIndex 1 #Derived.1; - inc #Derived_gen.10; + dec #Derived_gen.15; + let #Derived_gen.15 : {{Str, Str}} = Struct {#Attr.12}; + let #Derived_gen.12 : Str = "a"; + let #Derived_gen.14 : Str = StructAtIndex 0 #Derived.1; + inc #Derived_gen.14; + let #Derived_gen.13 : Str = CallByName Json.18 #Derived_gen.14; + let #Derived_gen.7 : {Str, Str} = Struct {#Derived_gen.12, #Derived_gen.13}; + let #Derived_gen.9 : Str = "b"; + let #Derived_gen.11 : Str = StructAtIndex 1 #Derived.1; + inc #Derived_gen.11; dec #Derived.1; - let #Derived_gen.9 : {Str} = CallByName Json.18 #Derived_gen.10; - let #Derived_gen.7 : {Str, {Str}} = Struct {#Derived_gen.8, #Derived_gen.9}; - let #Derived_gen.5 : List {Str, {Str}} = Array [#Derived_gen.6, #Derived_gen.7]; - let #Derived_gen.4 : {List {Str, {Str}}} = CallByName Json.20 #Derived_gen.5; - let #Derived_gen.3 : List U8 = CallByName Encode.23 #Derived.3 #Derived_gen.4 #Derived.4; - ret #Derived_gen.3; + let #Derived_gen.10 : Str = CallByName Json.18 #Derived_gen.11; + let #Derived_gen.8 : {Str, Str} = Struct {#Derived_gen.9, #Derived_gen.10}; + let #Derived_gen.6 : List {Str, Str} = Array [#Derived_gen.7, #Derived_gen.8]; + let #Derived_gen.5 : List {Str, Str} = CallByName Json.20 #Derived_gen.6; + let #Derived_gen.4 : List U8 = CallByName Encode.23 #Derived.3 #Derived_gen.5 #Derived.4; + ret #Derived_gen.4; procedure Encode.22 (Encode.93): ret Encode.93; @@ -46,7 +50,7 @@ procedure Encode.23 (Encode.94, Encode.102, Encode.96): procedure Encode.25 (Encode.100, Encode.101): let Encode.104 : List U8 = Array []; - let Encode.105 : {{Str, Str}} = CallByName #Derived.0 Encode.100; + let Encode.105 : {Str, Str} = CallByName #Derived.0 Encode.100; let Encode.103 : List U8 = CallByName Encode.23 Encode.104 Encode.105 Encode.101; ret Encode.103; @@ -55,96 +59,106 @@ procedure Json.1 (): ret Json.318; procedure Json.103 (Json.104, Json.321, #Attr.12): - let Json.102 : List {Str, {Str}} = StructAtIndex 0 #Attr.12; + let Json.102 : List {Str, Str} = StructAtIndex 0 Json.364; inc Json.102; - dec #Attr.12; - let Json.360 : I32 = 123i64; - let Json.359 : U8 = CallByName Num.123 Json.360; - let Json.106 : List U8 = CallByName List.4 Json.104 Json.359; - let Json.358 : U64 = CallByName List.6 Json.102; - let Json.335 : {List U8, U64} = Struct {Json.106, Json.358}; - let Json.336 : {} = Struct {}; - let Json.334 : {List U8, U64} = CallByName List.18 Json.102 Json.335 Json.336; + dec Json.364; + let Json.364 : {List {Str, Str}} = Struct {#Attr.12}; + let Json.363 : I32 = 123i64; + let Json.362 : U8 = CallByName Num.123 Json.363; + let Json.106 : List U8 = CallByName List.4 Json.104 Json.362; + let Json.361 : U64 = CallByName List.6 Json.102; + let Json.338 : {List U8, U64} = Struct {Json.106, Json.361}; + let Json.339 : {} = Struct {}; + let Json.337 : {List U8, U64} = CallByName List.18 Json.102 Json.338 Json.339; dec Json.102; - let Json.108 : List U8 = StructAtIndex 0 Json.334; + let Json.108 : List U8 = StructAtIndex 0 Json.337; inc Json.108; - dec Json.334; - let Json.333 : I32 = 125i64; - let Json.332 : U8 = CallByName Num.123 Json.333; - let Json.331 : List U8 = CallByName List.4 Json.108 Json.332; - ret Json.331; + dec Json.337; + let Json.336 : I32 = 125i64; + let Json.335 : U8 = CallByName Num.123 Json.336; + let Json.334 : List U8 = CallByName List.4 Json.108 Json.335; + ret Json.334; -procedure Json.105 (Json.329, Json.330): - let Json.111 : Str = StructAtIndex 0 Json.330; +procedure Json.105 (Json.332, Json.333): + let Json.111 : Str = StructAtIndex 0 Json.333; inc Json.111; - let Json.112 : {Str} = StructAtIndex 1 Json.330; + let Json.112 : Str = StructAtIndex 1 Json.333; inc Json.112; - dec Json.330; - let Json.109 : List U8 = StructAtIndex 0 Json.329; + dec Json.333; + let Json.109 : List U8 = StructAtIndex 0 Json.332; inc Json.109; - let Json.110 : U64 = StructAtIndex 1 Json.329; - dec Json.329; - let Json.357 : I32 = 34i64; - let Json.356 : U8 = CallByName Num.123 Json.357; - let Json.354 : List U8 = CallByName List.4 Json.109 Json.356; - let Json.355 : List U8 = CallByName Str.12 Json.111; - let Json.351 : List U8 = CallByName List.8 Json.354 Json.355; - let Json.353 : I32 = 34i64; + let Json.110 : U64 = StructAtIndex 1 Json.332; + dec Json.332; + let Json.360 : I32 = 34i64; + let Json.359 : U8 = CallByName Num.123 Json.360; + let Json.357 : List U8 = CallByName List.4 Json.109 Json.359; + let Json.358 : List U8 = CallByName Str.12 Json.111; + let Json.354 : List U8 = CallByName List.8 Json.357 Json.358; + let Json.356 : I32 = 34i64; + let Json.355 : U8 = CallByName Num.123 Json.356; + let Json.351 : List U8 = CallByName List.4 Json.354 Json.355; + let Json.353 : I32 = 58i64; let Json.352 : U8 = CallByName Num.123 Json.353; - let Json.348 : List U8 = CallByName List.4 Json.351 Json.352; - let Json.350 : I32 = 58i64; - let Json.349 : U8 = CallByName Num.123 Json.350; - let Json.346 : List U8 = CallByName List.4 Json.348 Json.349; - let Json.347 : {} = Struct {}; - let Json.113 : List U8 = CallByName Encode.23 Json.346 Json.112 Json.347; - joinpoint Json.341 Json.114: - let Json.339 : U64 = 1i64; - let Json.338 : U64 = CallByName Num.20 Json.110 Json.339; - let Json.337 : {List U8, U64} = Struct {Json.114, Json.338}; - ret Json.337; + let Json.349 : List U8 = CallByName List.4 Json.351 Json.352; + let Json.350 : {} = Struct {}; + let Json.113 : List U8 = CallByName Encode.23 Json.349 Json.112 Json.350; + joinpoint Json.344 Json.114: + let Json.342 : U64 = 1i64; + let Json.341 : U64 = CallByName Num.20 Json.110 Json.342; + let Json.340 : {List U8, U64} = Struct {Json.114, Json.341}; + ret Json.340; in - let Json.345 : U64 = 1i64; - let Json.342 : Int1 = CallByName Num.24 Json.110 Json.345; - if Json.342 then - let Json.344 : I32 = 44i64; - let Json.343 : U8 = CallByName Num.123 Json.344; - let Json.340 : List U8 = CallByName List.4 Json.113 Json.343; - jump Json.341 Json.340; + let Json.348 : U64 = 1i64; + let Json.345 : Int1 = CallByName Num.24 Json.110 Json.348; + if Json.345 then + let Json.347 : I32 = 44i64; + let Json.346 : U8 = CallByName Num.123 Json.347; + let Json.343 : List U8 = CallByName List.4 Json.113 Json.346; + jump Json.344 Json.343; else - jump Json.341 Json.113; + jump Json.344 Json.113; procedure Json.18 (Json.86): - let Json.326 : {Str} = Struct {Json.86}; - let Json.325 : {Str} = CallByName Encode.22 Json.326; - ret Json.325; + let Json.328 : Str = StructAtIndex 0 Json.330; + inc Json.328; + dec Json.330; + let Json.330 : {Str} = Struct {Json.86}; + let Json.327 : Str = CallByName Encode.22 Json.328; + ret Json.327; procedure Json.20 (Json.102): - let Json.320 : {List {Str, {Str}}} = Struct {Json.102}; - let Json.319 : {List {Str, {Str}}} = CallByName Encode.22 Json.320; + let Json.320 : List {Str, Str} = StructAtIndex 0 Json.322; + inc Json.320; + dec Json.322; + let Json.322 : {List {Str, Str}} = Struct {Json.102}; + let Json.319 : List {Str, Str} = CallByName Encode.22 Json.320; ret Json.319; -procedure Json.87 (Json.88, Json.324, #Attr.12): - let Json.86 : Str = StructAtIndex 0 #Attr.12; +procedure Json.87 (Json.88, Json.325, #Attr.12): + let Json.86 : Str = StructAtIndex 0 Json.374; inc Json.86; - dec #Attr.12; + dec Json.374; + let Json.374 : {Str} = Struct {#Attr.12}; + let Json.373 : I32 = 34i64; + let Json.372 : U8 = CallByName Num.123 Json.373; + let Json.370 : List U8 = CallByName List.4 Json.88 Json.372; + let Json.371 : List U8 = CallByName Str.12 Json.86; + let Json.367 : List U8 = CallByName List.8 Json.370 Json.371; let Json.369 : I32 = 34i64; let Json.368 : U8 = CallByName Num.123 Json.369; - let Json.366 : List U8 = CallByName List.4 Json.88 Json.368; - let Json.367 : List U8 = CallByName Str.12 Json.86; - let Json.363 : List U8 = CallByName List.8 Json.366 Json.367; - let Json.365 : I32 = 34i64; - let Json.364 : U8 = CallByName Num.123 Json.365; - let Json.362 : List U8 = CallByName List.4 Json.363 Json.364; - ret Json.362; + let Json.366 : List U8 = CallByName List.4 Json.367 Json.368; + ret Json.366; procedure List.133 (List.134, List.135, #Attr.12): - let List.132 : {} = StructAtIndex 0 #Attr.12; - let List.441 : {List U8, U64} = CallByName Json.105 List.134 List.135; - let List.440 : [C [], C {List U8, U64}] = TagId(1) List.441; - ret List.440; + let List.132 : {} = StructAtIndex 0 List.443; + let List.443 : {{}} = Struct {#Attr.12}; + let List.442 : {List U8, U64} = CallByName Json.105 List.134 List.135; + let List.441 : [C [], C {List U8, U64}] = TagId(1) List.442; + ret List.441; procedure List.18 (List.130, List.131, List.132): - let List.417 : {{}} = Struct {List.132}; + let List.417 : {} = StructAtIndex 0 List.418; + let List.418 : {{}} = Struct {List.132}; let List.411 : [C [], C {List U8, U64}] = CallByName List.75 List.130 List.131 List.417; let List.414 : U8 = 1i64; let List.415 : U8 = GetTagId List.411; @@ -171,61 +185,61 @@ procedure List.6 (#Attr.2): ret List.385; procedure List.6 (#Attr.2): - let List.420 : U64 = lowlevel ListLen #Attr.2; - ret List.420; - -procedure List.66 (#Attr.2, #Attr.3): - let List.439 : {Str, {Str}} = lowlevel ListGetUnsafe #Attr.2 #Attr.3; - ret List.439; - -procedure List.69 (#Attr.2): - let List.423 : {List U8, U64} = lowlevel Unreachable #Attr.2; - ret List.423; - -procedure List.70 (#Attr.2, #Attr.3): - let List.422 : List U8 = lowlevel ListReserve #Attr.2 #Attr.3; - ret List.422; - -procedure List.71 (#Attr.2, #Attr.3): - let List.421 : List U8 = lowlevel ListAppendUnsafe #Attr.2 #Attr.3; + let List.421 : U64 = lowlevel ListLen #Attr.2; ret List.421; -procedure List.75 (List.361, List.362, List.363): - let List.425 : U64 = 0i64; - let List.426 : U64 = CallByName List.6 List.361; - let List.424 : [C [], C {List U8, U64}] = CallByName List.86 List.361 List.362 List.363 List.425 List.426; +procedure List.66 (#Attr.2, #Attr.3): + let List.440 : {Str, Str} = lowlevel ListGetUnsafe #Attr.2 #Attr.3; + ret List.440; + +procedure List.69 (#Attr.2): + let List.424 : {List U8, U64} = lowlevel Unreachable #Attr.2; ret List.424; -procedure List.8 (#Attr.2, #Attr.3): - let List.419 : List U8 = lowlevel ListConcat #Attr.2 #Attr.3; - ret List.419; +procedure List.70 (#Attr.2, #Attr.3): + let List.423 : List U8 = lowlevel ListReserve #Attr.2 #Attr.3; + ret List.423; -procedure List.86 (List.455, List.456, List.457, List.458, List.459): - joinpoint List.427 List.364 List.365 List.366 List.367 List.368: - let List.429 : Int1 = CallByName Num.22 List.367 List.368; - if List.429 then - let List.438 : {Str, {Str}} = CallByName List.66 List.364 List.367; - let List.430 : [C [], C {List U8, U64}] = CallByName List.133 List.365 List.438 List.366; - let List.435 : U8 = 1i64; - let List.436 : U8 = GetTagId List.430; - let List.437 : Int1 = lowlevel Eq List.435 List.436; - if List.437 then - let List.369 : {List U8, U64} = UnionAtIndex (Id 1) (Index 0) List.430; +procedure List.71 (#Attr.2, #Attr.3): + let List.422 : List U8 = lowlevel ListAppendUnsafe #Attr.2 #Attr.3; + ret List.422; + +procedure List.75 (List.361, List.362, List.363): + let List.426 : U64 = 0i64; + let List.427 : U64 = CallByName List.6 List.361; + let List.425 : [C [], C {List U8, U64}] = CallByName List.86 List.361 List.362 List.363 List.426 List.427; + ret List.425; + +procedure List.8 (#Attr.2, #Attr.3): + let List.420 : List U8 = lowlevel ListConcat #Attr.2 #Attr.3; + ret List.420; + +procedure List.86 (List.457, List.458, List.459, List.460, List.461): + joinpoint List.428 List.364 List.365 List.366 List.367 List.368: + let List.430 : Int1 = CallByName Num.22 List.367 List.368; + if List.430 then + let List.439 : {Str, Str} = CallByName List.66 List.364 List.367; + let List.431 : [C [], C {List U8, U64}] = CallByName List.133 List.365 List.439 List.366; + let List.436 : U8 = 1i64; + let List.437 : U8 = GetTagId List.431; + let List.438 : Int1 = lowlevel Eq List.436 List.437; + if List.438 then + let List.369 : {List U8, U64} = UnionAtIndex (Id 1) (Index 0) List.431; inc List.369; - dec List.430; - let List.433 : U64 = 1i64; - let List.432 : U64 = CallByName Num.19 List.367 List.433; - jump List.427 List.364 List.369 List.366 List.432 List.368; + dec List.431; + let List.434 : U64 = 1i64; + let List.433 : U64 = CallByName Num.19 List.367 List.434; + jump List.428 List.364 List.369 List.366 List.433 List.368; else - let List.370 : [] = UnionAtIndex (Id 0) (Index 0) List.430; - dec List.430; - let List.434 : [C [], C {List U8, U64}] = TagId(0) List.370; - ret List.434; + let List.370 : [] = UnionAtIndex (Id 0) (Index 0) List.431; + dec List.431; + let List.435 : [C [], C {List U8, U64}] = TagId(0) List.370; + ret List.435; else - let List.428 : [C [], C {List U8, U64}] = TagId(1) List.365; - ret List.428; + let List.429 : [C [], C {List U8, U64}] = TagId(1) List.365; + ret List.429; in - jump List.427 List.455 List.456 List.457 List.458 List.459; + jump List.428 List.457 List.458 List.459 List.460 List.461; procedure Num.123 (#Attr.2): let Num.264 : U8 = lowlevel NumIntCast #Attr.2; diff --git a/crates/compiler/test_mono/generated/encode_derived_string.txt b/crates/compiler/test_mono/generated/encode_derived_string.txt index e4fe6488dd..aa3913651c 100644 --- a/crates/compiler/test_mono/generated/encode_derived_string.txt +++ b/crates/compiler/test_mono/generated/encode_derived_string.txt @@ -7,7 +7,7 @@ procedure Encode.23 (Encode.94, Encode.102, Encode.96): procedure Encode.25 (Encode.100, Encode.101): let Encode.104 : List U8 = Array []; - let Encode.105 : {Str} = CallByName Json.18 Encode.100; + let Encode.105 : Str = CallByName Json.18 Encode.100; let Encode.103 : List U8 = CallByName Encode.23 Encode.104 Encode.105 Encode.101; ret Encode.103; @@ -16,23 +16,27 @@ procedure Json.1 (): ret Json.318; procedure Json.18 (Json.86): - let Json.320 : {Str} = Struct {Json.86}; - let Json.319 : {Str} = CallByName Encode.22 Json.320; + let Json.320 : Str = StructAtIndex 0 Json.322; + inc Json.320; + dec Json.322; + let Json.322 : {Str} = Struct {Json.86}; + let Json.319 : Str = CallByName Encode.22 Json.320; ret Json.319; procedure Json.87 (Json.88, Json.321, #Attr.12): - let Json.86 : Str = StructAtIndex 0 #Attr.12; + let Json.86 : Str = StructAtIndex 0 Json.332; inc Json.86; - dec #Attr.12; - let Json.330 : I32 = 34i64; - let Json.329 : U8 = CallByName Num.123 Json.330; - let Json.327 : List U8 = CallByName List.4 Json.88 Json.329; - let Json.328 : List U8 = CallByName Str.12 Json.86; - let Json.324 : List U8 = CallByName List.8 Json.327 Json.328; - let Json.326 : I32 = 34i64; - let Json.325 : U8 = CallByName Num.123 Json.326; - let Json.323 : List U8 = CallByName List.4 Json.324 Json.325; - ret Json.323; + dec Json.332; + let Json.332 : {Str} = Struct {#Attr.12}; + let Json.331 : I32 = 34i64; + let Json.330 : U8 = CallByName Num.123 Json.331; + let Json.328 : List U8 = CallByName List.4 Json.88 Json.330; + let Json.329 : List U8 = CallByName Str.12 Json.86; + let Json.325 : List U8 = CallByName List.8 Json.328 Json.329; + let Json.327 : I32 = 34i64; + let Json.326 : U8 = CallByName Num.123 Json.327; + let Json.324 : List U8 = CallByName List.4 Json.325 Json.326; + ret Json.324; procedure List.4 (List.101, List.102): let List.392 : U64 = 1i64; 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 41fc52f97d..5915f977f7 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 @@ -1,21 +1,25 @@ procedure #Derived.0 (#Derived.1): - let #Derived_gen.1 : {Str} = Struct {#Derived.1}; - let #Derived_gen.0 : {Str} = CallByName Encode.22 #Derived_gen.1; + let #Derived_gen.1 : Str = StructAtIndex 0 #Derived_gen.2; + inc #Derived_gen.1; + dec #Derived_gen.2; + let #Derived_gen.2 : {Str} = Struct {#Derived.1}; + let #Derived_gen.0 : Str = CallByName Encode.22 #Derived_gen.1; ret #Derived_gen.0; procedure #Derived.3 (#Derived.4, #Derived.5, #Attr.12): - let #Derived.1 : Str = StructAtIndex 0 #Attr.12; + let #Derived.1 : Str = StructAtIndex 0 #Derived_gen.11; inc #Derived.1; - dec #Attr.12; - joinpoint #Derived_gen.5 #Derived_gen.4: - let #Derived_gen.3 : List U8 = CallByName Encode.23 #Derived.4 #Derived_gen.4 #Derived.5; - ret #Derived_gen.3; + dec #Derived_gen.11; + let #Derived_gen.11 : {Str} = Struct {#Attr.12}; + joinpoint #Derived_gen.6 #Derived_gen.5: + let #Derived_gen.4 : List U8 = CallByName Encode.23 #Derived.4 #Derived_gen.5 #Derived.5; + ret #Derived_gen.4; in - let #Derived_gen.7 : Str = "A"; - let #Derived_gen.9 : {Str} = CallByName Json.18 #Derived.1; - let #Derived_gen.8 : List {Str} = Array [#Derived_gen.9]; - let #Derived_gen.6 : {Str, List {Str}} = CallByName Json.21 #Derived_gen.7 #Derived_gen.8; - jump #Derived_gen.5 #Derived_gen.6; + let #Derived_gen.8 : Str = "A"; + let #Derived_gen.10 : Str = CallByName Json.18 #Derived.1; + let #Derived_gen.9 : List Str = Array [#Derived_gen.10]; + let #Derived_gen.7 : {Str, List Str} = CallByName Json.21 #Derived_gen.8 #Derived_gen.9; + jump #Derived_gen.6 #Derived_gen.7; procedure Encode.22 (Encode.93): ret Encode.93; @@ -40,7 +44,7 @@ procedure Encode.23 (Encode.94, Encode.102, Encode.96): procedure Encode.25 (Encode.100, Encode.101): let Encode.104 : List U8 = Array []; - let Encode.105 : {Str} = CallByName #Derived.0 Encode.100; + let Encode.105 : Str = CallByName #Derived.0 Encode.100; let Encode.103 : List U8 = CallByName Encode.23 Encode.104 Encode.105 Encode.101; ret Encode.103; @@ -49,99 +53,105 @@ procedure Json.1 (): ret Json.318; procedure Json.117 (Json.118, Json.321, #Attr.12): - let Json.116 : List {Str} = StructAtIndex 1 #Attr.12; + let Json.116 : List Str = StructAtIndex 1 #Attr.12; inc Json.116; let Json.115 : Str = StructAtIndex 0 #Attr.12; inc Json.115; dec #Attr.12; - let Json.362 : I32 = 123i64; - let Json.361 : U8 = CallByName Num.123 Json.362; - let Json.358 : List U8 = CallByName List.4 Json.118 Json.361; - let Json.360 : I32 = 34i64; - let Json.359 : U8 = CallByName Num.123 Json.360; - let Json.356 : List U8 = CallByName List.4 Json.358 Json.359; - let Json.357 : List U8 = CallByName Str.12 Json.115; - let Json.353 : List U8 = CallByName List.8 Json.356 Json.357; - let Json.355 : I32 = 34i64; - let Json.354 : U8 = CallByName Num.123 Json.355; - let Json.350 : List U8 = CallByName List.4 Json.353 Json.354; - let Json.352 : I32 = 58i64; - let Json.351 : U8 = CallByName Num.123 Json.352; - let Json.347 : List U8 = CallByName List.4 Json.350 Json.351; - let Json.349 : I32 = 91i64; - let Json.348 : U8 = CallByName Num.123 Json.349; - let Json.120 : List U8 = CallByName List.4 Json.347 Json.348; - let Json.346 : U64 = CallByName List.6 Json.116; - let Json.334 : {List U8, U64} = Struct {Json.120, Json.346}; - let Json.335 : {} = Struct {}; - let Json.333 : {List U8, U64} = CallByName List.18 Json.116 Json.334 Json.335; + let Json.363 : I32 = 123i64; + let Json.362 : U8 = CallByName Num.123 Json.363; + let Json.359 : List U8 = CallByName List.4 Json.118 Json.362; + let Json.361 : I32 = 34i64; + let Json.360 : U8 = CallByName Num.123 Json.361; + let Json.357 : List U8 = CallByName List.4 Json.359 Json.360; + let Json.358 : List U8 = CallByName Str.12 Json.115; + let Json.354 : List U8 = CallByName List.8 Json.357 Json.358; + let Json.356 : I32 = 34i64; + let Json.355 : U8 = CallByName Num.123 Json.356; + let Json.351 : List U8 = CallByName List.4 Json.354 Json.355; + let Json.353 : I32 = 58i64; + let Json.352 : U8 = CallByName Num.123 Json.353; + let Json.348 : List U8 = CallByName List.4 Json.351 Json.352; + let Json.350 : I32 = 91i64; + let Json.349 : U8 = CallByName Num.123 Json.350; + let Json.120 : List U8 = CallByName List.4 Json.348 Json.349; + let Json.347 : U64 = CallByName List.6 Json.116; + let Json.335 : {List U8, U64} = Struct {Json.120, Json.347}; + let Json.336 : {} = Struct {}; + let Json.334 : {List U8, U64} = CallByName List.18 Json.116 Json.335 Json.336; dec Json.116; - let Json.122 : List U8 = StructAtIndex 0 Json.333; + let Json.122 : List U8 = StructAtIndex 0 Json.334; inc Json.122; - dec Json.333; - let Json.332 : I32 = 93i64; - let Json.331 : U8 = CallByName Num.123 Json.332; - let Json.328 : List U8 = CallByName List.4 Json.122 Json.331; - let Json.330 : I32 = 125i64; - let Json.329 : U8 = CallByName Num.123 Json.330; - let Json.327 : List U8 = CallByName List.4 Json.328 Json.329; - ret Json.327; + dec Json.334; + let Json.333 : I32 = 93i64; + let Json.332 : U8 = CallByName Num.123 Json.333; + let Json.329 : List U8 = CallByName List.4 Json.122 Json.332; + let Json.331 : I32 = 125i64; + let Json.330 : U8 = CallByName Num.123 Json.331; + let Json.328 : List U8 = CallByName List.4 Json.329 Json.330; + ret Json.328; -procedure Json.119 (Json.326, Json.125): - let Json.123 : List U8 = StructAtIndex 0 Json.326; +procedure Json.119 (Json.327, Json.125): + let Json.123 : List U8 = StructAtIndex 0 Json.327; inc Json.123; - let Json.124 : U64 = StructAtIndex 1 Json.326; - dec Json.326; - let Json.345 : {} = Struct {}; - let Json.126 : List U8 = CallByName Encode.23 Json.123 Json.125 Json.345; - joinpoint Json.340 Json.127: - let Json.338 : U64 = 1i64; - let Json.337 : U64 = CallByName Num.20 Json.124 Json.338; - let Json.336 : {List U8, U64} = Struct {Json.127, Json.337}; - ret Json.336; + let Json.124 : U64 = StructAtIndex 1 Json.327; + dec Json.327; + let Json.346 : {} = Struct {}; + let Json.126 : List U8 = CallByName Encode.23 Json.123 Json.125 Json.346; + joinpoint Json.341 Json.127: + let Json.339 : U64 = 1i64; + let Json.338 : U64 = CallByName Num.20 Json.124 Json.339; + let Json.337 : {List U8, U64} = Struct {Json.127, Json.338}; + ret Json.337; in - let Json.344 : U64 = 1i64; - let Json.341 : Int1 = CallByName Num.24 Json.124 Json.344; - if Json.341 then - let Json.343 : I32 = 44i64; - let Json.342 : U8 = CallByName Num.123 Json.343; - let Json.339 : List U8 = CallByName List.4 Json.126 Json.342; - jump Json.340 Json.339; + let Json.345 : U64 = 1i64; + let Json.342 : Int1 = CallByName Num.24 Json.124 Json.345; + if Json.342 then + let Json.344 : I32 = 44i64; + let Json.343 : U8 = CallByName Num.123 Json.344; + let Json.340 : List U8 = CallByName List.4 Json.126 Json.343; + jump Json.341 Json.340; else - jump Json.340 Json.126; + jump Json.341 Json.126; procedure Json.18 (Json.86): - let Json.323 : {Str} = Struct {Json.86}; - let Json.322 : {Str} = CallByName Encode.22 Json.323; + let Json.323 : Str = StructAtIndex 0 Json.325; + inc Json.323; + dec Json.325; + let Json.325 : {Str} = Struct {Json.86}; + let Json.322 : Str = CallByName Encode.22 Json.323; ret Json.322; procedure Json.21 (Json.115, Json.116): - let Json.320 : {Str, List {Str}} = Struct {Json.115, Json.116}; - let Json.319 : {Str, List {Str}} = CallByName Encode.22 Json.320; + let Json.320 : {Str, List Str} = Struct {Json.115, Json.116}; + let Json.319 : {Str, List Str} = CallByName Encode.22 Json.320; ret Json.319; procedure Json.87 (Json.88, Json.324, #Attr.12): - let Json.86 : Str = StructAtIndex 0 #Attr.12; + let Json.86 : Str = StructAtIndex 0 Json.373; inc Json.86; - dec #Attr.12; - let Json.371 : I32 = 34i64; - let Json.370 : U8 = CallByName Num.123 Json.371; - let Json.368 : List U8 = CallByName List.4 Json.88 Json.370; - let Json.369 : List U8 = CallByName Str.12 Json.86; - let Json.365 : List U8 = CallByName List.8 Json.368 Json.369; - let Json.367 : I32 = 34i64; - let Json.366 : U8 = CallByName Num.123 Json.367; - let Json.364 : List U8 = CallByName List.4 Json.365 Json.366; - ret Json.364; + dec Json.373; + let Json.373 : {Str} = Struct {#Attr.12}; + let Json.372 : I32 = 34i64; + let Json.371 : U8 = CallByName Num.123 Json.372; + let Json.369 : List U8 = CallByName List.4 Json.88 Json.371; + let Json.370 : List U8 = CallByName Str.12 Json.86; + let Json.366 : List U8 = CallByName List.8 Json.369 Json.370; + let Json.368 : I32 = 34i64; + let Json.367 : U8 = CallByName Num.123 Json.368; + let Json.365 : List U8 = CallByName List.4 Json.366 Json.367; + ret Json.365; procedure List.133 (List.134, List.135, #Attr.12): - let List.132 : {} = StructAtIndex 0 #Attr.12; - let List.447 : {List U8, U64} = CallByName Json.119 List.134 List.135; - let List.446 : [C [], C {List U8, U64}] = TagId(1) List.447; - ret List.446; + let List.132 : {} = StructAtIndex 0 List.449; + let List.449 : {{}} = Struct {#Attr.12}; + let List.448 : {List U8, U64} = CallByName Json.119 List.134 List.135; + let List.447 : [C [], C {List U8, U64}] = TagId(1) List.448; + ret List.447; procedure List.18 (List.130, List.131, List.132): - let List.423 : {{}} = Struct {List.132}; + let List.423 : {} = StructAtIndex 0 List.424; + let List.424 : {{}} = Struct {List.132}; let List.417 : [C [], C {List U8, U64}] = CallByName List.75 List.130 List.131 List.423; let List.420 : U8 = 1i64; let List.421 : U8 = GetTagId List.417; @@ -168,61 +178,61 @@ procedure List.6 (#Attr.2): ret List.385; procedure List.6 (#Attr.2): - let List.424 : U64 = lowlevel ListLen #Attr.2; - ret List.424; + let List.425 : U64 = lowlevel ListLen #Attr.2; + ret List.425; procedure List.66 (#Attr.2, #Attr.3): - let List.445 : {Str} = lowlevel ListGetUnsafe #Attr.2 #Attr.3; - ret List.445; + let List.446 : Str = lowlevel ListGetUnsafe #Attr.2 #Attr.3; + ret List.446; procedure List.69 (#Attr.2): - let List.429 : {List U8, U64} = lowlevel Unreachable #Attr.2; - ret List.429; - -procedure List.70 (#Attr.2, #Attr.3): - let List.428 : List U8 = lowlevel ListReserve #Attr.2 #Attr.3; - ret List.428; - -procedure List.71 (#Attr.2, #Attr.3): - let List.427 : List U8 = lowlevel ListAppendUnsafe #Attr.2 #Attr.3; - ret List.427; - -procedure List.75 (List.361, List.362, List.363): - let List.431 : U64 = 0i64; - let List.432 : U64 = CallByName List.6 List.361; - let List.430 : [C [], C {List U8, U64}] = CallByName List.86 List.361 List.362 List.363 List.431 List.432; + let List.430 : {List U8, U64} = lowlevel Unreachable #Attr.2; ret List.430; -procedure List.8 (#Attr.2, #Attr.3): - let List.426 : List U8 = lowlevel ListConcat #Attr.2 #Attr.3; - ret List.426; +procedure List.70 (#Attr.2, #Attr.3): + let List.429 : List U8 = lowlevel ListReserve #Attr.2 #Attr.3; + ret List.429; -procedure List.86 (List.461, List.462, List.463, List.464, List.465): - joinpoint List.433 List.364 List.365 List.366 List.367 List.368: - let List.435 : Int1 = CallByName Num.22 List.367 List.368; - if List.435 then - let List.444 : {Str} = CallByName List.66 List.364 List.367; - let List.436 : [C [], C {List U8, U64}] = CallByName List.133 List.365 List.444 List.366; - let List.441 : U8 = 1i64; - let List.442 : U8 = GetTagId List.436; - let List.443 : Int1 = lowlevel Eq List.441 List.442; - if List.443 then - let List.369 : {List U8, U64} = UnionAtIndex (Id 1) (Index 0) List.436; +procedure List.71 (#Attr.2, #Attr.3): + let List.428 : List U8 = lowlevel ListAppendUnsafe #Attr.2 #Attr.3; + ret List.428; + +procedure List.75 (List.361, List.362, List.363): + let List.432 : U64 = 0i64; + let List.433 : U64 = CallByName List.6 List.361; + let List.431 : [C [], C {List U8, U64}] = CallByName List.86 List.361 List.362 List.363 List.432 List.433; + ret List.431; + +procedure List.8 (#Attr.2, #Attr.3): + let List.427 : List U8 = lowlevel ListConcat #Attr.2 #Attr.3; + ret List.427; + +procedure List.86 (List.463, List.464, List.465, List.466, List.467): + joinpoint List.434 List.364 List.365 List.366 List.367 List.368: + let List.436 : Int1 = CallByName Num.22 List.367 List.368; + if List.436 then + let List.445 : Str = CallByName List.66 List.364 List.367; + let List.437 : [C [], C {List U8, U64}] = CallByName List.133 List.365 List.445 List.366; + let List.442 : U8 = 1i64; + let List.443 : U8 = GetTagId List.437; + let List.444 : Int1 = lowlevel Eq List.442 List.443; + if List.444 then + let List.369 : {List U8, U64} = UnionAtIndex (Id 1) (Index 0) List.437; inc List.369; - dec List.436; - let List.439 : U64 = 1i64; - let List.438 : U64 = CallByName Num.19 List.367 List.439; - jump List.433 List.364 List.369 List.366 List.438 List.368; + dec List.437; + let List.440 : U64 = 1i64; + let List.439 : U64 = CallByName Num.19 List.367 List.440; + jump List.434 List.364 List.369 List.366 List.439 List.368; else - let List.370 : [] = UnionAtIndex (Id 0) (Index 0) List.436; - dec List.436; - let List.440 : [C [], C {List U8, U64}] = TagId(0) List.370; - ret List.440; + let List.370 : [] = UnionAtIndex (Id 0) (Index 0) List.437; + dec List.437; + let List.441 : [C [], C {List U8, U64}] = TagId(0) List.370; + ret List.441; else - let List.434 : [C [], C {List U8, U64}] = TagId(1) List.365; - ret List.434; + let List.435 : [C [], C {List U8, U64}] = TagId(1) List.365; + ret List.435; in - jump List.433 List.461 List.462 List.463 List.464 List.465; + jump List.434 List.463 List.464 List.465 List.466 List.467; procedure Num.123 (#Attr.2): let Num.266 : U8 = lowlevel NumIntCast #Attr.2; 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 fc88805f4c..f15a732461 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 @@ -1,27 +1,31 @@ procedure #Derived.0 (#Derived.1): - let #Derived_gen.1 : {{Str, Str}} = Struct {#Derived.1}; - let #Derived_gen.0 : {{Str, Str}} = CallByName Encode.22 #Derived_gen.1; + let #Derived_gen.1 : {Str, Str} = StructAtIndex 0 #Derived_gen.2; + inc #Derived_gen.1; + dec #Derived_gen.2; + let #Derived_gen.2 : {{Str, Str}} = Struct {#Derived.1}; + let #Derived_gen.0 : {Str, Str} = CallByName Encode.22 #Derived_gen.1; ret #Derived_gen.0; procedure #Derived.4 (#Derived.5, #Derived.6, #Attr.12): - let #Derived.1 : {Str, Str} = StructAtIndex 0 #Attr.12; + let #Derived.1 : {Str, Str} = StructAtIndex 0 #Derived_gen.12; inc #Derived.1; - dec #Attr.12; - joinpoint #Derived_gen.5 #Derived_gen.4: - let #Derived_gen.3 : List U8 = CallByName Encode.23 #Derived.5 #Derived_gen.4 #Derived.6; - ret #Derived_gen.3; + dec #Derived_gen.12; + let #Derived_gen.12 : {{Str, Str}} = Struct {#Attr.12}; + joinpoint #Derived_gen.6 #Derived_gen.5: + let #Derived_gen.4 : List U8 = CallByName Encode.23 #Derived.5 #Derived_gen.5 #Derived.6; + ret #Derived_gen.4; in let #Derived.2 : Str = StructAtIndex 0 #Derived.1; inc #Derived.2; let #Derived.3 : Str = StructAtIndex 1 #Derived.1; inc #Derived.3; dec #Derived.1; - let #Derived_gen.7 : Str = "A"; - let #Derived_gen.9 : {Str} = CallByName Json.18 #Derived.2; - let #Derived_gen.10 : {Str} = CallByName Json.18 #Derived.3; - let #Derived_gen.8 : List {Str} = Array [#Derived_gen.9, #Derived_gen.10]; - let #Derived_gen.6 : {Str, List {Str}} = CallByName Json.21 #Derived_gen.7 #Derived_gen.8; - jump #Derived_gen.5 #Derived_gen.6; + let #Derived_gen.8 : Str = "A"; + let #Derived_gen.10 : Str = CallByName Json.18 #Derived.2; + let #Derived_gen.11 : Str = CallByName Json.18 #Derived.3; + let #Derived_gen.9 : List Str = Array [#Derived_gen.10, #Derived_gen.11]; + let #Derived_gen.7 : {Str, List Str} = CallByName Json.21 #Derived_gen.8 #Derived_gen.9; + jump #Derived_gen.6 #Derived_gen.7; procedure Encode.22 (Encode.93): ret Encode.93; @@ -46,7 +50,7 @@ procedure Encode.23 (Encode.94, Encode.102, Encode.96): procedure Encode.25 (Encode.100, Encode.101): let Encode.104 : List U8 = Array []; - let Encode.105 : {{Str, Str}} = CallByName #Derived.0 Encode.100; + let Encode.105 : {Str, Str} = CallByName #Derived.0 Encode.100; let Encode.103 : List U8 = CallByName Encode.23 Encode.104 Encode.105 Encode.101; ret Encode.103; @@ -55,99 +59,105 @@ procedure Json.1 (): ret Json.318; procedure Json.117 (Json.118, Json.321, #Attr.12): - let Json.116 : List {Str} = StructAtIndex 1 #Attr.12; + let Json.116 : List Str = StructAtIndex 1 #Attr.12; inc Json.116; let Json.115 : Str = StructAtIndex 0 #Attr.12; inc Json.115; dec #Attr.12; - let Json.365 : I32 = 123i64; + let Json.367 : I32 = 123i64; + let Json.366 : U8 = CallByName Num.123 Json.367; + let Json.363 : List U8 = CallByName List.4 Json.118 Json.366; + let Json.365 : I32 = 34i64; let Json.364 : U8 = CallByName Num.123 Json.365; - let Json.361 : List U8 = CallByName List.4 Json.118 Json.364; - let Json.363 : I32 = 34i64; - let Json.362 : U8 = CallByName Num.123 Json.363; - let Json.359 : List U8 = CallByName List.4 Json.361 Json.362; - let Json.360 : List U8 = CallByName Str.12 Json.115; - let Json.356 : List U8 = CallByName List.8 Json.359 Json.360; - let Json.358 : I32 = 34i64; - let Json.357 : U8 = CallByName Num.123 Json.358; - let Json.353 : List U8 = CallByName List.4 Json.356 Json.357; - let Json.355 : I32 = 58i64; - let Json.354 : U8 = CallByName Num.123 Json.355; - let Json.350 : List U8 = CallByName List.4 Json.353 Json.354; - let Json.352 : I32 = 91i64; - let Json.351 : U8 = CallByName Num.123 Json.352; - let Json.120 : List U8 = CallByName List.4 Json.350 Json.351; - let Json.349 : U64 = CallByName List.6 Json.116; - let Json.337 : {List U8, U64} = Struct {Json.120, Json.349}; - let Json.338 : {} = Struct {}; - let Json.336 : {List U8, U64} = CallByName List.18 Json.116 Json.337 Json.338; + let Json.361 : List U8 = CallByName List.4 Json.363 Json.364; + let Json.362 : List U8 = CallByName Str.12 Json.115; + let Json.358 : List U8 = CallByName List.8 Json.361 Json.362; + let Json.360 : I32 = 34i64; + let Json.359 : U8 = CallByName Num.123 Json.360; + let Json.355 : List U8 = CallByName List.4 Json.358 Json.359; + let Json.357 : I32 = 58i64; + let Json.356 : U8 = CallByName Num.123 Json.357; + let Json.352 : List U8 = CallByName List.4 Json.355 Json.356; + let Json.354 : I32 = 91i64; + let Json.353 : U8 = CallByName Num.123 Json.354; + let Json.120 : List U8 = CallByName List.4 Json.352 Json.353; + let Json.351 : U64 = CallByName List.6 Json.116; + let Json.339 : {List U8, U64} = Struct {Json.120, Json.351}; + let Json.340 : {} = Struct {}; + let Json.338 : {List U8, U64} = CallByName List.18 Json.116 Json.339 Json.340; dec Json.116; - let Json.122 : List U8 = StructAtIndex 0 Json.336; + let Json.122 : List U8 = StructAtIndex 0 Json.338; inc Json.122; - dec Json.336; - let Json.335 : I32 = 93i64; + dec Json.338; + let Json.337 : I32 = 93i64; + let Json.336 : U8 = CallByName Num.123 Json.337; + let Json.333 : List U8 = CallByName List.4 Json.122 Json.336; + let Json.335 : I32 = 125i64; let Json.334 : U8 = CallByName Num.123 Json.335; - let Json.331 : List U8 = CallByName List.4 Json.122 Json.334; - let Json.333 : I32 = 125i64; - let Json.332 : U8 = CallByName Num.123 Json.333; - let Json.330 : List U8 = CallByName List.4 Json.331 Json.332; - ret Json.330; + let Json.332 : List U8 = CallByName List.4 Json.333 Json.334; + ret Json.332; -procedure Json.119 (Json.329, Json.125): - let Json.123 : List U8 = StructAtIndex 0 Json.329; +procedure Json.119 (Json.331, Json.125): + let Json.123 : List U8 = StructAtIndex 0 Json.331; inc Json.123; - let Json.124 : U64 = StructAtIndex 1 Json.329; - dec Json.329; - let Json.348 : {} = Struct {}; - let Json.126 : List U8 = CallByName Encode.23 Json.123 Json.125 Json.348; - joinpoint Json.343 Json.127: - let Json.341 : U64 = 1i64; - let Json.340 : U64 = CallByName Num.20 Json.124 Json.341; - let Json.339 : {List U8, U64} = Struct {Json.127, Json.340}; - ret Json.339; + let Json.124 : U64 = StructAtIndex 1 Json.331; + dec Json.331; + let Json.350 : {} = Struct {}; + let Json.126 : List U8 = CallByName Encode.23 Json.123 Json.125 Json.350; + joinpoint Json.345 Json.127: + let Json.343 : U64 = 1i64; + let Json.342 : U64 = CallByName Num.20 Json.124 Json.343; + let Json.341 : {List U8, U64} = Struct {Json.127, Json.342}; + ret Json.341; in - let Json.347 : U64 = 1i64; - let Json.344 : Int1 = CallByName Num.24 Json.124 Json.347; - if Json.344 then - let Json.346 : I32 = 44i64; - let Json.345 : U8 = CallByName Num.123 Json.346; - let Json.342 : List U8 = CallByName List.4 Json.126 Json.345; - jump Json.343 Json.342; + let Json.349 : U64 = 1i64; + let Json.346 : Int1 = CallByName Num.24 Json.124 Json.349; + if Json.346 then + let Json.348 : I32 = 44i64; + let Json.347 : U8 = CallByName Num.123 Json.348; + let Json.344 : List U8 = CallByName List.4 Json.126 Json.347; + jump Json.345 Json.344; else - jump Json.343 Json.126; + jump Json.345 Json.126; procedure Json.18 (Json.86): - let Json.326 : {Str} = Struct {Json.86}; - let Json.325 : {Str} = CallByName Encode.22 Json.326; - ret Json.325; + let Json.327 : Str = StructAtIndex 0 Json.329; + inc Json.327; + dec Json.329; + let Json.329 : {Str} = Struct {Json.86}; + let Json.326 : Str = CallByName Encode.22 Json.327; + ret Json.326; procedure Json.21 (Json.115, Json.116): - let Json.320 : {Str, List {Str}} = Struct {Json.115, Json.116}; - let Json.319 : {Str, List {Str}} = CallByName Encode.22 Json.320; + let Json.320 : {Str, List Str} = Struct {Json.115, Json.116}; + let Json.319 : {Str, List Str} = CallByName Encode.22 Json.320; ret Json.319; procedure Json.87 (Json.88, Json.324, #Attr.12): - let Json.86 : Str = StructAtIndex 0 #Attr.12; + let Json.86 : Str = StructAtIndex 0 Json.377; inc Json.86; - dec #Attr.12; - let Json.374 : I32 = 34i64; - let Json.373 : U8 = CallByName Num.123 Json.374; - let Json.371 : List U8 = CallByName List.4 Json.88 Json.373; - let Json.372 : List U8 = CallByName Str.12 Json.86; - let Json.368 : List U8 = CallByName List.8 Json.371 Json.372; - let Json.370 : I32 = 34i64; - let Json.369 : U8 = CallByName Num.123 Json.370; - let Json.367 : List U8 = CallByName List.4 Json.368 Json.369; - ret Json.367; + dec Json.377; + let Json.377 : {Str} = Struct {#Attr.12}; + let Json.376 : I32 = 34i64; + let Json.375 : U8 = CallByName Num.123 Json.376; + let Json.373 : List U8 = CallByName List.4 Json.88 Json.375; + let Json.374 : List U8 = CallByName Str.12 Json.86; + let Json.370 : List U8 = CallByName List.8 Json.373 Json.374; + let Json.372 : I32 = 34i64; + let Json.371 : U8 = CallByName Num.123 Json.372; + let Json.369 : List U8 = CallByName List.4 Json.370 Json.371; + ret Json.369; procedure List.133 (List.134, List.135, #Attr.12): - let List.132 : {} = StructAtIndex 0 #Attr.12; - let List.447 : {List U8, U64} = CallByName Json.119 List.134 List.135; - let List.446 : [C [], C {List U8, U64}] = TagId(1) List.447; - ret List.446; + let List.132 : {} = StructAtIndex 0 List.449; + let List.449 : {{}} = Struct {#Attr.12}; + let List.448 : {List U8, U64} = CallByName Json.119 List.134 List.135; + let List.447 : [C [], C {List U8, U64}] = TagId(1) List.448; + ret List.447; procedure List.18 (List.130, List.131, List.132): - let List.423 : {{}} = Struct {List.132}; + let List.423 : {} = StructAtIndex 0 List.424; + let List.424 : {{}} = Struct {List.132}; let List.417 : [C [], C {List U8, U64}] = CallByName List.75 List.130 List.131 List.423; let List.420 : U8 = 1i64; let List.421 : U8 = GetTagId List.417; @@ -174,61 +184,61 @@ procedure List.6 (#Attr.2): ret List.385; procedure List.6 (#Attr.2): - let List.424 : U64 = lowlevel ListLen #Attr.2; - ret List.424; + let List.425 : U64 = lowlevel ListLen #Attr.2; + ret List.425; procedure List.66 (#Attr.2, #Attr.3): - let List.445 : {Str} = lowlevel ListGetUnsafe #Attr.2 #Attr.3; - ret List.445; + let List.446 : Str = lowlevel ListGetUnsafe #Attr.2 #Attr.3; + ret List.446; procedure List.69 (#Attr.2): - let List.429 : {List U8, U64} = lowlevel Unreachable #Attr.2; - ret List.429; - -procedure List.70 (#Attr.2, #Attr.3): - let List.428 : List U8 = lowlevel ListReserve #Attr.2 #Attr.3; - ret List.428; - -procedure List.71 (#Attr.2, #Attr.3): - let List.427 : List U8 = lowlevel ListAppendUnsafe #Attr.2 #Attr.3; - ret List.427; - -procedure List.75 (List.361, List.362, List.363): - let List.431 : U64 = 0i64; - let List.432 : U64 = CallByName List.6 List.361; - let List.430 : [C [], C {List U8, U64}] = CallByName List.86 List.361 List.362 List.363 List.431 List.432; + let List.430 : {List U8, U64} = lowlevel Unreachable #Attr.2; ret List.430; -procedure List.8 (#Attr.2, #Attr.3): - let List.426 : List U8 = lowlevel ListConcat #Attr.2 #Attr.3; - ret List.426; +procedure List.70 (#Attr.2, #Attr.3): + let List.429 : List U8 = lowlevel ListReserve #Attr.2 #Attr.3; + ret List.429; -procedure List.86 (List.461, List.462, List.463, List.464, List.465): - joinpoint List.433 List.364 List.365 List.366 List.367 List.368: - let List.435 : Int1 = CallByName Num.22 List.367 List.368; - if List.435 then - let List.444 : {Str} = CallByName List.66 List.364 List.367; - let List.436 : [C [], C {List U8, U64}] = CallByName List.133 List.365 List.444 List.366; - let List.441 : U8 = 1i64; - let List.442 : U8 = GetTagId List.436; - let List.443 : Int1 = lowlevel Eq List.441 List.442; - if List.443 then - let List.369 : {List U8, U64} = UnionAtIndex (Id 1) (Index 0) List.436; +procedure List.71 (#Attr.2, #Attr.3): + let List.428 : List U8 = lowlevel ListAppendUnsafe #Attr.2 #Attr.3; + ret List.428; + +procedure List.75 (List.361, List.362, List.363): + let List.432 : U64 = 0i64; + let List.433 : U64 = CallByName List.6 List.361; + let List.431 : [C [], C {List U8, U64}] = CallByName List.86 List.361 List.362 List.363 List.432 List.433; + ret List.431; + +procedure List.8 (#Attr.2, #Attr.3): + let List.427 : List U8 = lowlevel ListConcat #Attr.2 #Attr.3; + ret List.427; + +procedure List.86 (List.463, List.464, List.465, List.466, List.467): + joinpoint List.434 List.364 List.365 List.366 List.367 List.368: + let List.436 : Int1 = CallByName Num.22 List.367 List.368; + if List.436 then + let List.445 : Str = CallByName List.66 List.364 List.367; + let List.437 : [C [], C {List U8, U64}] = CallByName List.133 List.365 List.445 List.366; + let List.442 : U8 = 1i64; + let List.443 : U8 = GetTagId List.437; + let List.444 : Int1 = lowlevel Eq List.442 List.443; + if List.444 then + let List.369 : {List U8, U64} = UnionAtIndex (Id 1) (Index 0) List.437; inc List.369; - dec List.436; - let List.439 : U64 = 1i64; - let List.438 : U64 = CallByName Num.19 List.367 List.439; - jump List.433 List.364 List.369 List.366 List.438 List.368; + dec List.437; + let List.440 : U64 = 1i64; + let List.439 : U64 = CallByName Num.19 List.367 List.440; + jump List.434 List.364 List.369 List.366 List.439 List.368; else - let List.370 : [] = UnionAtIndex (Id 0) (Index 0) List.436; - dec List.436; - let List.440 : [C [], C {List U8, U64}] = TagId(0) List.370; - ret List.440; + let List.370 : [] = UnionAtIndex (Id 0) (Index 0) List.437; + dec List.437; + let List.441 : [C [], C {List U8, U64}] = TagId(0) List.370; + ret List.441; else - let List.434 : [C [], C {List U8, U64}] = TagId(1) List.365; - ret List.434; + let List.435 : [C [], C {List U8, U64}] = TagId(1) List.365; + ret List.435; in - jump List.433 List.461 List.462 List.463 List.464 List.465; + jump List.434 List.463 List.464 List.465 List.466 List.467; procedure Num.123 (#Attr.2): let Num.266 : U8 = lowlevel NumIntCast #Attr.2; diff --git a/crates/compiler/test_mono/generated/lambda_capture_niches_have_captured_function_in_closure.txt b/crates/compiler/test_mono/generated/lambda_capture_niches_have_captured_function_in_closure.txt index 5228441c5b..8d4815f262 100644 --- a/crates/compiler/test_mono/generated/lambda_capture_niches_have_captured_function_in_closure.txt +++ b/crates/compiler/test_mono/generated/lambda_capture_niches_have_captured_function_in_closure.txt @@ -3,18 +3,19 @@ procedure Test.11 (Test.37): ret Test.38; procedure Test.13 (Test.51, #Attr.12): - let Test.12 : Str = StructAtIndex 0 #Attr.12; + let Test.12 : Str = StructAtIndex 0 Test.54; inc Test.12; - dec #Attr.12; + dec Test.54; + let Test.54 : {Str} = Struct {#Attr.12}; ret Test.12; procedure Test.15 (Test.39): let Test.40 : Str = ""; ret Test.40; -procedure Test.16 (Test.54): - let Test.56 : Str = "s1"; - ret Test.56; +procedure Test.16 (Test.56): + let Test.58 : Str = "s1"; + ret Test.58; procedure Test.2 (Test.7, Test.8): let Test.9 : [C {} {}, C {} {}] = TagId(0) Test.7 Test.8; @@ -29,7 +30,10 @@ procedure Test.3 (Test.17): ret Test.36; procedure Test.4 (Test.18): - let Test.50 : {Str} = Struct {Test.18}; + let Test.50 : Str = StructAtIndex 0 Test.55; + inc Test.50; + dec Test.55; + let Test.55 : {Str} = Struct {Test.18}; ret Test.50; procedure Test.9 (Test.29, #Attr.12): @@ -48,7 +52,7 @@ procedure Test.9 (Test.29, #Attr.12): let Test.7 : {} = UnionAtIndex (Id 1) (Index 0) #Attr.12; let Test.49 : {} = Struct {}; let Test.48 : Str = CallByName Test.16 Test.49; - let Test.45 : {Str} = CallByName Test.4 Test.48; + let Test.45 : Str = CallByName Test.4 Test.48; let Test.47 : {} = Struct {}; let Test.46 : Str = CallByName Test.13 Test.47 Test.45; ret Test.46; @@ -71,9 +75,9 @@ procedure Test.0 (): jump Test.22 Test.24; in - let Test.57 : Int1 = true; - let Test.58 : Int1 = lowlevel Eq Test.57 Test.5; - if Test.58 then + let Test.59 : Int1 = true; + let Test.60 : Int1 = lowlevel Eq Test.59 Test.5; + if Test.60 then let Test.27 : {} = Struct {}; let Test.28 : {} = Struct {}; let Test.26 : [C {} {}, C {} {}] = CallByName Test.2 Test.27 Test.28; diff --git a/crates/compiler/test_mono/generated/lambda_set_niche_same_layout_different_constructor.txt b/crates/compiler/test_mono/generated/lambda_set_niche_same_layout_different_constructor.txt index ae024a188f..8b7c7eaacd 100644 --- a/crates/compiler/test_mono/generated/lambda_set_niche_same_layout_different_constructor.txt +++ b/crates/compiler/test_mono/generated/lambda_set_niche_same_layout_different_constructor.txt @@ -1,11 +1,15 @@ procedure Test.1 (Test.4): - let Test.5 : {Str} = Struct {Test.4}; + let Test.5 : Str = StructAtIndex 0 Test.16; + inc Test.5; + dec Test.16; + let Test.16 : {Str} = Struct {Test.4}; ret Test.5; procedure Test.5 (Test.12, #Attr.12): - let Test.4 : Str = StructAtIndex 0 #Attr.12; + let Test.4 : Str = StructAtIndex 0 Test.15; inc Test.4; - dec #Attr.12; + dec Test.15; + let Test.15 : {Str} = Struct {#Attr.12}; let Test.14 : Str = ""; ret Test.14; @@ -14,13 +18,13 @@ procedure Test.0 (): joinpoint Test.9 Test.3: ret Test.3; in - let Test.19 : Int1 = true; - let Test.20 : Int1 = lowlevel Eq Test.19 Test.2; - if Test.20 then - let Test.15 : Str = ""; - let Test.10 : {Str} = CallByName Test.1 Test.15; + let Test.21 : Int1 = true; + let Test.22 : Int1 = lowlevel Eq Test.21 Test.2; + if Test.22 then + let Test.17 : Str = ""; + let Test.10 : Str = CallByName Test.1 Test.17; jump Test.9 Test.10; else - let Test.18 : Str = ""; - let Test.16 : {Str} = CallByName Test.1 Test.18; - jump Test.9 Test.16; + let Test.20 : Str = ""; + let Test.18 : Str = CallByName Test.1 Test.20; + jump Test.9 Test.18; diff --git a/crates/compiler/test_mono/generated/nested_closure.txt b/crates/compiler/test_mono/generated/nested_closure.txt index 304722fa96..6b6078bf3b 100644 --- a/crates/compiler/test_mono/generated/nested_closure.txt +++ b/crates/compiler/test_mono/generated/nested_closure.txt @@ -1,15 +1,17 @@ procedure Test.1 (Test.5): let Test.2 : I64 = 42i64; - let Test.3 : {I64} = Struct {Test.2}; + let Test.3 : I64 = StructAtIndex 0 Test.13; + let Test.13 : {I64} = Struct {Test.2}; ret Test.3; procedure Test.3 (Test.9, #Attr.12): - let Test.2 : I64 = StructAtIndex 0 #Attr.12; + let Test.2 : I64 = StructAtIndex 0 Test.12; + let Test.12 : {I64} = Struct {#Attr.12}; ret Test.2; procedure Test.0 (): let Test.8 : {} = Struct {}; - let Test.4 : {I64} = CallByName Test.1 Test.8; + let Test.4 : I64 = CallByName Test.1 Test.8; let Test.7 : {} = Struct {}; let Test.6 : I64 = CallByName Test.3 Test.7 Test.4; ret Test.6; diff --git a/crates/compiler/test_mono/generated/recursive_call_capturing_function.txt b/crates/compiler/test_mono/generated/recursive_call_capturing_function.txt index a298bf4ab4..00dafe3005 100644 --- a/crates/compiler/test_mono/generated/recursive_call_capturing_function.txt +++ b/crates/compiler/test_mono/generated/recursive_call_capturing_function.txt @@ -4,22 +4,25 @@ procedure Num.19 (#Attr.2, #Attr.3): procedure Test.1 (Test.2): let Test.9 : U32 = 0i64; - let Test.16 : {U32} = Struct {Test.2}; - let Test.8 : U32 = CallByName Test.3 Test.9 Test.16; + let Test.18 : U32 = StructAtIndex 0 Test.19; + let Test.19 : {U32} = Struct {Test.2}; + let Test.8 : U32 = CallByName Test.3 Test.9 Test.18; ret Test.8; -procedure Test.3 (Test.18, Test.19): +procedure Test.3 (Test.21, Test.22): joinpoint Test.10 Test.4 #Attr.12: - let Test.2 : U32 = StructAtIndex 0 #Attr.12; - let Test.14 : Int1 = true; - if Test.14 then + let Test.2 : U32 = StructAtIndex 0 Test.17; + let Test.17 : {U32} = Struct {#Attr.12}; + let Test.15 : Int1 = true; + if Test.15 then ret Test.4; else let Test.12 : U32 = CallByName Num.19 Test.4 Test.2; - let Test.13 : {U32} = Struct {Test.2}; + let Test.13 : U32 = StructAtIndex 0 Test.14; + let Test.14 : {U32} = Struct {Test.2}; jump Test.10 Test.12 Test.13; in - jump Test.10 Test.18 Test.19; + jump Test.10 Test.21 Test.22; procedure Test.0 (): let Test.7 : U32 = 6i64; From 62dde549e6cefb4326e06df2ece7b28bd1adfcf0 Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Wed, 10 Aug 2022 10:08:15 -0700 Subject: [PATCH 03/22] Determine whether lambda set is represented as an arg --- crates/compiler/mono/src/layout.rs | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/crates/compiler/mono/src/layout.rs b/crates/compiler/mono/src/layout.rs index 4039e33425..07b17b1fe7 100644 --- a/crates/compiler/mono/src/layout.rs +++ b/crates/compiler/mono/src/layout.rs @@ -840,13 +840,17 @@ impl<'a> LambdaSet<'a> { } pub fn is_represented(&self) -> Option> { - match self.representation { - Layout::Struct { - field_layouts: &[], .. + if self.has_unwrapped_capture_repr() { + Some(*self.representation) + } else if self.has_multi_dispatch_repr() { + None + } else { + match self.representation { + Layout::Struct { + field_layouts: &[], .. + } => None, + repr => Some(*repr), } - | Layout::Builtin(Builtin::Bool) - | Layout::Builtin(Builtin::Int(..)) => None, - repr => Some(*repr), } } From d4a79780b3ac5c49d28e7685238b4f107d7d68b4 Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Wed, 10 Aug 2022 10:09:00 -0700 Subject: [PATCH 04/22] Determine whether to extend lambda set arg to call args by checking call options --- crates/compiler/mono/src/layout.rs | 43 ++++++++++++++---------------- 1 file changed, 20 insertions(+), 23 deletions(-) diff --git a/crates/compiler/mono/src/layout.rs b/crates/compiler/mono/src/layout.rs index 07b17b1fe7..7cb53c91ac 100644 --- a/crates/compiler/mono/src/layout.rs +++ b/crates/compiler/mono/src/layout.rs @@ -1088,30 +1088,27 @@ impl<'a> LambdaSet<'a> { arena: &'a Bump, argument_layouts: &'a [Layout<'a>], ) -> &'a [Layout<'a>] { - if let [] = self.set { - // TERRIBLE HACK for builting functions - argument_layouts - } else { - match self.representation { - Layout::Struct { - field_layouts: &[], .. - } => { - // this function does not have anything in its closure, and the lambda set is a - // singleton, so we pass no extra argument - argument_layouts - } - Layout::Builtin(Builtin::Bool) - | Layout::Builtin(Builtin::Int(IntWidth::I8 | IntWidth::U8)) => { - // we don't pass this along either - argument_layouts - } - _ => { - let mut arguments = Vec::with_capacity_in(argument_layouts.len() + 1, arena); - arguments.extend(argument_layouts); - arguments.push(Layout::LambdaSet(*self)); + match self.call_by_name_options() { + ClosureCallOptions::Void => argument_layouts, + ClosureCallOptions::Struct { + field_layouts: &[], .. + } => { + // this function does not have anything in its closure, and the lambda set is a + // singleton, so we pass no extra argument + argument_layouts + } + ClosureCallOptions::Struct { .. } + | ClosureCallOptions::Union(_) + | ClosureCallOptions::UnwrappedCapture(_) => { + let mut arguments = Vec::with_capacity_in(argument_layouts.len() + 1, arena); + arguments.extend(argument_layouts); + arguments.push(Layout::LambdaSet(*self)); - arguments.into_bump_slice() - } + arguments.into_bump_slice() + } + ClosureCallOptions::MultiDispatch(_) => { + // No captures, don't pass this along + argument_layouts } } } From d6572ef3b75d8b238c4e05b5759037f759c6a1bf Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Wed, 10 Aug 2022 10:09:24 -0700 Subject: [PATCH 05/22] Match over call options in determining whether to extend lambda set arg --- crates/compiler/mono/src/ir.rs | 205 ++++++++++++++++++--------------- 1 file changed, 113 insertions(+), 92 deletions(-) diff --git a/crates/compiler/mono/src/ir.rs b/crates/compiler/mono/src/ir.rs index 5438801bce..b4070b0f6f 100644 --- a/crates/compiler/mono/src/ir.rs +++ b/crates/compiler/mono/src/ir.rs @@ -3247,19 +3247,26 @@ fn specialize_external<'a>( let wrap = Expr::Struct(arg_closure_slice); let wrap_sym = env.unique_symbol(); - let hole = env.arena.alloc(Stmt::Let( - wrap_sym, - wrap, - Layout::struct_no_name_order(layout_slice), - env.arena.alloc(specialized_body), - )); let unwrap = Expr::StructAtIndex { index: 0, field_layouts: layout_slice, structure: wrap_sym, }; - specialized_body = Stmt::Let(captured_symbol, unwrap, layout, hole); + + specialized_body = Stmt::Let( + captured_symbol, + unwrap, + layout, + env.arena.alloc(specialized_body), + ); + + specialized_body = Stmt::Let( + wrap_sym, + wrap, + Layout::struct_no_name_order(layout_slice), + env.arena.alloc(specialized_body), + ); } ClosureRepresentation::MultiDispatch(layout) => match layout { @@ -5422,21 +5429,24 @@ where // It should be optimized away later on. let layout_slice = env.arena.alloc([layout]); let captured_slice = env.arena.alloc([*captured_symbol]); + let wrap = Expr::Struct(captured_slice); let wrap_sym = env.unique_symbol(); - let hole = env.arena.alloc(Stmt::Let( - wrap_sym, - wrap, - Layout::struct_no_name_order(layout_slice), - hole, - )); let unwrap = Expr::StructAtIndex { index: 0, field_layouts: layout_slice, structure: wrap_sym, }; - Stmt::Let(assigned, unwrap, layout, hole) + + let hole = env.arena.alloc(Stmt::Let(assigned, unwrap, layout, hole)); + + Stmt::Let( + wrap_sym, + wrap, + Layout::struct_no_name_order(layout_slice), + hole, + ) } ClosureRepresentation::MultiDispatch(layout) => match layout { Layout::Builtin(Builtin::Bool) => { @@ -5903,10 +5913,7 @@ fn register_capturing_closure<'a>( Content::Structure(FlatType::Func(_, closure_var, _)) => { match LambdaSet::from_var(env.arena, env.subs, closure_var, env.target_info) { Ok(lambda_set) => { - if let Layout::Struct { - field_layouts: &[], .. - } = lambda_set.runtime_representation() - { + if lambda_set.is_represented().is_none() { CapturedSymbols::None } else { let mut temp = Vec::from_iter_in(captured_symbols, env.arena); @@ -9147,9 +9154,9 @@ fn lowlevel_match_on_lambda_set<'a, ToLowLevelCall>( where ToLowLevelCall: Fn(ToLowLevelCallArguments<'a>) -> Call<'a> + Copy, { - match lambda_set.runtime_representation() { - Layout::VOID => empty_lambda_set_error(), - Layout::Union(union_layout) => { + match lambda_set.call_by_name_options() { + ClosureCallOptions::Void => empty_lambda_set_error(), + ClosureCallOptions::Union(union_layout) => { let closure_tag_id_symbol = env.unique_symbol(); let result = lowlevel_union_lambda_set_to_switch( @@ -9178,7 +9185,7 @@ where env.arena.alloc(result), ) } - Layout::Struct { .. } => match lambda_set.iter_set().next() { + ClosureCallOptions::Struct { .. } => match lambda_set.iter_set().next() { Some(lambda_name) => { let call_spec_id = env.next_call_specialization_id(); let update_mode = env.next_update_mode_id(); @@ -9203,39 +9210,59 @@ where hole.clone() } }, - Layout::Builtin(Builtin::Bool) => { - let closure_tag_id_symbol = closure_data_symbol; + ClosureCallOptions::UnwrappedCapture(_) => { + let lambda_name = lambda_set + .iter_set() + .next() + .expect("no function in lambda set"); - lowlevel_enum_lambda_set_to_switch( - env, - lambda_set.iter_set(), - closure_tag_id_symbol, - Layout::Builtin(Builtin::Bool), + let call_spec_id = env.next_call_specialization_id(); + let update_mode = env.next_update_mode_id(); + let call = to_lowlevel_call(( + lambda_name, closure_data_symbol, lambda_set.is_represented(), - to_lowlevel_call, - return_layout, - assigned, - hole, - ) - } - Layout::Builtin(Builtin::Int(IntWidth::U8)) => { - let closure_tag_id_symbol = closure_data_symbol; + call_spec_id, + update_mode, + )); - lowlevel_enum_lambda_set_to_switch( - env, - lambda_set.iter_set(), - closure_tag_id_symbol, - Layout::Builtin(Builtin::Int(IntWidth::U8)), - closure_data_symbol, - lambda_set.is_represented(), - to_lowlevel_call, - return_layout, - assigned, - hole, - ) + build_call(env, call, assigned, return_layout, env.arena.alloc(hole)) } - other => todo!("{:?}", other), + ClosureCallOptions::MultiDispatch(layout) => match layout { + Layout::Builtin(Builtin::Bool) => { + let closure_tag_id_symbol = closure_data_symbol; + + lowlevel_enum_lambda_set_to_switch( + env, + lambda_set.iter_set(), + closure_tag_id_symbol, + Layout::Builtin(Builtin::Bool), + closure_data_symbol, + lambda_set.is_represented(), + to_lowlevel_call, + return_layout, + assigned, + hole, + ) + } + Layout::Builtin(Builtin::Int(IntWidth::U8)) => { + let closure_tag_id_symbol = closure_data_symbol; + + lowlevel_enum_lambda_set_to_switch( + env, + lambda_set.iter_set(), + closure_tag_id_symbol, + Layout::Builtin(Builtin::Int(IntWidth::U8)), + closure_data_symbol, + lambda_set.is_represented(), + to_lowlevel_call, + return_layout, + assigned, + hole, + ) + } + other => internal_error!("Unexpected multi-dispatch layout: {:?}", other), + }, } } @@ -9434,7 +9461,7 @@ fn match_on_lambda_set<'a>( lambda_set.iter_set(), closure_tag_id_symbol, Layout::Builtin(Builtin::Bool), - closure_data_symbol, + ClosureInfo::DoesNotCapture, argument_symbols, argument_layouts, return_layout, @@ -9450,7 +9477,7 @@ fn match_on_lambda_set<'a>( lambda_set.iter_set(), closure_tag_id_symbol, Layout::Builtin(Builtin::Int(IntWidth::U8)), - closure_data_symbol, + ClosureInfo::DoesNotCapture, argument_symbols, argument_layouts, return_layout, @@ -9566,6 +9593,7 @@ fn union_lambda_set_branch<'a>( ) } +#[derive(Clone, Copy)] enum ClosureInfo<'a> { Captures { closure_data_symbol: Symbol, @@ -9592,16 +9620,11 @@ fn union_lambda_set_branch_help<'a>( ClosureInfo::Captures { lambda_set, closure_data_symbol, - closure_data_layout, - } => match closure_data_layout { - Layout::Struct { - field_layouts: &[], .. - } - | Layout::Builtin(Builtin::Bool) - | Layout::Builtin(Builtin::Int(IntWidth::U8)) => { + closure_data_layout: _, + } => { + if lambda_set.is_represented().is_none() { (argument_layouts_slice, argument_symbols_slice) - } - _ => { + } else { // extend layouts with the layout of the closure environment let mut argument_layouts = Vec::with_capacity_in(argument_layouts_slice.len() + 1, env.arena); @@ -9619,7 +9642,7 @@ fn union_lambda_set_branch_help<'a>( argument_symbols.into_bump_slice(), ) } - }, + } ClosureInfo::DoesNotCapture => { // sometimes unification causes a function that does not itself capture anything // to still get a lambda set that does store information. We must not pass a closure @@ -9649,7 +9672,7 @@ fn enum_lambda_set_to_switch<'a>( lambda_set: impl ExactSizeIterator>, closure_tag_id_symbol: Symbol, closure_tag_id_layout: Layout<'a>, - closure_data_symbol: Symbol, + closure_info: ClosureInfo<'a>, argument_symbols: &'a [Symbol], argument_layouts: &'a [Layout<'a>], return_layout: &'a Layout<'a>, @@ -9662,15 +9685,12 @@ fn enum_lambda_set_to_switch<'a>( let mut branches = Vec::with_capacity_in(lambda_set.len(), env.arena); - let closure_layout = closure_tag_id_layout; - for (i, lambda_name) in lambda_set.into_iter().enumerate() { let stmt = enum_lambda_set_branch( env, join_point_id, lambda_name, - closure_data_symbol, - closure_layout, + closure_info, argument_symbols, argument_layouts, return_layout, @@ -9711,8 +9731,7 @@ fn enum_lambda_set_branch<'a>( env: &mut Env<'a, '_>, join_point_id: JoinPointId, lambda_name: LambdaName<'a>, - closure_data_symbol: Symbol, - closure_data_layout: Layout<'a>, + closure_info: ClosureInfo<'a>, argument_symbols_slice: &'a [Symbol], argument_layouts_slice: &'a [Layout<'a>], return_layout: &'a Layout<'a>, @@ -9723,32 +9742,34 @@ fn enum_lambda_set_branch<'a>( let assigned = result_symbol; - let (argument_layouts, argument_symbols) = match closure_data_layout { - Layout::Struct { - field_layouts: &[], .. - } - | Layout::Builtin(Builtin::Bool) - | Layout::Builtin(Builtin::Int(IntWidth::U8)) => { - (argument_layouts_slice, argument_symbols_slice) - } - _ => { - // extend layouts with the layout of the closure environment - let mut argument_layouts = - Vec::with_capacity_in(argument_layouts_slice.len() + 1, env.arena); - argument_layouts.extend(argument_layouts_slice); - argument_layouts.push(closure_data_layout); + let (argument_layouts, argument_symbols) = match closure_info { + ClosureInfo::Captures { + closure_data_symbol, + closure_data_layout, + lambda_set, + } => { + if lambda_set.is_represented().is_none() { + (argument_layouts_slice, argument_symbols_slice) + } else { + // extend layouts with the layout of the closure environment + let mut argument_layouts = + Vec::with_capacity_in(argument_layouts_slice.len() + 1, env.arena); + argument_layouts.extend(argument_layouts_slice); + argument_layouts.push(closure_data_layout); - // extend symbols with the symbol of the closure environment - let mut argument_symbols = - Vec::with_capacity_in(argument_symbols_slice.len() + 1, env.arena); - argument_symbols.extend(argument_symbols_slice); - argument_symbols.push(closure_data_symbol); + // extend symbols with the symbol of the closure environment + let mut argument_symbols = + Vec::with_capacity_in(argument_symbols_slice.len() + 1, env.arena); + argument_symbols.extend(argument_symbols_slice); + argument_symbols.push(closure_data_symbol); - ( - argument_layouts.into_bump_slice(), - argument_symbols.into_bump_slice(), - ) + ( + argument_layouts.into_bump_slice(), + argument_symbols.into_bump_slice(), + ) + } } + ClosureInfo::DoesNotCapture => (argument_layouts_slice, argument_symbols_slice), }; let call = self::Call { From c003b2d00799e7c91c4d2676e3d377e5fa5ec98b Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Wed, 10 Aug 2022 10:12:38 -0700 Subject: [PATCH 06/22] Simplify ClosureInfo and enum lambda set switching, which never captures --- crates/compiler/mono/src/ir.rs | 57 +++++----------------------------- 1 file changed, 7 insertions(+), 50 deletions(-) diff --git a/crates/compiler/mono/src/ir.rs b/crates/compiler/mono/src/ir.rs index b4070b0f6f..30ffc81f07 100644 --- a/crates/compiler/mono/src/ir.rs +++ b/crates/compiler/mono/src/ir.rs @@ -9361,7 +9361,6 @@ fn match_on_lambda_set<'a>( let result = union_lambda_set_to_switch( env, lambda_set, - Layout::Union(union_layout), closure_tag_id_symbol, union_layout.tag_id_layout(), closure_data_symbol, @@ -9387,7 +9386,7 @@ fn match_on_lambda_set<'a>( } ClosureCallOptions::Struct { field_layouts, - field_order_hash, + field_order_hash: _, } => { let function_symbol = match lambda_set.iter_set().next() { Some(function_symbol) => function_symbol, @@ -9411,10 +9410,6 @@ fn match_on_lambda_set<'a>( _ => ClosureInfo::Captures { lambda_set, closure_data_symbol, - closure_data_layout: Layout::Struct { - field_layouts, - field_order_hash, - }, }, }; @@ -9429,7 +9424,7 @@ fn match_on_lambda_set<'a>( hole, ) } - ClosureCallOptions::UnwrappedCapture(layout) => { + ClosureCallOptions::UnwrappedCapture(_) => { let function_symbol = lambda_set .iter_set() .next() @@ -9438,7 +9433,6 @@ fn match_on_lambda_set<'a>( let closure_info = ClosureInfo::Captures { lambda_set, closure_data_symbol, - closure_data_layout: layout, }; union_lambda_set_branch_help( @@ -9461,7 +9455,6 @@ fn match_on_lambda_set<'a>( lambda_set.iter_set(), closure_tag_id_symbol, Layout::Builtin(Builtin::Bool), - ClosureInfo::DoesNotCapture, argument_symbols, argument_layouts, return_layout, @@ -9477,7 +9470,6 @@ fn match_on_lambda_set<'a>( lambda_set.iter_set(), closure_tag_id_symbol, Layout::Builtin(Builtin::Int(IntWidth::U8)), - ClosureInfo::DoesNotCapture, argument_symbols, argument_layouts, return_layout, @@ -9494,7 +9486,6 @@ fn match_on_lambda_set<'a>( fn union_lambda_set_to_switch<'a>( env: &mut Env<'a, '_>, lambda_set: LambdaSet<'a>, - closure_layout: Layout<'a>, closure_tag_id_symbol: Symbol, closure_tag_id_layout: Layout<'a>, closure_data_symbol: Symbol, @@ -9523,7 +9514,6 @@ fn union_lambda_set_to_switch<'a>( ClosureInfo::Captures { lambda_set, closure_data_symbol, - closure_data_layout: closure_layout, } }; @@ -9597,8 +9587,6 @@ fn union_lambda_set_branch<'a>( enum ClosureInfo<'a> { Captures { closure_data_symbol: Symbol, - /// The layout of this closure variant - closure_data_layout: Layout<'a>, /// The whole lambda set representation this closure is a variant of lambda_set: LambdaSet<'a>, }, @@ -9620,7 +9608,6 @@ fn union_lambda_set_branch_help<'a>( ClosureInfo::Captures { lambda_set, closure_data_symbol, - closure_data_layout: _, } => { if lambda_set.is_represented().is_none() { (argument_layouts_slice, argument_symbols_slice) @@ -9666,13 +9653,14 @@ fn union_lambda_set_branch_help<'a>( build_call(env, call, assigned, *return_layout, hole) } +/// Switches over a enum lambda set, which may dispatch to different functions, none of which +/// capture. #[allow(clippy::too_many_arguments)] fn enum_lambda_set_to_switch<'a>( env: &mut Env<'a, '_>, lambda_set: impl ExactSizeIterator>, closure_tag_id_symbol: Symbol, closure_tag_id_layout: Layout<'a>, - closure_info: ClosureInfo<'a>, argument_symbols: &'a [Symbol], argument_layouts: &'a [Layout<'a>], return_layout: &'a Layout<'a>, @@ -9690,7 +9678,6 @@ fn enum_lambda_set_to_switch<'a>( env, join_point_id, lambda_name, - closure_info, argument_symbols, argument_layouts, return_layout, @@ -9726,14 +9713,14 @@ fn enum_lambda_set_to_switch<'a>( } } +/// A branch for an enum lambda set branch dispatch, which never capture! #[allow(clippy::too_many_arguments)] fn enum_lambda_set_branch<'a>( env: &mut Env<'a, '_>, join_point_id: JoinPointId, lambda_name: LambdaName<'a>, - closure_info: ClosureInfo<'a>, - argument_symbols_slice: &'a [Symbol], - argument_layouts_slice: &'a [Layout<'a>], + argument_symbols: &'a [Symbol], + argument_layouts: &'a [Layout<'a>], return_layout: &'a Layout<'a>, ) -> Stmt<'a> { let result_symbol = env.unique_symbol(); @@ -9742,36 +9729,6 @@ fn enum_lambda_set_branch<'a>( let assigned = result_symbol; - let (argument_layouts, argument_symbols) = match closure_info { - ClosureInfo::Captures { - closure_data_symbol, - closure_data_layout, - lambda_set, - } => { - if lambda_set.is_represented().is_none() { - (argument_layouts_slice, argument_symbols_slice) - } else { - // extend layouts with the layout of the closure environment - let mut argument_layouts = - Vec::with_capacity_in(argument_layouts_slice.len() + 1, env.arena); - argument_layouts.extend(argument_layouts_slice); - argument_layouts.push(closure_data_layout); - - // extend symbols with the symbol of the closure environment - let mut argument_symbols = - Vec::with_capacity_in(argument_symbols_slice.len() + 1, env.arena); - argument_symbols.extend(argument_symbols_slice); - argument_symbols.push(closure_data_symbol); - - ( - argument_layouts.into_bump_slice(), - argument_symbols.into_bump_slice(), - ) - } - } - ClosureInfo::DoesNotCapture => (argument_layouts_slice, argument_symbols_slice), - }; - let call = self::Call { call_type: CallType::ByName { name: lambda_name, From f5e3105b377b3d2b4d9971a1f66a9d20ac383771 Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Wed, 10 Aug 2022 10:15:01 -0700 Subject: [PATCH 07/22] Use extend_argument_list to add lambda set arguments --- crates/compiler/mono/src/ir.rs | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/crates/compiler/mono/src/ir.rs b/crates/compiler/mono/src/ir.rs index 30ffc81f07..35ed3e30ae 100644 --- a/crates/compiler/mono/src/ir.rs +++ b/crates/compiler/mono/src/ir.rs @@ -9609,26 +9609,19 @@ fn union_lambda_set_branch_help<'a>( lambda_set, closure_data_symbol, } => { - if lambda_set.is_represented().is_none() { - (argument_layouts_slice, argument_symbols_slice) - } else { - // extend layouts with the layout of the closure environment - let mut argument_layouts = - Vec::with_capacity_in(argument_layouts_slice.len() + 1, env.arena); - argument_layouts.extend(argument_layouts_slice); - argument_layouts.push(Layout::LambdaSet(lambda_set)); - + let argument_layouts = + lambda_set.extend_argument_list(env.arena, argument_layouts_slice); + let argument_symbols = if argument_layouts.len() > argument_layouts_slice.len() { // extend symbols with the symbol of the closure environment let mut argument_symbols = Vec::with_capacity_in(argument_symbols_slice.len() + 1, env.arena); argument_symbols.extend(argument_symbols_slice); argument_symbols.push(closure_data_symbol); - - ( - argument_layouts.into_bump_slice(), - argument_symbols.into_bump_slice(), - ) - } + argument_symbols.into_bump_slice() + } else { + argument_symbols_slice + }; + (argument_layouts, argument_symbols) } ClosureInfo::DoesNotCapture => { // sometimes unification causes a function that does not itself capture anything From a93735473a3d37f73822bc967a19b47a6a8333f1 Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Wed, 10 Aug 2022 10:20:56 -0700 Subject: [PATCH 08/22] Describe how a enum lambda set should be switched in the representation --- crates/compiler/mono/src/ir.rs | 48 ++++++++++-------------------- crates/compiler/mono/src/layout.rs | 43 ++++++++++++++++---------- 2 files changed, 43 insertions(+), 48 deletions(-) diff --git a/crates/compiler/mono/src/ir.rs b/crates/compiler/mono/src/ir.rs index 35ed3e30ae..4e01e48e27 100644 --- a/crates/compiler/mono/src/ir.rs +++ b/crates/compiler/mono/src/ir.rs @@ -1,8 +1,8 @@ #![allow(clippy::manual_map)] use crate::layout::{ - Builtin, CapturesNiche, ClosureCallOptions, ClosureRepresentation, LambdaName, LambdaSet, - Layout, LayoutCache, LayoutProblem, RawFunctionLayout, TagIdIntType, UnionLayout, + Builtin, CapturesNiche, ClosureCallOptions, ClosureRepresentation, EnumDispatch, LambdaName, + LambdaSet, Layout, LayoutCache, LayoutProblem, RawFunctionLayout, TagIdIntType, UnionLayout, WrappedVariant, }; use bumpalo::collections::{CollectIn, Vec}; @@ -3269,23 +3269,10 @@ fn specialize_external<'a>( ); } - ClosureRepresentation::MultiDispatch(layout) => match layout { - Layout::Builtin(Builtin::Bool) => { - // just ignore this value, since it's not a capture - // IDEA don't pass this value in the future - } - Layout::Builtin(Builtin::Int(IntWidth::U8)) => { - // just ignore this value, since it's not a capture - // IDEA don't pass this value in the future - } - other => { - // NOTE other values always should be wrapped in a 1-element record - unreachable!( - "{:?} is not a valid closure data representation", - other - ) - } - }, + ClosureRepresentation::EnumDispatch(_) => { + // just ignore this value, since it's not a capture + // IDEA don't pass this value in the future + } } } (None, CapturedSymbols::None) | (None, CapturedSymbols::Captured([])) => {} @@ -5448,8 +5435,8 @@ where hole, ) } - ClosureRepresentation::MultiDispatch(layout) => match layout { - Layout::Builtin(Builtin::Bool) => { + ClosureRepresentation::EnumDispatch(repr) => match repr { + EnumDispatch::Bool => { debug_assert_eq!(symbols.len(), 0); debug_assert_eq!(lambda_set.set.len(), 2); @@ -5458,7 +5445,7 @@ where Stmt::Let(assigned, expr, lambda_set_layout, hole) } - Layout::Builtin(Builtin::Int(IntWidth::U8)) => { + EnumDispatch::U8 => { debug_assert_eq!(symbols.len(), 0); debug_assert!(lambda_set.set.len() > 2); @@ -5471,9 +5458,6 @@ where Stmt::Let(assigned, expr, lambda_set_layout, hole) } - layout => { - internal_error!("Invalid layout for multi-dispatch closure: {:?}", layout) - } }, }; @@ -9228,8 +9212,8 @@ where build_call(env, call, assigned, return_layout, env.arena.alloc(hole)) } - ClosureCallOptions::MultiDispatch(layout) => match layout { - Layout::Builtin(Builtin::Bool) => { + ClosureCallOptions::EnumDispatch(repr) => match repr { + EnumDispatch::Bool => { let closure_tag_id_symbol = closure_data_symbol; lowlevel_enum_lambda_set_to_switch( @@ -9245,7 +9229,7 @@ where hole, ) } - Layout::Builtin(Builtin::Int(IntWidth::U8)) => { + EnumDispatch::U8 => { let closure_tag_id_symbol = closure_data_symbol; lowlevel_enum_lambda_set_to_switch( @@ -9261,7 +9245,6 @@ where hole, ) } - other => internal_error!("Unexpected multi-dispatch layout: {:?}", other), }, } } @@ -9446,8 +9429,8 @@ fn match_on_lambda_set<'a>( hole, ) } - ClosureCallOptions::MultiDispatch(layout) => match layout { - Layout::Builtin(Builtin::Bool) => { + ClosureCallOptions::EnumDispatch(repr) => match repr { + EnumDispatch::Bool => { let closure_tag_id_symbol = closure_data_symbol; enum_lambda_set_to_switch( @@ -9462,7 +9445,7 @@ fn match_on_lambda_set<'a>( hole, ) } - Layout::Builtin(Builtin::Int(IntWidth::U8)) => { + EnumDispatch::U8 => { let closure_tag_id_symbol = closure_data_symbol; enum_lambda_set_to_switch( @@ -9477,7 +9460,6 @@ fn match_on_lambda_set<'a>( hole, ) } - other => internal_error!("Unexpected multi-dispatch layout: {:?}", other), }, } } diff --git a/crates/compiler/mono/src/layout.rs b/crates/compiler/mono/src/layout.rs index 7cb53c91ac..7bf28fd3a3 100644 --- a/crates/compiler/mono/src/layout.rs +++ b/crates/compiler/mono/src/layout.rs @@ -788,6 +788,12 @@ pub struct LambdaSet<'a> { representation: &'a Layout<'a>, } +#[derive(Debug)] +pub enum EnumDispatch { + Bool, + U8, +} + /// representation of the closure *for a particular function* #[derive(Debug)] pub enum ClosureRepresentation<'a> { @@ -804,11 +810,11 @@ pub enum ClosureRepresentation<'a> { /// /// We MUST sort these according to their stack size before code gen! AlphabeticOrderStruct(&'a [Layout<'a>]), - /// The closure dispatches to multiple functions, but none of them capture anything, so this is - /// a boolean or integer flag. - MultiDispatch(Layout<'a>), /// The closure is one function that captures a single identifier, whose value is unwrapped. UnwrappedCapture(Layout<'a>), + /// The closure dispatches to multiple functions, but none of them capture anything, so this is + /// a boolean or integer flag. + EnumDispatch(EnumDispatch), } /// How the closure should be seen when determining a call-by-name. @@ -823,10 +829,10 @@ pub enum ClosureCallOptions<'a> { field_layouts: &'a [Layout<'a>], field_order_hash: FieldOrderHash, }, - /// The closure dispatches to multiple possible functions, none of which capture. - MultiDispatch(Layout<'a>), /// The closure is one function that captures a single identifier, whose value is unwrapped. UnwrappedCapture(Layout<'a>), + /// The closure dispatches to multiple possible functions, none of which capture. + EnumDispatch(EnumDispatch), } impl<'a> LambdaSet<'a> { @@ -842,7 +848,7 @@ impl<'a> LambdaSet<'a> { pub fn is_represented(&self) -> Option> { if self.has_unwrapped_capture_repr() { Some(*self.representation) - } else if self.has_multi_dispatch_repr() { + } else if self.has_enum_dispatch_repr() { None } else { match self.representation { @@ -1036,11 +1042,13 @@ impl<'a> LambdaSet<'a> { ClosureRepresentation::AlphabeticOrderStruct(fields) } layout => { - debug_assert!( - self.has_multi_dispatch_repr(), - "Expected this to be a multi-dispatching closure, but it was something else!" - ); - ClosureRepresentation::MultiDispatch(*layout) + debug_assert!(self.has_enum_dispatch_repr(),); + let enum_repr = match layout { + Layout::Builtin(Builtin::Bool) => EnumDispatch::Bool, + Layout::Builtin(Builtin::Int(IntWidth::U8)) => EnumDispatch::U8, + other => internal_error!("Invalid layout for enum dispatch: {:?}", other), + }; + ClosureRepresentation::EnumDispatch(enum_repr) } } } @@ -1049,7 +1057,7 @@ impl<'a> LambdaSet<'a> { self.set.len() == 1 && self.set[0].1.len() == 1 } - fn has_multi_dispatch_repr(&self) -> bool { + fn has_enum_dispatch_repr(&self) -> bool { self.set.len() > 1 && self.set.iter().all(|(_, captures)| captures.is_empty()) } @@ -1077,8 +1085,13 @@ impl<'a> LambdaSet<'a> { } } layout => { - debug_assert!(self.has_multi_dispatch_repr()); - ClosureCallOptions::MultiDispatch(*layout) + debug_assert!(self.has_enum_dispatch_repr()); + let enum_repr = match layout { + Layout::Builtin(Builtin::Bool) => EnumDispatch::Bool, + Layout::Builtin(Builtin::Int(IntWidth::U8)) => EnumDispatch::U8, + other => internal_error!("Invalid layout for enum dispatch: {:?}", other), + }; + ClosureCallOptions::EnumDispatch(enum_repr) } } } @@ -1106,7 +1119,7 @@ impl<'a> LambdaSet<'a> { arguments.into_bump_slice() } - ClosureCallOptions::MultiDispatch(_) => { + ClosureCallOptions::EnumDispatch(_) => { // No captures, don't pass this along argument_layouts } From 64fc60f55f468825704300f7c644975388a9d6dd Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Wed, 10 Aug 2022 10:23:47 -0700 Subject: [PATCH 09/22] Make lambda set `set` private --- crates/compiler/mono/src/ir.rs | 8 ++++---- crates/compiler/mono/src/layout.rs | 12 +++++++++++- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/crates/compiler/mono/src/ir.rs b/crates/compiler/mono/src/ir.rs index 4e01e48e27..8579d65d41 100644 --- a/crates/compiler/mono/src/ir.rs +++ b/crates/compiler/mono/src/ir.rs @@ -5439,7 +5439,7 @@ where EnumDispatch::Bool => { debug_assert_eq!(symbols.len(), 0); - debug_assert_eq!(lambda_set.set.len(), 2); + debug_assert_eq!(lambda_set.len(), 2); let tag_id = name.name() != lambda_set.iter_set().next().unwrap().name(); let expr = Expr::Literal(Literal::Bool(tag_id)); @@ -5448,7 +5448,7 @@ where EnumDispatch::U8 => { debug_assert_eq!(symbols.len(), 0); - debug_assert!(lambda_set.set.len() > 2); + debug_assert!(lambda_set.len() > 2); let tag_id = lambda_set .iter_set() .position(|s| s.name() == name.name()) @@ -9477,7 +9477,7 @@ fn union_lambda_set_to_switch<'a>( assigned: Symbol, hole: &'a Stmt<'a>, ) -> Stmt<'a> { - if lambda_set.set.is_empty() { + if lambda_set.is_empty() { // NOTE this can happen if there is a type error somewhere. Since the lambda set is empty, // there is really nothing we can do here. We generate a runtime error here which allows // code gen to proceed. We then assume that we hit another (more descriptive) error before @@ -9487,7 +9487,7 @@ fn union_lambda_set_to_switch<'a>( let join_point_id = JoinPointId(env.unique_symbol()); - let mut branches = Vec::with_capacity_in(lambda_set.set.len(), env.arena); + let mut branches = Vec::with_capacity_in(lambda_set.len(), env.arena); for (i, lambda_name) in lambda_set.iter_set().enumerate() { let closure_info = if lambda_name.no_captures() { diff --git a/crates/compiler/mono/src/layout.rs b/crates/compiler/mono/src/layout.rs index 7bf28fd3a3..6f3366cc99 100644 --- a/crates/compiler/mono/src/layout.rs +++ b/crates/compiler/mono/src/layout.rs @@ -783,7 +783,7 @@ impl<'a> LambdaName<'a> { #[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] pub struct LambdaSet<'a> { /// collection of function names and their closure arguments - pub set: &'a [(Symbol, &'a [Layout<'a>])], + set: &'a [(Symbol, &'a [Layout<'a>])], /// how the closure will be represented at runtime representation: &'a Layout<'a>, } @@ -867,6 +867,16 @@ impl<'a> LambdaSet<'a> { }) } + #[inline(always)] + pub fn len(&self) -> usize { + self.set.len() + } + + #[inline(always)] + pub fn is_empty(&self) -> bool { + self.set.is_empty() + } + pub fn layout_for_member_with_lambda_name( &self, lambda_name: LambdaName, From 68bb03ec09f1464dddf1132b5a62ae89263679f0 Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Wed, 10 Aug 2022 10:25:21 -0700 Subject: [PATCH 10/22] Update mono tests --- .../test_mono/generated/closure_in_list.txt | 4 +-- .../compiler/test_mono/generated/encode.txt | 10 ++++--- .../encode_derived_nested_record_string.txt | 28 +++++++++---------- ...encode_derived_record_one_field_string.txt | 16 +++++------ ...ncode_derived_record_two_field_strings.txt | 16 +++++------ .../generated/encode_derived_string.txt | 4 +-- .../encode_derived_tag_one_field_string.txt | 12 ++++---- ...encode_derived_tag_two_payloads_string.txt | 12 ++++---- ...ches_have_captured_function_in_closure.txt | 4 +-- ...iche_same_layout_different_constructor.txt | 4 +-- .../test_mono/generated/nested_closure.txt | 4 +-- .../recursive_call_capturing_function.txt | 6 ++-- 12 files changed, 61 insertions(+), 59 deletions(-) diff --git a/crates/compiler/test_mono/generated/closure_in_list.txt b/crates/compiler/test_mono/generated/closure_in_list.txt index 5545d2e4ba..ddbc6643a1 100644 --- a/crates/compiler/test_mono/generated/closure_in_list.txt +++ b/crates/compiler/test_mono/generated/closure_in_list.txt @@ -4,14 +4,14 @@ procedure List.6 (#Attr.2): procedure Test.1 (Test.5): let Test.2 : I64 = 41i64; - let Test.10 : I64 = StructAtIndex 0 Test.13; let Test.13 : {I64} = Struct {Test.2}; + let Test.10 : I64 = StructAtIndex 0 Test.13; let Test.9 : List I64 = Array [Test.10]; ret Test.9; procedure Test.3 (Test.8, #Attr.12): - let Test.2 : I64 = StructAtIndex 0 Test.12; let Test.12 : {I64} = Struct {#Attr.12}; + let Test.2 : I64 = StructAtIndex 0 Test.12; ret Test.2; procedure Test.0 (): diff --git a/crates/compiler/test_mono/generated/encode.txt b/crates/compiler/test_mono/generated/encode.txt index f7bc46f32d..7d0735e6c8 100644 --- a/crates/compiler/test_mono/generated/encode.txt +++ b/crates/compiler/test_mono/generated/encode.txt @@ -13,21 +13,23 @@ procedure List.71 (#Attr.2, #Attr.3): ret List.388; procedure Test.23 (Test.24, Test.35, #Attr.12): - let Test.22 : U8 = StructAtIndex 0 #Attr.12; + let Test.38 : {U8} = Struct {#Attr.12}; + let Test.22 : U8 = StructAtIndex 0 Test.38; let Test.37 : List U8 = CallByName List.4 Test.24 Test.22; ret Test.37; procedure Test.8 (Test.22): - let Test.34 : {U8} = Struct {Test.22}; + let Test.39 : {U8} = Struct {Test.22}; + let Test.34 : U8 = StructAtIndex 0 Test.39; ret Test.34; procedure Test.9 (Test.27): - let Test.33 : {U8} = CallByName Test.8 Test.27; + let Test.33 : U8 = CallByName Test.8 Test.27; ret Test.33; procedure Test.0 (): let Test.32 : U8 = 15i64; - let Test.28 : {U8} = CallByName Test.9 Test.32; + let Test.28 : U8 = CallByName Test.9 Test.32; let Test.30 : List U8 = Array []; let Test.31 : {} = Struct {}; let Test.29 : List U8 = CallByName Test.23 Test.30 Test.31 Test.28; 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 4ad29c4b24..dda11c5a61 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 @@ -1,16 +1,16 @@ procedure #Derived.0 (#Derived.1): + let #Derived_gen.2 : {Str} = Struct {#Derived.1}; let #Derived_gen.1 : Str = StructAtIndex 0 #Derived_gen.2; inc #Derived_gen.1; dec #Derived_gen.2; - let #Derived_gen.2 : {Str} = Struct {#Derived.1}; let #Derived_gen.0 : Str = CallByName Encode.22 #Derived_gen.1; ret #Derived_gen.0; procedure #Derived.2 (#Derived.3, #Derived.4, #Attr.12): + let #Derived_gen.11 : {Str} = Struct {#Attr.12}; let #Derived.1 : Str = StructAtIndex 0 #Derived_gen.11; inc #Derived.1; dec #Derived_gen.11; - let #Derived_gen.11 : {Str} = Struct {#Attr.12}; let #Derived_gen.8 : Str = "a"; let #Derived_gen.9 : Str = CallByName #Derived.5 #Derived.1; let #Derived_gen.7 : {Str, Str} = Struct {#Derived_gen.8, #Derived_gen.9}; @@ -20,18 +20,18 @@ procedure #Derived.2 (#Derived.3, #Derived.4, #Attr.12): ret #Derived_gen.4; procedure #Derived.5 (#Derived.6): + let #Derived_gen.18 : {Str} = Struct {#Derived.6}; let #Derived_gen.17 : Str = StructAtIndex 0 #Derived_gen.18; inc #Derived_gen.17; dec #Derived_gen.18; - let #Derived_gen.18 : {Str} = Struct {#Derived.6}; let #Derived_gen.16 : Str = CallByName Encode.22 #Derived_gen.17; ret #Derived_gen.16; procedure #Derived.7 (#Derived.8, #Derived.9, #Attr.12): + let #Derived_gen.27 : {Str} = Struct {#Attr.12}; let #Derived.6 : Str = StructAtIndex 0 #Derived_gen.27; inc #Derived.6; dec #Derived_gen.27; - let #Derived_gen.27 : {Str} = Struct {#Attr.12}; let #Derived_gen.24 : Str = "b"; let #Derived_gen.25 : Str = CallByName Json.18 #Derived.6; let #Derived_gen.23 : {Str, Str} = Struct {#Derived_gen.24, #Derived_gen.25}; @@ -86,10 +86,10 @@ procedure Json.1 (): ret Json.318; procedure Json.103 (Json.104, Json.321, #Attr.12): + let Json.356 : {List {Str, Str}} = Struct {#Attr.12}; let Json.102 : List {Str, Str} = StructAtIndex 0 Json.356; inc Json.102; dec Json.356; - let Json.356 : {List {Str, Str}} = Struct {#Attr.12}; let Json.355 : I32 = 123i64; let Json.354 : U8 = CallByName Num.123 Json.355; let Json.106 : List U8 = CallByName List.4 Json.104 Json.354; @@ -107,10 +107,10 @@ procedure Json.103 (Json.104, Json.321, #Attr.12): ret Json.326; procedure Json.103 (Json.104, Json.321, #Attr.12): + let Json.402 : {List {Str, Str}} = Struct {#Attr.12}; let Json.102 : List {Str, Str} = StructAtIndex 0 Json.402; inc Json.102; dec Json.402; - let Json.402 : {List {Str, Str}} = Struct {#Attr.12}; let Json.401 : I32 = 123i64; let Json.400 : U8 = CallByName Num.123 Json.401; let Json.106 : List U8 = CallByName List.4 Json.104 Json.400; @@ -206,34 +206,34 @@ procedure Json.105 (Json.324, Json.325): jump Json.382 Json.113; procedure Json.18 (Json.86): + let Json.370 : {Str} = Struct {Json.86}; let Json.368 : Str = StructAtIndex 0 Json.370; inc Json.368; dec Json.370; - let Json.370 : {Str} = Struct {Json.86}; let Json.367 : Str = CallByName Encode.22 Json.368; ret Json.367; procedure Json.20 (Json.102): + let Json.322 : {List {Str, Str}} = Struct {Json.102}; let Json.320 : List {Str, Str} = StructAtIndex 0 Json.322; inc Json.320; dec Json.322; - let Json.322 : {List {Str, Str}} = Struct {Json.102}; let Json.319 : List {Str, Str} = CallByName Encode.22 Json.320; ret Json.319; procedure Json.20 (Json.102): + let Json.366 : {List {Str, Str}} = Struct {Json.102}; let Json.364 : List {Str, Str} = StructAtIndex 0 Json.366; inc Json.364; dec Json.366; - let Json.366 : {List {Str, Str}} = Struct {Json.102}; let Json.363 : List {Str, Str} = CallByName Encode.22 Json.364; ret Json.363; procedure Json.87 (Json.88, Json.369, #Attr.12): + let Json.412 : {Str} = Struct {#Attr.12}; let Json.86 : Str = StructAtIndex 0 Json.412; inc Json.86; dec Json.412; - let Json.412 : {Str} = Struct {#Attr.12}; let Json.411 : I32 = 34i64; let Json.410 : U8 = CallByName Num.123 Json.411; let Json.408 : List U8 = CallByName List.4 Json.88 Json.410; @@ -245,22 +245,22 @@ procedure Json.87 (Json.88, Json.369, #Attr.12): ret Json.404; procedure List.133 (List.134, List.135, #Attr.12): - let List.132 : {} = StructAtIndex 0 List.436; let List.436 : {{}} = Struct {#Attr.12}; + let List.132 : {} = StructAtIndex 0 List.436; let List.435 : {List U8, U64} = CallByName Json.105 List.134 List.135; let List.434 : [C [], C {List U8, U64}] = TagId(1) List.435; ret List.434; procedure List.133 (List.134, List.135, #Attr.12): - let List.132 : {} = StructAtIndex 0 List.519; let List.519 : {{}} = Struct {#Attr.12}; + let List.132 : {} = StructAtIndex 0 List.519; let List.518 : {List U8, U64} = CallByName Json.105 List.134 List.135; let List.517 : [C [], C {List U8, U64}] = TagId(1) List.518; ret List.517; procedure List.18 (List.130, List.131, List.132): - let List.411 : {} = StructAtIndex 0 List.412; let List.412 : {{}} = Struct {List.132}; + let List.411 : {} = StructAtIndex 0 List.412; let List.405 : [C [], C {List U8, U64}] = CallByName List.75 List.130 List.131 List.411; let List.408 : U8 = 1i64; let List.409 : U8 = GetTagId List.405; @@ -277,8 +277,8 @@ procedure List.18 (List.130, List.131, List.132): ret List.407; procedure List.18 (List.130, List.131, List.132): - let List.493 : {} = StructAtIndex 0 List.494; let List.494 : {{}} = Struct {List.132}; + let List.493 : {} = StructAtIndex 0 List.494; let List.487 : [C [], C {List U8, U64}] = CallByName List.75 List.130 List.131 List.493; let List.490 : U8 = 1i64; let List.491 : U8 = GetTagId List.487; 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 401305cc93..7b666f85a2 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 @@ -1,16 +1,16 @@ procedure #Derived.0 (#Derived.1): + let #Derived_gen.2 : {Str} = Struct {#Derived.1}; let #Derived_gen.1 : Str = StructAtIndex 0 #Derived_gen.2; inc #Derived_gen.1; dec #Derived_gen.2; - let #Derived_gen.2 : {Str} = Struct {#Derived.1}; let #Derived_gen.0 : Str = CallByName Encode.22 #Derived_gen.1; ret #Derived_gen.0; procedure #Derived.2 (#Derived.3, #Derived.4, #Attr.12): + let #Derived_gen.11 : {Str} = Struct {#Attr.12}; let #Derived.1 : Str = StructAtIndex 0 #Derived_gen.11; inc #Derived.1; dec #Derived_gen.11; - let #Derived_gen.11 : {Str} = Struct {#Attr.12}; let #Derived_gen.8 : Str = "a"; let #Derived_gen.9 : Str = CallByName Json.18 #Derived.1; let #Derived_gen.7 : {Str, Str} = Struct {#Derived_gen.8, #Derived_gen.9}; @@ -51,10 +51,10 @@ procedure Json.1 (): ret Json.318; procedure Json.103 (Json.104, Json.321, #Attr.12): + let Json.360 : {List {Str, Str}} = Struct {#Attr.12}; let Json.102 : List {Str, Str} = StructAtIndex 0 Json.360; inc Json.102; dec Json.360; - let Json.360 : {List {Str, Str}} = Struct {#Attr.12}; let Json.359 : I32 = 123i64; let Json.358 : U8 = CallByName Num.123 Json.359; let Json.106 : List U8 = CallByName List.4 Json.104 Json.358; @@ -111,26 +111,26 @@ procedure Json.105 (Json.328, Json.329): jump Json.340 Json.113; procedure Json.18 (Json.86): + let Json.326 : {Str} = Struct {Json.86}; let Json.324 : Str = StructAtIndex 0 Json.326; inc Json.324; dec Json.326; - let Json.326 : {Str} = Struct {Json.86}; let Json.323 : Str = CallByName Encode.22 Json.324; ret Json.323; procedure Json.20 (Json.102): + let Json.322 : {List {Str, Str}} = Struct {Json.102}; let Json.320 : List {Str, Str} = StructAtIndex 0 Json.322; inc Json.320; dec Json.322; - let Json.322 : {List {Str, Str}} = Struct {Json.102}; let Json.319 : List {Str, Str} = CallByName Encode.22 Json.320; ret Json.319; procedure Json.87 (Json.88, Json.325, #Attr.12): + let Json.370 : {Str} = Struct {#Attr.12}; let Json.86 : Str = StructAtIndex 0 Json.370; inc Json.86; dec Json.370; - let Json.370 : {Str} = Struct {#Attr.12}; let Json.369 : I32 = 34i64; let Json.368 : U8 = CallByName Num.123 Json.369; let Json.366 : List U8 = CallByName List.4 Json.88 Json.368; @@ -142,15 +142,15 @@ procedure Json.87 (Json.88, Json.325, #Attr.12): ret Json.362; procedure List.133 (List.134, List.135, #Attr.12): - let List.132 : {} = StructAtIndex 0 List.443; let List.443 : {{}} = Struct {#Attr.12}; + let List.132 : {} = StructAtIndex 0 List.443; let List.442 : {List U8, U64} = CallByName Json.105 List.134 List.135; let List.441 : [C [], C {List U8, U64}] = TagId(1) List.442; ret List.441; procedure List.18 (List.130, List.131, List.132): - let List.417 : {} = StructAtIndex 0 List.418; let List.418 : {{}} = Struct {List.132}; + let List.417 : {} = StructAtIndex 0 List.418; let List.411 : [C [], C {List U8, U64}] = CallByName List.75 List.130 List.131 List.417; let List.414 : U8 = 1i64; let List.415 : U8 = GetTagId List.411; 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 ef4b7f9022..b53de6ab54 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 @@ -1,16 +1,16 @@ procedure #Derived.0 (#Derived.1): + let #Derived_gen.2 : {{Str, Str}} = Struct {#Derived.1}; let #Derived_gen.1 : {Str, Str} = StructAtIndex 0 #Derived_gen.2; inc #Derived_gen.1; dec #Derived_gen.2; - let #Derived_gen.2 : {{Str, Str}} = Struct {#Derived.1}; let #Derived_gen.0 : {Str, Str} = CallByName Encode.22 #Derived_gen.1; ret #Derived_gen.0; procedure #Derived.2 (#Derived.3, #Derived.4, #Attr.12): + let #Derived_gen.15 : {{Str, Str}} = Struct {#Attr.12}; let #Derived.1 : {Str, Str} = StructAtIndex 0 #Derived_gen.15; inc #Derived.1; dec #Derived_gen.15; - let #Derived_gen.15 : {{Str, Str}} = Struct {#Attr.12}; let #Derived_gen.12 : Str = "a"; let #Derived_gen.14 : Str = StructAtIndex 0 #Derived.1; inc #Derived_gen.14; @@ -59,10 +59,10 @@ procedure Json.1 (): ret Json.318; procedure Json.103 (Json.104, Json.321, #Attr.12): + let Json.364 : {List {Str, Str}} = Struct {#Attr.12}; let Json.102 : List {Str, Str} = StructAtIndex 0 Json.364; inc Json.102; dec Json.364; - let Json.364 : {List {Str, Str}} = Struct {#Attr.12}; let Json.363 : I32 = 123i64; let Json.362 : U8 = CallByName Num.123 Json.363; let Json.106 : List U8 = CallByName List.4 Json.104 Json.362; @@ -119,26 +119,26 @@ procedure Json.105 (Json.332, Json.333): jump Json.344 Json.113; procedure Json.18 (Json.86): + let Json.330 : {Str} = Struct {Json.86}; let Json.328 : Str = StructAtIndex 0 Json.330; inc Json.328; dec Json.330; - let Json.330 : {Str} = Struct {Json.86}; let Json.327 : Str = CallByName Encode.22 Json.328; ret Json.327; procedure Json.20 (Json.102): + let Json.322 : {List {Str, Str}} = Struct {Json.102}; let Json.320 : List {Str, Str} = StructAtIndex 0 Json.322; inc Json.320; dec Json.322; - let Json.322 : {List {Str, Str}} = Struct {Json.102}; let Json.319 : List {Str, Str} = CallByName Encode.22 Json.320; ret Json.319; procedure Json.87 (Json.88, Json.325, #Attr.12): + let Json.374 : {Str} = Struct {#Attr.12}; let Json.86 : Str = StructAtIndex 0 Json.374; inc Json.86; dec Json.374; - let Json.374 : {Str} = Struct {#Attr.12}; let Json.373 : I32 = 34i64; let Json.372 : U8 = CallByName Num.123 Json.373; let Json.370 : List U8 = CallByName List.4 Json.88 Json.372; @@ -150,15 +150,15 @@ procedure Json.87 (Json.88, Json.325, #Attr.12): ret Json.366; procedure List.133 (List.134, List.135, #Attr.12): - let List.132 : {} = StructAtIndex 0 List.443; let List.443 : {{}} = Struct {#Attr.12}; + let List.132 : {} = StructAtIndex 0 List.443; let List.442 : {List U8, U64} = CallByName Json.105 List.134 List.135; let List.441 : [C [], C {List U8, U64}] = TagId(1) List.442; ret List.441; procedure List.18 (List.130, List.131, List.132): - let List.417 : {} = StructAtIndex 0 List.418; let List.418 : {{}} = Struct {List.132}; + let List.417 : {} = StructAtIndex 0 List.418; let List.411 : [C [], C {List U8, U64}] = CallByName List.75 List.130 List.131 List.417; let List.414 : U8 = 1i64; let List.415 : U8 = GetTagId List.411; diff --git a/crates/compiler/test_mono/generated/encode_derived_string.txt b/crates/compiler/test_mono/generated/encode_derived_string.txt index aa3913651c..ba9effd84c 100644 --- a/crates/compiler/test_mono/generated/encode_derived_string.txt +++ b/crates/compiler/test_mono/generated/encode_derived_string.txt @@ -16,18 +16,18 @@ procedure Json.1 (): ret Json.318; procedure Json.18 (Json.86): + let Json.322 : {Str} = Struct {Json.86}; let Json.320 : Str = StructAtIndex 0 Json.322; inc Json.320; dec Json.322; - let Json.322 : {Str} = Struct {Json.86}; let Json.319 : Str = CallByName Encode.22 Json.320; ret Json.319; procedure Json.87 (Json.88, Json.321, #Attr.12): + let Json.332 : {Str} = Struct {#Attr.12}; let Json.86 : Str = StructAtIndex 0 Json.332; inc Json.86; dec Json.332; - let Json.332 : {Str} = Struct {#Attr.12}; let Json.331 : I32 = 34i64; let Json.330 : U8 = CallByName Num.123 Json.331; let Json.328 : List U8 = CallByName List.4 Json.88 Json.330; 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 5915f977f7..1bba624c75 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 @@ -1,16 +1,16 @@ procedure #Derived.0 (#Derived.1): + let #Derived_gen.2 : {Str} = Struct {#Derived.1}; let #Derived_gen.1 : Str = StructAtIndex 0 #Derived_gen.2; inc #Derived_gen.1; dec #Derived_gen.2; - let #Derived_gen.2 : {Str} = Struct {#Derived.1}; let #Derived_gen.0 : Str = CallByName Encode.22 #Derived_gen.1; ret #Derived_gen.0; procedure #Derived.3 (#Derived.4, #Derived.5, #Attr.12): + let #Derived_gen.11 : {Str} = Struct {#Attr.12}; let #Derived.1 : Str = StructAtIndex 0 #Derived_gen.11; inc #Derived.1; dec #Derived_gen.11; - let #Derived_gen.11 : {Str} = Struct {#Attr.12}; joinpoint #Derived_gen.6 #Derived_gen.5: let #Derived_gen.4 : List U8 = CallByName Encode.23 #Derived.4 #Derived_gen.5 #Derived.5; ret #Derived_gen.4; @@ -115,10 +115,10 @@ procedure Json.119 (Json.327, Json.125): jump Json.341 Json.126; procedure Json.18 (Json.86): + let Json.325 : {Str} = Struct {Json.86}; let Json.323 : Str = StructAtIndex 0 Json.325; inc Json.323; dec Json.325; - let Json.325 : {Str} = Struct {Json.86}; let Json.322 : Str = CallByName Encode.22 Json.323; ret Json.322; @@ -128,10 +128,10 @@ procedure Json.21 (Json.115, Json.116): ret Json.319; procedure Json.87 (Json.88, Json.324, #Attr.12): + let Json.373 : {Str} = Struct {#Attr.12}; let Json.86 : Str = StructAtIndex 0 Json.373; inc Json.86; dec Json.373; - let Json.373 : {Str} = Struct {#Attr.12}; let Json.372 : I32 = 34i64; let Json.371 : U8 = CallByName Num.123 Json.372; let Json.369 : List U8 = CallByName List.4 Json.88 Json.371; @@ -143,15 +143,15 @@ procedure Json.87 (Json.88, Json.324, #Attr.12): ret Json.365; procedure List.133 (List.134, List.135, #Attr.12): - let List.132 : {} = StructAtIndex 0 List.449; let List.449 : {{}} = Struct {#Attr.12}; + let List.132 : {} = StructAtIndex 0 List.449; let List.448 : {List U8, U64} = CallByName Json.119 List.134 List.135; let List.447 : [C [], C {List U8, U64}] = TagId(1) List.448; ret List.447; procedure List.18 (List.130, List.131, List.132): - let List.423 : {} = StructAtIndex 0 List.424; let List.424 : {{}} = Struct {List.132}; + let List.423 : {} = StructAtIndex 0 List.424; let List.417 : [C [], C {List U8, U64}] = CallByName List.75 List.130 List.131 List.423; let List.420 : U8 = 1i64; let List.421 : U8 = GetTagId List.417; 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 f15a732461..175b4b486e 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 @@ -1,16 +1,16 @@ procedure #Derived.0 (#Derived.1): + let #Derived_gen.2 : {{Str, Str}} = Struct {#Derived.1}; let #Derived_gen.1 : {Str, Str} = StructAtIndex 0 #Derived_gen.2; inc #Derived_gen.1; dec #Derived_gen.2; - let #Derived_gen.2 : {{Str, Str}} = Struct {#Derived.1}; let #Derived_gen.0 : {Str, Str} = CallByName Encode.22 #Derived_gen.1; ret #Derived_gen.0; procedure #Derived.4 (#Derived.5, #Derived.6, #Attr.12): + let #Derived_gen.12 : {{Str, Str}} = Struct {#Attr.12}; let #Derived.1 : {Str, Str} = StructAtIndex 0 #Derived_gen.12; inc #Derived.1; dec #Derived_gen.12; - let #Derived_gen.12 : {{Str, Str}} = Struct {#Attr.12}; joinpoint #Derived_gen.6 #Derived_gen.5: let #Derived_gen.4 : List U8 = CallByName Encode.23 #Derived.5 #Derived_gen.5 #Derived.6; ret #Derived_gen.4; @@ -121,10 +121,10 @@ procedure Json.119 (Json.331, Json.125): jump Json.345 Json.126; procedure Json.18 (Json.86): + let Json.329 : {Str} = Struct {Json.86}; let Json.327 : Str = StructAtIndex 0 Json.329; inc Json.327; dec Json.329; - let Json.329 : {Str} = Struct {Json.86}; let Json.326 : Str = CallByName Encode.22 Json.327; ret Json.326; @@ -134,10 +134,10 @@ procedure Json.21 (Json.115, Json.116): ret Json.319; procedure Json.87 (Json.88, Json.324, #Attr.12): + let Json.377 : {Str} = Struct {#Attr.12}; let Json.86 : Str = StructAtIndex 0 Json.377; inc Json.86; dec Json.377; - let Json.377 : {Str} = Struct {#Attr.12}; let Json.376 : I32 = 34i64; let Json.375 : U8 = CallByName Num.123 Json.376; let Json.373 : List U8 = CallByName List.4 Json.88 Json.375; @@ -149,15 +149,15 @@ procedure Json.87 (Json.88, Json.324, #Attr.12): ret Json.369; procedure List.133 (List.134, List.135, #Attr.12): - let List.132 : {} = StructAtIndex 0 List.449; let List.449 : {{}} = Struct {#Attr.12}; + let List.132 : {} = StructAtIndex 0 List.449; let List.448 : {List U8, U64} = CallByName Json.119 List.134 List.135; let List.447 : [C [], C {List U8, U64}] = TagId(1) List.448; ret List.447; procedure List.18 (List.130, List.131, List.132): - let List.423 : {} = StructAtIndex 0 List.424; let List.424 : {{}} = Struct {List.132}; + let List.423 : {} = StructAtIndex 0 List.424; let List.417 : [C [], C {List U8, U64}] = CallByName List.75 List.130 List.131 List.423; let List.420 : U8 = 1i64; let List.421 : U8 = GetTagId List.417; diff --git a/crates/compiler/test_mono/generated/lambda_capture_niches_have_captured_function_in_closure.txt b/crates/compiler/test_mono/generated/lambda_capture_niches_have_captured_function_in_closure.txt index 8d4815f262..373532cb37 100644 --- a/crates/compiler/test_mono/generated/lambda_capture_niches_have_captured_function_in_closure.txt +++ b/crates/compiler/test_mono/generated/lambda_capture_niches_have_captured_function_in_closure.txt @@ -3,10 +3,10 @@ procedure Test.11 (Test.37): ret Test.38; procedure Test.13 (Test.51, #Attr.12): + let Test.54 : {Str} = Struct {#Attr.12}; let Test.12 : Str = StructAtIndex 0 Test.54; inc Test.12; dec Test.54; - let Test.54 : {Str} = Struct {#Attr.12}; ret Test.12; procedure Test.15 (Test.39): @@ -30,10 +30,10 @@ procedure Test.3 (Test.17): ret Test.36; procedure Test.4 (Test.18): + let Test.55 : {Str} = Struct {Test.18}; let Test.50 : Str = StructAtIndex 0 Test.55; inc Test.50; dec Test.55; - let Test.55 : {Str} = Struct {Test.18}; ret Test.50; procedure Test.9 (Test.29, #Attr.12): diff --git a/crates/compiler/test_mono/generated/lambda_set_niche_same_layout_different_constructor.txt b/crates/compiler/test_mono/generated/lambda_set_niche_same_layout_different_constructor.txt index 8b7c7eaacd..0110980f98 100644 --- a/crates/compiler/test_mono/generated/lambda_set_niche_same_layout_different_constructor.txt +++ b/crates/compiler/test_mono/generated/lambda_set_niche_same_layout_different_constructor.txt @@ -1,15 +1,15 @@ procedure Test.1 (Test.4): + let Test.16 : {Str} = Struct {Test.4}; let Test.5 : Str = StructAtIndex 0 Test.16; inc Test.5; dec Test.16; - let Test.16 : {Str} = Struct {Test.4}; ret Test.5; procedure Test.5 (Test.12, #Attr.12): + let Test.15 : {Str} = Struct {#Attr.12}; let Test.4 : Str = StructAtIndex 0 Test.15; inc Test.4; dec Test.15; - let Test.15 : {Str} = Struct {#Attr.12}; let Test.14 : Str = ""; ret Test.14; diff --git a/crates/compiler/test_mono/generated/nested_closure.txt b/crates/compiler/test_mono/generated/nested_closure.txt index 6b6078bf3b..c5937b430c 100644 --- a/crates/compiler/test_mono/generated/nested_closure.txt +++ b/crates/compiler/test_mono/generated/nested_closure.txt @@ -1,12 +1,12 @@ procedure Test.1 (Test.5): let Test.2 : I64 = 42i64; - let Test.3 : I64 = StructAtIndex 0 Test.13; let Test.13 : {I64} = Struct {Test.2}; + let Test.3 : I64 = StructAtIndex 0 Test.13; ret Test.3; procedure Test.3 (Test.9, #Attr.12): - let Test.2 : I64 = StructAtIndex 0 Test.12; let Test.12 : {I64} = Struct {#Attr.12}; + let Test.2 : I64 = StructAtIndex 0 Test.12; ret Test.2; procedure Test.0 (): diff --git a/crates/compiler/test_mono/generated/recursive_call_capturing_function.txt b/crates/compiler/test_mono/generated/recursive_call_capturing_function.txt index 00dafe3005..b0f1a4b403 100644 --- a/crates/compiler/test_mono/generated/recursive_call_capturing_function.txt +++ b/crates/compiler/test_mono/generated/recursive_call_capturing_function.txt @@ -4,22 +4,22 @@ procedure Num.19 (#Attr.2, #Attr.3): procedure Test.1 (Test.2): let Test.9 : U32 = 0i64; - let Test.18 : U32 = StructAtIndex 0 Test.19; let Test.19 : {U32} = Struct {Test.2}; + let Test.18 : U32 = StructAtIndex 0 Test.19; let Test.8 : U32 = CallByName Test.3 Test.9 Test.18; ret Test.8; procedure Test.3 (Test.21, Test.22): joinpoint Test.10 Test.4 #Attr.12: - let Test.2 : U32 = StructAtIndex 0 Test.17; let Test.17 : {U32} = Struct {#Attr.12}; + let Test.2 : U32 = StructAtIndex 0 Test.17; let Test.15 : Int1 = true; if Test.15 then ret Test.4; else let Test.12 : U32 = CallByName Num.19 Test.4 Test.2; - let Test.13 : U32 = StructAtIndex 0 Test.14; let Test.14 : {U32} = Struct {Test.2}; + let Test.13 : U32 = StructAtIndex 0 Test.14; jump Test.10 Test.12 Test.13; in jump Test.10 Test.21 Test.22; From d8a8dff70de8580ea45c52eb351c21de7fcf7d12 Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Sun, 14 Aug 2022 15:26:52 -0500 Subject: [PATCH 11/22] Treat unwrapped capture sets as unwrapped directly --- crates/compiler/mono/src/ir.rs | 85 +-- .../test_mono/generated/closure_in_list.txt | 8 +- .../compiler/test_mono/generated/encode.txt | 8 +- .../encode_derived_nested_record_string.txt | 506 ++++++++---------- ...encode_derived_record_one_field_string.txt | 274 +++++----- ...ncode_derived_record_two_field_strings.txt | 292 +++++----- .../generated/encode_derived_string.txt | 30 +- .../encode_derived_tag_one_field_string.txt | 252 ++++----- ...encode_derived_tag_two_payloads_string.txt | 252 ++++----- ...ches_have_captured_function_in_closure.txt | 26 +- ...iche_same_layout_different_constructor.txt | 32 +- .../test_mono/generated/nested_closure.txt | 8 +- .../recursive_call_capturing_function.txt | 20 +- 13 files changed, 785 insertions(+), 1008 deletions(-) diff --git a/crates/compiler/mono/src/ir.rs b/crates/compiler/mono/src/ir.rs index 8579d65d41..9c26592bcd 100644 --- a/crates/compiler/mono/src/ir.rs +++ b/crates/compiler/mono/src/ir.rs @@ -3115,6 +3115,8 @@ fn specialize_external<'a>( closure: opt_closure_layout, ret_layout, } => { + let mut proc_args = Vec::from_iter_in(proc_args.iter().copied(), env.arena); + // unpack the closure symbols, if any match (opt_closure_layout, captured_symbols) { (Some(closure_layout), CapturedSymbols::Captured(captured)) => { @@ -3234,39 +3236,16 @@ fn specialize_external<'a>( } } - ClosureRepresentation::UnwrappedCapture(layout) => { + ClosureRepresentation::UnwrappedCapture(_layout) => { debug_assert_eq!(captured.len(), 1); let (captured_symbol, _) = captured[0]; + // The capture set is unwrapped, so simply replace the closure argument + // to the function with the unwrapped capture name. let captured_symbol = get_specialized_name(captured_symbol); - - // To avoid substitution, wrap in a struct and immediately unwrap. - // It should be optimized away later on. - let layout_slice = env.arena.alloc([layout]); - let arg_closure_slice = env.arena.alloc([Symbol::ARG_CLOSURE]); - - let wrap = Expr::Struct(arg_closure_slice); - let wrap_sym = env.unique_symbol(); - - let unwrap = Expr::StructAtIndex { - index: 0, - field_layouts: layout_slice, - structure: wrap_sym, - }; - - specialized_body = Stmt::Let( - captured_symbol, - unwrap, - layout, - env.arena.alloc(specialized_body), - ); - - specialized_body = Stmt::Let( - wrap_sym, - wrap, - Layout::struct_no_name_order(layout_slice), - env.arena.alloc(specialized_body), - ); + let closure_arg = proc_args.last_mut().unwrap(); + debug_assert_eq!(closure_arg.1, Symbol::ARG_CLOSURE); + closure_arg.1 = captured_symbol; } ClosureRepresentation::EnumDispatch(_) => { @@ -3279,18 +3258,13 @@ fn specialize_external<'a>( _ => unreachable!("to closure or not to closure?"), } - let proc_args: Vec<_> = proc_args - .iter() - .map(|&(layout, symbol)| { - // Grab the specialization symbol, if it exists. - let symbol = procs - .symbol_specializations - .remove_single(symbol) - .unwrap_or(symbol); - - (layout, symbol) - }) - .collect_in(env.arena); + proc_args.iter_mut().for_each(|(_layout, symbol)| { + // Grab the specialization symbol, if it exists. + *symbol = procs + .symbol_specializations + .remove_single(*symbol) + .unwrap_or(*symbol); + }); // reset subs, so we don't get type errors when specializing for a different signature layout_cache.rollback_to(cache_snapshot); @@ -5406,34 +5380,17 @@ where Stmt::Let(assigned, expr, lambda_set_layout, hole) } - ClosureRepresentation::UnwrappedCapture(layout) => { + ClosureRepresentation::UnwrappedCapture(_layout) => { debug_assert_eq!(symbols.len(), 1); let mut symbols = symbols; let (captured_symbol, _) = symbols.next().unwrap(); - // To avoid substitution, wrap in a struct and immediately unwrap. - // It should be optimized away later on. - let layout_slice = env.arena.alloc([layout]); - let captured_slice = env.arena.alloc([*captured_symbol]); - - let wrap = Expr::Struct(captured_slice); - let wrap_sym = env.unique_symbol(); - - let unwrap = Expr::StructAtIndex { - index: 0, - field_layouts: layout_slice, - structure: wrap_sym, - }; - - let hole = env.arena.alloc(Stmt::Let(assigned, unwrap, layout, hole)); - - Stmt::Let( - wrap_sym, - wrap, - Layout::struct_no_name_order(layout_slice), - hole, - ) + // The capture set is unwrapped, so just replaced the assigned capture symbol with the + // only capture. + let mut hole = hole.clone(); + substitute_in_exprs(env.arena, &mut hole, assigned, *captured_symbol); + hole } ClosureRepresentation::EnumDispatch(repr) => match repr { EnumDispatch::Bool => { diff --git a/crates/compiler/test_mono/generated/closure_in_list.txt b/crates/compiler/test_mono/generated/closure_in_list.txt index ddbc6643a1..26e9a06eae 100644 --- a/crates/compiler/test_mono/generated/closure_in_list.txt +++ b/crates/compiler/test_mono/generated/closure_in_list.txt @@ -4,14 +4,10 @@ procedure List.6 (#Attr.2): procedure Test.1 (Test.5): let Test.2 : I64 = 41i64; - let Test.13 : {I64} = Struct {Test.2}; - let Test.10 : I64 = StructAtIndex 0 Test.13; - let Test.9 : List I64 = Array [Test.10]; + let Test.9 : List I64 = Array [Test.2]; ret Test.9; -procedure Test.3 (Test.8, #Attr.12): - let Test.12 : {I64} = Struct {#Attr.12}; - let Test.2 : I64 = StructAtIndex 0 Test.12; +procedure Test.3 (Test.8, Test.2): ret Test.2; procedure Test.0 (): diff --git a/crates/compiler/test_mono/generated/encode.txt b/crates/compiler/test_mono/generated/encode.txt index 7d0735e6c8..03cb371d02 100644 --- a/crates/compiler/test_mono/generated/encode.txt +++ b/crates/compiler/test_mono/generated/encode.txt @@ -12,16 +12,12 @@ procedure List.71 (#Attr.2, #Attr.3): let List.388 : List U8 = lowlevel ListAppendUnsafe #Attr.2 #Attr.3; ret List.388; -procedure Test.23 (Test.24, Test.35, #Attr.12): - let Test.38 : {U8} = Struct {#Attr.12}; - let Test.22 : U8 = StructAtIndex 0 Test.38; +procedure Test.23 (Test.24, Test.35, Test.22): let Test.37 : List U8 = CallByName List.4 Test.24 Test.22; ret Test.37; procedure Test.8 (Test.22): - let Test.39 : {U8} = Struct {Test.22}; - let Test.34 : U8 = StructAtIndex 0 Test.39; - ret Test.34; + ret Test.22; procedure Test.9 (Test.27): let Test.33 : U8 = CallByName Test.8 Test.27; 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 dda11c5a61..2e9010b165 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 @@ -1,44 +1,28 @@ procedure #Derived.0 (#Derived.1): - let #Derived_gen.2 : {Str} = Struct {#Derived.1}; - let #Derived_gen.1 : Str = StructAtIndex 0 #Derived_gen.2; - inc #Derived_gen.1; - dec #Derived_gen.2; - let #Derived_gen.0 : Str = CallByName Encode.22 #Derived_gen.1; + let #Derived_gen.0 : Str = CallByName Encode.22 #Derived.1; ret #Derived_gen.0; -procedure #Derived.2 (#Derived.3, #Derived.4, #Attr.12): - let #Derived_gen.11 : {Str} = Struct {#Attr.12}; - let #Derived.1 : Str = StructAtIndex 0 #Derived_gen.11; - inc #Derived.1; - dec #Derived_gen.11; - let #Derived_gen.8 : Str = "a"; - let #Derived_gen.9 : Str = CallByName #Derived.5 #Derived.1; - let #Derived_gen.7 : {Str, Str} = Struct {#Derived_gen.8, #Derived_gen.9}; - let #Derived_gen.6 : List {Str, Str} = Array [#Derived_gen.7]; - let #Derived_gen.5 : List {Str, Str} = CallByName Json.20 #Derived_gen.6; - let #Derived_gen.4 : List U8 = CallByName Encode.23 #Derived.3 #Derived_gen.5 #Derived.4; - ret #Derived_gen.4; +procedure #Derived.2 (#Derived.3, #Derived.4, #Derived.1): + let #Derived_gen.7 : Str = "a"; + let #Derived_gen.8 : Str = CallByName #Derived.5 #Derived.1; + let #Derived_gen.6 : {Str, Str} = Struct {#Derived_gen.7, #Derived_gen.8}; + let #Derived_gen.5 : List {Str, Str} = Array [#Derived_gen.6]; + let #Derived_gen.4 : List {Str, Str} = CallByName Json.20 #Derived_gen.5; + let #Derived_gen.3 : List U8 = CallByName Encode.23 #Derived.3 #Derived_gen.4 #Derived.4; + ret #Derived_gen.3; procedure #Derived.5 (#Derived.6): - let #Derived_gen.18 : {Str} = Struct {#Derived.6}; - let #Derived_gen.17 : Str = StructAtIndex 0 #Derived_gen.18; - inc #Derived_gen.17; - dec #Derived_gen.18; - let #Derived_gen.16 : Str = CallByName Encode.22 #Derived_gen.17; - ret #Derived_gen.16; + let #Derived_gen.14 : Str = CallByName Encode.22 #Derived.6; + ret #Derived_gen.14; -procedure #Derived.7 (#Derived.8, #Derived.9, #Attr.12): - let #Derived_gen.27 : {Str} = Struct {#Attr.12}; - let #Derived.6 : Str = StructAtIndex 0 #Derived_gen.27; - inc #Derived.6; - dec #Derived_gen.27; - let #Derived_gen.24 : Str = "b"; - let #Derived_gen.25 : Str = CallByName Json.18 #Derived.6; - let #Derived_gen.23 : {Str, Str} = Struct {#Derived_gen.24, #Derived_gen.25}; - let #Derived_gen.22 : List {Str, Str} = Array [#Derived_gen.23]; - let #Derived_gen.21 : List {Str, Str} = CallByName Json.20 #Derived_gen.22; - let #Derived_gen.20 : List U8 = CallByName Encode.23 #Derived.8 #Derived_gen.21 #Derived.9; - ret #Derived_gen.20; +procedure #Derived.7 (#Derived.8, #Derived.9, #Derived.6): + let #Derived_gen.21 : Str = "b"; + let #Derived_gen.22 : Str = CallByName Json.18 #Derived.6; + let #Derived_gen.20 : {Str, Str} = Struct {#Derived_gen.21, #Derived_gen.22}; + let #Derived_gen.19 : List {Str, Str} = Array [#Derived_gen.20]; + let #Derived_gen.18 : List {Str, Str} = CallByName Json.20 #Derived_gen.19; + let #Derived_gen.17 : List U8 = CallByName Encode.23 #Derived.8 #Derived_gen.18 #Derived.9; + ret #Derived_gen.17; procedure Encode.22 (Encode.93): ret Encode.93; @@ -85,183 +69,153 @@ procedure Json.1 (): let Json.318 : {} = Struct {}; ret Json.318; -procedure Json.103 (Json.104, Json.321, #Attr.12): - let Json.356 : {List {Str, Str}} = Struct {#Attr.12}; - let Json.102 : List {Str, Str} = StructAtIndex 0 Json.356; - inc Json.102; - dec Json.356; - let Json.355 : I32 = 123i64; - let Json.354 : U8 = CallByName Num.123 Json.355; - let Json.106 : List U8 = CallByName List.4 Json.104 Json.354; - let Json.353 : U64 = CallByName List.6 Json.102; - let Json.330 : {List U8, U64} = Struct {Json.106, Json.353}; - let Json.331 : {} = Struct {}; - let Json.329 : {List U8, U64} = CallByName List.18 Json.102 Json.330 Json.331; +procedure Json.103 (Json.104, Json.321, Json.102): + let Json.354 : I32 = 123i64; + let Json.353 : U8 = CallByName Num.123 Json.354; + let Json.106 : List U8 = CallByName List.4 Json.104 Json.353; + let Json.352 : U64 = CallByName List.6 Json.102; + let Json.329 : {List U8, U64} = Struct {Json.106, Json.352}; + let Json.330 : {} = Struct {}; + let Json.328 : {List U8, U64} = CallByName List.18 Json.102 Json.329 Json.330; dec Json.102; - let Json.108 : List U8 = StructAtIndex 0 Json.329; + let Json.108 : List U8 = StructAtIndex 0 Json.328; inc Json.108; - dec Json.329; - let Json.328 : I32 = 125i64; - let Json.327 : U8 = CallByName Num.123 Json.328; - let Json.326 : List U8 = CallByName List.4 Json.108 Json.327; - ret Json.326; + dec Json.328; + let Json.327 : I32 = 125i64; + let Json.326 : U8 = CallByName Num.123 Json.327; + let Json.325 : List U8 = CallByName List.4 Json.108 Json.326; + ret Json.325; -procedure Json.103 (Json.104, Json.321, #Attr.12): - let Json.402 : {List {Str, Str}} = Struct {#Attr.12}; - let Json.102 : List {Str, Str} = StructAtIndex 0 Json.402; - inc Json.102; - dec Json.402; - let Json.401 : I32 = 123i64; - let Json.400 : U8 = CallByName Num.123 Json.401; - let Json.106 : List U8 = CallByName List.4 Json.104 Json.400; - let Json.399 : U64 = CallByName List.6 Json.102; - let Json.376 : {List U8, U64} = Struct {Json.106, Json.399}; - let Json.377 : {} = Struct {}; - let Json.375 : {List U8, U64} = CallByName List.18 Json.102 Json.376 Json.377; +procedure Json.103 (Json.104, Json.321, Json.102): + let Json.397 : I32 = 123i64; + let Json.396 : U8 = CallByName Num.123 Json.397; + let Json.106 : List U8 = CallByName List.4 Json.104 Json.396; + let Json.395 : U64 = CallByName List.6 Json.102; + let Json.372 : {List U8, U64} = Struct {Json.106, Json.395}; + let Json.373 : {} = Struct {}; + let Json.371 : {List U8, U64} = CallByName List.18 Json.102 Json.372 Json.373; dec Json.102; - let Json.108 : List U8 = StructAtIndex 0 Json.375; + let Json.108 : List U8 = StructAtIndex 0 Json.371; inc Json.108; - dec Json.375; - let Json.374 : I32 = 125i64; - let Json.373 : U8 = CallByName Num.123 Json.374; - let Json.372 : List U8 = CallByName List.4 Json.108 Json.373; - ret Json.372; + dec Json.371; + let Json.370 : I32 = 125i64; + let Json.369 : U8 = CallByName Num.123 Json.370; + let Json.368 : List U8 = CallByName List.4 Json.108 Json.369; + ret Json.368; -procedure Json.105 (Json.324, Json.325): - let Json.111 : Str = StructAtIndex 0 Json.325; +procedure Json.105 (Json.323, Json.324): + let Json.111 : Str = StructAtIndex 0 Json.324; inc Json.111; - let Json.112 : Str = StructAtIndex 1 Json.325; + let Json.112 : Str = StructAtIndex 1 Json.324; inc Json.112; - dec Json.325; - let Json.109 : List U8 = StructAtIndex 0 Json.324; - inc Json.109; - let Json.110 : U64 = StructAtIndex 1 Json.324; dec Json.324; - let Json.352 : I32 = 34i64; - let Json.351 : U8 = CallByName Num.123 Json.352; - let Json.349 : List U8 = CallByName List.4 Json.109 Json.351; - let Json.350 : List U8 = CallByName Str.12 Json.111; - let Json.346 : List U8 = CallByName List.8 Json.349 Json.350; - let Json.348 : I32 = 34i64; - let Json.347 : U8 = CallByName Num.123 Json.348; - let Json.343 : List U8 = CallByName List.4 Json.346 Json.347; - let Json.345 : I32 = 58i64; - let Json.344 : U8 = CallByName Num.123 Json.345; - let Json.341 : List U8 = CallByName List.4 Json.343 Json.344; - let Json.342 : {} = Struct {}; - let Json.113 : List U8 = CallByName Encode.23 Json.341 Json.112 Json.342; - joinpoint Json.336 Json.114: - let Json.334 : U64 = 1i64; - let Json.333 : U64 = CallByName Num.20 Json.110 Json.334; - let Json.332 : {List U8, U64} = Struct {Json.114, Json.333}; - ret Json.332; + let Json.109 : List U8 = StructAtIndex 0 Json.323; + inc Json.109; + let Json.110 : U64 = StructAtIndex 1 Json.323; + dec Json.323; + let Json.351 : I32 = 34i64; + let Json.350 : U8 = CallByName Num.123 Json.351; + let Json.348 : List U8 = CallByName List.4 Json.109 Json.350; + let Json.349 : List U8 = CallByName Str.12 Json.111; + let Json.345 : List U8 = CallByName List.8 Json.348 Json.349; + let Json.347 : I32 = 34i64; + let Json.346 : U8 = CallByName Num.123 Json.347; + let Json.342 : List U8 = CallByName List.4 Json.345 Json.346; + let Json.344 : I32 = 58i64; + let Json.343 : U8 = CallByName Num.123 Json.344; + let Json.340 : List U8 = CallByName List.4 Json.342 Json.343; + let Json.341 : {} = Struct {}; + let Json.113 : List U8 = CallByName Encode.23 Json.340 Json.112 Json.341; + joinpoint Json.335 Json.114: + let Json.333 : U64 = 1i64; + let Json.332 : U64 = CallByName Num.20 Json.110 Json.333; + let Json.331 : {List U8, U64} = Struct {Json.114, Json.332}; + ret Json.331; in - let Json.340 : U64 = 1i64; - let Json.337 : Int1 = CallByName Num.24 Json.110 Json.340; - if Json.337 then - let Json.339 : I32 = 44i64; - let Json.338 : U8 = CallByName Num.123 Json.339; - let Json.335 : List U8 = CallByName List.4 Json.113 Json.338; - jump Json.336 Json.335; + let Json.339 : U64 = 1i64; + let Json.336 : Int1 = CallByName Num.24 Json.110 Json.339; + if Json.336 then + let Json.338 : I32 = 44i64; + let Json.337 : U8 = CallByName Num.123 Json.338; + let Json.334 : List U8 = CallByName List.4 Json.113 Json.337; + jump Json.335 Json.334; else - jump Json.336 Json.113; + jump Json.335 Json.113; -procedure Json.105 (Json.324, Json.325): - let Json.111 : Str = StructAtIndex 0 Json.325; +procedure Json.105 (Json.323, Json.324): + let Json.111 : Str = StructAtIndex 0 Json.324; inc Json.111; - let Json.112 : Str = StructAtIndex 1 Json.325; + let Json.112 : Str = StructAtIndex 1 Json.324; inc Json.112; - dec Json.325; - let Json.109 : List U8 = StructAtIndex 0 Json.324; - inc Json.109; - let Json.110 : U64 = StructAtIndex 1 Json.324; dec Json.324; - let Json.398 : I32 = 34i64; - let Json.397 : U8 = CallByName Num.123 Json.398; - let Json.395 : List U8 = CallByName List.4 Json.109 Json.397; - let Json.396 : List U8 = CallByName Str.12 Json.111; - let Json.392 : List U8 = CallByName List.8 Json.395 Json.396; + let Json.109 : List U8 = StructAtIndex 0 Json.323; + inc Json.109; + let Json.110 : U64 = StructAtIndex 1 Json.323; + dec Json.323; let Json.394 : I32 = 34i64; let Json.393 : U8 = CallByName Num.123 Json.394; - let Json.389 : List U8 = CallByName List.4 Json.392 Json.393; - let Json.391 : I32 = 58i64; - let Json.390 : U8 = CallByName Num.123 Json.391; - let Json.387 : List U8 = CallByName List.4 Json.389 Json.390; - let Json.388 : {} = Struct {}; - let Json.113 : List U8 = CallByName Encode.23 Json.387 Json.112 Json.388; - joinpoint Json.382 Json.114: - let Json.380 : U64 = 1i64; - let Json.379 : U64 = CallByName Num.20 Json.110 Json.380; - let Json.378 : {List U8, U64} = Struct {Json.114, Json.379}; - ret Json.378; + let Json.391 : List U8 = CallByName List.4 Json.109 Json.393; + let Json.392 : List U8 = CallByName Str.12 Json.111; + let Json.388 : List U8 = CallByName List.8 Json.391 Json.392; + let Json.390 : I32 = 34i64; + let Json.389 : U8 = CallByName Num.123 Json.390; + let Json.385 : List U8 = CallByName List.4 Json.388 Json.389; + let Json.387 : I32 = 58i64; + let Json.386 : U8 = CallByName Num.123 Json.387; + let Json.383 : List U8 = CallByName List.4 Json.385 Json.386; + let Json.384 : {} = Struct {}; + let Json.113 : List U8 = CallByName Encode.23 Json.383 Json.112 Json.384; + joinpoint Json.378 Json.114: + let Json.376 : U64 = 1i64; + let Json.375 : U64 = CallByName Num.20 Json.110 Json.376; + let Json.374 : {List U8, U64} = Struct {Json.114, Json.375}; + ret Json.374; in - let Json.386 : U64 = 1i64; - let Json.383 : Int1 = CallByName Num.24 Json.110 Json.386; - if Json.383 then - let Json.385 : I32 = 44i64; - let Json.384 : U8 = CallByName Num.123 Json.385; - let Json.381 : List U8 = CallByName List.4 Json.113 Json.384; - jump Json.382 Json.381; + let Json.382 : U64 = 1i64; + let Json.379 : Int1 = CallByName Num.24 Json.110 Json.382; + if Json.379 then + let Json.381 : I32 = 44i64; + let Json.380 : U8 = CallByName Num.123 Json.381; + let Json.377 : List U8 = CallByName List.4 Json.113 Json.380; + jump Json.378 Json.377; else - jump Json.382 Json.113; + jump Json.378 Json.113; procedure Json.18 (Json.86): - let Json.370 : {Str} = Struct {Json.86}; - let Json.368 : Str = StructAtIndex 0 Json.370; - inc Json.368; - dec Json.370; - let Json.367 : Str = CallByName Encode.22 Json.368; - ret Json.367; + let Json.364 : Str = CallByName Encode.22 Json.86; + ret Json.364; procedure Json.20 (Json.102): - let Json.322 : {List {Str, Str}} = Struct {Json.102}; - let Json.320 : List {Str, Str} = StructAtIndex 0 Json.322; - inc Json.320; - dec Json.322; - let Json.319 : List {Str, Str} = CallByName Encode.22 Json.320; + let Json.319 : List {Str, Str} = CallByName Encode.22 Json.102; ret Json.319; procedure Json.20 (Json.102): - let Json.366 : {List {Str, Str}} = Struct {Json.102}; - let Json.364 : List {Str, Str} = StructAtIndex 0 Json.366; - inc Json.364; - dec Json.366; - let Json.363 : List {Str, Str} = CallByName Encode.22 Json.364; - ret Json.363; + let Json.361 : List {Str, Str} = CallByName Encode.22 Json.102; + ret Json.361; -procedure Json.87 (Json.88, Json.369, #Attr.12): - let Json.412 : {Str} = Struct {#Attr.12}; - let Json.86 : Str = StructAtIndex 0 Json.412; - inc Json.86; - dec Json.412; - let Json.411 : I32 = 34i64; - let Json.410 : U8 = CallByName Num.123 Json.411; - let Json.408 : List U8 = CallByName List.4 Json.88 Json.410; - let Json.409 : List U8 = CallByName Str.12 Json.86; - let Json.405 : List U8 = CallByName List.8 Json.408 Json.409; - let Json.407 : I32 = 34i64; - let Json.406 : U8 = CallByName Num.123 Json.407; - let Json.404 : List U8 = CallByName List.4 Json.405 Json.406; - ret Json.404; +procedure Json.87 (Json.88, Json.366, Json.86): + let Json.406 : I32 = 34i64; + let Json.405 : U8 = CallByName Num.123 Json.406; + let Json.403 : List U8 = CallByName List.4 Json.88 Json.405; + let Json.404 : List U8 = CallByName Str.12 Json.86; + let Json.400 : List U8 = CallByName List.8 Json.403 Json.404; + let Json.402 : I32 = 34i64; + let Json.401 : U8 = CallByName Num.123 Json.402; + let Json.399 : List U8 = CallByName List.4 Json.400 Json.401; + ret Json.399; -procedure List.133 (List.134, List.135, #Attr.12): - let List.436 : {{}} = Struct {#Attr.12}; - let List.132 : {} = StructAtIndex 0 List.436; - let List.435 : {List U8, U64} = CallByName Json.105 List.134 List.135; - let List.434 : [C [], C {List U8, U64}] = TagId(1) List.435; - ret List.434; +procedure List.133 (List.134, List.135, List.132): + let List.434 : {List U8, U64} = CallByName Json.105 List.134 List.135; + let List.433 : [C [], C {List U8, U64}] = TagId(1) List.434; + ret List.433; -procedure List.133 (List.134, List.135, #Attr.12): - let List.519 : {{}} = Struct {#Attr.12}; - let List.132 : {} = StructAtIndex 0 List.519; - let List.518 : {List U8, U64} = CallByName Json.105 List.134 List.135; - let List.517 : [C [], C {List U8, U64}] = TagId(1) List.518; - ret List.517; +procedure List.133 (List.134, List.135, List.132): + let List.515 : {List U8, U64} = CallByName Json.105 List.134 List.135; + let List.514 : [C [], C {List U8, U64}] = TagId(1) List.515; + ret List.514; procedure List.18 (List.130, List.131, List.132): - let List.412 : {{}} = Struct {List.132}; - let List.411 : {} = StructAtIndex 0 List.412; - let List.405 : [C [], C {List U8, U64}] = CallByName List.75 List.130 List.131 List.411; + let List.405 : [C [], C {List U8, U64}] = CallByName List.75 List.130 List.131 List.132; let List.408 : U8 = 1i64; let List.409 : U8 = GetTagId List.405; let List.410 : Int1 = lowlevel Eq List.408 List.409; @@ -277,130 +231,128 @@ procedure List.18 (List.130, List.131, List.132): ret List.407; procedure List.18 (List.130, List.131, List.132): - let List.494 : {{}} = Struct {List.132}; - let List.493 : {} = StructAtIndex 0 List.494; - let List.487 : [C [], C {List U8, U64}] = CallByName List.75 List.130 List.131 List.493; - let List.490 : U8 = 1i64; - let List.491 : U8 = GetTagId List.487; - let List.492 : Int1 = lowlevel Eq List.490 List.491; - if List.492 then - let List.137 : {List U8, U64} = UnionAtIndex (Id 1) (Index 0) List.487; + let List.485 : [C [], C {List U8, U64}] = CallByName List.75 List.130 List.131 List.132; + let List.488 : U8 = 1i64; + let List.489 : U8 = GetTagId List.485; + let List.490 : Int1 = lowlevel Eq List.488 List.489; + if List.490 then + let List.137 : {List U8, U64} = UnionAtIndex (Id 1) (Index 0) List.485; inc List.137; - dec List.487; + dec List.485; ret List.137; else - let List.138 : [] = UnionAtIndex (Id 0) (Index 0) List.487; - dec List.487; - let List.489 : {List U8, U64} = CallByName List.69 List.138; - ret List.489; + let List.138 : [] = UnionAtIndex (Id 0) (Index 0) List.485; + dec List.485; + let List.487 : {List U8, U64} = CallByName List.69 List.138; + ret List.487; procedure List.4 (List.101, List.102): - let List.486 : U64 = 1i64; - let List.485 : List U8 = CallByName List.70 List.101 List.486; - let List.484 : List U8 = CallByName List.71 List.485 List.102; - ret List.484; + let List.484 : U64 = 1i64; + let List.483 : List U8 = CallByName List.70 List.101 List.484; + let List.482 : List U8 = CallByName List.71 List.483 List.102; + ret List.482; procedure List.6 (#Attr.2): let List.385 : U64 = lowlevel ListLen #Attr.2; ret List.385; procedure List.6 (#Attr.2): - let List.414 : U64 = lowlevel ListLen #Attr.2; - ret List.414; + let List.413 : U64 = lowlevel ListLen #Attr.2; + ret List.413; procedure List.6 (#Attr.2): - let List.497 : U64 = lowlevel ListLen #Attr.2; - ret List.497; + let List.494 : U64 = lowlevel ListLen #Attr.2; + ret List.494; procedure List.66 (#Attr.2, #Attr.3): - let List.433 : {Str, Str} = lowlevel ListGetUnsafe #Attr.2 #Attr.3; - ret List.433; + let List.432 : {Str, Str} = lowlevel ListGetUnsafe #Attr.2 #Attr.3; + ret List.432; procedure List.66 (#Attr.2, #Attr.3): - let List.516 : {Str, Str} = lowlevel ListGetUnsafe #Attr.2 #Attr.3; - ret List.516; + let List.513 : {Str, Str} = lowlevel ListGetUnsafe #Attr.2 #Attr.3; + ret List.513; procedure List.69 (#Attr.2): - let List.500 : {List U8, U64} = lowlevel Unreachable #Attr.2; - ret List.500; + let List.497 : {List U8, U64} = lowlevel Unreachable #Attr.2; + ret List.497; procedure List.70 (#Attr.2, #Attr.3): - let List.499 : List U8 = lowlevel ListReserve #Attr.2 #Attr.3; - ret List.499; - -procedure List.71 (#Attr.2, #Attr.3): - let List.498 : List U8 = lowlevel ListAppendUnsafe #Attr.2 #Attr.3; - ret List.498; - -procedure List.75 (List.361, List.362, List.363): - let List.419 : U64 = 0i64; - let List.420 : U64 = CallByName List.6 List.361; - let List.418 : [C [], C {List U8, U64}] = CallByName List.86 List.361 List.362 List.363 List.419 List.420; - ret List.418; - -procedure List.75 (List.361, List.362, List.363): - let List.502 : U64 = 0i64; - let List.503 : U64 = CallByName List.6 List.361; - let List.501 : [C [], C {List U8, U64}] = CallByName List.86 List.361 List.362 List.363 List.502 List.503; - ret List.501; - -procedure List.8 (#Attr.2, #Attr.3): - let List.496 : List U8 = lowlevel ListConcat #Attr.2 #Attr.3; + let List.496 : List U8 = lowlevel ListReserve #Attr.2 #Attr.3; ret List.496; -procedure List.86 (List.450, List.451, List.452, List.453, List.454): - joinpoint List.421 List.364 List.365 List.366 List.367 List.368: - let List.423 : Int1 = CallByName Num.22 List.367 List.368; - if List.423 then - let List.432 : {Str, Str} = CallByName List.66 List.364 List.367; - let List.424 : [C [], C {List U8, U64}] = CallByName List.133 List.365 List.432 List.366; - let List.429 : U8 = 1i64; - let List.430 : U8 = GetTagId List.424; - let List.431 : Int1 = lowlevel Eq List.429 List.430; - if List.431 then - let List.369 : {List U8, U64} = UnionAtIndex (Id 1) (Index 0) List.424; - inc List.369; - dec List.424; - let List.427 : U64 = 1i64; - let List.426 : U64 = CallByName Num.19 List.367 List.427; - jump List.421 List.364 List.369 List.366 List.426 List.368; - else - let List.370 : [] = UnionAtIndex (Id 0) (Index 0) List.424; - dec List.424; - let List.428 : [C [], C {List U8, U64}] = TagId(0) List.370; - ret List.428; - else - let List.422 : [C [], C {List U8, U64}] = TagId(1) List.365; - ret List.422; - in - jump List.421 List.450 List.451 List.452 List.453 List.454; +procedure List.71 (#Attr.2, #Attr.3): + let List.495 : List U8 = lowlevel ListAppendUnsafe #Attr.2 #Attr.3; + ret List.495; -procedure List.86 (List.533, List.534, List.535, List.536, List.537): - joinpoint List.504 List.364 List.365 List.366 List.367 List.368: - let List.506 : Int1 = CallByName Num.22 List.367 List.368; - if List.506 then - let List.515 : {Str, Str} = CallByName List.66 List.364 List.367; - let List.507 : [C [], C {List U8, U64}] = CallByName List.133 List.365 List.515 List.366; - let List.512 : U8 = 1i64; - let List.513 : U8 = GetTagId List.507; - let List.514 : Int1 = lowlevel Eq List.512 List.513; - if List.514 then - let List.369 : {List U8, U64} = UnionAtIndex (Id 1) (Index 0) List.507; +procedure List.75 (List.361, List.362, List.363): + let List.418 : U64 = 0i64; + let List.419 : U64 = CallByName List.6 List.361; + let List.417 : [C [], C {List U8, U64}] = CallByName List.86 List.361 List.362 List.363 List.418 List.419; + ret List.417; + +procedure List.75 (List.361, List.362, List.363): + let List.499 : U64 = 0i64; + let List.500 : U64 = CallByName List.6 List.361; + let List.498 : [C [], C {List U8, U64}] = CallByName List.86 List.361 List.362 List.363 List.499 List.500; + ret List.498; + +procedure List.8 (#Attr.2, #Attr.3): + let List.493 : List U8 = lowlevel ListConcat #Attr.2 #Attr.3; + ret List.493; + +procedure List.86 (List.448, List.449, List.450, List.451, List.452): + joinpoint List.420 List.364 List.365 List.366 List.367 List.368: + let List.422 : Int1 = CallByName Num.22 List.367 List.368; + if List.422 then + let List.431 : {Str, Str} = CallByName List.66 List.364 List.367; + let List.423 : [C [], C {List U8, U64}] = CallByName List.133 List.365 List.431 List.366; + let List.428 : U8 = 1i64; + let List.429 : U8 = GetTagId List.423; + let List.430 : Int1 = lowlevel Eq List.428 List.429; + if List.430 then + let List.369 : {List U8, U64} = UnionAtIndex (Id 1) (Index 0) List.423; inc List.369; - dec List.507; - let List.510 : U64 = 1i64; - let List.509 : U64 = CallByName Num.19 List.367 List.510; - jump List.504 List.364 List.369 List.366 List.509 List.368; + dec List.423; + let List.426 : U64 = 1i64; + let List.425 : U64 = CallByName Num.19 List.367 List.426; + jump List.420 List.364 List.369 List.366 List.425 List.368; else - let List.370 : [] = UnionAtIndex (Id 0) (Index 0) List.507; - dec List.507; - let List.511 : [C [], C {List U8, U64}] = TagId(0) List.370; - ret List.511; + let List.370 : [] = UnionAtIndex (Id 0) (Index 0) List.423; + dec List.423; + let List.427 : [C [], C {List U8, U64}] = TagId(0) List.370; + ret List.427; else - let List.505 : [C [], C {List U8, U64}] = TagId(1) List.365; - ret List.505; + let List.421 : [C [], C {List U8, U64}] = TagId(1) List.365; + ret List.421; in - jump List.504 List.533 List.534 List.535 List.536 List.537; + jump List.420 List.448 List.449 List.450 List.451 List.452; + +procedure List.86 (List.529, List.530, List.531, List.532, List.533): + joinpoint List.501 List.364 List.365 List.366 List.367 List.368: + let List.503 : Int1 = CallByName Num.22 List.367 List.368; + if List.503 then + let List.512 : {Str, Str} = CallByName List.66 List.364 List.367; + let List.504 : [C [], C {List U8, U64}] = CallByName List.133 List.365 List.512 List.366; + let List.509 : U8 = 1i64; + let List.510 : U8 = GetTagId List.504; + let List.511 : Int1 = lowlevel Eq List.509 List.510; + if List.511 then + let List.369 : {List U8, U64} = UnionAtIndex (Id 1) (Index 0) List.504; + inc List.369; + dec List.504; + let List.507 : U64 = 1i64; + let List.506 : U64 = CallByName Num.19 List.367 List.507; + jump List.501 List.364 List.369 List.366 List.506 List.368; + else + let List.370 : [] = UnionAtIndex (Id 0) (Index 0) List.504; + dec List.504; + let List.508 : [C [], C {List U8, U64}] = TagId(0) List.370; + ret List.508; + else + let List.502 : [C [], C {List U8, U64}] = TagId(1) List.365; + ret List.502; + in + jump List.501 List.529 List.530 List.531 List.532 List.533; procedure Num.123 (#Attr.2): let Num.283 : U8 = lowlevel NumIntCast #Attr.2; 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 7b666f85a2..3398a4c5e9 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 @@ -1,23 +1,15 @@ procedure #Derived.0 (#Derived.1): - let #Derived_gen.2 : {Str} = Struct {#Derived.1}; - let #Derived_gen.1 : Str = StructAtIndex 0 #Derived_gen.2; - inc #Derived_gen.1; - dec #Derived_gen.2; - let #Derived_gen.0 : Str = CallByName Encode.22 #Derived_gen.1; + let #Derived_gen.0 : Str = CallByName Encode.22 #Derived.1; ret #Derived_gen.0; -procedure #Derived.2 (#Derived.3, #Derived.4, #Attr.12): - let #Derived_gen.11 : {Str} = Struct {#Attr.12}; - let #Derived.1 : Str = StructAtIndex 0 #Derived_gen.11; - inc #Derived.1; - dec #Derived_gen.11; - let #Derived_gen.8 : Str = "a"; - let #Derived_gen.9 : Str = CallByName Json.18 #Derived.1; - let #Derived_gen.7 : {Str, Str} = Struct {#Derived_gen.8, #Derived_gen.9}; - let #Derived_gen.6 : List {Str, Str} = Array [#Derived_gen.7]; - let #Derived_gen.5 : List {Str, Str} = CallByName Json.20 #Derived_gen.6; - let #Derived_gen.4 : List U8 = CallByName Encode.23 #Derived.3 #Derived_gen.5 #Derived.4; - ret #Derived_gen.4; +procedure #Derived.2 (#Derived.3, #Derived.4, #Derived.1): + let #Derived_gen.7 : Str = "a"; + let #Derived_gen.8 : Str = CallByName Json.18 #Derived.1; + let #Derived_gen.6 : {Str, Str} = Struct {#Derived_gen.7, #Derived_gen.8}; + let #Derived_gen.5 : List {Str, Str} = Array [#Derived_gen.6]; + let #Derived_gen.4 : List {Str, Str} = CallByName Json.20 #Derived_gen.5; + let #Derived_gen.3 : List U8 = CallByName Encode.23 #Derived.3 #Derived_gen.4 #Derived.4; + ret #Derived_gen.3; procedure Encode.22 (Encode.93): ret Encode.93; @@ -50,108 +42,88 @@ procedure Json.1 (): let Json.318 : {} = Struct {}; ret Json.318; -procedure Json.103 (Json.104, Json.321, #Attr.12): - let Json.360 : {List {Str, Str}} = Struct {#Attr.12}; - let Json.102 : List {Str, Str} = StructAtIndex 0 Json.360; - inc Json.102; - dec Json.360; - let Json.359 : I32 = 123i64; - let Json.358 : U8 = CallByName Num.123 Json.359; - let Json.106 : List U8 = CallByName List.4 Json.104 Json.358; - let Json.357 : U64 = CallByName List.6 Json.102; - let Json.334 : {List U8, U64} = Struct {Json.106, Json.357}; - let Json.335 : {} = Struct {}; - let Json.333 : {List U8, U64} = CallByName List.18 Json.102 Json.334 Json.335; +procedure Json.103 (Json.104, Json.321, Json.102): + let Json.357 : I32 = 123i64; + let Json.356 : U8 = CallByName Num.123 Json.357; + let Json.106 : List U8 = CallByName List.4 Json.104 Json.356; + let Json.355 : U64 = CallByName List.6 Json.102; + let Json.332 : {List U8, U64} = Struct {Json.106, Json.355}; + let Json.333 : {} = Struct {}; + let Json.331 : {List U8, U64} = CallByName List.18 Json.102 Json.332 Json.333; dec Json.102; - let Json.108 : List U8 = StructAtIndex 0 Json.333; + let Json.108 : List U8 = StructAtIndex 0 Json.331; inc Json.108; - dec Json.333; - let Json.332 : I32 = 125i64; - let Json.331 : U8 = CallByName Num.123 Json.332; - let Json.330 : List U8 = CallByName List.4 Json.108 Json.331; - ret Json.330; + dec Json.331; + let Json.330 : I32 = 125i64; + let Json.329 : U8 = CallByName Num.123 Json.330; + let Json.328 : List U8 = CallByName List.4 Json.108 Json.329; + ret Json.328; -procedure Json.105 (Json.328, Json.329): - let Json.111 : Str = StructAtIndex 0 Json.329; +procedure Json.105 (Json.326, Json.327): + let Json.111 : Str = StructAtIndex 0 Json.327; inc Json.111; - let Json.112 : Str = StructAtIndex 1 Json.329; + let Json.112 : Str = StructAtIndex 1 Json.327; inc Json.112; - dec Json.329; - let Json.109 : List U8 = StructAtIndex 0 Json.328; + dec Json.327; + let Json.109 : List U8 = StructAtIndex 0 Json.326; inc Json.109; - let Json.110 : U64 = StructAtIndex 1 Json.328; - dec Json.328; - let Json.356 : I32 = 34i64; - let Json.355 : U8 = CallByName Num.123 Json.356; - let Json.353 : List U8 = CallByName List.4 Json.109 Json.355; - let Json.354 : List U8 = CallByName Str.12 Json.111; - let Json.350 : List U8 = CallByName List.8 Json.353 Json.354; - let Json.352 : I32 = 34i64; - let Json.351 : U8 = CallByName Num.123 Json.352; - let Json.347 : List U8 = CallByName List.4 Json.350 Json.351; - let Json.349 : I32 = 58i64; - let Json.348 : U8 = CallByName Num.123 Json.349; - let Json.345 : List U8 = CallByName List.4 Json.347 Json.348; - let Json.346 : {} = Struct {}; - let Json.113 : List U8 = CallByName Encode.23 Json.345 Json.112 Json.346; - joinpoint Json.340 Json.114: - let Json.338 : U64 = 1i64; - let Json.337 : U64 = CallByName Num.20 Json.110 Json.338; - let Json.336 : {List U8, U64} = Struct {Json.114, Json.337}; - ret Json.336; + let Json.110 : U64 = StructAtIndex 1 Json.326; + dec Json.326; + let Json.354 : I32 = 34i64; + let Json.353 : U8 = CallByName Num.123 Json.354; + let Json.351 : List U8 = CallByName List.4 Json.109 Json.353; + let Json.352 : List U8 = CallByName Str.12 Json.111; + let Json.348 : List U8 = CallByName List.8 Json.351 Json.352; + let Json.350 : I32 = 34i64; + let Json.349 : U8 = CallByName Num.123 Json.350; + let Json.345 : List U8 = CallByName List.4 Json.348 Json.349; + let Json.347 : I32 = 58i64; + let Json.346 : U8 = CallByName Num.123 Json.347; + let Json.343 : List U8 = CallByName List.4 Json.345 Json.346; + let Json.344 : {} = Struct {}; + let Json.113 : List U8 = CallByName Encode.23 Json.343 Json.112 Json.344; + joinpoint Json.338 Json.114: + let Json.336 : U64 = 1i64; + let Json.335 : U64 = CallByName Num.20 Json.110 Json.336; + let Json.334 : {List U8, U64} = Struct {Json.114, Json.335}; + ret Json.334; in - let Json.344 : U64 = 1i64; - let Json.341 : Int1 = CallByName Num.24 Json.110 Json.344; - if Json.341 then - let Json.343 : I32 = 44i64; - let Json.342 : U8 = CallByName Num.123 Json.343; - let Json.339 : List U8 = CallByName List.4 Json.113 Json.342; - jump Json.340 Json.339; + let Json.342 : U64 = 1i64; + let Json.339 : Int1 = CallByName Num.24 Json.110 Json.342; + if Json.339 then + let Json.341 : I32 = 44i64; + let Json.340 : U8 = CallByName Num.123 Json.341; + let Json.337 : List U8 = CallByName List.4 Json.113 Json.340; + jump Json.338 Json.337; else - jump Json.340 Json.113; + jump Json.338 Json.113; procedure Json.18 (Json.86): - let Json.326 : {Str} = Struct {Json.86}; - let Json.324 : Str = StructAtIndex 0 Json.326; - inc Json.324; - dec Json.326; - let Json.323 : Str = CallByName Encode.22 Json.324; - ret Json.323; + let Json.322 : Str = CallByName Encode.22 Json.86; + ret Json.322; procedure Json.20 (Json.102): - let Json.322 : {List {Str, Str}} = Struct {Json.102}; - let Json.320 : List {Str, Str} = StructAtIndex 0 Json.322; - inc Json.320; - dec Json.322; - let Json.319 : List {Str, Str} = CallByName Encode.22 Json.320; + let Json.319 : List {Str, Str} = CallByName Encode.22 Json.102; ret Json.319; -procedure Json.87 (Json.88, Json.325, #Attr.12): - let Json.370 : {Str} = Struct {#Attr.12}; - let Json.86 : Str = StructAtIndex 0 Json.370; - inc Json.86; - dec Json.370; - let Json.369 : I32 = 34i64; - let Json.368 : U8 = CallByName Num.123 Json.369; - let Json.366 : List U8 = CallByName List.4 Json.88 Json.368; - let Json.367 : List U8 = CallByName Str.12 Json.86; - let Json.363 : List U8 = CallByName List.8 Json.366 Json.367; - let Json.365 : I32 = 34i64; - let Json.364 : U8 = CallByName Num.123 Json.365; - let Json.362 : List U8 = CallByName List.4 Json.363 Json.364; - ret Json.362; +procedure Json.87 (Json.88, Json.324, Json.86): + let Json.366 : I32 = 34i64; + let Json.365 : U8 = CallByName Num.123 Json.366; + let Json.363 : List U8 = CallByName List.4 Json.88 Json.365; + let Json.364 : List U8 = CallByName Str.12 Json.86; + let Json.360 : List U8 = CallByName List.8 Json.363 Json.364; + let Json.362 : I32 = 34i64; + let Json.361 : U8 = CallByName Num.123 Json.362; + let Json.359 : List U8 = CallByName List.4 Json.360 Json.361; + ret Json.359; -procedure List.133 (List.134, List.135, #Attr.12): - let List.443 : {{}} = Struct {#Attr.12}; - let List.132 : {} = StructAtIndex 0 List.443; - let List.442 : {List U8, U64} = CallByName Json.105 List.134 List.135; - let List.441 : [C [], C {List U8, U64}] = TagId(1) List.442; - ret List.441; +procedure List.133 (List.134, List.135, List.132): + let List.441 : {List U8, U64} = CallByName Json.105 List.134 List.135; + let List.440 : [C [], C {List U8, U64}] = TagId(1) List.441; + ret List.440; procedure List.18 (List.130, List.131, List.132): - let List.418 : {{}} = Struct {List.132}; - let List.417 : {} = StructAtIndex 0 List.418; - let List.411 : [C [], C {List U8, U64}] = CallByName List.75 List.130 List.131 List.417; + let List.411 : [C [], C {List U8, U64}] = CallByName List.75 List.130 List.131 List.132; let List.414 : U8 = 1i64; let List.415 : U8 = GetTagId List.411; let List.416 : Int1 = lowlevel Eq List.414 List.415; @@ -177,61 +149,61 @@ procedure List.6 (#Attr.2): ret List.385; procedure List.6 (#Attr.2): - let List.421 : U64 = lowlevel ListLen #Attr.2; - ret List.421; - -procedure List.66 (#Attr.2, #Attr.3): - let List.440 : {Str, Str} = lowlevel ListGetUnsafe #Attr.2 #Attr.3; - ret List.440; - -procedure List.69 (#Attr.2): - let List.424 : {List U8, U64} = lowlevel Unreachable #Attr.2; - ret List.424; - -procedure List.70 (#Attr.2, #Attr.3): - let List.423 : List U8 = lowlevel ListReserve #Attr.2 #Attr.3; - ret List.423; - -procedure List.71 (#Attr.2, #Attr.3): - let List.422 : List U8 = lowlevel ListAppendUnsafe #Attr.2 #Attr.3; - ret List.422; - -procedure List.75 (List.361, List.362, List.363): - let List.426 : U64 = 0i64; - let List.427 : U64 = CallByName List.6 List.361; - let List.425 : [C [], C {List U8, U64}] = CallByName List.86 List.361 List.362 List.363 List.426 List.427; - ret List.425; - -procedure List.8 (#Attr.2, #Attr.3): - let List.420 : List U8 = lowlevel ListConcat #Attr.2 #Attr.3; + let List.420 : U64 = lowlevel ListLen #Attr.2; ret List.420; -procedure List.86 (List.457, List.458, List.459, List.460, List.461): - joinpoint List.428 List.364 List.365 List.366 List.367 List.368: - let List.430 : Int1 = CallByName Num.22 List.367 List.368; - if List.430 then - let List.439 : {Str, Str} = CallByName List.66 List.364 List.367; - let List.431 : [C [], C {List U8, U64}] = CallByName List.133 List.365 List.439 List.366; - let List.436 : U8 = 1i64; - let List.437 : U8 = GetTagId List.431; - let List.438 : Int1 = lowlevel Eq List.436 List.437; - if List.438 then - let List.369 : {List U8, U64} = UnionAtIndex (Id 1) (Index 0) List.431; +procedure List.66 (#Attr.2, #Attr.3): + let List.439 : {Str, Str} = lowlevel ListGetUnsafe #Attr.2 #Attr.3; + ret List.439; + +procedure List.69 (#Attr.2): + let List.423 : {List U8, U64} = lowlevel Unreachable #Attr.2; + ret List.423; + +procedure List.70 (#Attr.2, #Attr.3): + let List.422 : List U8 = lowlevel ListReserve #Attr.2 #Attr.3; + ret List.422; + +procedure List.71 (#Attr.2, #Attr.3): + let List.421 : List U8 = lowlevel ListAppendUnsafe #Attr.2 #Attr.3; + ret List.421; + +procedure List.75 (List.361, List.362, List.363): + let List.425 : U64 = 0i64; + let List.426 : U64 = CallByName List.6 List.361; + let List.424 : [C [], C {List U8, U64}] = CallByName List.86 List.361 List.362 List.363 List.425 List.426; + ret List.424; + +procedure List.8 (#Attr.2, #Attr.3): + let List.419 : List U8 = lowlevel ListConcat #Attr.2 #Attr.3; + ret List.419; + +procedure List.86 (List.455, List.456, List.457, List.458, List.459): + joinpoint List.427 List.364 List.365 List.366 List.367 List.368: + let List.429 : Int1 = CallByName Num.22 List.367 List.368; + if List.429 then + let List.438 : {Str, Str} = CallByName List.66 List.364 List.367; + let List.430 : [C [], C {List U8, U64}] = CallByName List.133 List.365 List.438 List.366; + let List.435 : U8 = 1i64; + let List.436 : U8 = GetTagId List.430; + let List.437 : Int1 = lowlevel Eq List.435 List.436; + if List.437 then + let List.369 : {List U8, U64} = UnionAtIndex (Id 1) (Index 0) List.430; inc List.369; - dec List.431; - let List.434 : U64 = 1i64; - let List.433 : U64 = CallByName Num.19 List.367 List.434; - jump List.428 List.364 List.369 List.366 List.433 List.368; + dec List.430; + let List.433 : U64 = 1i64; + let List.432 : U64 = CallByName Num.19 List.367 List.433; + jump List.427 List.364 List.369 List.366 List.432 List.368; else - let List.370 : [] = UnionAtIndex (Id 0) (Index 0) List.431; - dec List.431; - let List.435 : [C [], C {List U8, U64}] = TagId(0) List.370; - ret List.435; + let List.370 : [] = UnionAtIndex (Id 0) (Index 0) List.430; + dec List.430; + let List.434 : [C [], C {List U8, U64}] = TagId(0) List.370; + ret List.434; else - let List.429 : [C [], C {List U8, U64}] = TagId(1) List.365; - ret List.429; + let List.428 : [C [], C {List U8, U64}] = TagId(1) List.365; + ret List.428; in - jump List.428 List.457 List.458 List.459 List.460 List.461; + jump List.427 List.455 List.456 List.457 List.458 List.459; procedure Num.123 (#Attr.2): let Num.264 : U8 = lowlevel NumIntCast #Attr.2; 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 b53de6ab54..0aff7f2c04 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 @@ -1,31 +1,23 @@ procedure #Derived.0 (#Derived.1): - let #Derived_gen.2 : {{Str, Str}} = Struct {#Derived.1}; - let #Derived_gen.1 : {Str, Str} = StructAtIndex 0 #Derived_gen.2; - inc #Derived_gen.1; - dec #Derived_gen.2; - let #Derived_gen.0 : {Str, Str} = CallByName Encode.22 #Derived_gen.1; + let #Derived_gen.0 : {Str, Str} = CallByName Encode.22 #Derived.1; ret #Derived_gen.0; -procedure #Derived.2 (#Derived.3, #Derived.4, #Attr.12): - let #Derived_gen.15 : {{Str, Str}} = Struct {#Attr.12}; - let #Derived.1 : {Str, Str} = StructAtIndex 0 #Derived_gen.15; - inc #Derived.1; - dec #Derived_gen.15; - let #Derived_gen.12 : Str = "a"; - let #Derived_gen.14 : Str = StructAtIndex 0 #Derived.1; - inc #Derived_gen.14; - let #Derived_gen.13 : Str = CallByName Json.18 #Derived_gen.14; - let #Derived_gen.7 : {Str, Str} = Struct {#Derived_gen.12, #Derived_gen.13}; - let #Derived_gen.9 : Str = "b"; - let #Derived_gen.11 : Str = StructAtIndex 1 #Derived.1; - inc #Derived_gen.11; +procedure #Derived.2 (#Derived.3, #Derived.4, #Derived.1): + let #Derived_gen.11 : Str = "a"; + let #Derived_gen.13 : Str = StructAtIndex 0 #Derived.1; + inc #Derived_gen.13; + let #Derived_gen.12 : Str = CallByName Json.18 #Derived_gen.13; + let #Derived_gen.6 : {Str, Str} = Struct {#Derived_gen.11, #Derived_gen.12}; + let #Derived_gen.8 : Str = "b"; + let #Derived_gen.10 : Str = StructAtIndex 1 #Derived.1; + inc #Derived_gen.10; dec #Derived.1; - let #Derived_gen.10 : Str = CallByName Json.18 #Derived_gen.11; - let #Derived_gen.8 : {Str, Str} = Struct {#Derived_gen.9, #Derived_gen.10}; - let #Derived_gen.6 : List {Str, Str} = Array [#Derived_gen.7, #Derived_gen.8]; - let #Derived_gen.5 : List {Str, Str} = CallByName Json.20 #Derived_gen.6; - let #Derived_gen.4 : List U8 = CallByName Encode.23 #Derived.3 #Derived_gen.5 #Derived.4; - ret #Derived_gen.4; + let #Derived_gen.9 : Str = CallByName Json.18 #Derived_gen.10; + let #Derived_gen.7 : {Str, Str} = Struct {#Derived_gen.8, #Derived_gen.9}; + let #Derived_gen.5 : List {Str, Str} = Array [#Derived_gen.6, #Derived_gen.7]; + let #Derived_gen.4 : List {Str, Str} = CallByName Json.20 #Derived_gen.5; + let #Derived_gen.3 : List U8 = CallByName Encode.23 #Derived.3 #Derived_gen.4 #Derived.4; + ret #Derived_gen.3; procedure Encode.22 (Encode.93): ret Encode.93; @@ -58,108 +50,88 @@ procedure Json.1 (): let Json.318 : {} = Struct {}; ret Json.318; -procedure Json.103 (Json.104, Json.321, #Attr.12): - let Json.364 : {List {Str, Str}} = Struct {#Attr.12}; - let Json.102 : List {Str, Str} = StructAtIndex 0 Json.364; - inc Json.102; - dec Json.364; - let Json.363 : I32 = 123i64; - let Json.362 : U8 = CallByName Num.123 Json.363; - let Json.106 : List U8 = CallByName List.4 Json.104 Json.362; - let Json.361 : U64 = CallByName List.6 Json.102; - let Json.338 : {List U8, U64} = Struct {Json.106, Json.361}; - let Json.339 : {} = Struct {}; - let Json.337 : {List U8, U64} = CallByName List.18 Json.102 Json.338 Json.339; - dec Json.102; - let Json.108 : List U8 = StructAtIndex 0 Json.337; - inc Json.108; - dec Json.337; - let Json.336 : I32 = 125i64; - let Json.335 : U8 = CallByName Num.123 Json.336; - let Json.334 : List U8 = CallByName List.4 Json.108 Json.335; - ret Json.334; - -procedure Json.105 (Json.332, Json.333): - let Json.111 : Str = StructAtIndex 0 Json.333; - inc Json.111; - let Json.112 : Str = StructAtIndex 1 Json.333; - inc Json.112; - dec Json.333; - let Json.109 : List U8 = StructAtIndex 0 Json.332; - inc Json.109; - let Json.110 : U64 = StructAtIndex 1 Json.332; - dec Json.332; - let Json.360 : I32 = 34i64; +procedure Json.103 (Json.104, Json.321, Json.102): + let Json.360 : I32 = 123i64; let Json.359 : U8 = CallByName Num.123 Json.360; - let Json.357 : List U8 = CallByName List.4 Json.109 Json.359; - let Json.358 : List U8 = CallByName Str.12 Json.111; - let Json.354 : List U8 = CallByName List.8 Json.357 Json.358; - let Json.356 : I32 = 34i64; - let Json.355 : U8 = CallByName Num.123 Json.356; - let Json.351 : List U8 = CallByName List.4 Json.354 Json.355; - let Json.353 : I32 = 58i64; + let Json.106 : List U8 = CallByName List.4 Json.104 Json.359; + let Json.358 : U64 = CallByName List.6 Json.102; + let Json.335 : {List U8, U64} = Struct {Json.106, Json.358}; + let Json.336 : {} = Struct {}; + let Json.334 : {List U8, U64} = CallByName List.18 Json.102 Json.335 Json.336; + dec Json.102; + let Json.108 : List U8 = StructAtIndex 0 Json.334; + inc Json.108; + dec Json.334; + let Json.333 : I32 = 125i64; + let Json.332 : U8 = CallByName Num.123 Json.333; + let Json.331 : List U8 = CallByName List.4 Json.108 Json.332; + ret Json.331; + +procedure Json.105 (Json.329, Json.330): + let Json.111 : Str = StructAtIndex 0 Json.330; + inc Json.111; + let Json.112 : Str = StructAtIndex 1 Json.330; + inc Json.112; + dec Json.330; + let Json.109 : List U8 = StructAtIndex 0 Json.329; + inc Json.109; + let Json.110 : U64 = StructAtIndex 1 Json.329; + dec Json.329; + let Json.357 : I32 = 34i64; + let Json.356 : U8 = CallByName Num.123 Json.357; + let Json.354 : List U8 = CallByName List.4 Json.109 Json.356; + let Json.355 : List U8 = CallByName Str.12 Json.111; + let Json.351 : List U8 = CallByName List.8 Json.354 Json.355; + let Json.353 : I32 = 34i64; let Json.352 : U8 = CallByName Num.123 Json.353; - let Json.349 : List U8 = CallByName List.4 Json.351 Json.352; - let Json.350 : {} = Struct {}; - let Json.113 : List U8 = CallByName Encode.23 Json.349 Json.112 Json.350; - joinpoint Json.344 Json.114: - let Json.342 : U64 = 1i64; - let Json.341 : U64 = CallByName Num.20 Json.110 Json.342; - let Json.340 : {List U8, U64} = Struct {Json.114, Json.341}; - ret Json.340; + let Json.348 : List U8 = CallByName List.4 Json.351 Json.352; + let Json.350 : I32 = 58i64; + let Json.349 : U8 = CallByName Num.123 Json.350; + let Json.346 : List U8 = CallByName List.4 Json.348 Json.349; + let Json.347 : {} = Struct {}; + let Json.113 : List U8 = CallByName Encode.23 Json.346 Json.112 Json.347; + joinpoint Json.341 Json.114: + let Json.339 : U64 = 1i64; + let Json.338 : U64 = CallByName Num.20 Json.110 Json.339; + let Json.337 : {List U8, U64} = Struct {Json.114, Json.338}; + ret Json.337; in - let Json.348 : U64 = 1i64; - let Json.345 : Int1 = CallByName Num.24 Json.110 Json.348; - if Json.345 then - let Json.347 : I32 = 44i64; - let Json.346 : U8 = CallByName Num.123 Json.347; - let Json.343 : List U8 = CallByName List.4 Json.113 Json.346; - jump Json.344 Json.343; + let Json.345 : U64 = 1i64; + let Json.342 : Int1 = CallByName Num.24 Json.110 Json.345; + if Json.342 then + let Json.344 : I32 = 44i64; + let Json.343 : U8 = CallByName Num.123 Json.344; + let Json.340 : List U8 = CallByName List.4 Json.113 Json.343; + jump Json.341 Json.340; else - jump Json.344 Json.113; + jump Json.341 Json.113; procedure Json.18 (Json.86): - let Json.330 : {Str} = Struct {Json.86}; - let Json.328 : Str = StructAtIndex 0 Json.330; - inc Json.328; - dec Json.330; - let Json.327 : Str = CallByName Encode.22 Json.328; - ret Json.327; + let Json.325 : Str = CallByName Encode.22 Json.86; + ret Json.325; procedure Json.20 (Json.102): - let Json.322 : {List {Str, Str}} = Struct {Json.102}; - let Json.320 : List {Str, Str} = StructAtIndex 0 Json.322; - inc Json.320; - dec Json.322; - let Json.319 : List {Str, Str} = CallByName Encode.22 Json.320; + let Json.319 : List {Str, Str} = CallByName Encode.22 Json.102; ret Json.319; -procedure Json.87 (Json.88, Json.325, #Attr.12): - let Json.374 : {Str} = Struct {#Attr.12}; - let Json.86 : Str = StructAtIndex 0 Json.374; - inc Json.86; - dec Json.374; - let Json.373 : I32 = 34i64; - let Json.372 : U8 = CallByName Num.123 Json.373; - let Json.370 : List U8 = CallByName List.4 Json.88 Json.372; - let Json.371 : List U8 = CallByName Str.12 Json.86; - let Json.367 : List U8 = CallByName List.8 Json.370 Json.371; +procedure Json.87 (Json.88, Json.324, Json.86): let Json.369 : I32 = 34i64; let Json.368 : U8 = CallByName Num.123 Json.369; - let Json.366 : List U8 = CallByName List.4 Json.367 Json.368; - ret Json.366; + let Json.366 : List U8 = CallByName List.4 Json.88 Json.368; + let Json.367 : List U8 = CallByName Str.12 Json.86; + let Json.363 : List U8 = CallByName List.8 Json.366 Json.367; + let Json.365 : I32 = 34i64; + let Json.364 : U8 = CallByName Num.123 Json.365; + let Json.362 : List U8 = CallByName List.4 Json.363 Json.364; + ret Json.362; -procedure List.133 (List.134, List.135, #Attr.12): - let List.443 : {{}} = Struct {#Attr.12}; - let List.132 : {} = StructAtIndex 0 List.443; - let List.442 : {List U8, U64} = CallByName Json.105 List.134 List.135; - let List.441 : [C [], C {List U8, U64}] = TagId(1) List.442; - ret List.441; +procedure List.133 (List.134, List.135, List.132): + let List.441 : {List U8, U64} = CallByName Json.105 List.134 List.135; + let List.440 : [C [], C {List U8, U64}] = TagId(1) List.441; + ret List.440; procedure List.18 (List.130, List.131, List.132): - let List.418 : {{}} = Struct {List.132}; - let List.417 : {} = StructAtIndex 0 List.418; - let List.411 : [C [], C {List U8, U64}] = CallByName List.75 List.130 List.131 List.417; + let List.411 : [C [], C {List U8, U64}] = CallByName List.75 List.130 List.131 List.132; let List.414 : U8 = 1i64; let List.415 : U8 = GetTagId List.411; let List.416 : Int1 = lowlevel Eq List.414 List.415; @@ -185,61 +157,61 @@ procedure List.6 (#Attr.2): ret List.385; procedure List.6 (#Attr.2): - let List.421 : U64 = lowlevel ListLen #Attr.2; - ret List.421; - -procedure List.66 (#Attr.2, #Attr.3): - let List.440 : {Str, Str} = lowlevel ListGetUnsafe #Attr.2 #Attr.3; - ret List.440; - -procedure List.69 (#Attr.2): - let List.424 : {List U8, U64} = lowlevel Unreachable #Attr.2; - ret List.424; - -procedure List.70 (#Attr.2, #Attr.3): - let List.423 : List U8 = lowlevel ListReserve #Attr.2 #Attr.3; - ret List.423; - -procedure List.71 (#Attr.2, #Attr.3): - let List.422 : List U8 = lowlevel ListAppendUnsafe #Attr.2 #Attr.3; - ret List.422; - -procedure List.75 (List.361, List.362, List.363): - let List.426 : U64 = 0i64; - let List.427 : U64 = CallByName List.6 List.361; - let List.425 : [C [], C {List U8, U64}] = CallByName List.86 List.361 List.362 List.363 List.426 List.427; - ret List.425; - -procedure List.8 (#Attr.2, #Attr.3): - let List.420 : List U8 = lowlevel ListConcat #Attr.2 #Attr.3; + let List.420 : U64 = lowlevel ListLen #Attr.2; ret List.420; -procedure List.86 (List.457, List.458, List.459, List.460, List.461): - joinpoint List.428 List.364 List.365 List.366 List.367 List.368: - let List.430 : Int1 = CallByName Num.22 List.367 List.368; - if List.430 then - let List.439 : {Str, Str} = CallByName List.66 List.364 List.367; - let List.431 : [C [], C {List U8, U64}] = CallByName List.133 List.365 List.439 List.366; - let List.436 : U8 = 1i64; - let List.437 : U8 = GetTagId List.431; - let List.438 : Int1 = lowlevel Eq List.436 List.437; - if List.438 then - let List.369 : {List U8, U64} = UnionAtIndex (Id 1) (Index 0) List.431; +procedure List.66 (#Attr.2, #Attr.3): + let List.439 : {Str, Str} = lowlevel ListGetUnsafe #Attr.2 #Attr.3; + ret List.439; + +procedure List.69 (#Attr.2): + let List.423 : {List U8, U64} = lowlevel Unreachable #Attr.2; + ret List.423; + +procedure List.70 (#Attr.2, #Attr.3): + let List.422 : List U8 = lowlevel ListReserve #Attr.2 #Attr.3; + ret List.422; + +procedure List.71 (#Attr.2, #Attr.3): + let List.421 : List U8 = lowlevel ListAppendUnsafe #Attr.2 #Attr.3; + ret List.421; + +procedure List.75 (List.361, List.362, List.363): + let List.425 : U64 = 0i64; + let List.426 : U64 = CallByName List.6 List.361; + let List.424 : [C [], C {List U8, U64}] = CallByName List.86 List.361 List.362 List.363 List.425 List.426; + ret List.424; + +procedure List.8 (#Attr.2, #Attr.3): + let List.419 : List U8 = lowlevel ListConcat #Attr.2 #Attr.3; + ret List.419; + +procedure List.86 (List.455, List.456, List.457, List.458, List.459): + joinpoint List.427 List.364 List.365 List.366 List.367 List.368: + let List.429 : Int1 = CallByName Num.22 List.367 List.368; + if List.429 then + let List.438 : {Str, Str} = CallByName List.66 List.364 List.367; + let List.430 : [C [], C {List U8, U64}] = CallByName List.133 List.365 List.438 List.366; + let List.435 : U8 = 1i64; + let List.436 : U8 = GetTagId List.430; + let List.437 : Int1 = lowlevel Eq List.435 List.436; + if List.437 then + let List.369 : {List U8, U64} = UnionAtIndex (Id 1) (Index 0) List.430; inc List.369; - dec List.431; - let List.434 : U64 = 1i64; - let List.433 : U64 = CallByName Num.19 List.367 List.434; - jump List.428 List.364 List.369 List.366 List.433 List.368; + dec List.430; + let List.433 : U64 = 1i64; + let List.432 : U64 = CallByName Num.19 List.367 List.433; + jump List.427 List.364 List.369 List.366 List.432 List.368; else - let List.370 : [] = UnionAtIndex (Id 0) (Index 0) List.431; - dec List.431; - let List.435 : [C [], C {List U8, U64}] = TagId(0) List.370; - ret List.435; + let List.370 : [] = UnionAtIndex (Id 0) (Index 0) List.430; + dec List.430; + let List.434 : [C [], C {List U8, U64}] = TagId(0) List.370; + ret List.434; else - let List.429 : [C [], C {List U8, U64}] = TagId(1) List.365; - ret List.429; + let List.428 : [C [], C {List U8, U64}] = TagId(1) List.365; + ret List.428; in - jump List.428 List.457 List.458 List.459 List.460 List.461; + jump List.427 List.455 List.456 List.457 List.458 List.459; procedure Num.123 (#Attr.2): let Num.264 : U8 = lowlevel NumIntCast #Attr.2; diff --git a/crates/compiler/test_mono/generated/encode_derived_string.txt b/crates/compiler/test_mono/generated/encode_derived_string.txt index ba9effd84c..5fd131fd3f 100644 --- a/crates/compiler/test_mono/generated/encode_derived_string.txt +++ b/crates/compiler/test_mono/generated/encode_derived_string.txt @@ -16,27 +16,19 @@ procedure Json.1 (): ret Json.318; procedure Json.18 (Json.86): - let Json.322 : {Str} = Struct {Json.86}; - let Json.320 : Str = StructAtIndex 0 Json.322; - inc Json.320; - dec Json.322; - let Json.319 : Str = CallByName Encode.22 Json.320; + let Json.319 : Str = CallByName Encode.22 Json.86; ret Json.319; -procedure Json.87 (Json.88, Json.321, #Attr.12): - let Json.332 : {Str} = Struct {#Attr.12}; - let Json.86 : Str = StructAtIndex 0 Json.332; - inc Json.86; - dec Json.332; - let Json.331 : I32 = 34i64; - let Json.330 : U8 = CallByName Num.123 Json.331; - let Json.328 : List U8 = CallByName List.4 Json.88 Json.330; - let Json.329 : List U8 = CallByName Str.12 Json.86; - let Json.325 : List U8 = CallByName List.8 Json.328 Json.329; - let Json.327 : I32 = 34i64; - let Json.326 : U8 = CallByName Num.123 Json.327; - let Json.324 : List U8 = CallByName List.4 Json.325 Json.326; - ret Json.324; +procedure Json.87 (Json.88, Json.321, Json.86): + let Json.330 : I32 = 34i64; + let Json.329 : U8 = CallByName Num.123 Json.330; + let Json.327 : List U8 = CallByName List.4 Json.88 Json.329; + let Json.328 : List U8 = CallByName Str.12 Json.86; + let Json.324 : List U8 = CallByName List.8 Json.327 Json.328; + let Json.326 : I32 = 34i64; + let Json.325 : U8 = CallByName Num.123 Json.326; + let Json.323 : List U8 = CallByName List.4 Json.324 Json.325; + ret Json.323; procedure List.4 (List.101, List.102): let List.392 : U64 = 1i64; 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 1bba624c75..1dab5efd61 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 @@ -1,25 +1,17 @@ procedure #Derived.0 (#Derived.1): - let #Derived_gen.2 : {Str} = Struct {#Derived.1}; - let #Derived_gen.1 : Str = StructAtIndex 0 #Derived_gen.2; - inc #Derived_gen.1; - dec #Derived_gen.2; - let #Derived_gen.0 : Str = CallByName Encode.22 #Derived_gen.1; + let #Derived_gen.0 : Str = CallByName Encode.22 #Derived.1; ret #Derived_gen.0; -procedure #Derived.3 (#Derived.4, #Derived.5, #Attr.12): - let #Derived_gen.11 : {Str} = Struct {#Attr.12}; - let #Derived.1 : Str = StructAtIndex 0 #Derived_gen.11; - inc #Derived.1; - dec #Derived_gen.11; - joinpoint #Derived_gen.6 #Derived_gen.5: - let #Derived_gen.4 : List U8 = CallByName Encode.23 #Derived.4 #Derived_gen.5 #Derived.5; - ret #Derived_gen.4; +procedure #Derived.3 (#Derived.4, #Derived.5, #Derived.1): + joinpoint #Derived_gen.5 #Derived_gen.4: + let #Derived_gen.3 : List U8 = CallByName Encode.23 #Derived.4 #Derived_gen.4 #Derived.5; + ret #Derived_gen.3; in - let #Derived_gen.8 : Str = "A"; - let #Derived_gen.10 : Str = CallByName Json.18 #Derived.1; - let #Derived_gen.9 : List Str = Array [#Derived_gen.10]; - let #Derived_gen.7 : {Str, List Str} = CallByName Json.21 #Derived_gen.8 #Derived_gen.9; - jump #Derived_gen.6 #Derived_gen.7; + let #Derived_gen.7 : Str = "A"; + let #Derived_gen.9 : Str = CallByName Json.18 #Derived.1; + let #Derived_gen.8 : List Str = Array [#Derived_gen.9]; + let #Derived_gen.6 : {Str, List Str} = CallByName Json.21 #Derived_gen.7 #Derived_gen.8; + jump #Derived_gen.5 #Derived_gen.6; procedure Encode.22 (Encode.93): ret Encode.93; @@ -58,68 +50,64 @@ procedure Json.117 (Json.118, Json.321, #Attr.12): let Json.115 : Str = StructAtIndex 0 #Attr.12; inc Json.115; dec #Attr.12; - let Json.363 : I32 = 123i64; - let Json.362 : U8 = CallByName Num.123 Json.363; - let Json.359 : List U8 = CallByName List.4 Json.118 Json.362; - let Json.361 : I32 = 34i64; - let Json.360 : U8 = CallByName Num.123 Json.361; - let Json.357 : List U8 = CallByName List.4 Json.359 Json.360; - let Json.358 : List U8 = CallByName Str.12 Json.115; - let Json.354 : List U8 = CallByName List.8 Json.357 Json.358; - let Json.356 : I32 = 34i64; - let Json.355 : U8 = CallByName Num.123 Json.356; - let Json.351 : List U8 = CallByName List.4 Json.354 Json.355; - let Json.353 : I32 = 58i64; - let Json.352 : U8 = CallByName Num.123 Json.353; - let Json.348 : List U8 = CallByName List.4 Json.351 Json.352; - let Json.350 : I32 = 91i64; - let Json.349 : U8 = CallByName Num.123 Json.350; - let Json.120 : List U8 = CallByName List.4 Json.348 Json.349; - let Json.347 : U64 = CallByName List.6 Json.116; - let Json.335 : {List U8, U64} = Struct {Json.120, Json.347}; - let Json.336 : {} = Struct {}; - let Json.334 : {List U8, U64} = CallByName List.18 Json.116 Json.335 Json.336; + let Json.362 : I32 = 123i64; + let Json.361 : U8 = CallByName Num.123 Json.362; + let Json.358 : List U8 = CallByName List.4 Json.118 Json.361; + let Json.360 : I32 = 34i64; + let Json.359 : U8 = CallByName Num.123 Json.360; + let Json.356 : List U8 = CallByName List.4 Json.358 Json.359; + let Json.357 : List U8 = CallByName Str.12 Json.115; + let Json.353 : List U8 = CallByName List.8 Json.356 Json.357; + let Json.355 : I32 = 34i64; + let Json.354 : U8 = CallByName Num.123 Json.355; + let Json.350 : List U8 = CallByName List.4 Json.353 Json.354; + let Json.352 : I32 = 58i64; + let Json.351 : U8 = CallByName Num.123 Json.352; + let Json.347 : List U8 = CallByName List.4 Json.350 Json.351; + let Json.349 : I32 = 91i64; + let Json.348 : U8 = CallByName Num.123 Json.349; + let Json.120 : List U8 = CallByName List.4 Json.347 Json.348; + let Json.346 : U64 = CallByName List.6 Json.116; + let Json.334 : {List U8, U64} = Struct {Json.120, Json.346}; + let Json.335 : {} = Struct {}; + let Json.333 : {List U8, U64} = CallByName List.18 Json.116 Json.334 Json.335; dec Json.116; - let Json.122 : List U8 = StructAtIndex 0 Json.334; + let Json.122 : List U8 = StructAtIndex 0 Json.333; inc Json.122; - dec Json.334; - let Json.333 : I32 = 93i64; - let Json.332 : U8 = CallByName Num.123 Json.333; - let Json.329 : List U8 = CallByName List.4 Json.122 Json.332; - let Json.331 : I32 = 125i64; - let Json.330 : U8 = CallByName Num.123 Json.331; - let Json.328 : List U8 = CallByName List.4 Json.329 Json.330; - ret Json.328; + dec Json.333; + let Json.332 : I32 = 93i64; + let Json.331 : U8 = CallByName Num.123 Json.332; + let Json.328 : List U8 = CallByName List.4 Json.122 Json.331; + let Json.330 : I32 = 125i64; + let Json.329 : U8 = CallByName Num.123 Json.330; + let Json.327 : List U8 = CallByName List.4 Json.328 Json.329; + ret Json.327; -procedure Json.119 (Json.327, Json.125): - let Json.123 : List U8 = StructAtIndex 0 Json.327; +procedure Json.119 (Json.326, Json.125): + let Json.123 : List U8 = StructAtIndex 0 Json.326; inc Json.123; - let Json.124 : U64 = StructAtIndex 1 Json.327; - dec Json.327; - let Json.346 : {} = Struct {}; - let Json.126 : List U8 = CallByName Encode.23 Json.123 Json.125 Json.346; - joinpoint Json.341 Json.127: - let Json.339 : U64 = 1i64; - let Json.338 : U64 = CallByName Num.20 Json.124 Json.339; - let Json.337 : {List U8, U64} = Struct {Json.127, Json.338}; - ret Json.337; + let Json.124 : U64 = StructAtIndex 1 Json.326; + dec Json.326; + let Json.345 : {} = Struct {}; + let Json.126 : List U8 = CallByName Encode.23 Json.123 Json.125 Json.345; + joinpoint Json.340 Json.127: + let Json.338 : U64 = 1i64; + let Json.337 : U64 = CallByName Num.20 Json.124 Json.338; + let Json.336 : {List U8, U64} = Struct {Json.127, Json.337}; + ret Json.336; in - let Json.345 : U64 = 1i64; - let Json.342 : Int1 = CallByName Num.24 Json.124 Json.345; - if Json.342 then - let Json.344 : I32 = 44i64; - let Json.343 : U8 = CallByName Num.123 Json.344; - let Json.340 : List U8 = CallByName List.4 Json.126 Json.343; - jump Json.341 Json.340; + let Json.344 : U64 = 1i64; + let Json.341 : Int1 = CallByName Num.24 Json.124 Json.344; + if Json.341 then + let Json.343 : I32 = 44i64; + let Json.342 : U8 = CallByName Num.123 Json.343; + let Json.339 : List U8 = CallByName List.4 Json.126 Json.342; + jump Json.340 Json.339; else - jump Json.341 Json.126; + jump Json.340 Json.126; procedure Json.18 (Json.86): - let Json.325 : {Str} = Struct {Json.86}; - let Json.323 : Str = StructAtIndex 0 Json.325; - inc Json.323; - dec Json.325; - let Json.322 : Str = CallByName Encode.22 Json.323; + let Json.322 : Str = CallByName Encode.22 Json.86; ret Json.322; procedure Json.21 (Json.115, Json.116): @@ -127,32 +115,24 @@ procedure Json.21 (Json.115, Json.116): let Json.319 : {Str, List Str} = CallByName Encode.22 Json.320; ret Json.319; -procedure Json.87 (Json.88, Json.324, #Attr.12): - let Json.373 : {Str} = Struct {#Attr.12}; - let Json.86 : Str = StructAtIndex 0 Json.373; - inc Json.86; - dec Json.373; - let Json.372 : I32 = 34i64; - let Json.371 : U8 = CallByName Num.123 Json.372; - let Json.369 : List U8 = CallByName List.4 Json.88 Json.371; - let Json.370 : List U8 = CallByName Str.12 Json.86; - let Json.366 : List U8 = CallByName List.8 Json.369 Json.370; - let Json.368 : I32 = 34i64; - let Json.367 : U8 = CallByName Num.123 Json.368; - let Json.365 : List U8 = CallByName List.4 Json.366 Json.367; - ret Json.365; +procedure Json.87 (Json.88, Json.324, Json.86): + let Json.371 : I32 = 34i64; + let Json.370 : U8 = CallByName Num.123 Json.371; + let Json.368 : List U8 = CallByName List.4 Json.88 Json.370; + let Json.369 : List U8 = CallByName Str.12 Json.86; + let Json.365 : List U8 = CallByName List.8 Json.368 Json.369; + let Json.367 : I32 = 34i64; + let Json.366 : U8 = CallByName Num.123 Json.367; + let Json.364 : List U8 = CallByName List.4 Json.365 Json.366; + ret Json.364; -procedure List.133 (List.134, List.135, #Attr.12): - let List.449 : {{}} = Struct {#Attr.12}; - let List.132 : {} = StructAtIndex 0 List.449; - let List.448 : {List U8, U64} = CallByName Json.119 List.134 List.135; - let List.447 : [C [], C {List U8, U64}] = TagId(1) List.448; - ret List.447; +procedure List.133 (List.134, List.135, List.132): + let List.447 : {List U8, U64} = CallByName Json.119 List.134 List.135; + let List.446 : [C [], C {List U8, U64}] = TagId(1) List.447; + ret List.446; procedure List.18 (List.130, List.131, List.132): - let List.424 : {{}} = Struct {List.132}; - let List.423 : {} = StructAtIndex 0 List.424; - let List.417 : [C [], C {List U8, U64}] = CallByName List.75 List.130 List.131 List.423; + let List.417 : [C [], C {List U8, U64}] = CallByName List.75 List.130 List.131 List.132; let List.420 : U8 = 1i64; let List.421 : U8 = GetTagId List.417; let List.422 : Int1 = lowlevel Eq List.420 List.421; @@ -178,61 +158,61 @@ procedure List.6 (#Attr.2): ret List.385; procedure List.6 (#Attr.2): - let List.425 : U64 = lowlevel ListLen #Attr.2; - ret List.425; + let List.424 : U64 = lowlevel ListLen #Attr.2; + ret List.424; procedure List.66 (#Attr.2, #Attr.3): - let List.446 : Str = lowlevel ListGetUnsafe #Attr.2 #Attr.3; - ret List.446; + let List.445 : Str = lowlevel ListGetUnsafe #Attr.2 #Attr.3; + ret List.445; procedure List.69 (#Attr.2): - let List.430 : {List U8, U64} = lowlevel Unreachable #Attr.2; - ret List.430; - -procedure List.70 (#Attr.2, #Attr.3): - let List.429 : List U8 = lowlevel ListReserve #Attr.2 #Attr.3; + let List.429 : {List U8, U64} = lowlevel Unreachable #Attr.2; ret List.429; -procedure List.71 (#Attr.2, #Attr.3): - let List.428 : List U8 = lowlevel ListAppendUnsafe #Attr.2 #Attr.3; +procedure List.70 (#Attr.2, #Attr.3): + let List.428 : List U8 = lowlevel ListReserve #Attr.2 #Attr.3; ret List.428; -procedure List.75 (List.361, List.362, List.363): - let List.432 : U64 = 0i64; - let List.433 : U64 = CallByName List.6 List.361; - let List.431 : [C [], C {List U8, U64}] = CallByName List.86 List.361 List.362 List.363 List.432 List.433; - ret List.431; - -procedure List.8 (#Attr.2, #Attr.3): - let List.427 : List U8 = lowlevel ListConcat #Attr.2 #Attr.3; +procedure List.71 (#Attr.2, #Attr.3): + let List.427 : List U8 = lowlevel ListAppendUnsafe #Attr.2 #Attr.3; ret List.427; -procedure List.86 (List.463, List.464, List.465, List.466, List.467): - joinpoint List.434 List.364 List.365 List.366 List.367 List.368: - let List.436 : Int1 = CallByName Num.22 List.367 List.368; - if List.436 then - let List.445 : Str = CallByName List.66 List.364 List.367; - let List.437 : [C [], C {List U8, U64}] = CallByName List.133 List.365 List.445 List.366; - let List.442 : U8 = 1i64; - let List.443 : U8 = GetTagId List.437; - let List.444 : Int1 = lowlevel Eq List.442 List.443; - if List.444 then - let List.369 : {List U8, U64} = UnionAtIndex (Id 1) (Index 0) List.437; +procedure List.75 (List.361, List.362, List.363): + let List.431 : U64 = 0i64; + let List.432 : U64 = CallByName List.6 List.361; + let List.430 : [C [], C {List U8, U64}] = CallByName List.86 List.361 List.362 List.363 List.431 List.432; + ret List.430; + +procedure List.8 (#Attr.2, #Attr.3): + let List.426 : List U8 = lowlevel ListConcat #Attr.2 #Attr.3; + ret List.426; + +procedure List.86 (List.461, List.462, List.463, List.464, List.465): + joinpoint List.433 List.364 List.365 List.366 List.367 List.368: + let List.435 : Int1 = CallByName Num.22 List.367 List.368; + if List.435 then + let List.444 : Str = CallByName List.66 List.364 List.367; + let List.436 : [C [], C {List U8, U64}] = CallByName List.133 List.365 List.444 List.366; + let List.441 : U8 = 1i64; + let List.442 : U8 = GetTagId List.436; + let List.443 : Int1 = lowlevel Eq List.441 List.442; + if List.443 then + let List.369 : {List U8, U64} = UnionAtIndex (Id 1) (Index 0) List.436; inc List.369; - dec List.437; - let List.440 : U64 = 1i64; - let List.439 : U64 = CallByName Num.19 List.367 List.440; - jump List.434 List.364 List.369 List.366 List.439 List.368; + dec List.436; + let List.439 : U64 = 1i64; + let List.438 : U64 = CallByName Num.19 List.367 List.439; + jump List.433 List.364 List.369 List.366 List.438 List.368; else - let List.370 : [] = UnionAtIndex (Id 0) (Index 0) List.437; - dec List.437; - let List.441 : [C [], C {List U8, U64}] = TagId(0) List.370; - ret List.441; + let List.370 : [] = UnionAtIndex (Id 0) (Index 0) List.436; + dec List.436; + let List.440 : [C [], C {List U8, U64}] = TagId(0) List.370; + ret List.440; else - let List.435 : [C [], C {List U8, U64}] = TagId(1) List.365; - ret List.435; + let List.434 : [C [], C {List U8, U64}] = TagId(1) List.365; + ret List.434; in - jump List.434 List.463 List.464 List.465 List.466 List.467; + jump List.433 List.461 List.462 List.463 List.464 List.465; procedure Num.123 (#Attr.2): let Num.266 : U8 = lowlevel NumIntCast #Attr.2; 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 175b4b486e..81035c77b5 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 @@ -1,31 +1,23 @@ procedure #Derived.0 (#Derived.1): - let #Derived_gen.2 : {{Str, Str}} = Struct {#Derived.1}; - let #Derived_gen.1 : {Str, Str} = StructAtIndex 0 #Derived_gen.2; - inc #Derived_gen.1; - dec #Derived_gen.2; - let #Derived_gen.0 : {Str, Str} = CallByName Encode.22 #Derived_gen.1; + let #Derived_gen.0 : {Str, Str} = CallByName Encode.22 #Derived.1; ret #Derived_gen.0; -procedure #Derived.4 (#Derived.5, #Derived.6, #Attr.12): - let #Derived_gen.12 : {{Str, Str}} = Struct {#Attr.12}; - let #Derived.1 : {Str, Str} = StructAtIndex 0 #Derived_gen.12; - inc #Derived.1; - dec #Derived_gen.12; - joinpoint #Derived_gen.6 #Derived_gen.5: - let #Derived_gen.4 : List U8 = CallByName Encode.23 #Derived.5 #Derived_gen.5 #Derived.6; - ret #Derived_gen.4; +procedure #Derived.4 (#Derived.5, #Derived.6, #Derived.1): + joinpoint #Derived_gen.5 #Derived_gen.4: + let #Derived_gen.3 : List U8 = CallByName Encode.23 #Derived.5 #Derived_gen.4 #Derived.6; + ret #Derived_gen.3; in let #Derived.2 : Str = StructAtIndex 0 #Derived.1; inc #Derived.2; let #Derived.3 : Str = StructAtIndex 1 #Derived.1; inc #Derived.3; dec #Derived.1; - let #Derived_gen.8 : Str = "A"; - let #Derived_gen.10 : Str = CallByName Json.18 #Derived.2; - let #Derived_gen.11 : Str = CallByName Json.18 #Derived.3; - let #Derived_gen.9 : List Str = Array [#Derived_gen.10, #Derived_gen.11]; - let #Derived_gen.7 : {Str, List Str} = CallByName Json.21 #Derived_gen.8 #Derived_gen.9; - jump #Derived_gen.6 #Derived_gen.7; + let #Derived_gen.7 : Str = "A"; + let #Derived_gen.9 : Str = CallByName Json.18 #Derived.2; + let #Derived_gen.10 : Str = CallByName Json.18 #Derived.3; + let #Derived_gen.8 : List Str = Array [#Derived_gen.9, #Derived_gen.10]; + let #Derived_gen.6 : {Str, List Str} = CallByName Json.21 #Derived_gen.7 #Derived_gen.8; + jump #Derived_gen.5 #Derived_gen.6; procedure Encode.22 (Encode.93): ret Encode.93; @@ -64,101 +56,89 @@ procedure Json.117 (Json.118, Json.321, #Attr.12): let Json.115 : Str = StructAtIndex 0 #Attr.12; inc Json.115; dec #Attr.12; - let Json.367 : I32 = 123i64; - let Json.366 : U8 = CallByName Num.123 Json.367; - let Json.363 : List U8 = CallByName List.4 Json.118 Json.366; - let Json.365 : I32 = 34i64; + let Json.365 : I32 = 123i64; let Json.364 : U8 = CallByName Num.123 Json.365; - let Json.361 : List U8 = CallByName List.4 Json.363 Json.364; - let Json.362 : List U8 = CallByName Str.12 Json.115; - let Json.358 : List U8 = CallByName List.8 Json.361 Json.362; - let Json.360 : I32 = 34i64; - let Json.359 : U8 = CallByName Num.123 Json.360; - let Json.355 : List U8 = CallByName List.4 Json.358 Json.359; - let Json.357 : I32 = 58i64; - let Json.356 : U8 = CallByName Num.123 Json.357; - let Json.352 : List U8 = CallByName List.4 Json.355 Json.356; - let Json.354 : I32 = 91i64; - let Json.353 : U8 = CallByName Num.123 Json.354; - let Json.120 : List U8 = CallByName List.4 Json.352 Json.353; - let Json.351 : U64 = CallByName List.6 Json.116; - let Json.339 : {List U8, U64} = Struct {Json.120, Json.351}; - let Json.340 : {} = Struct {}; - let Json.338 : {List U8, U64} = CallByName List.18 Json.116 Json.339 Json.340; + let Json.361 : List U8 = CallByName List.4 Json.118 Json.364; + let Json.363 : I32 = 34i64; + let Json.362 : U8 = CallByName Num.123 Json.363; + let Json.359 : List U8 = CallByName List.4 Json.361 Json.362; + let Json.360 : List U8 = CallByName Str.12 Json.115; + let Json.356 : List U8 = CallByName List.8 Json.359 Json.360; + let Json.358 : I32 = 34i64; + let Json.357 : U8 = CallByName Num.123 Json.358; + let Json.353 : List U8 = CallByName List.4 Json.356 Json.357; + let Json.355 : I32 = 58i64; + let Json.354 : U8 = CallByName Num.123 Json.355; + let Json.350 : List U8 = CallByName List.4 Json.353 Json.354; + let Json.352 : I32 = 91i64; + let Json.351 : U8 = CallByName Num.123 Json.352; + let Json.120 : List U8 = CallByName List.4 Json.350 Json.351; + let Json.349 : U64 = CallByName List.6 Json.116; + let Json.337 : {List U8, U64} = Struct {Json.120, Json.349}; + let Json.338 : {} = Struct {}; + let Json.336 : {List U8, U64} = CallByName List.18 Json.116 Json.337 Json.338; dec Json.116; - let Json.122 : List U8 = StructAtIndex 0 Json.338; + let Json.122 : List U8 = StructAtIndex 0 Json.336; inc Json.122; - dec Json.338; - let Json.337 : I32 = 93i64; - let Json.336 : U8 = CallByName Num.123 Json.337; - let Json.333 : List U8 = CallByName List.4 Json.122 Json.336; - let Json.335 : I32 = 125i64; + dec Json.336; + let Json.335 : I32 = 93i64; let Json.334 : U8 = CallByName Num.123 Json.335; - let Json.332 : List U8 = CallByName List.4 Json.333 Json.334; - ret Json.332; + let Json.331 : List U8 = CallByName List.4 Json.122 Json.334; + let Json.333 : I32 = 125i64; + let Json.332 : U8 = CallByName Num.123 Json.333; + let Json.330 : List U8 = CallByName List.4 Json.331 Json.332; + ret Json.330; -procedure Json.119 (Json.331, Json.125): - let Json.123 : List U8 = StructAtIndex 0 Json.331; +procedure Json.119 (Json.329, Json.125): + let Json.123 : List U8 = StructAtIndex 0 Json.329; inc Json.123; - let Json.124 : U64 = StructAtIndex 1 Json.331; - dec Json.331; - let Json.350 : {} = Struct {}; - let Json.126 : List U8 = CallByName Encode.23 Json.123 Json.125 Json.350; - joinpoint Json.345 Json.127: - let Json.343 : U64 = 1i64; - let Json.342 : U64 = CallByName Num.20 Json.124 Json.343; - let Json.341 : {List U8, U64} = Struct {Json.127, Json.342}; - ret Json.341; + let Json.124 : U64 = StructAtIndex 1 Json.329; + dec Json.329; + let Json.348 : {} = Struct {}; + let Json.126 : List U8 = CallByName Encode.23 Json.123 Json.125 Json.348; + joinpoint Json.343 Json.127: + let Json.341 : U64 = 1i64; + let Json.340 : U64 = CallByName Num.20 Json.124 Json.341; + let Json.339 : {List U8, U64} = Struct {Json.127, Json.340}; + ret Json.339; in - let Json.349 : U64 = 1i64; - let Json.346 : Int1 = CallByName Num.24 Json.124 Json.349; - if Json.346 then - let Json.348 : I32 = 44i64; - let Json.347 : U8 = CallByName Num.123 Json.348; - let Json.344 : List U8 = CallByName List.4 Json.126 Json.347; - jump Json.345 Json.344; + let Json.347 : U64 = 1i64; + let Json.344 : Int1 = CallByName Num.24 Json.124 Json.347; + if Json.344 then + let Json.346 : I32 = 44i64; + let Json.345 : U8 = CallByName Num.123 Json.346; + let Json.342 : List U8 = CallByName List.4 Json.126 Json.345; + jump Json.343 Json.342; else - jump Json.345 Json.126; + jump Json.343 Json.126; procedure Json.18 (Json.86): - let Json.329 : {Str} = Struct {Json.86}; - let Json.327 : Str = StructAtIndex 0 Json.329; - inc Json.327; - dec Json.329; - let Json.326 : Str = CallByName Encode.22 Json.327; - ret Json.326; + let Json.325 : Str = CallByName Encode.22 Json.86; + ret Json.325; procedure Json.21 (Json.115, Json.116): let Json.320 : {Str, List Str} = Struct {Json.115, Json.116}; let Json.319 : {Str, List Str} = CallByName Encode.22 Json.320; ret Json.319; -procedure Json.87 (Json.88, Json.324, #Attr.12): - let Json.377 : {Str} = Struct {#Attr.12}; - let Json.86 : Str = StructAtIndex 0 Json.377; - inc Json.86; - dec Json.377; - let Json.376 : I32 = 34i64; - let Json.375 : U8 = CallByName Num.123 Json.376; - let Json.373 : List U8 = CallByName List.4 Json.88 Json.375; - let Json.374 : List U8 = CallByName Str.12 Json.86; - let Json.370 : List U8 = CallByName List.8 Json.373 Json.374; - let Json.372 : I32 = 34i64; - let Json.371 : U8 = CallByName Num.123 Json.372; - let Json.369 : List U8 = CallByName List.4 Json.370 Json.371; - ret Json.369; +procedure Json.87 (Json.88, Json.324, Json.86): + let Json.374 : I32 = 34i64; + let Json.373 : U8 = CallByName Num.123 Json.374; + let Json.371 : List U8 = CallByName List.4 Json.88 Json.373; + let Json.372 : List U8 = CallByName Str.12 Json.86; + let Json.368 : List U8 = CallByName List.8 Json.371 Json.372; + let Json.370 : I32 = 34i64; + let Json.369 : U8 = CallByName Num.123 Json.370; + let Json.367 : List U8 = CallByName List.4 Json.368 Json.369; + ret Json.367; -procedure List.133 (List.134, List.135, #Attr.12): - let List.449 : {{}} = Struct {#Attr.12}; - let List.132 : {} = StructAtIndex 0 List.449; - let List.448 : {List U8, U64} = CallByName Json.119 List.134 List.135; - let List.447 : [C [], C {List U8, U64}] = TagId(1) List.448; - ret List.447; +procedure List.133 (List.134, List.135, List.132): + let List.447 : {List U8, U64} = CallByName Json.119 List.134 List.135; + let List.446 : [C [], C {List U8, U64}] = TagId(1) List.447; + ret List.446; procedure List.18 (List.130, List.131, List.132): - let List.424 : {{}} = Struct {List.132}; - let List.423 : {} = StructAtIndex 0 List.424; - let List.417 : [C [], C {List U8, U64}] = CallByName List.75 List.130 List.131 List.423; + let List.417 : [C [], C {List U8, U64}] = CallByName List.75 List.130 List.131 List.132; let List.420 : U8 = 1i64; let List.421 : U8 = GetTagId List.417; let List.422 : Int1 = lowlevel Eq List.420 List.421; @@ -184,61 +164,61 @@ procedure List.6 (#Attr.2): ret List.385; procedure List.6 (#Attr.2): - let List.425 : U64 = lowlevel ListLen #Attr.2; - ret List.425; + let List.424 : U64 = lowlevel ListLen #Attr.2; + ret List.424; procedure List.66 (#Attr.2, #Attr.3): - let List.446 : Str = lowlevel ListGetUnsafe #Attr.2 #Attr.3; - ret List.446; + let List.445 : Str = lowlevel ListGetUnsafe #Attr.2 #Attr.3; + ret List.445; procedure List.69 (#Attr.2): - let List.430 : {List U8, U64} = lowlevel Unreachable #Attr.2; - ret List.430; - -procedure List.70 (#Attr.2, #Attr.3): - let List.429 : List U8 = lowlevel ListReserve #Attr.2 #Attr.3; + let List.429 : {List U8, U64} = lowlevel Unreachable #Attr.2; ret List.429; -procedure List.71 (#Attr.2, #Attr.3): - let List.428 : List U8 = lowlevel ListAppendUnsafe #Attr.2 #Attr.3; +procedure List.70 (#Attr.2, #Attr.3): + let List.428 : List U8 = lowlevel ListReserve #Attr.2 #Attr.3; ret List.428; -procedure List.75 (List.361, List.362, List.363): - let List.432 : U64 = 0i64; - let List.433 : U64 = CallByName List.6 List.361; - let List.431 : [C [], C {List U8, U64}] = CallByName List.86 List.361 List.362 List.363 List.432 List.433; - ret List.431; - -procedure List.8 (#Attr.2, #Attr.3): - let List.427 : List U8 = lowlevel ListConcat #Attr.2 #Attr.3; +procedure List.71 (#Attr.2, #Attr.3): + let List.427 : List U8 = lowlevel ListAppendUnsafe #Attr.2 #Attr.3; ret List.427; -procedure List.86 (List.463, List.464, List.465, List.466, List.467): - joinpoint List.434 List.364 List.365 List.366 List.367 List.368: - let List.436 : Int1 = CallByName Num.22 List.367 List.368; - if List.436 then - let List.445 : Str = CallByName List.66 List.364 List.367; - let List.437 : [C [], C {List U8, U64}] = CallByName List.133 List.365 List.445 List.366; - let List.442 : U8 = 1i64; - let List.443 : U8 = GetTagId List.437; - let List.444 : Int1 = lowlevel Eq List.442 List.443; - if List.444 then - let List.369 : {List U8, U64} = UnionAtIndex (Id 1) (Index 0) List.437; +procedure List.75 (List.361, List.362, List.363): + let List.431 : U64 = 0i64; + let List.432 : U64 = CallByName List.6 List.361; + let List.430 : [C [], C {List U8, U64}] = CallByName List.86 List.361 List.362 List.363 List.431 List.432; + ret List.430; + +procedure List.8 (#Attr.2, #Attr.3): + let List.426 : List U8 = lowlevel ListConcat #Attr.2 #Attr.3; + ret List.426; + +procedure List.86 (List.461, List.462, List.463, List.464, List.465): + joinpoint List.433 List.364 List.365 List.366 List.367 List.368: + let List.435 : Int1 = CallByName Num.22 List.367 List.368; + if List.435 then + let List.444 : Str = CallByName List.66 List.364 List.367; + let List.436 : [C [], C {List U8, U64}] = CallByName List.133 List.365 List.444 List.366; + let List.441 : U8 = 1i64; + let List.442 : U8 = GetTagId List.436; + let List.443 : Int1 = lowlevel Eq List.441 List.442; + if List.443 then + let List.369 : {List U8, U64} = UnionAtIndex (Id 1) (Index 0) List.436; inc List.369; - dec List.437; - let List.440 : U64 = 1i64; - let List.439 : U64 = CallByName Num.19 List.367 List.440; - jump List.434 List.364 List.369 List.366 List.439 List.368; + dec List.436; + let List.439 : U64 = 1i64; + let List.438 : U64 = CallByName Num.19 List.367 List.439; + jump List.433 List.364 List.369 List.366 List.438 List.368; else - let List.370 : [] = UnionAtIndex (Id 0) (Index 0) List.437; - dec List.437; - let List.441 : [C [], C {List U8, U64}] = TagId(0) List.370; - ret List.441; + let List.370 : [] = UnionAtIndex (Id 0) (Index 0) List.436; + dec List.436; + let List.440 : [C [], C {List U8, U64}] = TagId(0) List.370; + ret List.440; else - let List.435 : [C [], C {List U8, U64}] = TagId(1) List.365; - ret List.435; + let List.434 : [C [], C {List U8, U64}] = TagId(1) List.365; + ret List.434; in - jump List.434 List.463 List.464 List.465 List.466 List.467; + jump List.433 List.461 List.462 List.463 List.464 List.465; procedure Num.123 (#Attr.2): let Num.266 : U8 = lowlevel NumIntCast #Attr.2; diff --git a/crates/compiler/test_mono/generated/lambda_capture_niches_have_captured_function_in_closure.txt b/crates/compiler/test_mono/generated/lambda_capture_niches_have_captured_function_in_closure.txt index 373532cb37..83658eacbb 100644 --- a/crates/compiler/test_mono/generated/lambda_capture_niches_have_captured_function_in_closure.txt +++ b/crates/compiler/test_mono/generated/lambda_capture_niches_have_captured_function_in_closure.txt @@ -2,20 +2,16 @@ procedure Test.11 (Test.37): let Test.38 : Str = ""; ret Test.38; -procedure Test.13 (Test.51, #Attr.12): - let Test.54 : {Str} = Struct {#Attr.12}; - let Test.12 : Str = StructAtIndex 0 Test.54; - inc Test.12; - dec Test.54; +procedure Test.13 (Test.51, Test.12): ret Test.12; procedure Test.15 (Test.39): let Test.40 : Str = ""; ret Test.40; -procedure Test.16 (Test.56): - let Test.58 : Str = "s1"; - ret Test.58; +procedure Test.16 (Test.54): + let Test.56 : Str = "s1"; + ret Test.56; procedure Test.2 (Test.7, Test.8): let Test.9 : [C {} {}, C {} {}] = TagId(0) Test.7 Test.8; @@ -30,11 +26,8 @@ procedure Test.3 (Test.17): ret Test.36; procedure Test.4 (Test.18): - let Test.55 : {Str} = Struct {Test.18}; - let Test.50 : Str = StructAtIndex 0 Test.55; - inc Test.50; - dec Test.55; - ret Test.50; + inc Test.18; + ret Test.18; procedure Test.9 (Test.29, #Attr.12): let Test.8 : {} = UnionAtIndex (Id 0) (Index 1) #Attr.12; @@ -53,6 +46,7 @@ procedure Test.9 (Test.29, #Attr.12): let Test.49 : {} = Struct {}; let Test.48 : Str = CallByName Test.16 Test.49; let Test.45 : Str = CallByName Test.4 Test.48; + dec Test.48; let Test.47 : {} = Struct {}; let Test.46 : Str = CallByName Test.13 Test.47 Test.45; ret Test.46; @@ -75,9 +69,9 @@ procedure Test.0 (): jump Test.22 Test.24; in - let Test.59 : Int1 = true; - let Test.60 : Int1 = lowlevel Eq Test.59 Test.5; - if Test.60 then + let Test.57 : Int1 = true; + let Test.58 : Int1 = lowlevel Eq Test.57 Test.5; + if Test.58 then let Test.27 : {} = Struct {}; let Test.28 : {} = Struct {}; let Test.26 : [C {} {}, C {} {}] = CallByName Test.2 Test.27 Test.28; diff --git a/crates/compiler/test_mono/generated/lambda_set_niche_same_layout_different_constructor.txt b/crates/compiler/test_mono/generated/lambda_set_niche_same_layout_different_constructor.txt index 0110980f98..7e624d7a76 100644 --- a/crates/compiler/test_mono/generated/lambda_set_niche_same_layout_different_constructor.txt +++ b/crates/compiler/test_mono/generated/lambda_set_niche_same_layout_different_constructor.txt @@ -1,15 +1,9 @@ procedure Test.1 (Test.4): - let Test.16 : {Str} = Struct {Test.4}; - let Test.5 : Str = StructAtIndex 0 Test.16; - inc Test.5; - dec Test.16; - ret Test.5; - -procedure Test.5 (Test.12, #Attr.12): - let Test.15 : {Str} = Struct {#Attr.12}; - let Test.4 : Str = StructAtIndex 0 Test.15; inc Test.4; - dec Test.15; + ret Test.4; + +procedure Test.5 (Test.12, Test.4): + dec Test.4; let Test.14 : Str = ""; ret Test.14; @@ -18,13 +12,15 @@ procedure Test.0 (): joinpoint Test.9 Test.3: ret Test.3; in - let Test.21 : Int1 = true; - let Test.22 : Int1 = lowlevel Eq Test.21 Test.2; - if Test.22 then - let Test.17 : Str = ""; - let Test.10 : Str = CallByName Test.1 Test.17; + let Test.19 : Int1 = true; + let Test.20 : Int1 = lowlevel Eq Test.19 Test.2; + if Test.20 then + let Test.15 : Str = ""; + let Test.10 : Str = CallByName Test.1 Test.15; + dec Test.15; jump Test.9 Test.10; else - let Test.20 : Str = ""; - let Test.18 : Str = CallByName Test.1 Test.20; - jump Test.9 Test.18; + let Test.18 : Str = ""; + let Test.16 : Str = CallByName Test.1 Test.18; + dec Test.18; + jump Test.9 Test.16; diff --git a/crates/compiler/test_mono/generated/nested_closure.txt b/crates/compiler/test_mono/generated/nested_closure.txt index c5937b430c..1b9d1a6f1d 100644 --- a/crates/compiler/test_mono/generated/nested_closure.txt +++ b/crates/compiler/test_mono/generated/nested_closure.txt @@ -1,12 +1,8 @@ procedure Test.1 (Test.5): let Test.2 : I64 = 42i64; - let Test.13 : {I64} = Struct {Test.2}; - let Test.3 : I64 = StructAtIndex 0 Test.13; - ret Test.3; + ret Test.2; -procedure Test.3 (Test.9, #Attr.12): - let Test.12 : {I64} = Struct {#Attr.12}; - let Test.2 : I64 = StructAtIndex 0 Test.12; +procedure Test.3 (Test.9, Test.2): ret Test.2; procedure Test.0 (): diff --git a/crates/compiler/test_mono/generated/recursive_call_capturing_function.txt b/crates/compiler/test_mono/generated/recursive_call_capturing_function.txt index b0f1a4b403..95837c3b32 100644 --- a/crates/compiler/test_mono/generated/recursive_call_capturing_function.txt +++ b/crates/compiler/test_mono/generated/recursive_call_capturing_function.txt @@ -4,25 +4,19 @@ procedure Num.19 (#Attr.2, #Attr.3): procedure Test.1 (Test.2): let Test.9 : U32 = 0i64; - let Test.19 : {U32} = Struct {Test.2}; - let Test.18 : U32 = StructAtIndex 0 Test.19; - let Test.8 : U32 = CallByName Test.3 Test.9 Test.18; + let Test.8 : U32 = CallByName Test.3 Test.9 Test.2; ret Test.8; -procedure Test.3 (Test.21, Test.22): - joinpoint Test.10 Test.4 #Attr.12: - let Test.17 : {U32} = Struct {#Attr.12}; - let Test.2 : U32 = StructAtIndex 0 Test.17; - let Test.15 : Int1 = true; - if Test.15 then +procedure Test.3 (Test.18, Test.19): + joinpoint Test.10 Test.4 Test.2: + let Test.14 : Int1 = true; + if Test.14 then ret Test.4; else let Test.12 : U32 = CallByName Num.19 Test.4 Test.2; - let Test.14 : {U32} = Struct {Test.2}; - let Test.13 : U32 = StructAtIndex 0 Test.14; - jump Test.10 Test.12 Test.13; + jump Test.10 Test.12 Test.2; in - jump Test.10 Test.21 Test.22; + jump Test.10 Test.18 Test.19; procedure Test.0 (): let Test.7 : U32 = 6i64; From b18af7e1f3122401d991ecabe68c887e98ec2007 Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Sun, 14 Aug 2022 15:35:09 -0500 Subject: [PATCH 12/22] Fix return type of closure --- crates/compiler/test_gen/src/gen_primitives.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/compiler/test_gen/src/gen_primitives.rs b/crates/compiler/test_gen/src/gen_primitives.rs index 8ed0dbc8bb..bd9d6eb350 100644 --- a/crates/compiler/test_gen/src/gen_primitives.rs +++ b/crates/compiler/test_gen/src/gen_primitives.rs @@ -1234,8 +1234,8 @@ fn return_wrapped_closure() { main = foo "# ), - [5], - [i64; 1] + 5, + i64 ); } From 0606086eb6cde4844f54797ae4509b6f7807cf39 Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Sun, 14 Aug 2022 15:43:26 -0500 Subject: [PATCH 13/22] Compare values with runtime representation --- crates/compiler/gen_wasm/src/low_level.rs | 10 +++++++--- crates/compiler/mono/src/ir.rs | 2 +- crates/compiler/mono/src/layout.rs | 7 +++++++ 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/crates/compiler/gen_wasm/src/low_level.rs b/crates/compiler/gen_wasm/src/low_level.rs index 0941e83c01..8be059576c 100644 --- a/crates/compiler/gen_wasm/src/low_level.rs +++ b/crates/compiler/gen_wasm/src/low_level.rs @@ -1857,11 +1857,15 @@ impl<'a> LowLevelCall<'a> { /// Equality and inequality /// These can operate on any data type (except functions) so they're more complex than other operators. fn eq_or_neq(&self, backend: &mut WasmBackend<'a>) { - let arg_layout = backend.storage.symbol_layouts[&self.arguments[0]]; - let other_arg_layout = backend.storage.symbol_layouts[&self.arguments[1]]; + let arg_layout = + backend.storage.symbol_layouts[&self.arguments[0]].runtime_representation(); + let other_arg_layout = + backend.storage.symbol_layouts[&self.arguments[1]].runtime_representation(); debug_assert!( arg_layout == other_arg_layout, - "Cannot do `==` comparison on different types" + "Cannot do `==` comparison on different types: {:?} vs {:?}", + arg_layout, + other_arg_layout ); let invert_result = matches!(self.lowlevel, LowLevel::NotEq); diff --git a/crates/compiler/mono/src/ir.rs b/crates/compiler/mono/src/ir.rs index 9c26592bcd..cc08598ca5 100644 --- a/crates/compiler/mono/src/ir.rs +++ b/crates/compiler/mono/src/ir.rs @@ -3238,7 +3238,7 @@ fn specialize_external<'a>( ClosureRepresentation::UnwrappedCapture(_layout) => { debug_assert_eq!(captured.len(), 1); - let (captured_symbol, _) = captured[0]; + let (captured_symbol, _captured_layout) = captured[0]; // The capture set is unwrapped, so simply replace the closure argument // to the function with the unwrapped capture name. diff --git a/crates/compiler/mono/src/layout.rs b/crates/compiler/mono/src/layout.rs index 6f3366cc99..48efdf91f8 100644 --- a/crates/compiler/mono/src/layout.rs +++ b/crates/compiler/mono/src/layout.rs @@ -1825,6 +1825,13 @@ impl<'a> Layout<'a> { } } } + + pub fn runtime_representation(&self) -> Self { + match self { + Layout::LambdaSet(lambda_set) => lambda_set.runtime_representation(), + other => *other, + } + } } /// Avoid recomputing Layout from Variable multiple times. From cefbf3aa5128b4bca8169a8faa0b6a3ab9b23d58 Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Sun, 14 Aug 2022 17:59:44 -0500 Subject: [PATCH 14/22] Unwrap lambda sets in cc type choosing --- crates/compiler/gen_llvm/src/llvm/build.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/compiler/gen_llvm/src/llvm/build.rs b/crates/compiler/gen_llvm/src/llvm/build.rs index 9c6c11110d..ee4cc886af 100644 --- a/crates/compiler/gen_llvm/src/llvm/build.rs +++ b/crates/compiler/gen_llvm/src/llvm/build.rs @@ -6411,11 +6411,11 @@ fn to_cc_type<'a, 'ctx, 'env>( env: &Env<'a, 'ctx, 'env>, layout: &Layout<'a>, ) -> BasicTypeEnum<'ctx> { - match layout { - Layout::Builtin(builtin) => to_cc_type_builtin(env, builtin), - _ => { + match layout.runtime_representation() { + Layout::Builtin(builtin) => to_cc_type_builtin(env, &builtin), + layout => { // TODO this is almost certainly incorrect for bigger structs - basic_type_from_layout(env, layout) + basic_type_from_layout(env, &layout) } } } From 15ef517cf20cad4a0df528a848e84d2a2f46051b Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Mon, 15 Aug 2022 09:31:54 -0500 Subject: [PATCH 15/22] gen-wasm: box captured data before passing it to a higher-order lowlevel Previously, when it existed, captured data would always be represented as a struct, and hence implicitly boxed. That meant that passing captured data would always pass a pointer. However, now, captured data can live unwrapped. This poses a challenge for the higher-order lowlevels, which always expect captures data to be passed as an opaque pointer. As such, always box captured data. It's possible to optimize this so that only unwrapped captures data needs to be boxed; however, that is not attempted in this patch. --- crates/compiler/gen_wasm/src/backend.rs | 13 ++++- crates/compiler/gen_wasm/src/low_level.rs | 70 ++++++++++++++++++++--- 2 files changed, 74 insertions(+), 9 deletions(-) diff --git a/crates/compiler/gen_wasm/src/backend.rs b/crates/compiler/gen_wasm/src/backend.rs index b87bffe0c8..586a83427f 100644 --- a/crates/compiler/gen_wasm/src/backend.rs +++ b/crates/compiler/gen_wasm/src/backend.rs @@ -517,7 +517,7 @@ impl<'a> WasmBackend<'a> { // Load all the arguments for the inner function for (i, wrapper_arg) in wrapper_arg_layouts.iter().enumerate() { - let is_closure_data = i == 0; // Skip closure data (first for wrapper, last for inner) + let is_closure_data = i == 0; // Skip closure data (first for wrapper, last for inner). We'll handle it below. let is_return_pointer = i == wrapper_arg_layouts.len() - 1; // Skip return pointer (may not be an arg for inner. And if it is, swaps from end to start) if is_closure_data || is_return_pointer { continue; @@ -540,7 +540,16 @@ impl<'a> WasmBackend<'a> { // If the inner function has closure data, it's the last arg of the inner fn let closure_data_layout = wrapper_arg_layouts[0]; if closure_data_layout.stack_size(TARGET_INFO) > 0 { + // The closure data exists, and will have been passed in to the wrapper as boxed. + let inner_closure_data_layout = match closure_data_layout { + Layout::Boxed(inner) => inner, + other => internal_error!( + "Expected a boxed layout for wrapped closure data, got {:?}", + other + ), + }; self.code_builder.get_local(LocalId(0)); + self.dereference_boxed_value(inner_closure_data_layout); } // Call the wrapped inner function @@ -1870,7 +1879,7 @@ impl<'a> WasmBackend<'a> { /// If the data size is known at compile time, pass it in comptime_data_size. /// If size is only known at runtime, push *data* size to the VM stack first. /// Leaves the *data* address on the VM stack - fn allocate_with_refcount( + pub fn allocate_with_refcount( &mut self, comptime_data_size: Option, alignment_bytes: u32, diff --git a/crates/compiler/gen_wasm/src/low_level.rs b/crates/compiler/gen_wasm/src/low_level.rs index 8be059576c..ba3dc94826 100644 --- a/crates/compiler/gen_wasm/src/low_level.rs +++ b/crates/compiler/gen_wasm/src/low_level.rs @@ -2117,6 +2117,17 @@ pub fn call_higher_order_lowlevel<'a>( .. } = passed_function; + // The zig lowlevel builtins expect the passed functions' closure data to always + // be sent as an opaque pointer. On the Roc side, however, we need to call the passed function + // with the Roc representation of the closure data. There are three possible cases for that + // representation: + // + // 1. The closure data is a struct + // 2. The closure data is an unwrapped value + // 3. There is no closure data + // + // To uniformly deal with the first two cases, always box these layouts before calling the + // builtin; the wrapper around the passed function will unbox them. let (closure_data_layout, closure_data_exists) = match backend.storage.symbol_layouts[captured_environment] { Layout::LambdaSet(lambda_set) => { @@ -2135,6 +2146,49 @@ pub fn call_higher_order_lowlevel<'a>( x => internal_error!("Closure data has an invalid layout\n{:?}", x), }; + let (wrapped_captured_environment, wrapped_captures_layout) = if closure_data_exists { + // If there is closure data, make sure we box it before passing it to the external builtin + // impl. + let boxed_sym = backend.create_symbol("boxed_captures"); + let boxed_captures_layout = Layout::Boxed(backend.env.arena.alloc(closure_data_layout)); + + // create a local variable for the box + let boxed_storage = backend.storage.allocate_var( + boxed_captures_layout, + boxed_sym, + crate::storage::StoredVarKind::Variable, + ); + let boxed_local_id = match backend.storage.ensure_value_has_local( + &mut backend.code_builder, + boxed_sym, + boxed_storage.clone(), + ) { + StoredValue::Local { local_id, .. } => local_id, + _ => internal_error!("Expected a local"), + }; + + // allocate heap memory and load its data address onto the value stack + let (size, alignment) = closure_data_layout.stack_size_and_alignment(TARGET_INFO); + backend.allocate_with_refcount(Some(size), alignment, 1); + + // store the pointer value from the value stack into the local variable + backend.code_builder.set_local(boxed_local_id); + + // copy the argument to the pointer address + backend.storage.copy_value_to_memory( + &mut backend.code_builder, + boxed_local_id, + 0, + *captured_environment, + ); + + (boxed_sym, boxed_captures_layout) + } else { + // If we don't capture anything, pass along the captured environment as-is - the wrapper + // function will take care not to unbox this. + (*captured_environment, closure_data_layout) + }; + // We create a wrapper around the passed function, which just unboxes the arguments. // This allows Zig builtins to have a generic pointer-based interface. let helper_proc_source = { @@ -2168,7 +2222,7 @@ pub fn call_higher_order_lowlevel<'a>( argument_layouts.len() }; - wrapper_arg_layouts.push(closure_data_layout); + wrapper_arg_layouts.push(wrapped_captures_layout); wrapper_arg_layouts.extend( argument_layouts .iter() @@ -2208,7 +2262,7 @@ pub fn call_higher_order_lowlevel<'a>( .get_refcount_fn_index(Layout::Builtin(Builtin::Int(IntWidth::I32)), HelperOp::Inc); backend.get_fn_ptr(inc_fn) } else { - let inc_fn = backend.get_refcount_fn_index(closure_data_layout, HelperOp::Inc); + let inc_fn = backend.get_refcount_fn_index(wrapped_captures_layout, HelperOp::Inc); backend.get_fn_ptr(inc_fn) }; @@ -2222,7 +2276,7 @@ pub fn call_higher_order_lowlevel<'a>( wrapper_fn_ptr, inc_fn_ptr, closure_data_exists, - *captured_environment, + wrapped_captured_environment, *owns_captured_environment, ), @@ -2235,7 +2289,7 @@ pub fn call_higher_order_lowlevel<'a>( wrapper_fn_ptr, inc_fn_ptr, closure_data_exists, - *captured_environment, + wrapped_captured_environment, *owns_captured_environment, ), @@ -2248,7 +2302,7 @@ pub fn call_higher_order_lowlevel<'a>( wrapper_fn_ptr, inc_fn_ptr, closure_data_exists, - *captured_environment, + wrapped_captured_environment, *owns_captured_environment, ), @@ -2261,7 +2315,7 @@ pub fn call_higher_order_lowlevel<'a>( wrapper_fn_ptr, inc_fn_ptr, closure_data_exists, - *captured_environment, + wrapped_captured_environment, *owns_captured_environment, ), @@ -2284,7 +2338,9 @@ pub fn call_higher_order_lowlevel<'a>( backend.storage.load_symbol_zig(cb, *xs); cb.i32_const(wrapper_fn_ptr); if closure_data_exists { - backend.storage.load_symbols(cb, &[*captured_environment]); + backend + .storage + .load_symbols(cb, &[wrapped_captured_environment]); } else { // load_symbols assumes that a zero-size arg should be eliminated in code gen, // but that's a specialization that our Zig code doesn't have! Pass a null pointer. From fb4282757a41275421d8cc5750bd556d1132d5ea Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Mon, 15 Aug 2022 09:43:19 -0500 Subject: [PATCH 16/22] gen-wasm: Do not repoint stack memory to locals upon copy It is possible that other code paths will use the stack memory before a copy to a local is done. For example, if the copy happens behind a branch, the local variable may not be assigned the stack content. --- crates/compiler/gen_wasm/src/storage.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/crates/compiler/gen_wasm/src/storage.rs b/crates/compiler/gen_wasm/src/storage.rs index 90000cc0ff..46cf604dc5 100644 --- a/crates/compiler/gen_wasm/src/storage.rs +++ b/crates/compiler/gen_wasm/src/storage.rs @@ -721,7 +721,11 @@ impl<'a> Storage<'a> { debug_assert!(to_size == from_size); self.load_symbols(code_builder, &[from_symbol]); code_builder.set_local(*to_local_id); - self.symbol_storage_map.insert(from_symbol, to.clone()); + + // Do not repoint the stack memory to the local variable, because it is + // possible that other code paths will use the stack memory before this copy. + // For example, if the copy happens behind a branch, the local variable may not be + // assigned the stack content. } ( From f08fc432104aea77ba117f3743860802e8eb7237 Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Mon, 15 Aug 2022 11:15:29 -0500 Subject: [PATCH 17/22] Remove unneeded clone --- crates/compiler/gen_wasm/src/low_level.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/compiler/gen_wasm/src/low_level.rs b/crates/compiler/gen_wasm/src/low_level.rs index ba3dc94826..824c387c8e 100644 --- a/crates/compiler/gen_wasm/src/low_level.rs +++ b/crates/compiler/gen_wasm/src/low_level.rs @@ -2161,7 +2161,7 @@ pub fn call_higher_order_lowlevel<'a>( let boxed_local_id = match backend.storage.ensure_value_has_local( &mut backend.code_builder, boxed_sym, - boxed_storage.clone(), + boxed_storage, ) { StoredValue::Local { local_id, .. } => local_id, _ => internal_error!("Expected a local"), From cea53c127339706cbb9cd6d8393075b554f30f65 Mon Sep 17 00:00:00 2001 From: Anton-4 <17049058+Anton-4@users.noreply.github.com> Date: Mon, 15 Aug 2022 20:15:01 +0200 Subject: [PATCH 18/22] Only add debian testing as extra sources for gcc-10 Signed-off-by: Anton-4 <17049058+Anton-4@users.noreply.github.com> --- Earthfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Earthfile b/Earthfile index 5310740526..aa9092e8e4 100644 --- a/Earthfile +++ b/Earthfile @@ -59,7 +59,7 @@ test-zig: build-rust-test: FROM +copy-dirs - RUN echo "deb http://deb.debian.org/debian testing main contrib non-free" >> /etc/apt/sources.list # to get gcc 10.3 + RUN echo "deb http://deb.debian.org/debian testing" >> /etc/apt/sources.list # to get gcc 10.3 RUN apt -y update RUN apt -y install gcc-10 g++-10 && rm /usr/bin/gcc && ln -s /usr/bin/gcc-10 /usr/bin/gcc # gcc-9 maybe causes segfault RUN gcc --version From d24b47360f7d87a9fda77d78086e52bdcdce66a8 Mon Sep 17 00:00:00 2001 From: Anton-4 <17049058+Anton-4@users.noreply.github.com> Date: Tue, 16 Aug 2022 12:36:23 +0200 Subject: [PATCH 19/22] re-enable all debian channels Signed-off-by: Anton-4 <17049058+Anton-4@users.noreply.github.com> --- Earthfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Earthfile b/Earthfile index aa9092e8e4..5310740526 100644 --- a/Earthfile +++ b/Earthfile @@ -59,7 +59,7 @@ test-zig: build-rust-test: FROM +copy-dirs - RUN echo "deb http://deb.debian.org/debian testing" >> /etc/apt/sources.list # to get gcc 10.3 + RUN echo "deb http://deb.debian.org/debian testing main contrib non-free" >> /etc/apt/sources.list # to get gcc 10.3 RUN apt -y update RUN apt -y install gcc-10 g++-10 && rm /usr/bin/gcc && ln -s /usr/bin/gcc-10 /usr/bin/gcc # gcc-9 maybe causes segfault RUN gcc --version From 1078badd58c107a9ded5b9ccbabe8b02a652b47b Mon Sep 17 00:00:00 2001 From: Brian Carroll Date: Wed, 17 Aug 2022 21:38:02 +0100 Subject: [PATCH 20/22] wasm: comment on why we don't need to modify symbol storage after clone --- crates/compiler/gen_wasm/src/storage.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/crates/compiler/gen_wasm/src/storage.rs b/crates/compiler/gen_wasm/src/storage.rs index 46cf604dc5..830361f20d 100644 --- a/crates/compiler/gen_wasm/src/storage.rs +++ b/crates/compiler/gen_wasm/src/storage.rs @@ -719,13 +719,10 @@ impl<'a> Storage<'a> { ) => { debug_assert!(to_value_type == from_value_type); debug_assert!(to_size == from_size); + // Note: load_symbols will not destroy the value, so we can use it again later. + // It will leave a Popped marker in the VM stack model in CodeBuilder self.load_symbols(code_builder, &[from_symbol]); code_builder.set_local(*to_local_id); - - // Do not repoint the stack memory to the local variable, because it is - // possible that other code paths will use the stack memory before this copy. - // For example, if the copy happens behind a branch, the local variable may not be - // assigned the stack content. } ( From b7c799702f4ad6329e2e1c77d9786ee97d3ec588 Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Wed, 17 Aug 2022 16:33:03 -0500 Subject: [PATCH 21/22] wasm: store closure data passed to higher-order low-level in struct, not box --- crates/compiler/gen_wasm/src/backend.rs | 11 ++++- crates/compiler/gen_wasm/src/low_level.rs | 56 +++++++++++------------ 2 files changed, 36 insertions(+), 31 deletions(-) diff --git a/crates/compiler/gen_wasm/src/backend.rs b/crates/compiler/gen_wasm/src/backend.rs index 586a83427f..ac60dc4c24 100644 --- a/crates/compiler/gen_wasm/src/backend.rs +++ b/crates/compiler/gen_wasm/src/backend.rs @@ -540,15 +540,22 @@ impl<'a> WasmBackend<'a> { // If the inner function has closure data, it's the last arg of the inner fn let closure_data_layout = wrapper_arg_layouts[0]; if closure_data_layout.stack_size(TARGET_INFO) > 0 { - // The closure data exists, and will have been passed in to the wrapper as boxed. + // The closure data exists, and will have been passed in to the wrapper as a + // one-element struct. let inner_closure_data_layout = match closure_data_layout { - Layout::Boxed(inner) => inner, + Layout::Struct { + field_layouts: [inner], + .. + } => inner, other => internal_error!( "Expected a boxed layout for wrapped closure data, got {:?}", other ), }; self.code_builder.get_local(LocalId(0)); + // Since the closure data is wrapped in a one-element struct, we've been passed in the + // pointer to that struct in the stack memory. To get the closure data we just need to + // dereference the pointer. self.dereference_boxed_value(inner_closure_data_layout); } diff --git a/crates/compiler/gen_wasm/src/low_level.rs b/crates/compiler/gen_wasm/src/low_level.rs index 824c387c8e..5da5f22212 100644 --- a/crates/compiler/gen_wasm/src/low_level.rs +++ b/crates/compiler/gen_wasm/src/low_level.rs @@ -2126,8 +2126,9 @@ pub fn call_higher_order_lowlevel<'a>( // 2. The closure data is an unwrapped value // 3. There is no closure data // - // To uniformly deal with the first two cases, always box these layouts before calling the - // builtin; the wrapper around the passed function will unbox them. + // To uniformly deal with the first two cases, always put the closure data, when it exists, + // into a one-element struct. That way, we get a pointer (i32) that can be passed to the zig lowlevels. + // The wrapper around the passed function will access the actual closure data in the struct. let (closure_data_layout, closure_data_exists) = match backend.storage.symbol_layouts[captured_environment] { Layout::LambdaSet(lambda_set) => { @@ -2147,45 +2148,42 @@ pub fn call_higher_order_lowlevel<'a>( }; let (wrapped_captured_environment, wrapped_captures_layout) = if closure_data_exists { - // If there is closure data, make sure we box it before passing it to the external builtin - // impl. - let boxed_sym = backend.create_symbol("boxed_captures"); - let boxed_captures_layout = Layout::Boxed(backend.env.arena.alloc(closure_data_layout)); + // If there is closure data, make sure we put in a struct it before passing it to the + // external builtin impl. That way it's always an `i32` pointer. + let wrapped_closure_data_sym = backend.create_symbol("wrapped_captures"); + let wrapped_captures_layout = + Layout::struct_no_name_order(backend.env.arena.alloc([closure_data_layout])); - // create a local variable for the box - let boxed_storage = backend.storage.allocate_var( - boxed_captures_layout, - boxed_sym, + // make sure that the wrapping struct is available in stack memory, so we can hand out a + // pointer to it. + let wrapped_storage = backend.storage.allocate_var( + wrapped_captures_layout, + wrapped_closure_data_sym, crate::storage::StoredVarKind::Variable, ); - let boxed_local_id = match backend.storage.ensure_value_has_local( - &mut backend.code_builder, - boxed_sym, - boxed_storage, - ) { - StoredValue::Local { local_id, .. } => local_id, - _ => internal_error!("Expected a local"), + + let (wrapped_storage_local_ptr, wrapped_storage_offset) = match wrapped_storage { + StoredValue::StackMemory { location, .. } => { + location.local_and_offset(backend.storage.stack_frame_pointer) + } + other => internal_error!( + "Struct should be allocated in stack memory, but it's in {:?}", + other + ), }; - // allocate heap memory and load its data address onto the value stack - let (size, alignment) = closure_data_layout.stack_size_and_alignment(TARGET_INFO); - backend.allocate_with_refcount(Some(size), alignment, 1); - - // store the pointer value from the value stack into the local variable - backend.code_builder.set_local(boxed_local_id); - - // copy the argument to the pointer address + // copy the actual closure data into the first and only element of the wrapping struct. backend.storage.copy_value_to_memory( &mut backend.code_builder, - boxed_local_id, - 0, + wrapped_storage_local_ptr, + wrapped_storage_offset, *captured_environment, ); - (boxed_sym, boxed_captures_layout) + (wrapped_closure_data_sym, wrapped_captures_layout) } else { // If we don't capture anything, pass along the captured environment as-is - the wrapper - // function will take care not to unbox this. + // function will take care not to unwrap this. (*captured_environment, closure_data_layout) }; From 79a57668547546037e2db7abe3e15ea5a5dc6cb5 Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Thu, 18 Aug 2022 18:24:38 -0500 Subject: [PATCH 22/22] Make method private --- crates/compiler/gen_wasm/src/backend.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/compiler/gen_wasm/src/backend.rs b/crates/compiler/gen_wasm/src/backend.rs index ac60dc4c24..6bf90f5309 100644 --- a/crates/compiler/gen_wasm/src/backend.rs +++ b/crates/compiler/gen_wasm/src/backend.rs @@ -1886,7 +1886,7 @@ impl<'a> WasmBackend<'a> { /// If the data size is known at compile time, pass it in comptime_data_size. /// If size is only known at runtime, push *data* size to the VM stack first. /// Leaves the *data* address on the VM stack - pub fn allocate_with_refcount( + fn allocate_with_refcount( &mut self, comptime_data_size: Option, alignment_bytes: u32,