Merge pull request #3742 from roc-lang/cleanup-mono-layout

Cleanup/refactoring of lambda set layout generation
This commit is contained in:
Brian Carroll 2022-08-20 15:48:05 +01:00 committed by GitHub
commit 334bc7174f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 545 additions and 508 deletions

View File

@ -6411,11 +6411,11 @@ fn to_cc_type<'a, 'ctx, 'env>(
env: &Env<'a, 'ctx, 'env>, env: &Env<'a, 'ctx, 'env>,
layout: &Layout<'a>, layout: &Layout<'a>,
) -> BasicTypeEnum<'ctx> { ) -> BasicTypeEnum<'ctx> {
match layout { match layout.runtime_representation() {
Layout::Builtin(builtin) => to_cc_type_builtin(env, builtin), Layout::Builtin(builtin) => to_cc_type_builtin(env, &builtin),
_ => { layout => {
// TODO this is almost certainly incorrect for bigger structs // TODO this is almost certainly incorrect for bigger structs
basic_type_from_layout(env, layout) basic_type_from_layout(env, &layout)
} }
} }
} }

View File

@ -517,7 +517,7 @@ impl<'a> WasmBackend<'a> {
// Load all the arguments for the inner function // Load all the arguments for the inner function
for (i, wrapper_arg) in wrapper_arg_layouts.iter().enumerate() { 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) 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 { if is_closure_data || is_return_pointer {
continue; continue;
@ -540,7 +540,23 @@ impl<'a> WasmBackend<'a> {
// If the inner function has closure data, it's the last arg of the inner fn // If the inner function has closure data, it's the last arg of the inner fn
let closure_data_layout = wrapper_arg_layouts[0]; let closure_data_layout = wrapper_arg_layouts[0];
if closure_data_layout.stack_size(TARGET_INFO) > 0 { if closure_data_layout.stack_size(TARGET_INFO) > 0 {
// 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::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)); 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);
} }
// Call the wrapped inner function // Call the wrapped inner function

View File

@ -1857,11 +1857,15 @@ impl<'a> LowLevelCall<'a> {
/// Equality and inequality /// Equality and inequality
/// These can operate on any data type (except functions) so they're more complex than other operators. /// 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>) { fn eq_or_neq(&self, backend: &mut WasmBackend<'a>) {
let arg_layout = backend.storage.symbol_layouts[&self.arguments[0]]; let arg_layout =
let other_arg_layout = backend.storage.symbol_layouts[&self.arguments[1]]; backend.storage.symbol_layouts[&self.arguments[0]].runtime_representation();
let other_arg_layout =
backend.storage.symbol_layouts[&self.arguments[1]].runtime_representation();
debug_assert!( debug_assert!(
arg_layout == other_arg_layout, 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); let invert_result = matches!(self.lowlevel, LowLevel::NotEq);
@ -2113,6 +2117,18 @@ pub fn call_higher_order_lowlevel<'a>(
.. ..
} = passed_function; } = 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 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) = let (closure_data_layout, closure_data_exists) =
match backend.storage.symbol_layouts[captured_environment] { match backend.storage.symbol_layouts[captured_environment] {
Layout::LambdaSet(lambda_set) => { Layout::LambdaSet(lambda_set) => {
@ -2131,6 +2147,46 @@ pub fn call_higher_order_lowlevel<'a>(
x => internal_error!("Closure data has an invalid layout\n{:?}", x), 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 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]));
// 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 (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
),
};
// 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,
wrapped_storage_local_ptr,
wrapped_storage_offset,
*captured_environment,
);
(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 unwrap this.
(*captured_environment, closure_data_layout)
};
// We create a wrapper around the passed function, which just unboxes the arguments. // We create a wrapper around the passed function, which just unboxes the arguments.
// This allows Zig builtins to have a generic pointer-based interface. // This allows Zig builtins to have a generic pointer-based interface.
let helper_proc_source = { let helper_proc_source = {
@ -2164,7 +2220,7 @@ pub fn call_higher_order_lowlevel<'a>(
argument_layouts.len() argument_layouts.len()
}; };
wrapper_arg_layouts.push(closure_data_layout); wrapper_arg_layouts.push(wrapped_captures_layout);
wrapper_arg_layouts.extend( wrapper_arg_layouts.extend(
argument_layouts argument_layouts
.iter() .iter()
@ -2204,7 +2260,7 @@ pub fn call_higher_order_lowlevel<'a>(
.get_refcount_fn_index(Layout::Builtin(Builtin::Int(IntWidth::I32)), HelperOp::Inc); .get_refcount_fn_index(Layout::Builtin(Builtin::Int(IntWidth::I32)), HelperOp::Inc);
backend.get_fn_ptr(inc_fn) backend.get_fn_ptr(inc_fn)
} else { } 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) backend.get_fn_ptr(inc_fn)
}; };
@ -2218,7 +2274,7 @@ pub fn call_higher_order_lowlevel<'a>(
wrapper_fn_ptr, wrapper_fn_ptr,
inc_fn_ptr, inc_fn_ptr,
closure_data_exists, closure_data_exists,
*captured_environment, wrapped_captured_environment,
*owns_captured_environment, *owns_captured_environment,
), ),
@ -2231,7 +2287,7 @@ pub fn call_higher_order_lowlevel<'a>(
wrapper_fn_ptr, wrapper_fn_ptr,
inc_fn_ptr, inc_fn_ptr,
closure_data_exists, closure_data_exists,
*captured_environment, wrapped_captured_environment,
*owns_captured_environment, *owns_captured_environment,
), ),
@ -2244,7 +2300,7 @@ pub fn call_higher_order_lowlevel<'a>(
wrapper_fn_ptr, wrapper_fn_ptr,
inc_fn_ptr, inc_fn_ptr,
closure_data_exists, closure_data_exists,
*captured_environment, wrapped_captured_environment,
*owns_captured_environment, *owns_captured_environment,
), ),
@ -2257,7 +2313,7 @@ pub fn call_higher_order_lowlevel<'a>(
wrapper_fn_ptr, wrapper_fn_ptr,
inc_fn_ptr, inc_fn_ptr,
closure_data_exists, closure_data_exists,
*captured_environment, wrapped_captured_environment,
*owns_captured_environment, *owns_captured_environment,
), ),
@ -2280,7 +2336,9 @@ pub fn call_higher_order_lowlevel<'a>(
backend.storage.load_symbol_zig(cb, *xs); backend.storage.load_symbol_zig(cb, *xs);
cb.i32_const(wrapper_fn_ptr); cb.i32_const(wrapper_fn_ptr);
if closure_data_exists { if closure_data_exists {
backend.storage.load_symbols(cb, &[*captured_environment]); backend
.storage
.load_symbols(cb, &[wrapped_captured_environment]);
} else { } else {
// load_symbols assumes that a zero-size arg should be eliminated in code gen, // 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. // but that's a specialization that our Zig code doesn't have! Pass a null pointer.

View File

@ -719,9 +719,10 @@ impl<'a> Storage<'a> {
) => { ) => {
debug_assert!(to_value_type == from_value_type); debug_assert!(to_value_type == from_value_type);
debug_assert!(to_size == from_size); 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]); self.load_symbols(code_builder, &[from_symbol]);
code_builder.set_local(*to_local_id); code_builder.set_local(*to_local_id);
self.symbol_storage_map.insert(from_symbol, to.clone());
} }
( (

View File

@ -1,8 +1,9 @@
#![allow(clippy::manual_map)] #![allow(clippy::manual_map)]
use crate::layout::{ use crate::layout::{
Builtin, CapturesNiche, ClosureRepresentation, LambdaName, LambdaSet, Layout, LayoutCache, Builtin, CapturesNiche, ClosureCallOptions, ClosureRepresentation, EnumDispatch, LambdaName,
LayoutProblem, RawFunctionLayout, TagIdIntType, UnionLayout, WrappedVariant, LambdaSet, Layout, LayoutCache, LayoutProblem, RawFunctionLayout, TagIdIntType, UnionLayout,
WrappedVariant,
}; };
use bumpalo::collections::{CollectIn, Vec}; use bumpalo::collections::{CollectIn, Vec};
use bumpalo::Bump; use bumpalo::Bump;
@ -3114,6 +3115,8 @@ fn specialize_external<'a>(
closure: opt_closure_layout, closure: opt_closure_layout,
ret_layout, ret_layout,
} => { } => {
let mut proc_args = Vec::from_iter_in(proc_args.iter().copied(), env.arena);
// unpack the closure symbols, if any // unpack the closure symbols, if any
match (opt_closure_layout, captured_symbols) { match (opt_closure_layout, captured_symbols) {
(Some(closure_layout), CapturedSymbols::Captured(captured)) => { (Some(closure_layout), CapturedSymbols::Captured(captured)) => {
@ -3233,41 +3236,35 @@ fn specialize_external<'a>(
} }
} }
ClosureRepresentation::Other(layout) => match layout { ClosureRepresentation::UnwrappedCapture(_layout) => {
Layout::Builtin(Builtin::Bool) => { debug_assert_eq!(captured.len(), 1);
// just ignore this value let (captured_symbol, _captured_layout) = captured[0];
// IDEA don't pass this value in the future
} // The capture set is unwrapped, so simply replace the closure argument
Layout::Builtin(Builtin::Int(IntWidth::U8)) => { // to the function with the unwrapped capture name.
// just ignore this value let captured_symbol = get_specialized_name(captured_symbol);
// IDEA don't pass this value in the future let closure_arg = proc_args.last_mut().unwrap();
} debug_assert_eq!(closure_arg.1, Symbol::ARG_CLOSURE);
other => { closure_arg.1 = captured_symbol;
// NOTE other values always should be wrapped in a 1-element record }
unreachable!(
"{:?} is not a valid closure data representation", ClosureRepresentation::EnumDispatch(_) => {
other // 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([])) => {} (None, CapturedSymbols::None) | (None, CapturedSymbols::Captured([])) => {}
_ => unreachable!("to closure or not to closure?"), _ => unreachable!("to closure or not to closure?"),
} }
let proc_args: Vec<_> = proc_args proc_args.iter_mut().for_each(|(_layout, symbol)| {
.iter() // Grab the specialization symbol, if it exists.
.map(|&(layout, symbol)| { *symbol = procs
// Grab the specialization symbol, if it exists. .symbol_specializations
let symbol = procs .remove_single(*symbol)
.symbol_specializations .unwrap_or(*symbol);
.remove_single(symbol) });
.unwrap_or(symbol);
(layout, symbol)
})
.collect_in(env.arena);
// reset subs, so we don't get type errors when specializing for a different signature // reset subs, so we don't get type errors when specializing for a different signature
layout_cache.rollback_to(cache_snapshot); layout_cache.rollback_to(cache_snapshot);
@ -5383,29 +5380,42 @@ where
Stmt::Let(assigned, expr, lambda_set_layout, hole) Stmt::Let(assigned, expr, lambda_set_layout, hole)
} }
ClosureRepresentation::Other(Layout::Builtin(Builtin::Bool)) => { ClosureRepresentation::UnwrappedCapture(_layout) => {
debug_assert_eq!(symbols.len(), 0); debug_assert_eq!(symbols.len(), 1);
debug_assert_eq!(lambda_set.set.len(), 2); let mut symbols = symbols;
let tag_id = name.name() != lambda_set.iter_set().next().unwrap().name(); let (captured_symbol, _) = symbols.next().unwrap();
let expr = Expr::Literal(Literal::Bool(tag_id));
Stmt::Let(assigned, expr, lambda_set_layout, 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::Other(Layout::Builtin(Builtin::Int(IntWidth::U8))) => { ClosureRepresentation::EnumDispatch(repr) => match repr {
debug_assert_eq!(symbols.len(), 0); EnumDispatch::Bool => {
debug_assert_eq!(symbols.len(), 0);
debug_assert!(lambda_set.set.len() > 2); debug_assert_eq!(lambda_set.len(), 2);
let tag_id = lambda_set let tag_id = name.name() != lambda_set.iter_set().next().unwrap().name();
.iter_set() let expr = Expr::Literal(Literal::Bool(tag_id));
.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)
}
EnumDispatch::U8 => {
debug_assert_eq!(symbols.len(), 0);
Stmt::Let(assigned, expr, lambda_set_layout, hole) debug_assert!(lambda_set.len() > 2);
} let tag_id = lambda_set
_ => unreachable!(), .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)
}
},
}; };
result result
@ -5844,10 +5854,7 @@ fn register_capturing_closure<'a>(
Content::Structure(FlatType::Func(_, closure_var, _)) => { Content::Structure(FlatType::Func(_, closure_var, _)) => {
match LambdaSet::from_var(env.arena, env.subs, closure_var, env.target_info) { match LambdaSet::from_var(env.arena, env.subs, closure_var, env.target_info) {
Ok(lambda_set) => { Ok(lambda_set) => {
if let Layout::Struct { if lambda_set.is_represented().is_none() {
field_layouts: &[], ..
} = lambda_set.runtime_representation()
{
CapturedSymbols::None CapturedSymbols::None
} else { } else {
let mut temp = Vec::from_iter_in(captured_symbols, env.arena); let mut temp = Vec::from_iter_in(captured_symbols, env.arena);
@ -9088,9 +9095,9 @@ fn lowlevel_match_on_lambda_set<'a, ToLowLevelCall>(
where where
ToLowLevelCall: Fn(ToLowLevelCallArguments<'a>) -> Call<'a> + Copy, ToLowLevelCall: Fn(ToLowLevelCallArguments<'a>) -> Call<'a> + Copy,
{ {
match lambda_set.runtime_representation() { match lambda_set.call_by_name_options() {
Layout::VOID => empty_lambda_set_error(), ClosureCallOptions::Void => empty_lambda_set_error(),
Layout::Union(union_layout) => { ClosureCallOptions::Union(union_layout) => {
let closure_tag_id_symbol = env.unique_symbol(); let closure_tag_id_symbol = env.unique_symbol();
let result = lowlevel_union_lambda_set_to_switch( let result = lowlevel_union_lambda_set_to_switch(
@ -9119,7 +9126,7 @@ where
env.arena.alloc(result), env.arena.alloc(result),
) )
} }
Layout::Struct { .. } => match lambda_set.iter_set().next() { ClosureCallOptions::Struct { .. } => match lambda_set.iter_set().next() {
Some(lambda_name) => { Some(lambda_name) => {
let call_spec_id = env.next_call_specialization_id(); let call_spec_id = env.next_call_specialization_id();
let update_mode = env.next_update_mode_id(); let update_mode = env.next_update_mode_id();
@ -9144,39 +9151,58 @@ where
hole.clone() hole.clone()
} }
}, },
Layout::Builtin(Builtin::Bool) => { ClosureCallOptions::UnwrappedCapture(_) => {
let closure_tag_id_symbol = closure_data_symbol; let lambda_name = lambda_set
.iter_set()
.next()
.expect("no function in lambda set");
lowlevel_enum_lambda_set_to_switch( let call_spec_id = env.next_call_specialization_id();
env, let update_mode = env.next_update_mode_id();
lambda_set.iter_set(), let call = to_lowlevel_call((
closure_tag_id_symbol, lambda_name,
Layout::Builtin(Builtin::Bool),
closure_data_symbol, closure_data_symbol,
lambda_set.is_represented(), lambda_set.is_represented(),
to_lowlevel_call, call_spec_id,
return_layout, update_mode,
assigned, ));
hole,
)
}
Layout::Builtin(Builtin::Int(IntWidth::U8)) => {
let closure_tag_id_symbol = closure_data_symbol;
lowlevel_enum_lambda_set_to_switch( build_call(env, call, assigned, return_layout, env.arena.alloc(hole))
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 => todo!("{:?}", other), ClosureCallOptions::EnumDispatch(repr) => match repr {
EnumDispatch::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,
)
}
EnumDispatch::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,
)
}
},
} }
} }
@ -9267,15 +9293,14 @@ fn match_on_lambda_set<'a>(
assigned: Symbol, assigned: Symbol,
hole: &'a Stmt<'a>, hole: &'a Stmt<'a>,
) -> Stmt<'a> { ) -> Stmt<'a> {
match lambda_set.runtime_representation() { match lambda_set.call_by_name_options() {
Layout::VOID => empty_lambda_set_error(), ClosureCallOptions::Void => empty_lambda_set_error(),
Layout::Union(union_layout) => { ClosureCallOptions::Union(union_layout) => {
let closure_tag_id_symbol = env.unique_symbol(); let closure_tag_id_symbol = env.unique_symbol();
let result = union_lambda_set_to_switch( let result = union_lambda_set_to_switch(
env, env,
lambda_set, lambda_set,
Layout::Union(union_layout),
closure_tag_id_symbol, closure_tag_id_symbol,
union_layout.tag_id_layout(), union_layout.tag_id_layout(),
closure_data_symbol, closure_data_symbol,
@ -9299,9 +9324,9 @@ fn match_on_lambda_set<'a>(
env.arena.alloc(result), env.arena.alloc(result),
) )
} }
Layout::Struct { ClosureCallOptions::Struct {
field_layouts, field_layouts,
field_order_hash, field_order_hash: _,
} => { } => {
let function_symbol = match lambda_set.iter_set().next() { let function_symbol = match lambda_set.iter_set().next() {
Some(function_symbol) => function_symbol, Some(function_symbol) => function_symbol,
@ -9325,10 +9350,6 @@ fn match_on_lambda_set<'a>(
_ => ClosureInfo::Captures { _ => ClosureInfo::Captures {
lambda_set, lambda_set,
closure_data_symbol, closure_data_symbol,
closure_data_layout: Layout::Struct {
field_layouts,
field_order_hash,
},
}, },
}; };
@ -9343,15 +9364,21 @@ fn match_on_lambda_set<'a>(
hole, hole,
) )
} }
Layout::Builtin(Builtin::Bool) => { ClosureCallOptions::UnwrappedCapture(_) => {
let closure_tag_id_symbol = closure_data_symbol; let function_symbol = lambda_set
.iter_set()
.next()
.expect("no function in lambda set");
enum_lambda_set_to_switch( let closure_info = ClosureInfo::Captures {
env, lambda_set,
lambda_set.iter_set(),
closure_tag_id_symbol,
Layout::Builtin(Builtin::Bool),
closure_data_symbol, closure_data_symbol,
};
union_lambda_set_branch_help(
env,
function_symbol,
closure_info,
argument_symbols, argument_symbols,
argument_layouts, argument_layouts,
return_layout, return_layout,
@ -9359,23 +9386,38 @@ fn match_on_lambda_set<'a>(
hole, hole,
) )
} }
Layout::Builtin(Builtin::Int(IntWidth::U8)) => { ClosureCallOptions::EnumDispatch(repr) => match repr {
let closure_tag_id_symbol = closure_data_symbol; EnumDispatch::Bool => {
let closure_tag_id_symbol = closure_data_symbol;
enum_lambda_set_to_switch( enum_lambda_set_to_switch(
env, env,
lambda_set.iter_set(), lambda_set.iter_set(),
closure_tag_id_symbol, closure_tag_id_symbol,
Layout::Builtin(Builtin::Int(IntWidth::U8)), Layout::Builtin(Builtin::Bool),
closure_data_symbol, argument_symbols,
argument_symbols, argument_layouts,
argument_layouts, return_layout,
return_layout, assigned,
assigned, hole,
hole, )
) }
} EnumDispatch::U8 => {
other => todo!("{:?}", other), 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)),
argument_symbols,
argument_layouts,
return_layout,
assigned,
hole,
)
}
},
} }
} }
@ -9383,7 +9425,6 @@ fn match_on_lambda_set<'a>(
fn union_lambda_set_to_switch<'a>( fn union_lambda_set_to_switch<'a>(
env: &mut Env<'a, '_>, env: &mut Env<'a, '_>,
lambda_set: LambdaSet<'a>, lambda_set: LambdaSet<'a>,
closure_layout: Layout<'a>,
closure_tag_id_symbol: Symbol, closure_tag_id_symbol: Symbol,
closure_tag_id_layout: Layout<'a>, closure_tag_id_layout: Layout<'a>,
closure_data_symbol: Symbol, closure_data_symbol: Symbol,
@ -9393,7 +9434,7 @@ fn union_lambda_set_to_switch<'a>(
assigned: Symbol, assigned: Symbol,
hole: &'a Stmt<'a>, hole: &'a Stmt<'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, // 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 // 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 // code gen to proceed. We then assume that we hit another (more descriptive) error before
@ -9403,7 +9444,7 @@ fn union_lambda_set_to_switch<'a>(
let join_point_id = JoinPointId(env.unique_symbol()); 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() { for (i, lambda_name) in lambda_set.iter_set().enumerate() {
let closure_info = if lambda_name.no_captures() { let closure_info = if lambda_name.no_captures() {
@ -9412,7 +9453,6 @@ fn union_lambda_set_to_switch<'a>(
ClosureInfo::Captures { ClosureInfo::Captures {
lambda_set, lambda_set,
closure_data_symbol, closure_data_symbol,
closure_data_layout: closure_layout,
} }
}; };
@ -9482,11 +9522,10 @@ fn union_lambda_set_branch<'a>(
) )
} }
#[derive(Clone, Copy)]
enum ClosureInfo<'a> { enum ClosureInfo<'a> {
Captures { Captures {
closure_data_symbol: Symbol, 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 /// The whole lambda set representation this closure is a variant of
lambda_set: LambdaSet<'a>, lambda_set: LambdaSet<'a>,
}, },
@ -9508,34 +9547,21 @@ fn union_lambda_set_branch_help<'a>(
ClosureInfo::Captures { ClosureInfo::Captures {
lambda_set, lambda_set,
closure_data_symbol, closure_data_symbol,
closure_data_layout, } => {
} => match closure_data_layout { let argument_layouts =
Layout::Struct { lambda_set.extend_argument_list(env.arena, argument_layouts_slice);
field_layouts: &[], .. let argument_symbols = if argument_layouts.len() > argument_layouts_slice.len() {
}
| 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(Layout::LambdaSet(lambda_set));
// extend symbols with the symbol of the closure environment // extend symbols with the symbol of the closure environment
let mut argument_symbols = let mut argument_symbols =
Vec::with_capacity_in(argument_symbols_slice.len() + 1, env.arena); Vec::with_capacity_in(argument_symbols_slice.len() + 1, env.arena);
argument_symbols.extend(argument_symbols_slice); argument_symbols.extend(argument_symbols_slice);
argument_symbols.push(closure_data_symbol); argument_symbols.push(closure_data_symbol);
argument_symbols.into_bump_slice()
( } else {
argument_layouts.into_bump_slice(), argument_symbols_slice
argument_symbols.into_bump_slice(), };
) (argument_layouts, argument_symbols)
} }
},
ClosureInfo::DoesNotCapture => { ClosureInfo::DoesNotCapture => {
// sometimes unification causes a function that does not itself capture anything // 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 // to still get a lambda set that does store information. We must not pass a closure
@ -9559,13 +9585,14 @@ fn union_lambda_set_branch_help<'a>(
build_call(env, call, assigned, *return_layout, hole) 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)] #[allow(clippy::too_many_arguments)]
fn enum_lambda_set_to_switch<'a>( fn enum_lambda_set_to_switch<'a>(
env: &mut Env<'a, '_>, env: &mut Env<'a, '_>,
lambda_set: impl ExactSizeIterator<Item = LambdaName<'a>>, lambda_set: impl ExactSizeIterator<Item = LambdaName<'a>>,
closure_tag_id_symbol: Symbol, closure_tag_id_symbol: Symbol,
closure_tag_id_layout: Layout<'a>, closure_tag_id_layout: Layout<'a>,
closure_data_symbol: Symbol,
argument_symbols: &'a [Symbol], argument_symbols: &'a [Symbol],
argument_layouts: &'a [Layout<'a>], argument_layouts: &'a [Layout<'a>],
return_layout: &'a Layout<'a>, return_layout: &'a Layout<'a>,
@ -9578,15 +9605,11 @@ fn enum_lambda_set_to_switch<'a>(
let mut branches = Vec::with_capacity_in(lambda_set.len(), env.arena); 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() { for (i, lambda_name) in lambda_set.into_iter().enumerate() {
let stmt = enum_lambda_set_branch( let stmt = enum_lambda_set_branch(
env, env,
join_point_id, join_point_id,
lambda_name, lambda_name,
closure_data_symbol,
closure_layout,
argument_symbols, argument_symbols,
argument_layouts, argument_layouts,
return_layout, return_layout,
@ -9622,15 +9645,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)] #[allow(clippy::too_many_arguments)]
fn enum_lambda_set_branch<'a>( fn enum_lambda_set_branch<'a>(
env: &mut Env<'a, '_>, env: &mut Env<'a, '_>,
join_point_id: JoinPointId, join_point_id: JoinPointId,
lambda_name: LambdaName<'a>, lambda_name: LambdaName<'a>,
closure_data_symbol: Symbol, argument_symbols: &'a [Symbol],
closure_data_layout: Layout<'a>, argument_layouts: &'a [Layout<'a>],
argument_symbols_slice: &'a [Symbol],
argument_layouts_slice: &'a [Layout<'a>],
return_layout: &'a Layout<'a>, return_layout: &'a Layout<'a>,
) -> Stmt<'a> { ) -> Stmt<'a> {
let result_symbol = env.unique_symbol(); let result_symbol = env.unique_symbol();
@ -9639,34 +9661,6 @@ fn enum_lambda_set_branch<'a>(
let assigned = result_symbol; 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);
// 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(),
)
}
};
let call = self::Call { let call = self::Call {
call_type: CallType::ByName { call_type: CallType::ByName {
name: lambda_name, name: lambda_name,

View File

@ -783,28 +783,56 @@ impl<'a> LambdaName<'a> {
#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] #[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct LambdaSet<'a> { pub struct LambdaSet<'a> {
/// collection of function names and their closure arguments /// 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 /// how the closure will be represented at runtime
representation: &'a Layout<'a>, representation: &'a Layout<'a>,
} }
#[derive(Debug)]
pub enum EnumDispatch {
Bool,
U8,
}
/// representation of the closure *for a particular function* /// representation of the closure *for a particular function*
#[derive(Debug)] #[derive(Debug)]
pub enum ClosureRepresentation<'a> { 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 { Union {
alphabetic_order_fields: &'a [Layout<'a>], alphabetic_order_fields: &'a [Layout<'a>],
closure_name: Symbol, closure_name: Symbol,
tag_id: TagIdIntType, tag_id: TagIdIntType,
union_layout: UnionLayout<'a>, union_layout: UnionLayout<'a>,
}, },
/// The closure is represented as a struct. The layouts are sorted /// The closure is one function, whose captures are represented as a struct.
/// alphabetically by the identifier that is captured. /// The layouts are sorted alphabetically by the identifier that is captured.
/// ///
/// We MUST sort these according to their stack size before code gen! /// We MUST sort these according to their stack size before code gen!
AlphabeticOrderStruct(&'a [Layout<'a>]), AlphabeticOrderStruct(&'a [Layout<'a>]),
/// the representation is anything but a union /// The closure is one function that captures a single identifier, whose value is unwrapped.
Other(Layout<'a>), 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.
#[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 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> { impl<'a> LambdaSet<'a> {
@ -818,13 +846,17 @@ impl<'a> LambdaSet<'a> {
} }
pub fn is_represented(&self) -> Option<Layout<'a>> { pub fn is_represented(&self) -> Option<Layout<'a>> {
match self.representation { if self.has_unwrapped_capture_repr() {
Layout::Struct { Some(*self.representation)
field_layouts: &[], .. } else if self.has_enum_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),
} }
} }
@ -835,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( pub fn layout_for_member_with_lambda_name(
&self, &self,
lambda_name: LambdaName, lambda_name: LambdaName,
@ -923,6 +965,11 @@ impl<'a> LambdaSet<'a> {
where where
F: Fn(Symbol, &[Layout]) -> bool, 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 { match self.representation {
Layout::Union(union) => { Layout::Union(union) => {
// here we rely on the fact that a union in a closure would be stored in a one-element record. // here we rely on the fact that a union in a closure would be stored in a one-element record.
@ -1004,7 +1051,58 @@ impl<'a> LambdaSet<'a> {
ClosureRepresentation::AlphabeticOrderStruct(fields) ClosureRepresentation::AlphabeticOrderStruct(fields)
} }
_ => ClosureRepresentation::Other(*self.representation), 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)
}
}
}
fn has_unwrapped_capture_repr(&self) -> bool {
self.set.len() == 1 && self.set[0].1.len() == 1
}
fn has_enum_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_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)
}
} }
} }
@ -1013,30 +1111,27 @@ impl<'a> LambdaSet<'a> {
arena: &'a Bump, arena: &'a Bump,
argument_layouts: &'a [Layout<'a>], argument_layouts: &'a [Layout<'a>],
) -> &'a [Layout<'a>] { ) -> &'a [Layout<'a>] {
if let [] = self.set { match self.call_by_name_options() {
// TERRIBLE HACK for builting functions ClosureCallOptions::Void => argument_layouts,
argument_layouts ClosureCallOptions::Struct {
} else { field_layouts: &[], ..
match self.representation { } => {
Layout::Struct { // this function does not have anything in its closure, and the lambda set is a
field_layouts: &[], .. // singleton, so we pass no extra argument
} => { argument_layouts
// this function does not have anything in its closure, and the lambda set is a }
// singleton, so we pass no extra argument ClosureCallOptions::Struct { .. }
argument_layouts | ClosureCallOptions::Union(_)
} | ClosureCallOptions::UnwrappedCapture(_) => {
Layout::Builtin(Builtin::Bool) let mut arguments = Vec::with_capacity_in(argument_layouts.len() + 1, arena);
| Layout::Builtin(Builtin::Int(IntWidth::I8 | IntWidth::U8)) => { arguments.extend(argument_layouts);
// we don't pass this along either arguments.push(Layout::LambdaSet(*self));
argument_layouts
}
_ => {
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::EnumDispatch(_) => {
// No captures, don't pass this along
argument_layouts
} }
} }
} }
@ -1053,7 +1148,7 @@ impl<'a> LambdaSet<'a> {
lambdas.sort_by_key(|(sym, _)| *sym); lambdas.sort_by_key(|(sym, _)| *sym);
let mut set: Vec<(Symbol, &[Layout])> = Vec::with_capacity_in(lambdas.len(), arena); 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<Variable>)> = let mut set_with_variables: std::vec::Vec<(&Symbol, &[Variable])> =
std::vec::Vec::with_capacity(lambdas.len()); std::vec::Vec::with_capacity(lambdas.len());
let mut last_function_symbol = None; let mut last_function_symbol = None;
@ -1090,7 +1185,7 @@ impl<'a> LambdaSet<'a> {
has_duplicate_lambda_names = has_duplicate_lambda_names || is_multimorphic; has_duplicate_lambda_names = has_duplicate_lambda_names || is_multimorphic;
set.push((*function_symbol, arguments)); 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); last_function_symbol = Some(function_symbol);
} }
@ -1151,70 +1246,23 @@ impl<'a> LambdaSet<'a> {
fn make_representation( fn make_representation(
arena: &'a Bump, arena: &'a Bump,
subs: &Subs, subs: &Subs,
tags: std::vec::Vec<(Symbol, std::vec::Vec<Variable>)>, tags: std::vec::Vec<(&Symbol, &[Variable])>,
opt_rec_var: Option<Variable>, opt_rec_var: Option<Variable>,
target_info: TargetInfo, target_info: TargetInfo,
) -> Layout<'a> { ) -> Layout<'a> {
if let Some(rec_var) = opt_rec_var { let union_labels = UnsortedUnionLabels { tags };
let tags: std::vec::Vec<_> = tags let mut env = Env {
.iter() seen: Vec::new_in(arena),
.map(|(sym, vars)| (sym, vars.as_slice())) target_info,
.collect(); arena,
let tags = UnsortedUnionLabels { tags }; subs,
let mut env = Env { };
seen: Vec::new_in(arena),
target_info,
arena,
subs,
};
return layout_from_recursive_union(&mut env, rec_var, &tags) match opt_rec_var {
.expect("unable to create lambda set representation"); 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 None => layout_from_union(&mut env, &union_labels),
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")
}
}
}
} }
} }
@ -1777,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. /// Avoid recomputing Layout from Variable multiple times.

View File

@ -1234,8 +1234,8 @@ fn return_wrapped_closure() {
main = foo main = foo
"# "#
), ),
[5], 5,
[i64; 1] i64
); );
} }

View File

@ -4,17 +4,15 @@ procedure List.6 (#Attr.2):
procedure Test.1 (Test.5): procedure Test.1 (Test.5):
let Test.2 : I64 = 41i64; let Test.2 : I64 = 41i64;
let Test.10 : {I64} = Struct {Test.2}; let Test.9 : List I64 = Array [Test.2];
let Test.9 : List {I64} = Array [Test.10];
ret Test.9; ret Test.9;
procedure Test.3 (Test.8, #Attr.12): procedure Test.3 (Test.8, Test.2):
let Test.2 : I64 = StructAtIndex 0 #Attr.12;
ret Test.2; ret Test.2;
procedure Test.0 (): procedure Test.0 ():
let Test.7 : {} = Struct {}; 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; let Test.6 : U64 = CallByName List.6 Test.4;
dec Test.4; dec Test.4;
ret Test.6; ret Test.6;

View File

@ -12,22 +12,20 @@ procedure List.71 (#Attr.2, #Attr.3):
let List.388 : List U8 = lowlevel ListAppendUnsafe #Attr.2 #Attr.3; let List.388 : List U8 = lowlevel ListAppendUnsafe #Attr.2 #Attr.3;
ret List.388; ret List.388;
procedure Test.23 (Test.24, Test.35, #Attr.12): procedure Test.23 (Test.24, Test.35, Test.22):
let Test.22 : U8 = StructAtIndex 0 #Attr.12;
let Test.37 : List U8 = CallByName List.4 Test.24 Test.22; let Test.37 : List U8 = CallByName List.4 Test.24 Test.22;
ret Test.37; ret Test.37;
procedure Test.8 (Test.22): procedure Test.8 (Test.22):
let Test.34 : {U8} = Struct {Test.22}; ret Test.22;
ret Test.34;
procedure Test.9 (Test.27): 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; ret Test.33;
procedure Test.0 (): procedure Test.0 ():
let Test.32 : U8 = 15i64; 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.30 : List U8 = Array [];
let Test.31 : {} = Struct {}; let Test.31 : {} = Struct {};
let Test.29 : List U8 = CallByName Test.23 Test.30 Test.31 Test.28; let Test.29 : List U8 = CallByName Test.23 Test.30 Test.31 Test.28;

View File

@ -1,34 +1,26 @@
procedure #Derived.0 (#Derived.1): procedure #Derived.0 (#Derived.1):
let #Derived_gen.1 : {Str} = Struct {#Derived.1}; let #Derived_gen.0 : Str = CallByName Encode.22 #Derived.1;
let #Derived_gen.0 : {Str} = CallByName Encode.22 #Derived_gen.1;
ret #Derived_gen.0; ret #Derived_gen.0;
procedure #Derived.2 (#Derived.3, #Derived.4, #Attr.12): procedure #Derived.2 (#Derived.3, #Derived.4, #Derived.1):
let #Derived.1 : Str = StructAtIndex 0 #Attr.12;
inc #Derived.1;
dec #Attr.12;
let #Derived_gen.7 : Str = "a"; let #Derived_gen.7 : Str = "a";
let #Derived_gen.8 : {Str} = CallByName #Derived.5 #Derived.1; 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.6 : {Str, Str} = Struct {#Derived_gen.7, #Derived_gen.8};
let #Derived_gen.5 : List {Str, {Str}} = Array [#Derived_gen.6]; 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.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; let #Derived_gen.3 : List U8 = CallByName Encode.23 #Derived.3 #Derived_gen.4 #Derived.4;
ret #Derived_gen.3; ret #Derived_gen.3;
procedure #Derived.5 (#Derived.6): procedure #Derived.5 (#Derived.6):
let #Derived_gen.15 : {Str} = Struct {#Derived.6}; let #Derived_gen.14 : Str = CallByName Encode.22 #Derived.6;
let #Derived_gen.14 : {Str} = CallByName Encode.22 #Derived_gen.15;
ret #Derived_gen.14; ret #Derived_gen.14;
procedure #Derived.7 (#Derived.8, #Derived.9, #Attr.12): procedure #Derived.7 (#Derived.8, #Derived.9, #Derived.6):
let #Derived.6 : Str = StructAtIndex 0 #Attr.12;
inc #Derived.6;
dec #Attr.12;
let #Derived_gen.21 : Str = "b"; let #Derived_gen.21 : Str = "b";
let #Derived_gen.22 : {Str} = CallByName Json.18 #Derived.6; 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.20 : {Str, Str} = Struct {#Derived_gen.21, #Derived_gen.22};
let #Derived_gen.19 : List {Str, {Str}} = Array [#Derived_gen.20]; 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.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; let #Derived_gen.17 : List U8 = CallByName Encode.23 #Derived.8 #Derived_gen.18 #Derived.9;
ret #Derived_gen.17; ret #Derived_gen.17;
@ -69,7 +61,7 @@ procedure Encode.23 (Encode.94, Encode.102, Encode.96):
procedure Encode.25 (Encode.100, Encode.101): procedure Encode.25 (Encode.100, Encode.101):
let Encode.104 : List U8 = Array []; 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; let Encode.103 : List U8 = CallByName Encode.23 Encode.104 Encode.105 Encode.101;
ret Encode.103; ret Encode.103;
@ -77,10 +69,7 @@ procedure Json.1 ():
let Json.318 : {} = Struct {}; let Json.318 : {} = Struct {};
ret Json.318; ret Json.318;
procedure Json.103 (Json.104, Json.321, #Attr.12): procedure Json.103 (Json.104, Json.321, Json.102):
let Json.102 : List {Str, {Str}} = StructAtIndex 0 #Attr.12;
inc Json.102;
dec #Attr.12;
let Json.354 : I32 = 123i64; let Json.354 : I32 = 123i64;
let Json.353 : U8 = CallByName Num.123 Json.354; let Json.353 : U8 = CallByName Num.123 Json.354;
let Json.106 : List U8 = CallByName List.4 Json.104 Json.353; let Json.106 : List U8 = CallByName List.4 Json.104 Json.353;
@ -97,10 +86,7 @@ procedure Json.103 (Json.104, Json.321, #Attr.12):
let Json.325 : List U8 = CallByName List.4 Json.108 Json.326; let Json.325 : List U8 = CallByName List.4 Json.108 Json.326;
ret Json.325; ret Json.325;
procedure Json.103 (Json.104, Json.321, #Attr.12): procedure Json.103 (Json.104, Json.321, Json.102):
let Json.102 : List {Str, {Str}} = StructAtIndex 0 #Attr.12;
inc Json.102;
dec #Attr.12;
let Json.397 : I32 = 123i64; let Json.397 : I32 = 123i64;
let Json.396 : U8 = CallByName Num.123 Json.397; let Json.396 : U8 = CallByName Num.123 Json.397;
let Json.106 : List U8 = CallByName List.4 Json.104 Json.396; let Json.106 : List U8 = CallByName List.4 Json.104 Json.396;
@ -120,7 +106,7 @@ procedure Json.103 (Json.104, Json.321, #Attr.12):
procedure Json.105 (Json.323, Json.324): procedure Json.105 (Json.323, Json.324):
let Json.111 : Str = StructAtIndex 0 Json.324; let Json.111 : Str = StructAtIndex 0 Json.324;
inc Json.111; inc Json.111;
let Json.112 : {Str} = StructAtIndex 1 Json.324; let Json.112 : Str = StructAtIndex 1 Json.324;
inc Json.112; inc Json.112;
dec Json.324; dec Json.324;
let Json.109 : List U8 = StructAtIndex 0 Json.323; let Json.109 : List U8 = StructAtIndex 0 Json.323;
@ -159,7 +145,7 @@ procedure Json.105 (Json.323, Json.324):
procedure Json.105 (Json.323, Json.324): procedure Json.105 (Json.323, Json.324):
let Json.111 : Str = StructAtIndex 0 Json.324; let Json.111 : Str = StructAtIndex 0 Json.324;
inc Json.111; inc Json.111;
let Json.112 : {Str} = StructAtIndex 1 Json.324; let Json.112 : Str = StructAtIndex 1 Json.324;
inc Json.112; inc Json.112;
dec Json.324; dec Json.324;
let Json.109 : List U8 = StructAtIndex 0 Json.323; let Json.109 : List U8 = StructAtIndex 0 Json.323;
@ -196,24 +182,18 @@ procedure Json.105 (Json.323, Json.324):
jump Json.378 Json.113; jump Json.378 Json.113;
procedure Json.18 (Json.86): procedure Json.18 (Json.86):
let Json.365 : {Str} = Struct {Json.86}; let Json.364 : Str = CallByName Encode.22 Json.86;
let Json.364 : {Str} = CallByName Encode.22 Json.365;
ret Json.364; ret Json.364;
procedure Json.20 (Json.102): procedure Json.20 (Json.102):
let Json.320 : {List {Str, {Str}}} = Struct {Json.102}; let Json.319 : List {Str, Str} = CallByName Encode.22 Json.102;
let Json.319 : {List {Str, {Str}}} = CallByName Encode.22 Json.320;
ret Json.319; ret Json.319;
procedure Json.20 (Json.102): procedure Json.20 (Json.102):
let Json.362 : {List {Str, {Str}}} = Struct {Json.102}; let Json.361 : List {Str, Str} = CallByName Encode.22 Json.102;
let Json.361 : {List {Str, {Str}}} = CallByName Encode.22 Json.362;
ret Json.361; ret Json.361;
procedure Json.87 (Json.88, Json.366, #Attr.12): procedure Json.87 (Json.88, Json.366, Json.86):
let Json.86 : Str = StructAtIndex 0 #Attr.12;
inc Json.86;
dec #Attr.12;
let Json.406 : I32 = 34i64; let Json.406 : I32 = 34i64;
let Json.405 : U8 = CallByName Num.123 Json.406; let Json.405 : U8 = CallByName Num.123 Json.406;
let Json.403 : List U8 = CallByName List.4 Json.88 Json.405; let Json.403 : List U8 = CallByName List.4 Json.88 Json.405;
@ -224,21 +204,18 @@ procedure Json.87 (Json.88, Json.366, #Attr.12):
let Json.399 : List U8 = CallByName List.4 Json.400 Json.401; let Json.399 : List U8 = CallByName List.4 Json.400 Json.401;
ret Json.399; ret Json.399;
procedure List.133 (List.134, List.135, #Attr.12): procedure List.133 (List.134, List.135, List.132):
let List.132 : {} = StructAtIndex 0 #Attr.12;
let List.434 : {List U8, U64} = CallByName Json.105 List.134 List.135; 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; let List.433 : [C [], C {List U8, U64}] = TagId(1) List.434;
ret List.433; ret List.433;
procedure List.133 (List.134, List.135, #Attr.12): procedure List.133 (List.134, List.135, List.132):
let List.132 : {} = StructAtIndex 0 #Attr.12;
let List.515 : {List U8, U64} = CallByName Json.105 List.134 List.135; 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; let List.514 : [C [], C {List U8, U64}] = TagId(1) List.515;
ret List.514; ret List.514;
procedure List.18 (List.130, List.131, List.132): procedure List.18 (List.130, List.131, List.132):
let List.411 : {{}} = Struct {List.132}; let List.405 : [C [], C {List U8, U64}] = CallByName List.75 List.130 List.131 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.408 : U8 = 1i64;
let List.409 : U8 = GetTagId List.405; let List.409 : U8 = GetTagId List.405;
let List.410 : Int1 = lowlevel Eq List.408 List.409; let List.410 : Int1 = lowlevel Eq List.408 List.409;
@ -254,8 +231,7 @@ procedure List.18 (List.130, List.131, List.132):
ret List.407; ret List.407;
procedure List.18 (List.130, List.131, List.132): 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.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.488 : U8 = 1i64;
let List.489 : U8 = GetTagId List.485; let List.489 : U8 = GetTagId List.485;
let List.490 : Int1 = lowlevel Eq List.488 List.489; let List.490 : Int1 = lowlevel Eq List.488 List.489;
@ -289,11 +265,11 @@ procedure List.6 (#Attr.2):
ret List.494; ret List.494;
procedure List.66 (#Attr.2, #Attr.3): procedure List.66 (#Attr.2, #Attr.3):
let List.432 : {Str, {Str}} = lowlevel ListGetUnsafe #Attr.2 #Attr.3; let List.432 : {Str, Str} = lowlevel ListGetUnsafe #Attr.2 #Attr.3;
ret List.432; ret List.432;
procedure List.66 (#Attr.2, #Attr.3): procedure List.66 (#Attr.2, #Attr.3):
let List.513 : {Str, {Str}} = lowlevel ListGetUnsafe #Attr.2 #Attr.3; let List.513 : {Str, Str} = lowlevel ListGetUnsafe #Attr.2 #Attr.3;
ret List.513; ret List.513;
procedure List.69 (#Attr.2): procedure List.69 (#Attr.2):
@ -328,7 +304,7 @@ 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: joinpoint List.420 List.364 List.365 List.366 List.367 List.368:
let List.422 : Int1 = CallByName Num.22 List.367 List.368; let List.422 : Int1 = CallByName Num.22 List.367 List.368;
if List.422 then if List.422 then
let List.431 : {Str, {Str}} = CallByName List.66 List.364 List.367; 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.423 : [C [], C {List U8, U64}] = CallByName List.133 List.365 List.431 List.366;
let List.428 : U8 = 1i64; let List.428 : U8 = 1i64;
let List.429 : U8 = GetTagId List.423; let List.429 : U8 = GetTagId List.423;
@ -355,7 +331,7 @@ 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: joinpoint List.501 List.364 List.365 List.366 List.367 List.368:
let List.503 : Int1 = CallByName Num.22 List.367 List.368; let List.503 : Int1 = CallByName Num.22 List.367 List.368;
if List.503 then if List.503 then
let List.512 : {Str, {Str}} = CallByName List.66 List.364 List.367; 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.504 : [C [], C {List U8, U64}] = CallByName List.133 List.365 List.512 List.366;
let List.509 : U8 = 1i64; let List.509 : U8 = 1i64;
let List.510 : U8 = GetTagId List.504; let List.510 : U8 = GetTagId List.504;

View File

@ -1,17 +1,13 @@
procedure #Derived.0 (#Derived.1): procedure #Derived.0 (#Derived.1):
let #Derived_gen.1 : {Str} = Struct {#Derived.1}; let #Derived_gen.0 : Str = CallByName Encode.22 #Derived.1;
let #Derived_gen.0 : {Str} = CallByName Encode.22 #Derived_gen.1;
ret #Derived_gen.0; ret #Derived_gen.0;
procedure #Derived.2 (#Derived.3, #Derived.4, #Attr.12): procedure #Derived.2 (#Derived.3, #Derived.4, #Derived.1):
let #Derived.1 : Str = StructAtIndex 0 #Attr.12;
inc #Derived.1;
dec #Attr.12;
let #Derived_gen.7 : Str = "a"; let #Derived_gen.7 : Str = "a";
let #Derived_gen.8 : {Str} = CallByName Json.18 #Derived.1; 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.6 : {Str, Str} = Struct {#Derived_gen.7, #Derived_gen.8};
let #Derived_gen.5 : List {Str, {Str}} = Array [#Derived_gen.6]; 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.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; let #Derived_gen.3 : List U8 = CallByName Encode.23 #Derived.3 #Derived_gen.4 #Derived.4;
ret #Derived_gen.3; ret #Derived_gen.3;
@ -38,7 +34,7 @@ procedure Encode.23 (Encode.94, Encode.102, Encode.96):
procedure Encode.25 (Encode.100, Encode.101): procedure Encode.25 (Encode.100, Encode.101):
let Encode.104 : List U8 = Array []; 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; let Encode.103 : List U8 = CallByName Encode.23 Encode.104 Encode.105 Encode.101;
ret Encode.103; ret Encode.103;
@ -46,10 +42,7 @@ procedure Json.1 ():
let Json.318 : {} = Struct {}; let Json.318 : {} = Struct {};
ret Json.318; ret Json.318;
procedure Json.103 (Json.104, Json.321, #Attr.12): procedure Json.103 (Json.104, Json.321, Json.102):
let Json.102 : List {Str, {Str}} = StructAtIndex 0 #Attr.12;
inc Json.102;
dec #Attr.12;
let Json.357 : I32 = 123i64; let Json.357 : I32 = 123i64;
let Json.356 : U8 = CallByName Num.123 Json.357; let Json.356 : U8 = CallByName Num.123 Json.357;
let Json.106 : List U8 = CallByName List.4 Json.104 Json.356; let Json.106 : List U8 = CallByName List.4 Json.104 Json.356;
@ -69,7 +62,7 @@ procedure Json.103 (Json.104, Json.321, #Attr.12):
procedure Json.105 (Json.326, Json.327): procedure Json.105 (Json.326, Json.327):
let Json.111 : Str = StructAtIndex 0 Json.327; let Json.111 : Str = StructAtIndex 0 Json.327;
inc Json.111; inc Json.111;
let Json.112 : {Str} = StructAtIndex 1 Json.327; let Json.112 : Str = StructAtIndex 1 Json.327;
inc Json.112; inc Json.112;
dec Json.327; dec Json.327;
let Json.109 : List U8 = StructAtIndex 0 Json.326; let Json.109 : List U8 = StructAtIndex 0 Json.326;
@ -106,19 +99,14 @@ procedure Json.105 (Json.326, Json.327):
jump Json.338 Json.113; jump Json.338 Json.113;
procedure Json.18 (Json.86): procedure Json.18 (Json.86):
let Json.323 : {Str} = Struct {Json.86}; let Json.322 : Str = CallByName Encode.22 Json.86;
let Json.322 : {Str} = CallByName Encode.22 Json.323;
ret Json.322; ret Json.322;
procedure Json.20 (Json.102): procedure Json.20 (Json.102):
let Json.320 : {List {Str, {Str}}} = Struct {Json.102}; let Json.319 : List {Str, Str} = CallByName Encode.22 Json.102;
let Json.319 : {List {Str, {Str}}} = CallByName Encode.22 Json.320;
ret Json.319; ret Json.319;
procedure Json.87 (Json.88, Json.324, #Attr.12): procedure Json.87 (Json.88, Json.324, Json.86):
let Json.86 : Str = StructAtIndex 0 #Attr.12;
inc Json.86;
dec #Attr.12;
let Json.366 : I32 = 34i64; let Json.366 : I32 = 34i64;
let Json.365 : U8 = CallByName Num.123 Json.366; let Json.365 : U8 = CallByName Num.123 Json.366;
let Json.363 : List U8 = CallByName List.4 Json.88 Json.365; let Json.363 : List U8 = CallByName List.4 Json.88 Json.365;
@ -129,15 +117,13 @@ procedure Json.87 (Json.88, Json.324, #Attr.12):
let Json.359 : List U8 = CallByName List.4 Json.360 Json.361; let Json.359 : List U8 = CallByName List.4 Json.360 Json.361;
ret Json.359; ret Json.359;
procedure List.133 (List.134, List.135, #Attr.12): procedure List.133 (List.134, List.135, List.132):
let List.132 : {} = StructAtIndex 0 #Attr.12;
let List.441 : {List U8, U64} = CallByName Json.105 List.134 List.135; 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; let List.440 : [C [], C {List U8, U64}] = TagId(1) List.441;
ret List.440; ret List.440;
procedure List.18 (List.130, List.131, List.132): procedure List.18 (List.130, List.131, List.132):
let List.417 : {{}} = Struct {List.132}; let List.411 : [C [], C {List U8, U64}] = CallByName List.75 List.130 List.131 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.414 : U8 = 1i64;
let List.415 : U8 = GetTagId List.411; let List.415 : U8 = GetTagId List.411;
let List.416 : Int1 = lowlevel Eq List.414 List.415; let List.416 : Int1 = lowlevel Eq List.414 List.415;
@ -167,7 +153,7 @@ procedure List.6 (#Attr.2):
ret List.420; ret List.420;
procedure List.66 (#Attr.2, #Attr.3): procedure List.66 (#Attr.2, #Attr.3):
let List.439 : {Str, {Str}} = lowlevel ListGetUnsafe #Attr.2 #Attr.3; let List.439 : {Str, Str} = lowlevel ListGetUnsafe #Attr.2 #Attr.3;
ret List.439; ret List.439;
procedure List.69 (#Attr.2): procedure List.69 (#Attr.2):
@ -196,7 +182,7 @@ 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: joinpoint List.427 List.364 List.365 List.366 List.367 List.368:
let List.429 : Int1 = CallByName Num.22 List.367 List.368; let List.429 : Int1 = CallByName Num.22 List.367 List.368;
if List.429 then if List.429 then
let List.438 : {Str, {Str}} = CallByName List.66 List.364 List.367; 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.430 : [C [], C {List U8, U64}] = CallByName List.133 List.365 List.438 List.366;
let List.435 : U8 = 1i64; let List.435 : U8 = 1i64;
let List.436 : U8 = GetTagId List.430; let List.436 : U8 = GetTagId List.430;

View File

@ -1,25 +1,21 @@
procedure #Derived.0 (#Derived.1): procedure #Derived.0 (#Derived.1):
let #Derived_gen.1 : {{Str, Str}} = Struct {#Derived.1}; let #Derived_gen.0 : {Str, Str} = CallByName Encode.22 #Derived.1;
let #Derived_gen.0 : {{Str, Str}} = CallByName Encode.22 #Derived_gen.1;
ret #Derived_gen.0; ret #Derived_gen.0;
procedure #Derived.2 (#Derived.3, #Derived.4, #Attr.12): procedure #Derived.2 (#Derived.3, #Derived.4, #Derived.1):
let #Derived.1 : {Str, Str} = StructAtIndex 0 #Attr.12;
inc #Derived.1;
dec #Attr.12;
let #Derived_gen.11 : Str = "a"; let #Derived_gen.11 : Str = "a";
let #Derived_gen.13 : Str = StructAtIndex 0 #Derived.1; let #Derived_gen.13 : Str = StructAtIndex 0 #Derived.1;
inc #Derived_gen.13; inc #Derived_gen.13;
let #Derived_gen.12 : {Str} = CallByName Json.18 #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.6 : {Str, Str} = Struct {#Derived_gen.11, #Derived_gen.12};
let #Derived_gen.8 : Str = "b"; let #Derived_gen.8 : Str = "b";
let #Derived_gen.10 : Str = StructAtIndex 1 #Derived.1; let #Derived_gen.10 : Str = StructAtIndex 1 #Derived.1;
inc #Derived_gen.10; inc #Derived_gen.10;
dec #Derived.1; dec #Derived.1;
let #Derived_gen.9 : {Str} = CallByName Json.18 #Derived_gen.10; 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.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.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.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; let #Derived_gen.3 : List U8 = CallByName Encode.23 #Derived.3 #Derived_gen.4 #Derived.4;
ret #Derived_gen.3; ret #Derived_gen.3;
@ -46,7 +42,7 @@ procedure Encode.23 (Encode.94, Encode.102, Encode.96):
procedure Encode.25 (Encode.100, Encode.101): procedure Encode.25 (Encode.100, Encode.101):
let Encode.104 : List U8 = Array []; 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; let Encode.103 : List U8 = CallByName Encode.23 Encode.104 Encode.105 Encode.101;
ret Encode.103; ret Encode.103;
@ -54,10 +50,7 @@ procedure Json.1 ():
let Json.318 : {} = Struct {}; let Json.318 : {} = Struct {};
ret Json.318; ret Json.318;
procedure Json.103 (Json.104, Json.321, #Attr.12): procedure Json.103 (Json.104, Json.321, Json.102):
let Json.102 : List {Str, {Str}} = StructAtIndex 0 #Attr.12;
inc Json.102;
dec #Attr.12;
let Json.360 : I32 = 123i64; let Json.360 : I32 = 123i64;
let Json.359 : U8 = CallByName Num.123 Json.360; let Json.359 : U8 = CallByName Num.123 Json.360;
let Json.106 : List U8 = CallByName List.4 Json.104 Json.359; let Json.106 : List U8 = CallByName List.4 Json.104 Json.359;
@ -77,7 +70,7 @@ procedure Json.103 (Json.104, Json.321, #Attr.12):
procedure Json.105 (Json.329, Json.330): procedure Json.105 (Json.329, Json.330):
let Json.111 : Str = StructAtIndex 0 Json.330; let Json.111 : Str = StructAtIndex 0 Json.330;
inc Json.111; inc Json.111;
let Json.112 : {Str} = StructAtIndex 1 Json.330; let Json.112 : Str = StructAtIndex 1 Json.330;
inc Json.112; inc Json.112;
dec Json.330; dec Json.330;
let Json.109 : List U8 = StructAtIndex 0 Json.329; let Json.109 : List U8 = StructAtIndex 0 Json.329;
@ -114,19 +107,14 @@ procedure Json.105 (Json.329, Json.330):
jump Json.341 Json.113; jump Json.341 Json.113;
procedure Json.18 (Json.86): procedure Json.18 (Json.86):
let Json.326 : {Str} = Struct {Json.86}; let Json.325 : Str = CallByName Encode.22 Json.86;
let Json.325 : {Str} = CallByName Encode.22 Json.326;
ret Json.325; ret Json.325;
procedure Json.20 (Json.102): procedure Json.20 (Json.102):
let Json.320 : {List {Str, {Str}}} = Struct {Json.102}; let Json.319 : List {Str, Str} = CallByName Encode.22 Json.102;
let Json.319 : {List {Str, {Str}}} = CallByName Encode.22 Json.320;
ret Json.319; ret Json.319;
procedure Json.87 (Json.88, Json.324, #Attr.12): procedure Json.87 (Json.88, Json.324, Json.86):
let Json.86 : Str = StructAtIndex 0 #Attr.12;
inc Json.86;
dec #Attr.12;
let Json.369 : I32 = 34i64; let Json.369 : I32 = 34i64;
let Json.368 : U8 = CallByName Num.123 Json.369; let Json.368 : U8 = CallByName Num.123 Json.369;
let Json.366 : List U8 = CallByName List.4 Json.88 Json.368; let Json.366 : List U8 = CallByName List.4 Json.88 Json.368;
@ -137,15 +125,13 @@ procedure Json.87 (Json.88, Json.324, #Attr.12):
let Json.362 : List U8 = CallByName List.4 Json.363 Json.364; let Json.362 : List U8 = CallByName List.4 Json.363 Json.364;
ret Json.362; ret Json.362;
procedure List.133 (List.134, List.135, #Attr.12): procedure List.133 (List.134, List.135, List.132):
let List.132 : {} = StructAtIndex 0 #Attr.12;
let List.441 : {List U8, U64} = CallByName Json.105 List.134 List.135; 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; let List.440 : [C [], C {List U8, U64}] = TagId(1) List.441;
ret List.440; ret List.440;
procedure List.18 (List.130, List.131, List.132): procedure List.18 (List.130, List.131, List.132):
let List.417 : {{}} = Struct {List.132}; let List.411 : [C [], C {List U8, U64}] = CallByName List.75 List.130 List.131 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.414 : U8 = 1i64;
let List.415 : U8 = GetTagId List.411; let List.415 : U8 = GetTagId List.411;
let List.416 : Int1 = lowlevel Eq List.414 List.415; let List.416 : Int1 = lowlevel Eq List.414 List.415;
@ -175,7 +161,7 @@ procedure List.6 (#Attr.2):
ret List.420; ret List.420;
procedure List.66 (#Attr.2, #Attr.3): procedure List.66 (#Attr.2, #Attr.3):
let List.439 : {Str, {Str}} = lowlevel ListGetUnsafe #Attr.2 #Attr.3; let List.439 : {Str, Str} = lowlevel ListGetUnsafe #Attr.2 #Attr.3;
ret List.439; ret List.439;
procedure List.69 (#Attr.2): procedure List.69 (#Attr.2):
@ -204,7 +190,7 @@ 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: joinpoint List.427 List.364 List.365 List.366 List.367 List.368:
let List.429 : Int1 = CallByName Num.22 List.367 List.368; let List.429 : Int1 = CallByName Num.22 List.367 List.368;
if List.429 then if List.429 then
let List.438 : {Str, {Str}} = CallByName List.66 List.364 List.367; 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.430 : [C [], C {List U8, U64}] = CallByName List.133 List.365 List.438 List.366;
let List.435 : U8 = 1i64; let List.435 : U8 = 1i64;
let List.436 : U8 = GetTagId List.430; let List.436 : U8 = GetTagId List.430;

View File

@ -7,7 +7,7 @@ procedure Encode.23 (Encode.94, Encode.102, Encode.96):
procedure Encode.25 (Encode.100, Encode.101): procedure Encode.25 (Encode.100, Encode.101):
let Encode.104 : List U8 = Array []; 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; let Encode.103 : List U8 = CallByName Encode.23 Encode.104 Encode.105 Encode.101;
ret Encode.103; ret Encode.103;
@ -16,14 +16,10 @@ procedure Json.1 ():
ret Json.318; ret Json.318;
procedure Json.18 (Json.86): procedure Json.18 (Json.86):
let Json.320 : {Str} = Struct {Json.86}; let Json.319 : Str = CallByName Encode.22 Json.86;
let Json.319 : {Str} = CallByName Encode.22 Json.320;
ret Json.319; ret Json.319;
procedure Json.87 (Json.88, Json.321, #Attr.12): procedure Json.87 (Json.88, Json.321, Json.86):
let Json.86 : Str = StructAtIndex 0 #Attr.12;
inc Json.86;
dec #Attr.12;
let Json.330 : I32 = 34i64; let Json.330 : I32 = 34i64;
let Json.329 : U8 = CallByName Num.123 Json.330; let Json.329 : U8 = CallByName Num.123 Json.330;
let Json.327 : List U8 = CallByName List.4 Json.88 Json.329; let Json.327 : List U8 = CallByName List.4 Json.88 Json.329;

View File

@ -1,20 +1,16 @@
procedure #Derived.0 (#Derived.1): procedure #Derived.0 (#Derived.1):
let #Derived_gen.1 : {Str} = Struct {#Derived.1}; let #Derived_gen.0 : Str = CallByName Encode.22 #Derived.1;
let #Derived_gen.0 : {Str} = CallByName Encode.22 #Derived_gen.1;
ret #Derived_gen.0; ret #Derived_gen.0;
procedure #Derived.3 (#Derived.4, #Derived.5, #Attr.12): procedure #Derived.3 (#Derived.4, #Derived.5, #Derived.1):
let #Derived.1 : Str = StructAtIndex 0 #Attr.12;
inc #Derived.1;
dec #Attr.12;
joinpoint #Derived_gen.5 #Derived_gen.4: joinpoint #Derived_gen.5 #Derived_gen.4:
let #Derived_gen.3 : List U8 = CallByName Encode.23 #Derived.4 #Derived_gen.4 #Derived.5; let #Derived_gen.3 : List U8 = CallByName Encode.23 #Derived.4 #Derived_gen.4 #Derived.5;
ret #Derived_gen.3; ret #Derived_gen.3;
in in
let #Derived_gen.7 : Str = "A"; let #Derived_gen.7 : Str = "A";
let #Derived_gen.9 : {Str} = CallByName Json.18 #Derived.1; let #Derived_gen.9 : Str = CallByName Json.18 #Derived.1;
let #Derived_gen.8 : List {Str} = Array [#Derived_gen.9]; 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; let #Derived_gen.6 : {Str, List Str} = CallByName Json.21 #Derived_gen.7 #Derived_gen.8;
jump #Derived_gen.5 #Derived_gen.6; jump #Derived_gen.5 #Derived_gen.6;
procedure Encode.22 (Encode.93): procedure Encode.22 (Encode.93):
@ -40,7 +36,7 @@ procedure Encode.23 (Encode.94, Encode.102, Encode.96):
procedure Encode.25 (Encode.100, Encode.101): procedure Encode.25 (Encode.100, Encode.101):
let Encode.104 : List U8 = Array []; 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; let Encode.103 : List U8 = CallByName Encode.23 Encode.104 Encode.105 Encode.101;
ret Encode.103; ret Encode.103;
@ -49,7 +45,7 @@ procedure Json.1 ():
ret Json.318; ret Json.318;
procedure Json.117 (Json.118, Json.321, #Attr.12): 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; inc Json.116;
let Json.115 : Str = StructAtIndex 0 #Attr.12; let Json.115 : Str = StructAtIndex 0 #Attr.12;
inc Json.115; inc Json.115;
@ -111,19 +107,15 @@ procedure Json.119 (Json.326, Json.125):
jump Json.340 Json.126; jump Json.340 Json.126;
procedure Json.18 (Json.86): procedure Json.18 (Json.86):
let Json.323 : {Str} = Struct {Json.86}; let Json.322 : Str = CallByName Encode.22 Json.86;
let Json.322 : {Str} = CallByName Encode.22 Json.323;
ret Json.322; ret Json.322;
procedure Json.21 (Json.115, Json.116): procedure Json.21 (Json.115, Json.116):
let Json.320 : {Str, List {Str}} = Struct {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.319 : {Str, List Str} = CallByName Encode.22 Json.320;
ret Json.319; ret Json.319;
procedure Json.87 (Json.88, Json.324, #Attr.12): procedure Json.87 (Json.88, Json.324, Json.86):
let Json.86 : Str = StructAtIndex 0 #Attr.12;
inc Json.86;
dec #Attr.12;
let Json.371 : I32 = 34i64; let Json.371 : I32 = 34i64;
let Json.370 : U8 = CallByName Num.123 Json.371; let Json.370 : U8 = CallByName Num.123 Json.371;
let Json.368 : List U8 = CallByName List.4 Json.88 Json.370; let Json.368 : List U8 = CallByName List.4 Json.88 Json.370;
@ -134,15 +126,13 @@ procedure Json.87 (Json.88, Json.324, #Attr.12):
let Json.364 : List U8 = CallByName List.4 Json.365 Json.366; let Json.364 : List U8 = CallByName List.4 Json.365 Json.366;
ret Json.364; ret Json.364;
procedure List.133 (List.134, List.135, #Attr.12): procedure List.133 (List.134, List.135, List.132):
let List.132 : {} = StructAtIndex 0 #Attr.12;
let List.447 : {List U8, U64} = CallByName Json.119 List.134 List.135; 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; let List.446 : [C [], C {List U8, U64}] = TagId(1) List.447;
ret List.446; ret List.446;
procedure List.18 (List.130, List.131, List.132): procedure List.18 (List.130, List.131, List.132):
let List.423 : {{}} = Struct {List.132}; let List.417 : [C [], C {List U8, U64}] = CallByName List.75 List.130 List.131 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.420 : U8 = 1i64;
let List.421 : U8 = GetTagId List.417; let List.421 : U8 = GetTagId List.417;
let List.422 : Int1 = lowlevel Eq List.420 List.421; let List.422 : Int1 = lowlevel Eq List.420 List.421;
@ -172,7 +162,7 @@ procedure List.6 (#Attr.2):
ret List.424; ret List.424;
procedure List.66 (#Attr.2, #Attr.3): procedure List.66 (#Attr.2, #Attr.3):
let List.445 : {Str} = lowlevel ListGetUnsafe #Attr.2 #Attr.3; let List.445 : Str = lowlevel ListGetUnsafe #Attr.2 #Attr.3;
ret List.445; ret List.445;
procedure List.69 (#Attr.2): procedure List.69 (#Attr.2):
@ -201,7 +191,7 @@ 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: joinpoint List.433 List.364 List.365 List.366 List.367 List.368:
let List.435 : Int1 = CallByName Num.22 List.367 List.368; let List.435 : Int1 = CallByName Num.22 List.367 List.368;
if List.435 then if List.435 then
let List.444 : {Str} = CallByName List.66 List.364 List.367; 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.436 : [C [], C {List U8, U64}] = CallByName List.133 List.365 List.444 List.366;
let List.441 : U8 = 1i64; let List.441 : U8 = 1i64;
let List.442 : U8 = GetTagId List.436; let List.442 : U8 = GetTagId List.436;

View File

@ -1,12 +1,8 @@
procedure #Derived.0 (#Derived.1): procedure #Derived.0 (#Derived.1):
let #Derived_gen.1 : {{Str, Str}} = Struct {#Derived.1}; let #Derived_gen.0 : {Str, Str} = CallByName Encode.22 #Derived.1;
let #Derived_gen.0 : {{Str, Str}} = CallByName Encode.22 #Derived_gen.1;
ret #Derived_gen.0; ret #Derived_gen.0;
procedure #Derived.4 (#Derived.5, #Derived.6, #Attr.12): procedure #Derived.4 (#Derived.5, #Derived.6, #Derived.1):
let #Derived.1 : {Str, Str} = StructAtIndex 0 #Attr.12;
inc #Derived.1;
dec #Attr.12;
joinpoint #Derived_gen.5 #Derived_gen.4: joinpoint #Derived_gen.5 #Derived_gen.4:
let #Derived_gen.3 : List U8 = CallByName Encode.23 #Derived.5 #Derived_gen.4 #Derived.6; let #Derived_gen.3 : List U8 = CallByName Encode.23 #Derived.5 #Derived_gen.4 #Derived.6;
ret #Derived_gen.3; ret #Derived_gen.3;
@ -17,10 +13,10 @@ procedure #Derived.4 (#Derived.5, #Derived.6, #Attr.12):
inc #Derived.3; inc #Derived.3;
dec #Derived.1; dec #Derived.1;
let #Derived_gen.7 : Str = "A"; let #Derived_gen.7 : Str = "A";
let #Derived_gen.9 : {Str} = CallByName Json.18 #Derived.2; let #Derived_gen.9 : Str = CallByName Json.18 #Derived.2;
let #Derived_gen.10 : {Str} = CallByName Json.18 #Derived.3; 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.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; let #Derived_gen.6 : {Str, List Str} = CallByName Json.21 #Derived_gen.7 #Derived_gen.8;
jump #Derived_gen.5 #Derived_gen.6; jump #Derived_gen.5 #Derived_gen.6;
procedure Encode.22 (Encode.93): procedure Encode.22 (Encode.93):
@ -46,7 +42,7 @@ procedure Encode.23 (Encode.94, Encode.102, Encode.96):
procedure Encode.25 (Encode.100, Encode.101): procedure Encode.25 (Encode.100, Encode.101):
let Encode.104 : List U8 = Array []; 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; let Encode.103 : List U8 = CallByName Encode.23 Encode.104 Encode.105 Encode.101;
ret Encode.103; ret Encode.103;
@ -55,7 +51,7 @@ procedure Json.1 ():
ret Json.318; ret Json.318;
procedure Json.117 (Json.118, Json.321, #Attr.12): 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; inc Json.116;
let Json.115 : Str = StructAtIndex 0 #Attr.12; let Json.115 : Str = StructAtIndex 0 #Attr.12;
inc Json.115; inc Json.115;
@ -117,19 +113,15 @@ procedure Json.119 (Json.329, Json.125):
jump Json.343 Json.126; jump Json.343 Json.126;
procedure Json.18 (Json.86): procedure Json.18 (Json.86):
let Json.326 : {Str} = Struct {Json.86}; let Json.325 : Str = CallByName Encode.22 Json.86;
let Json.325 : {Str} = CallByName Encode.22 Json.326;
ret Json.325; ret Json.325;
procedure Json.21 (Json.115, Json.116): procedure Json.21 (Json.115, Json.116):
let Json.320 : {Str, List {Str}} = Struct {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.319 : {Str, List Str} = CallByName Encode.22 Json.320;
ret Json.319; ret Json.319;
procedure Json.87 (Json.88, Json.324, #Attr.12): procedure Json.87 (Json.88, Json.324, Json.86):
let Json.86 : Str = StructAtIndex 0 #Attr.12;
inc Json.86;
dec #Attr.12;
let Json.374 : I32 = 34i64; let Json.374 : I32 = 34i64;
let Json.373 : U8 = CallByName Num.123 Json.374; let Json.373 : U8 = CallByName Num.123 Json.374;
let Json.371 : List U8 = CallByName List.4 Json.88 Json.373; let Json.371 : List U8 = CallByName List.4 Json.88 Json.373;
@ -140,15 +132,13 @@ procedure Json.87 (Json.88, Json.324, #Attr.12):
let Json.367 : List U8 = CallByName List.4 Json.368 Json.369; let Json.367 : List U8 = CallByName List.4 Json.368 Json.369;
ret Json.367; ret Json.367;
procedure List.133 (List.134, List.135, #Attr.12): procedure List.133 (List.134, List.135, List.132):
let List.132 : {} = StructAtIndex 0 #Attr.12;
let List.447 : {List U8, U64} = CallByName Json.119 List.134 List.135; 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; let List.446 : [C [], C {List U8, U64}] = TagId(1) List.447;
ret List.446; ret List.446;
procedure List.18 (List.130, List.131, List.132): procedure List.18 (List.130, List.131, List.132):
let List.423 : {{}} = Struct {List.132}; let List.417 : [C [], C {List U8, U64}] = CallByName List.75 List.130 List.131 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.420 : U8 = 1i64;
let List.421 : U8 = GetTagId List.417; let List.421 : U8 = GetTagId List.417;
let List.422 : Int1 = lowlevel Eq List.420 List.421; let List.422 : Int1 = lowlevel Eq List.420 List.421;
@ -178,7 +168,7 @@ procedure List.6 (#Attr.2):
ret List.424; ret List.424;
procedure List.66 (#Attr.2, #Attr.3): procedure List.66 (#Attr.2, #Attr.3):
let List.445 : {Str} = lowlevel ListGetUnsafe #Attr.2 #Attr.3; let List.445 : Str = lowlevel ListGetUnsafe #Attr.2 #Attr.3;
ret List.445; ret List.445;
procedure List.69 (#Attr.2): procedure List.69 (#Attr.2):
@ -207,7 +197,7 @@ 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: joinpoint List.433 List.364 List.365 List.366 List.367 List.368:
let List.435 : Int1 = CallByName Num.22 List.367 List.368; let List.435 : Int1 = CallByName Num.22 List.367 List.368;
if List.435 then if List.435 then
let List.444 : {Str} = CallByName List.66 List.364 List.367; 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.436 : [C [], C {List U8, U64}] = CallByName List.133 List.365 List.444 List.366;
let List.441 : U8 = 1i64; let List.441 : U8 = 1i64;
let List.442 : U8 = GetTagId List.436; let List.442 : U8 = GetTagId List.436;

View File

@ -2,10 +2,7 @@ procedure Test.11 (Test.37):
let Test.38 : Str = ""; let Test.38 : Str = "";
ret Test.38; ret Test.38;
procedure Test.13 (Test.51, #Attr.12): procedure Test.13 (Test.51, Test.12):
let Test.12 : Str = StructAtIndex 0 #Attr.12;
inc Test.12;
dec #Attr.12;
ret Test.12; ret Test.12;
procedure Test.15 (Test.39): procedure Test.15 (Test.39):
@ -29,8 +26,8 @@ procedure Test.3 (Test.17):
ret Test.36; ret Test.36;
procedure Test.4 (Test.18): procedure Test.4 (Test.18):
let Test.50 : {Str} = Struct {Test.18}; inc Test.18;
ret Test.50; ret Test.18;
procedure Test.9 (Test.29, #Attr.12): procedure Test.9 (Test.29, #Attr.12):
let Test.8 : {} = UnionAtIndex (Id 0) (Index 1) #Attr.12; let Test.8 : {} = UnionAtIndex (Id 0) (Index 1) #Attr.12;
@ -48,7 +45,8 @@ procedure Test.9 (Test.29, #Attr.12):
let Test.7 : {} = UnionAtIndex (Id 1) (Index 0) #Attr.12; let Test.7 : {} = UnionAtIndex (Id 1) (Index 0) #Attr.12;
let Test.49 : {} = Struct {}; let Test.49 : {} = Struct {};
let Test.48 : Str = CallByName Test.16 Test.49; 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;
dec Test.48;
let Test.47 : {} = Struct {}; let Test.47 : {} = Struct {};
let Test.46 : Str = CallByName Test.13 Test.47 Test.45; let Test.46 : Str = CallByName Test.13 Test.47 Test.45;
ret Test.46; ret Test.46;

View File

@ -1,11 +1,9 @@
procedure Test.1 (Test.4): procedure Test.1 (Test.4):
let Test.5 : {Str} = Struct {Test.4};
ret Test.5;
procedure Test.5 (Test.12, #Attr.12):
let Test.4 : Str = StructAtIndex 0 #Attr.12;
inc Test.4; inc Test.4;
dec #Attr.12; ret Test.4;
procedure Test.5 (Test.12, Test.4):
dec Test.4;
let Test.14 : Str = ""; let Test.14 : Str = "";
ret Test.14; ret Test.14;
@ -18,9 +16,11 @@ procedure Test.0 ():
let Test.20 : Int1 = lowlevel Eq Test.19 Test.2; let Test.20 : Int1 = lowlevel Eq Test.19 Test.2;
if Test.20 then if Test.20 then
let Test.15 : Str = ""; let Test.15 : Str = "";
let Test.10 : {Str} = CallByName Test.1 Test.15; let Test.10 : Str = CallByName Test.1 Test.15;
dec Test.15;
jump Test.9 Test.10; jump Test.9 Test.10;
else else
let Test.18 : Str = ""; let Test.18 : Str = "";
let Test.16 : {Str} = CallByName Test.1 Test.18; let Test.16 : Str = CallByName Test.1 Test.18;
dec Test.18;
jump Test.9 Test.16; jump Test.9 Test.16;

View File

@ -1,15 +1,13 @@
procedure Test.1 (Test.5): procedure Test.1 (Test.5):
let Test.2 : I64 = 42i64; let Test.2 : I64 = 42i64;
let Test.3 : {I64} = Struct {Test.2}; ret Test.2;
ret Test.3;
procedure Test.3 (Test.9, #Attr.12): procedure Test.3 (Test.9, Test.2):
let Test.2 : I64 = StructAtIndex 0 #Attr.12;
ret Test.2; ret Test.2;
procedure Test.0 (): procedure Test.0 ():
let Test.8 : {} = Struct {}; 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.7 : {} = Struct {};
let Test.6 : I64 = CallByName Test.3 Test.7 Test.4; let Test.6 : I64 = CallByName Test.3 Test.7 Test.4;
ret Test.6; ret Test.6;

View File

@ -4,20 +4,17 @@ procedure Num.19 (#Attr.2, #Attr.3):
procedure Test.1 (Test.2): procedure Test.1 (Test.2):
let Test.9 : U32 = 0i64; let Test.9 : U32 = 0i64;
let Test.16 : {U32} = Struct {Test.2}; let Test.8 : U32 = CallByName Test.3 Test.9 Test.2;
let Test.8 : U32 = CallByName Test.3 Test.9 Test.16;
ret Test.8; ret Test.8;
procedure Test.3 (Test.18, Test.19): procedure Test.3 (Test.18, Test.19):
joinpoint Test.10 Test.4 #Attr.12: joinpoint Test.10 Test.4 Test.2:
let Test.2 : U32 = StructAtIndex 0 #Attr.12;
let Test.14 : Int1 = true; let Test.14 : Int1 = true;
if Test.14 then if Test.14 then
ret Test.4; ret Test.4;
else else
let Test.12 : U32 = CallByName Num.19 Test.4 Test.2; let Test.12 : U32 = CallByName Num.19 Test.4 Test.2;
let Test.13 : {U32} = Struct {Test.2}; jump Test.10 Test.12 Test.2;
jump Test.10 Test.12 Test.13;
in in
jump Test.10 Test.18 Test.19; jump Test.10 Test.18 Test.19;