mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-26 13:29:12 +00:00
Merge pull request #5622 from roc-lang/reset-reuse-free
free or reuse unconditionally when value is unique
This commit is contained in:
commit
0ade2a85d2
37 changed files with 583 additions and 295 deletions
|
@ -510,6 +510,12 @@ fn apply_refcount_operation(
|
||||||
builder.add_recursive_touch(block, argument)?;
|
builder.add_recursive_touch(block, argument)?;
|
||||||
}
|
}
|
||||||
ModifyRc::DecRef(symbol) => {
|
ModifyRc::DecRef(symbol) => {
|
||||||
|
// this is almost certainly suboptimal, but not incorrect
|
||||||
|
let argument = env.symbols[symbol];
|
||||||
|
builder.add_recursive_touch(block, argument)?;
|
||||||
|
}
|
||||||
|
ModifyRc::Free(symbol) => {
|
||||||
|
// this is almost certainly suboptimal, but not incorrect
|
||||||
let argument = env.symbols[symbol];
|
let argument = env.symbols[symbol];
|
||||||
builder.add_recursive_touch(block, argument)?;
|
builder.add_recursive_touch(block, argument)?;
|
||||||
}
|
}
|
||||||
|
|
|
@ -195,8 +195,10 @@ comptime {
|
||||||
exportUtilsFn(utils.test_panic, "test_panic");
|
exportUtilsFn(utils.test_panic, "test_panic");
|
||||||
exportUtilsFn(utils.increfRcPtrC, "incref_rc_ptr");
|
exportUtilsFn(utils.increfRcPtrC, "incref_rc_ptr");
|
||||||
exportUtilsFn(utils.decrefRcPtrC, "decref_rc_ptr");
|
exportUtilsFn(utils.decrefRcPtrC, "decref_rc_ptr");
|
||||||
|
exportUtilsFn(utils.freeRcPtrC, "free_rc_ptr");
|
||||||
exportUtilsFn(utils.increfDataPtrC, "incref_data_ptr");
|
exportUtilsFn(utils.increfDataPtrC, "incref_data_ptr");
|
||||||
exportUtilsFn(utils.decrefDataPtrC, "decref_data_ptr");
|
exportUtilsFn(utils.decrefDataPtrC, "decref_data_ptr");
|
||||||
|
exportUtilsFn(utils.freeDataPtrC, "free_data_ptr");
|
||||||
exportUtilsFn(utils.isUnique, "is_unique");
|
exportUtilsFn(utils.isUnique, "is_unique");
|
||||||
exportUtilsFn(utils.decrefCheckNullC, "decref_check_null");
|
exportUtilsFn(utils.decrefCheckNullC, "decref_check_null");
|
||||||
exportUtilsFn(utils.allocateWithRefcountC, "allocate_with_refcount");
|
exportUtilsFn(utils.allocateWithRefcountC, "allocate_with_refcount");
|
||||||
|
|
|
@ -220,6 +220,29 @@ pub fn increfDataPtrC(
|
||||||
return increfRcPtrC(isizes, inc_amount);
|
return increfRcPtrC(isizes, inc_amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn freeDataPtrC(
|
||||||
|
bytes_or_null: ?[*]isize,
|
||||||
|
alignment: u32,
|
||||||
|
) callconv(.C) void {
|
||||||
|
var bytes = bytes_or_null orelse return;
|
||||||
|
|
||||||
|
const ptr = @ptrToInt(bytes);
|
||||||
|
const tag_mask: usize = if (@sizeOf(usize) == 8) 0b111 else 0b11;
|
||||||
|
const masked_ptr = ptr & ~tag_mask;
|
||||||
|
|
||||||
|
const isizes: [*]isize = @intToPtr([*]isize, masked_ptr);
|
||||||
|
|
||||||
|
return freeRcPtrC(isizes - 1, alignment);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn freeRcPtrC(
|
||||||
|
bytes_or_null: ?[*]isize,
|
||||||
|
alignment: u32,
|
||||||
|
) callconv(.C) void {
|
||||||
|
var bytes = bytes_or_null orelse return;
|
||||||
|
return free_ptr_to_refcount(bytes, alignment);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn decref(
|
pub fn decref(
|
||||||
bytes_or_null: ?[*]u8,
|
bytes_or_null: ?[*]u8,
|
||||||
data_bytes: usize,
|
data_bytes: usize,
|
||||||
|
@ -236,13 +259,23 @@ pub fn decref(
|
||||||
decref_ptr_to_refcount(isizes - 1, alignment);
|
decref_ptr_to_refcount(isizes - 1, alignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fn decref_ptr_to_refcount(
|
inline fn free_ptr_to_refcount(
|
||||||
refcount_ptr: [*]isize,
|
refcount_ptr: [*]isize,
|
||||||
alignment: u32,
|
alignment: u32,
|
||||||
) void {
|
) void {
|
||||||
if (RC_TYPE == Refcount.none) return;
|
if (RC_TYPE == Refcount.none) return;
|
||||||
const extra_bytes = std.math.max(alignment, @sizeOf(usize));
|
const extra_bytes = std.math.max(alignment, @sizeOf(usize));
|
||||||
|
|
||||||
|
// NOTE: we don't even check whether the refcount is "infinity" here!
|
||||||
|
dealloc(@ptrCast([*]u8, refcount_ptr) - (extra_bytes - @sizeOf(usize)), alignment);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fn decref_ptr_to_refcount(
|
||||||
|
refcount_ptr: [*]isize,
|
||||||
|
alignment: u32,
|
||||||
|
) void {
|
||||||
|
if (RC_TYPE == Refcount.none) return;
|
||||||
|
|
||||||
if (DEBUG_INCDEC and builtin.target.cpu.arch != .wasm32) {
|
if (DEBUG_INCDEC and builtin.target.cpu.arch != .wasm32) {
|
||||||
std.debug.print("| decrement {*}: ", .{refcount_ptr});
|
std.debug.print("| decrement {*}: ", .{refcount_ptr});
|
||||||
}
|
}
|
||||||
|
@ -264,13 +297,13 @@ inline fn decref_ptr_to_refcount(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (refcount == REFCOUNT_ONE_ISIZE) {
|
if (refcount == REFCOUNT_ONE_ISIZE) {
|
||||||
dealloc(@ptrCast([*]u8, refcount_ptr) - (extra_bytes - @sizeOf(usize)), alignment);
|
free_ptr_to_refcount(refcount_ptr, alignment);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Refcount.atomic => {
|
Refcount.atomic => {
|
||||||
var last = @atomicRmw(isize, &refcount_ptr[0], std.builtin.AtomicRmwOp.Sub, 1, Monotonic);
|
var last = @atomicRmw(isize, &refcount_ptr[0], std.builtin.AtomicRmwOp.Sub, 1, Monotonic);
|
||||||
if (last == REFCOUNT_ONE_ISIZE) {
|
if (last == REFCOUNT_ONE_ISIZE) {
|
||||||
dealloc(@ptrCast([*]u8, refcount_ptr) - (extra_bytes - @sizeOf(usize)), alignment);
|
free_ptr_to_refcount(refcount_ptr, alignment);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Refcount.none => unreachable,
|
Refcount.none => unreachable,
|
||||||
|
|
|
@ -393,8 +393,10 @@ pub const UTILS_TEST_PANIC: &str = "roc_builtins.utils.test_panic";
|
||||||
pub const UTILS_ALLOCATE_WITH_REFCOUNT: &str = "roc_builtins.utils.allocate_with_refcount";
|
pub const UTILS_ALLOCATE_WITH_REFCOUNT: &str = "roc_builtins.utils.allocate_with_refcount";
|
||||||
pub const UTILS_INCREF_RC_PTR: &str = "roc_builtins.utils.incref_rc_ptr";
|
pub const UTILS_INCREF_RC_PTR: &str = "roc_builtins.utils.incref_rc_ptr";
|
||||||
pub const UTILS_DECREF_RC_PTR: &str = "roc_builtins.utils.decref_rc_ptr";
|
pub const UTILS_DECREF_RC_PTR: &str = "roc_builtins.utils.decref_rc_ptr";
|
||||||
|
pub const UTILS_FREE_RC_PTR: &str = "roc_builtins.utils.free_rc_ptr";
|
||||||
pub const UTILS_INCREF_DATA_PTR: &str = "roc_builtins.utils.incref_data_ptr";
|
pub const UTILS_INCREF_DATA_PTR: &str = "roc_builtins.utils.incref_data_ptr";
|
||||||
pub const UTILS_DECREF_DATA_PTR: &str = "roc_builtins.utils.decref_data_ptr";
|
pub const UTILS_DECREF_DATA_PTR: &str = "roc_builtins.utils.decref_data_ptr";
|
||||||
|
pub const UTILS_FREE_DATA_PTR: &str = "roc_builtins.utils.free_data_ptr";
|
||||||
pub const UTILS_IS_UNIQUE: &str = "roc_builtins.utils.is_unique";
|
pub const UTILS_IS_UNIQUE: &str = "roc_builtins.utils.is_unique";
|
||||||
pub const UTILS_DECREF_CHECK_NULL: &str = "roc_builtins.utils.decref_check_null";
|
pub const UTILS_DECREF_CHECK_NULL: &str = "roc_builtins.utils.decref_check_null";
|
||||||
pub const UTILS_DICT_PSEUDO_SEED: &str = "roc_builtins.utils.dict_pseudo_seed";
|
pub const UTILS_DICT_PSEUDO_SEED: &str = "roc_builtins.utils.dict_pseudo_seed";
|
||||||
|
|
|
@ -87,6 +87,7 @@ macro_rules! map_symbol_to_lowlevel_and_arity {
|
||||||
LowLevel::PtrCast => unimplemented!(),
|
LowLevel::PtrCast => unimplemented!(),
|
||||||
LowLevel::PtrStore => unimplemented!(),
|
LowLevel::PtrStore => unimplemented!(),
|
||||||
LowLevel::PtrLoad => unimplemented!(),
|
LowLevel::PtrLoad => unimplemented!(),
|
||||||
|
LowLevel::PtrClearTagId => unimplemented!(),
|
||||||
LowLevel::Alloca => unimplemented!(),
|
LowLevel::Alloca => unimplemented!(),
|
||||||
LowLevel::RefCountIncRcPtr => unimplemented!(),
|
LowLevel::RefCountIncRcPtr => unimplemented!(),
|
||||||
LowLevel::RefCountDecRcPtr=> unimplemented!(),
|
LowLevel::RefCountDecRcPtr=> unimplemented!(),
|
||||||
|
|
|
@ -2996,12 +2996,17 @@ impl<
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_ptr_to_stack_value(
|
fn build_ptr_clear_tag_id(&mut self, sym: Symbol, ptr: Symbol) {
|
||||||
&mut self,
|
let buf = &mut self.buf;
|
||||||
sym: Symbol,
|
|
||||||
value: Symbol,
|
let ptr_reg = self.storage_manager.load_to_general_reg(buf, &ptr);
|
||||||
element_layout: InLayout<'a>,
|
let sym_reg = self.storage_manager.claim_general_reg(buf, &sym);
|
||||||
) {
|
|
||||||
|
ASM::mov_reg64_imm64(buf, sym_reg, !0b111);
|
||||||
|
ASM::and_reg64_reg64_reg64(buf, sym_reg, sym_reg, ptr_reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_alloca(&mut self, sym: Symbol, value: Symbol, element_layout: InLayout<'a>) {
|
||||||
// 1. acquire some stack space
|
// 1. acquire some stack space
|
||||||
let element_width = self.interner().stack_size(element_layout);
|
let element_width = self.interner().stack_size(element_layout);
|
||||||
let allocation = self.debug_symbol("stack_allocation");
|
let allocation = self.debug_symbol("stack_allocation");
|
||||||
|
|
|
@ -17,7 +17,7 @@ use roc_module::symbol::{Interns, ModuleId, Symbol};
|
||||||
use roc_mono::code_gen_help::{CallerProc, CodeGenHelp};
|
use roc_mono::code_gen_help::{CallerProc, CodeGenHelp};
|
||||||
use roc_mono::ir::{
|
use roc_mono::ir::{
|
||||||
BranchInfo, CallType, CrashTag, Expr, HigherOrderLowLevel, JoinPointId, ListLiteralElement,
|
BranchInfo, CallType, CrashTag, Expr, HigherOrderLowLevel, JoinPointId, ListLiteralElement,
|
||||||
Literal, Param, Proc, ProcLayout, SelfRecursive, Stmt,
|
Literal, ModifyRc, Param, Proc, ProcLayout, SelfRecursive, Stmt,
|
||||||
};
|
};
|
||||||
use roc_mono::layout::{
|
use roc_mono::layout::{
|
||||||
Builtin, InLayout, LambdaName, Layout, LayoutIds, LayoutInterner, LayoutRepr, STLayoutInterner,
|
Builtin, InLayout, LambdaName, Layout, LayoutIds, LayoutInterner, LayoutRepr, STLayoutInterner,
|
||||||
|
@ -525,6 +525,29 @@ trait Backend<'a> {
|
||||||
self.return_symbol(sym, ret_layout);
|
self.return_symbol(sym, ret_layout);
|
||||||
self.free_symbols(stmt);
|
self.free_symbols(stmt);
|
||||||
}
|
}
|
||||||
|
Stmt::Refcounting(ModifyRc::Free(symbol), following) => {
|
||||||
|
let dst = Symbol::DEV_TMP;
|
||||||
|
|
||||||
|
let layout = *self.layout_map().get(symbol).unwrap();
|
||||||
|
let alignment_bytes = self.interner().allocation_alignment_bytes(layout);
|
||||||
|
let alignment = self.debug_symbol("alignment");
|
||||||
|
self.load_literal_i32(&alignment, alignment_bytes as i32);
|
||||||
|
|
||||||
|
// NOTE: UTILS_FREE_DATA_PTR clears any tag id bits
|
||||||
|
|
||||||
|
self.build_fn_call(
|
||||||
|
&dst,
|
||||||
|
bitcode::UTILS_FREE_DATA_PTR.to_string(),
|
||||||
|
&[*symbol, alignment],
|
||||||
|
&[Layout::I64, Layout::I32],
|
||||||
|
&Layout::UNIT,
|
||||||
|
);
|
||||||
|
|
||||||
|
self.free_symbol(&dst);
|
||||||
|
self.free_symbol(&alignment);
|
||||||
|
|
||||||
|
self.build_stmt(layout_ids, following, ret_layout)
|
||||||
|
}
|
||||||
Stmt::Refcounting(modify, following) => {
|
Stmt::Refcounting(modify, following) => {
|
||||||
let sym = modify.get_symbol();
|
let sym = modify.get_symbol();
|
||||||
let layout = *self.layout_map().get(&sym).unwrap();
|
let layout = *self.layout_map().get(&sym).unwrap();
|
||||||
|
@ -1605,8 +1628,12 @@ trait Backend<'a> {
|
||||||
self.build_ptr_load(*sym, args[0], *ret_layout);
|
self.build_ptr_load(*sym, args[0], *ret_layout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LowLevel::PtrClearTagId => {
|
||||||
|
self.build_ptr_clear_tag_id(*sym, args[0]);
|
||||||
|
}
|
||||||
|
|
||||||
LowLevel::Alloca => {
|
LowLevel::Alloca => {
|
||||||
self.build_ptr_to_stack_value(*sym, args[0], arg_layouts[0]);
|
self.build_alloca(*sym, args[0], arg_layouts[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
LowLevel::RefCountDecRcPtr => self.build_fn_call(
|
LowLevel::RefCountDecRcPtr => self.build_fn_call(
|
||||||
|
@ -2247,12 +2274,9 @@ trait Backend<'a> {
|
||||||
|
|
||||||
fn build_ptr_load(&mut self, sym: Symbol, ptr: Symbol, element_layout: InLayout<'a>);
|
fn build_ptr_load(&mut self, sym: Symbol, ptr: Symbol, element_layout: InLayout<'a>);
|
||||||
|
|
||||||
fn build_ptr_to_stack_value(
|
fn build_ptr_clear_tag_id(&mut self, sym: Symbol, ptr: Symbol);
|
||||||
&mut self,
|
|
||||||
sym: Symbol,
|
fn build_alloca(&mut self, sym: Symbol, value: Symbol, element_layout: InLayout<'a>);
|
||||||
value: Symbol,
|
|
||||||
element_layout: InLayout<'a>,
|
|
||||||
);
|
|
||||||
|
|
||||||
/// literal_map gets the map from symbol to literal and layout, used for lazy loading and literal folding.
|
/// literal_map gets the map from symbol to literal and layout, used for lazy loading and literal folding.
|
||||||
fn literal_map(&mut self) -> &mut MutMap<Symbol, (*const Literal<'a>, *const InLayout<'a>)>;
|
fn literal_map(&mut self) -> &mut MutMap<Symbol, (*const Literal<'a>, *const InLayout<'a>)>;
|
||||||
|
|
|
@ -1180,8 +1180,14 @@ pub(crate) fn build_exp_expr<'a, 'ctx>(
|
||||||
let then_block = ctx.append_basic_block(parent, "then_reset");
|
let then_block = ctx.append_basic_block(parent, "then_reset");
|
||||||
let else_block = ctx.append_basic_block(parent, "else_decref");
|
let else_block = ctx.append_basic_block(parent, "else_decref");
|
||||||
|
|
||||||
let refcount_ptr =
|
let refcount_ptr = PointerToRefcount::from_ptr_to_data(
|
||||||
PointerToRefcount::from_ptr_to_data(env, tag_pointer_clear_tag_id(env, tag_ptr));
|
env,
|
||||||
|
if union_layout.stores_tag_id_in_pointer(env.target_info) {
|
||||||
|
tag_pointer_clear_tag_id(env, tag_ptr)
|
||||||
|
} else {
|
||||||
|
tag_ptr
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
let is_unique = match update_mode {
|
let is_unique = match update_mode {
|
||||||
UpdateMode::InPlace => env.context.bool_type().const_int(1, false),
|
UpdateMode::InPlace => env.context.bool_type().const_int(1, false),
|
||||||
|
@ -1265,8 +1271,20 @@ pub(crate) fn build_exp_expr<'a, 'ctx>(
|
||||||
|
|
||||||
let not_unique_block = ctx.append_basic_block(parent, "else_decref");
|
let not_unique_block = ctx.append_basic_block(parent, "else_decref");
|
||||||
|
|
||||||
let refcount_ptr =
|
// reset is only generated for union values
|
||||||
PointerToRefcount::from_ptr_to_data(env, tag_pointer_clear_tag_id(env, tag_ptr));
|
let union_layout = match layout_interner.get_repr(layout) {
|
||||||
|
LayoutRepr::Union(ul) => ul,
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let refcount_ptr = PointerToRefcount::from_ptr_to_data(
|
||||||
|
env,
|
||||||
|
if union_layout.stores_tag_id_in_pointer(env.target_info) {
|
||||||
|
tag_pointer_clear_tag_id(env, tag_ptr)
|
||||||
|
} else {
|
||||||
|
tag_ptr
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
let is_unique = match update_mode {
|
let is_unique = match update_mode {
|
||||||
UpdateMode::InPlace => env.context.bool_type().const_int(1, false),
|
UpdateMode::InPlace => env.context.bool_type().const_int(1, false),
|
||||||
|
@ -2930,6 +2948,39 @@ pub(crate) fn build_exp_stmt<'a, 'ctx>(
|
||||||
cont,
|
cont,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Free(symbol) => {
|
||||||
|
// unconditionally deallocate the symbol
|
||||||
|
let (value, layout) = scope.load_symbol_and_layout(symbol);
|
||||||
|
let alignment = layout_interner.alignment_bytes(layout);
|
||||||
|
|
||||||
|
debug_assert!(value.is_pointer_value());
|
||||||
|
let value = value.into_pointer_value();
|
||||||
|
|
||||||
|
let clear_tag_id = match layout_interner.chase_recursive(layout) {
|
||||||
|
LayoutRepr::Union(union) => union.stores_tag_id_in_pointer(env.target_info),
|
||||||
|
_ => false,
|
||||||
|
};
|
||||||
|
|
||||||
|
let ptr = if clear_tag_id {
|
||||||
|
tag_pointer_clear_tag_id(env, value)
|
||||||
|
} else {
|
||||||
|
value
|
||||||
|
};
|
||||||
|
|
||||||
|
let rc_ptr = PointerToRefcount::from_ptr_to_data(env, ptr);
|
||||||
|
rc_ptr.deallocate(env, alignment);
|
||||||
|
|
||||||
|
build_exp_stmt(
|
||||||
|
env,
|
||||||
|
layout_interner,
|
||||||
|
layout_ids,
|
||||||
|
func_spec_solutions,
|
||||||
|
scope,
|
||||||
|
parent,
|
||||||
|
cont,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1325,6 +1325,12 @@ pub(crate) fn run_low_level<'a, 'ctx>(
|
||||||
.new_build_load(element_type, ptr.into_pointer_value(), "ptr_load")
|
.new_build_load(element_type, ptr.into_pointer_value(), "ptr_load")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PtrClearTagId => {
|
||||||
|
arguments!(ptr);
|
||||||
|
|
||||||
|
tag_pointer_clear_tag_id(env, ptr.into_pointer_value()).into()
|
||||||
|
}
|
||||||
|
|
||||||
Alloca => {
|
Alloca => {
|
||||||
arguments!(initial_value);
|
arguments!(initial_value);
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ use bumpalo::collections::Vec;
|
||||||
use inkwell::basic_block::BasicBlock;
|
use inkwell::basic_block::BasicBlock;
|
||||||
use inkwell::module::Linkage;
|
use inkwell::module::Linkage;
|
||||||
use inkwell::types::{AnyTypeEnum, BasicMetadataTypeEnum, BasicType, BasicTypeEnum};
|
use inkwell::types::{AnyTypeEnum, BasicMetadataTypeEnum, BasicType, BasicTypeEnum};
|
||||||
use inkwell::values::{BasicValueEnum, FunctionValue, IntValue, PointerValue};
|
use inkwell::values::{BasicValueEnum, FunctionValue, InstructionValue, IntValue, PointerValue};
|
||||||
use inkwell::{AddressSpace, IntPredicate};
|
use inkwell::{AddressSpace, IntPredicate};
|
||||||
use roc_module::symbol::Interns;
|
use roc_module::symbol::Interns;
|
||||||
use roc_module::symbol::Symbol;
|
use roc_module::symbol::Symbol;
|
||||||
|
@ -193,6 +193,14 @@ impl<'ctx> PointerToRefcount<'ctx> {
|
||||||
|
|
||||||
builder.build_return(None);
|
builder.build_return(None);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn deallocate<'a, 'env>(
|
||||||
|
&self,
|
||||||
|
env: &Env<'a, 'ctx, 'env>,
|
||||||
|
alignment: u32,
|
||||||
|
) -> InstructionValue<'ctx> {
|
||||||
|
free_pointer(env, self.value, alignment)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn incref_pointer<'ctx>(
|
fn incref_pointer<'ctx>(
|
||||||
|
@ -216,6 +224,28 @@ fn incref_pointer<'ctx>(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn free_pointer<'ctx>(
|
||||||
|
env: &Env<'_, 'ctx, '_>,
|
||||||
|
pointer: PointerValue<'ctx>,
|
||||||
|
alignment: u32,
|
||||||
|
) -> InstructionValue<'ctx> {
|
||||||
|
let alignment = env.context.i32_type().const_int(alignment as _, false);
|
||||||
|
call_void_bitcode_fn(
|
||||||
|
env,
|
||||||
|
&[
|
||||||
|
env.builder
|
||||||
|
.build_pointer_cast(
|
||||||
|
pointer,
|
||||||
|
env.ptr_int().ptr_type(AddressSpace::default()),
|
||||||
|
"to_isize_ptr",
|
||||||
|
)
|
||||||
|
.into(),
|
||||||
|
alignment.into(),
|
||||||
|
],
|
||||||
|
roc_builtins::bitcode::UTILS_FREE_RC_PTR,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fn decref_pointer<'ctx>(env: &Env<'_, 'ctx, '_>, pointer: PointerValue<'ctx>, alignment: u32) {
|
fn decref_pointer<'ctx>(env: &Env<'_, 'ctx, '_>, pointer: PointerValue<'ctx>, alignment: u32) {
|
||||||
let alignment = env.context.i32_type().const_int(alignment as _, false);
|
let alignment = env.context.i32_type().const_int(alignment as _, false);
|
||||||
call_void_bitcode_fn(
|
call_void_bitcode_fn(
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use bitvec::vec::BitVec;
|
use bitvec::vec::BitVec;
|
||||||
use bumpalo::collections::{String, Vec};
|
use bumpalo::collections::{String, Vec};
|
||||||
|
|
||||||
use roc_builtins::bitcode::{FloatWidth, IntWidth};
|
use roc_builtins::bitcode::{self, FloatWidth, IntWidth};
|
||||||
use roc_collections::all::MutMap;
|
use roc_collections::all::MutMap;
|
||||||
use roc_error_macros::internal_error;
|
use roc_error_macros::internal_error;
|
||||||
use roc_module::low_level::{LowLevel, LowLevelWrapperType};
|
use roc_module::low_level::{LowLevel, LowLevelWrapperType};
|
||||||
|
@ -719,7 +719,10 @@ impl<'a, 'r> WasmBackend<'a, 'r> {
|
||||||
|
|
||||||
Stmt::Jump(id, arguments) => self.stmt_jump(*id, arguments),
|
Stmt::Jump(id, arguments) => self.stmt_jump(*id, arguments),
|
||||||
|
|
||||||
Stmt::Refcounting(modify, following) => self.stmt_refcounting(modify, following),
|
Stmt::Refcounting(modify, following) => match modify {
|
||||||
|
ModifyRc::Free(symbol) => self.stmt_refcounting_free(*symbol, following),
|
||||||
|
_ => self.stmt_refcounting(modify, following),
|
||||||
|
},
|
||||||
|
|
||||||
Stmt::Dbg { .. } => todo!("dbg is not implemented in the wasm backend"),
|
Stmt::Dbg { .. } => todo!("dbg is not implemented in the wasm backend"),
|
||||||
Stmt::Expect { .. } => todo!("expect is not implemented in the wasm backend"),
|
Stmt::Expect { .. } => todo!("expect is not implemented in the wasm backend"),
|
||||||
|
@ -999,6 +1002,43 @@ impl<'a, 'r> WasmBackend<'a, 'r> {
|
||||||
self.stmt(rc_stmt);
|
self.stmt(rc_stmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn stmt_refcounting_free(&mut self, value: Symbol, following: &'a Stmt<'a>) {
|
||||||
|
let layout = self.storage.symbol_layouts[&value];
|
||||||
|
let alignment = self.layout_interner.allocation_alignment_bytes(layout);
|
||||||
|
|
||||||
|
// Get pointer and offset
|
||||||
|
let value_storage = self.storage.get(&value).to_owned();
|
||||||
|
let stored_with_local =
|
||||||
|
self.storage
|
||||||
|
.ensure_value_has_local(&mut self.code_builder, value, value_storage);
|
||||||
|
let (tag_local_id, tag_offset) = match stored_with_local {
|
||||||
|
StoredValue::StackMemory { location, .. } => {
|
||||||
|
location.local_and_offset(self.storage.stack_frame_pointer)
|
||||||
|
}
|
||||||
|
StoredValue::Local { local_id, .. } => (local_id, 0),
|
||||||
|
StoredValue::VirtualMachineStack { .. } => {
|
||||||
|
internal_error!("{:?} should have a local variable", value)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// load pointer, and add the offset to the pointer
|
||||||
|
self.code_builder.get_local(tag_local_id);
|
||||||
|
|
||||||
|
if tag_offset > 0 {
|
||||||
|
self.code_builder.i32_const(tag_offset as i32);
|
||||||
|
self.code_builder.i32_add();
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: UTILS_FREE_DATA_PTR clears any tag id bits
|
||||||
|
|
||||||
|
// push the allocation's alignment
|
||||||
|
self.code_builder.i32_const(alignment as i32);
|
||||||
|
|
||||||
|
self.call_host_fn_after_loading_args(bitcode::UTILS_FREE_DATA_PTR, 2, false);
|
||||||
|
|
||||||
|
self.stmt(following);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn stmt_internal_error(&mut self, msg: &'a str) {
|
pub fn stmt_internal_error(&mut self, msg: &'a str) {
|
||||||
let msg_sym = self.create_symbol("panic_str");
|
let msg_sym = self.create_symbol("panic_str");
|
||||||
let msg_storage = self.storage.allocate_var(
|
let msg_storage = self.storage.allocate_var(
|
||||||
|
|
|
@ -1979,6 +1979,19 @@ impl<'a> LowLevelCall<'a> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
PtrLoad => backend.expr_unbox(self.ret_symbol, self.arguments[0]),
|
PtrLoad => backend.expr_unbox(self.ret_symbol, self.arguments[0]),
|
||||||
|
PtrClearTagId => {
|
||||||
|
let ptr = self.arguments[0];
|
||||||
|
|
||||||
|
let ptr_local_id = match backend.storage.get(&ptr) {
|
||||||
|
StoredValue::Local { local_id, .. } => *local_id,
|
||||||
|
_ => internal_error!("A pointer will always be an i32"),
|
||||||
|
};
|
||||||
|
|
||||||
|
backend.code_builder.get_local(ptr_local_id);
|
||||||
|
|
||||||
|
backend.code_builder.i32_const(-4); // 11111111...1100
|
||||||
|
backend.code_builder.i32_and();
|
||||||
|
}
|
||||||
Alloca => {
|
Alloca => {
|
||||||
// Alloca : a -> Ptr a
|
// Alloca : a -> Ptr a
|
||||||
let arg = self.arguments[0];
|
let arg = self.arguments[0];
|
||||||
|
|
|
@ -3141,6 +3141,7 @@ fn update<'a>(
|
||||||
arena,
|
arena,
|
||||||
&layout_interner,
|
&layout_interner,
|
||||||
module_id,
|
module_id,
|
||||||
|
state.target_info,
|
||||||
ident_ids,
|
ident_ids,
|
||||||
&mut update_mode_ids,
|
&mut update_mode_ids,
|
||||||
&mut state.procedures,
|
&mut state.procedures,
|
||||||
|
|
|
@ -120,6 +120,7 @@ pub enum LowLevel {
|
||||||
PtrCast,
|
PtrCast,
|
||||||
PtrStore,
|
PtrStore,
|
||||||
PtrLoad,
|
PtrLoad,
|
||||||
|
PtrClearTagId,
|
||||||
Alloca,
|
Alloca,
|
||||||
RefCountIncRcPtr,
|
RefCountIncRcPtr,
|
||||||
RefCountDecRcPtr,
|
RefCountDecRcPtr,
|
||||||
|
@ -232,6 +233,7 @@ macro_rules! map_symbol_to_lowlevel {
|
||||||
LowLevel::PtrCast => unimplemented!(),
|
LowLevel::PtrCast => unimplemented!(),
|
||||||
LowLevel::PtrStore => unimplemented!(),
|
LowLevel::PtrStore => unimplemented!(),
|
||||||
LowLevel::PtrLoad => unimplemented!(),
|
LowLevel::PtrLoad => unimplemented!(),
|
||||||
|
LowLevel::PtrClearTagId => unimplemented!(),
|
||||||
LowLevel::Alloca => unimplemented!(),
|
LowLevel::Alloca => unimplemented!(),
|
||||||
LowLevel::RefCountIncRcPtr => unimplemented!(),
|
LowLevel::RefCountIncRcPtr => unimplemented!(),
|
||||||
LowLevel::RefCountDecRcPtr=> unimplemented!(),
|
LowLevel::RefCountDecRcPtr=> unimplemented!(),
|
||||||
|
|
|
@ -1047,8 +1047,8 @@ pub fn lowlevel_borrow_signature(arena: &Bump, op: LowLevel) -> &[Ownership] {
|
||||||
PtrLoad => arena.alloc_slice_copy(&[owned]),
|
PtrLoad => arena.alloc_slice_copy(&[owned]),
|
||||||
Alloca => arena.alloc_slice_copy(&[owned]),
|
Alloca => arena.alloc_slice_copy(&[owned]),
|
||||||
|
|
||||||
PtrCast | RefCountIncRcPtr | RefCountDecRcPtr | RefCountIncDataPtr | RefCountDecDataPtr
|
PtrClearTagId | PtrCast | RefCountIncRcPtr | RefCountDecRcPtr | RefCountIncDataPtr
|
||||||
| RefCountIsUnique => {
|
| RefCountDecDataPtr | RefCountIsUnique => {
|
||||||
unreachable!("Only inserted *after* borrow checking: {:?}", op);
|
unreachable!("Only inserted *after* borrow checking: {:?}", op);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -141,6 +141,7 @@ impl<'a> CodeGenHelp<'a> {
|
||||||
let jp_decref = JoinPointId(self.create_symbol(ident_ids, "jp_decref"));
|
let jp_decref = JoinPointId(self.create_symbol(ident_ids, "jp_decref"));
|
||||||
HelperOp::DecRef(jp_decref)
|
HelperOp::DecRef(jp_decref)
|
||||||
}
|
}
|
||||||
|
ModifyRc::Free(_) => unreachable!("free should be handled by the backend directly"),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut ctx = Context {
|
let mut ctx = Context {
|
||||||
|
|
|
@ -118,6 +118,9 @@ pub fn refcount_stmt<'a>(
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ModifyRc::Free(_) => {
|
||||||
|
unreachable!("free should be handled by the backend directly")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -453,8 +456,10 @@ pub fn refcount_reset_proc_body<'a>(
|
||||||
root.arena.alloc(refcount_1_stmt),
|
root.arena.alloc(refcount_1_stmt),
|
||||||
);
|
);
|
||||||
|
|
||||||
// a Box never masks bits
|
let mask_lower_bits = match layout_interner.get_repr(layout) {
|
||||||
let mask_lower_bits = false;
|
LayoutRepr::Union(ul) => ul.stores_tag_id_in_pointer(root.target_info),
|
||||||
|
_ => false,
|
||||||
|
};
|
||||||
|
|
||||||
// Refcount pointer
|
// Refcount pointer
|
||||||
let rc_ptr_stmt = {
|
let rc_ptr_stmt = {
|
||||||
|
@ -576,8 +581,10 @@ pub fn refcount_resetref_proc_body<'a>(
|
||||||
root.arena.alloc(refcount_1_stmt),
|
root.arena.alloc(refcount_1_stmt),
|
||||||
);
|
);
|
||||||
|
|
||||||
// a Box never masks bits
|
let mask_lower_bits = match layout_interner.get_repr(layout) {
|
||||||
let mask_lower_bits = false;
|
LayoutRepr::Union(ul) => ul.stores_tag_id_in_pointer(root.target_info),
|
||||||
|
_ => false,
|
||||||
|
};
|
||||||
|
|
||||||
// Refcount pointer
|
// Refcount pointer
|
||||||
let rc_ptr_stmt = {
|
let rc_ptr_stmt = {
|
||||||
|
@ -629,39 +636,33 @@ fn rc_ptr_from_data_ptr_help<'a>(
|
||||||
addr_sym: Symbol,
|
addr_sym: Symbol,
|
||||||
recursion_ptr: InLayout<'a>,
|
recursion_ptr: InLayout<'a>,
|
||||||
) -> Stmt<'a> {
|
) -> Stmt<'a> {
|
||||||
use std::ops::Neg;
|
// symbol of a pointer with any tag id bits cleared
|
||||||
|
let cleared_sym = if mask_lower_bits {
|
||||||
|
root.create_symbol(ident_ids, "cleared")
|
||||||
|
} else {
|
||||||
|
structure
|
||||||
|
};
|
||||||
|
|
||||||
|
let clear_tag_id_expr = Expr::Call(Call {
|
||||||
|
call_type: CallType::LowLevel {
|
||||||
|
op: LowLevel::PtrClearTagId,
|
||||||
|
update_mode: UpdateModeId::BACKEND_DUMMY,
|
||||||
|
},
|
||||||
|
arguments: root.arena.alloc([structure]),
|
||||||
|
});
|
||||||
|
let clear_tag_id_stmt =
|
||||||
|
|next| Stmt::Let(cleared_sym, clear_tag_id_expr, root.layout_isize, next);
|
||||||
|
|
||||||
// Typecast the structure pointer to an integer
|
// Typecast the structure pointer to an integer
|
||||||
// Backends expect a number Layout to choose the right "subtract" instruction
|
// Backends expect a number Layout to choose the right "subtract" instruction
|
||||||
let as_int_sym = if mask_lower_bits {
|
|
||||||
root.create_symbol(ident_ids, "as_int")
|
|
||||||
} else {
|
|
||||||
addr_sym
|
|
||||||
};
|
|
||||||
let as_int_expr = Expr::Call(Call {
|
let as_int_expr = Expr::Call(Call {
|
||||||
call_type: CallType::LowLevel {
|
call_type: CallType::LowLevel {
|
||||||
op: LowLevel::PtrCast,
|
op: LowLevel::PtrCast,
|
||||||
update_mode: UpdateModeId::BACKEND_DUMMY,
|
update_mode: UpdateModeId::BACKEND_DUMMY,
|
||||||
},
|
},
|
||||||
arguments: root.arena.alloc([structure]),
|
arguments: root.arena.alloc([cleared_sym]),
|
||||||
});
|
});
|
||||||
let as_int_stmt = |next| Stmt::Let(as_int_sym, as_int_expr, root.layout_isize, next);
|
let as_int_stmt = |next| Stmt::Let(addr_sym, as_int_expr, root.layout_isize, next);
|
||||||
|
|
||||||
// Mask for lower bits (for tag union id)
|
|
||||||
let mask_sym = root.create_symbol(ident_ids, "mask");
|
|
||||||
let mask_expr = Expr::Literal(Literal::Int(
|
|
||||||
(root.target_info.ptr_width() as i128).neg().to_ne_bytes(),
|
|
||||||
));
|
|
||||||
let mask_stmt = |next| Stmt::Let(mask_sym, mask_expr, root.layout_isize, next);
|
|
||||||
|
|
||||||
let and_expr = Expr::Call(Call {
|
|
||||||
call_type: CallType::LowLevel {
|
|
||||||
op: LowLevel::And,
|
|
||||||
update_mode: UpdateModeId::BACKEND_DUMMY,
|
|
||||||
},
|
|
||||||
arguments: root.arena.alloc([as_int_sym, mask_sym]),
|
|
||||||
});
|
|
||||||
let and_stmt = |next| Stmt::Let(addr_sym, and_expr, root.layout_isize, next);
|
|
||||||
|
|
||||||
// Pointer size constant
|
// Pointer size constant
|
||||||
let ptr_size_sym = root.create_symbol(ident_ids, "ptr_size");
|
let ptr_size_sym = root.create_symbol(ident_ids, "ptr_size");
|
||||||
|
@ -691,40 +692,24 @@ fn rc_ptr_from_data_ptr_help<'a>(
|
||||||
});
|
});
|
||||||
let cast_stmt = |next| Stmt::Let(rc_ptr_sym, cast_expr, recursion_ptr, next);
|
let cast_stmt = |next| Stmt::Let(rc_ptr_sym, cast_expr, recursion_ptr, next);
|
||||||
|
|
||||||
|
let body = as_int_stmt(root.arena.alloc(
|
||||||
|
//
|
||||||
|
ptr_size_stmt(root.arena.alloc(
|
||||||
|
//
|
||||||
|
sub_stmt(root.arena.alloc(
|
||||||
|
//
|
||||||
|
cast_stmt(root.arena.alloc(
|
||||||
|
//
|
||||||
|
following,
|
||||||
|
)),
|
||||||
|
)),
|
||||||
|
)),
|
||||||
|
));
|
||||||
|
|
||||||
if mask_lower_bits {
|
if mask_lower_bits {
|
||||||
as_int_stmt(root.arena.alloc(
|
clear_tag_id_stmt(root.arena.alloc(body))
|
||||||
//
|
|
||||||
mask_stmt(root.arena.alloc(
|
|
||||||
//
|
|
||||||
and_stmt(root.arena.alloc(
|
|
||||||
//
|
|
||||||
ptr_size_stmt(root.arena.alloc(
|
|
||||||
//
|
|
||||||
sub_stmt(root.arena.alloc(
|
|
||||||
//
|
|
||||||
cast_stmt(root.arena.alloc(
|
|
||||||
//
|
|
||||||
following,
|
|
||||||
)),
|
|
||||||
)),
|
|
||||||
)),
|
|
||||||
)),
|
|
||||||
)),
|
|
||||||
))
|
|
||||||
} else {
|
} else {
|
||||||
as_int_stmt(root.arena.alloc(
|
body
|
||||||
//
|
|
||||||
ptr_size_stmt(root.arena.alloc(
|
|
||||||
//
|
|
||||||
sub_stmt(root.arena.alloc(
|
|
||||||
//
|
|
||||||
cast_stmt(root.arena.alloc(
|
|
||||||
//
|
|
||||||
following,
|
|
||||||
)),
|
|
||||||
)),
|
|
||||||
)),
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -716,8 +716,10 @@ impl<'a, 'r> Ctx<'a, 'r> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_modify_rc(&mut self, rc: ModifyRc) {
|
fn check_modify_rc(&mut self, rc: ModifyRc) {
|
||||||
|
use ModifyRc::*;
|
||||||
|
|
||||||
match rc {
|
match rc {
|
||||||
ModifyRc::Inc(sym, _) | ModifyRc::Dec(sym) | ModifyRc::DecRef(sym) => {
|
Inc(sym, _) | Dec(sym) | DecRef(sym) | Free(sym) => {
|
||||||
// TODO: also check that sym layout needs refcounting
|
// TODO: also check that sym layout needs refcounting
|
||||||
self.check_sym_exists(sym);
|
self.check_sym_exists(sym);
|
||||||
}
|
}
|
||||||
|
|
|
@ -582,8 +582,9 @@ fn specialize_drops_stmt<'a, 'i>(
|
||||||
updated_stmt
|
updated_stmt
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ModifyRc::DecRef(_) => {
|
ModifyRc::DecRef(_) | ModifyRc::Free(_) => {
|
||||||
// Inlining has no point, since it doesn't decrement it's children
|
// These operations are not recursive (the children are not touched)
|
||||||
|
// so inlining is not useful
|
||||||
arena.alloc(Stmt::Refcounting(
|
arena.alloc(Stmt::Refcounting(
|
||||||
*rc,
|
*rc,
|
||||||
specialize_drops_stmt(
|
specialize_drops_stmt(
|
||||||
|
@ -1031,8 +1032,10 @@ fn specialize_union<'a, 'i>(
|
||||||
))
|
))
|
||||||
}),
|
}),
|
||||||
arena.alloc(Stmt::Refcounting(
|
arena.alloc(Stmt::Refcounting(
|
||||||
// TODO this could be replaced by a free if ever added to the IR.
|
// we know for sure that the allocation is unique at
|
||||||
ModifyRc::DecRef(*symbol),
|
// this point. Therefore we can free (or maybe reuse)
|
||||||
|
// without checking the refcount again.
|
||||||
|
ModifyRc::Free(*symbol),
|
||||||
continuation,
|
continuation,
|
||||||
)),
|
)),
|
||||||
)
|
)
|
||||||
|
@ -1101,8 +1104,10 @@ fn specialize_boxed<'a, 'i>(
|
||||||
// - free the box
|
// - free the box
|
||||||
|_, _, continuation| {
|
|_, _, continuation| {
|
||||||
arena.alloc(Stmt::Refcounting(
|
arena.alloc(Stmt::Refcounting(
|
||||||
// TODO can be replaced by free if ever added to the IR.
|
// we know for sure that the allocation is unique at
|
||||||
ModifyRc::DecRef(*symbol),
|
// this point. Therefore we can free (or maybe reuse)
|
||||||
|
// without checking the refcount again.
|
||||||
|
ModifyRc::Free(*symbol),
|
||||||
continuation,
|
continuation,
|
||||||
))
|
))
|
||||||
},
|
},
|
||||||
|
@ -1682,8 +1687,8 @@ fn low_level_no_rc(lowlevel: &LowLevel) -> RC {
|
||||||
PtrLoad => RC::NoRc,
|
PtrLoad => RC::NoRc,
|
||||||
Alloca => RC::NoRc,
|
Alloca => RC::NoRc,
|
||||||
|
|
||||||
PtrCast | RefCountIncRcPtr | RefCountDecRcPtr | RefCountIncDataPtr | RefCountDecDataPtr
|
PtrClearTagId | PtrCast | RefCountIncRcPtr | RefCountDecRcPtr | RefCountIncDataPtr
|
||||||
| RefCountIsUnique => {
|
| RefCountDecDataPtr | RefCountIsUnique => {
|
||||||
unreachable!("Only inserted *after* borrow checking: {:?}", lowlevel);
|
unreachable!("Only inserted *after* borrow checking: {:?}", lowlevel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1612,6 +1612,9 @@ pub enum ModifyRc {
|
||||||
/// sometimes we know we already dealt with the elements (e.g. by copying them all over
|
/// sometimes we know we already dealt with the elements (e.g. by copying them all over
|
||||||
/// to a new list) and so we can just do a DecRef, which is much cheaper in such a case.
|
/// to a new list) and so we can just do a DecRef, which is much cheaper in such a case.
|
||||||
DecRef(Symbol),
|
DecRef(Symbol),
|
||||||
|
/// Unconditionally deallocate the memory. For tag union that do pointer tagging (store the tag
|
||||||
|
/// id in the pointer) the backend has to clear the tag id!
|
||||||
|
Free(Symbol),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ModifyRc {
|
impl ModifyRc {
|
||||||
|
@ -1641,6 +1644,10 @@ impl ModifyRc {
|
||||||
.text("decref ")
|
.text("decref ")
|
||||||
.append(symbol_to_doc(alloc, symbol, pretty))
|
.append(symbol_to_doc(alloc, symbol, pretty))
|
||||||
.append(";"),
|
.append(";"),
|
||||||
|
Free(symbol) => alloc
|
||||||
|
.text("free ")
|
||||||
|
.append(symbol_to_doc(alloc, symbol, pretty))
|
||||||
|
.append(";"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1651,6 +1658,7 @@ impl ModifyRc {
|
||||||
Inc(symbol, _) => *symbol,
|
Inc(symbol, _) => *symbol,
|
||||||
Dec(symbol) => *symbol,
|
Dec(symbol) => *symbol,
|
||||||
DecRef(symbol) => *symbol,
|
DecRef(symbol) => *symbol,
|
||||||
|
Free(symbol) => *symbol,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,9 @@ use bumpalo::Bump;
|
||||||
use bumpalo::collections::vec::Vec;
|
use bumpalo::collections::vec::Vec;
|
||||||
use bumpalo::collections::CollectIn;
|
use bumpalo::collections::CollectIn;
|
||||||
use roc_collections::{MutMap, MutSet};
|
use roc_collections::{MutMap, MutSet};
|
||||||
|
use roc_module::low_level::LowLevel;
|
||||||
use roc_module::symbol::{IdentIds, ModuleId, Symbol};
|
use roc_module::symbol::{IdentIds, ModuleId, Symbol};
|
||||||
|
use roc_target::TargetInfo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Insert reset and reuse operations into the IR.
|
Insert reset and reuse operations into the IR.
|
||||||
|
@ -29,6 +31,7 @@ pub fn insert_reset_reuse_operations<'a, 'i>(
|
||||||
arena: &'a Bump,
|
arena: &'a Bump,
|
||||||
layout_interner: &'i STLayoutInterner<'a>,
|
layout_interner: &'i STLayoutInterner<'a>,
|
||||||
home: ModuleId,
|
home: ModuleId,
|
||||||
|
target_info: TargetInfo,
|
||||||
ident_ids: &'i mut IdentIds,
|
ident_ids: &'i mut IdentIds,
|
||||||
update_mode_ids: &'i mut UpdateModeIds,
|
update_mode_ids: &'i mut UpdateModeIds,
|
||||||
procs: &mut MutMap<(Symbol, ProcLayout<'a>), Proc<'a>>,
|
procs: &mut MutMap<(Symbol, ProcLayout<'a>), Proc<'a>>,
|
||||||
|
@ -42,6 +45,7 @@ pub fn insert_reset_reuse_operations<'a, 'i>(
|
||||||
let new_proc = insert_reset_reuse_operations_proc(
|
let new_proc = insert_reset_reuse_operations_proc(
|
||||||
arena,
|
arena,
|
||||||
layout_interner,
|
layout_interner,
|
||||||
|
target_info,
|
||||||
home,
|
home,
|
||||||
ident_ids,
|
ident_ids,
|
||||||
update_mode_ids,
|
update_mode_ids,
|
||||||
|
@ -55,6 +59,7 @@ pub fn insert_reset_reuse_operations<'a, 'i>(
|
||||||
fn insert_reset_reuse_operations_proc<'a, 'i>(
|
fn insert_reset_reuse_operations_proc<'a, 'i>(
|
||||||
arena: &'a Bump,
|
arena: &'a Bump,
|
||||||
layout_interner: &'i STLayoutInterner<'a>,
|
layout_interner: &'i STLayoutInterner<'a>,
|
||||||
|
target_info: TargetInfo,
|
||||||
home: ModuleId,
|
home: ModuleId,
|
||||||
ident_ids: &'i mut IdentIds,
|
ident_ids: &'i mut IdentIds,
|
||||||
update_mode_ids: &'i mut UpdateModeIds,
|
update_mode_ids: &'i mut UpdateModeIds,
|
||||||
|
@ -66,6 +71,7 @@ fn insert_reset_reuse_operations_proc<'a, 'i>(
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut env = ReuseEnvironment {
|
let mut env = ReuseEnvironment {
|
||||||
|
target_info,
|
||||||
symbol_tags: MutMap::default(),
|
symbol_tags: MutMap::default(),
|
||||||
non_unique_symbols: MutSet::default(),
|
non_unique_symbols: MutSet::default(),
|
||||||
reuse_tokens: MutMap::default(),
|
reuse_tokens: MutMap::default(),
|
||||||
|
@ -398,33 +404,83 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
Stmt::Refcounting(rc, continuation) => {
|
Stmt::Refcounting(rc, continuation) => {
|
||||||
let reuse_pair = match rc {
|
enum SymbolIsUnique {
|
||||||
ModifyRc::Dec(symbol) | ModifyRc::DecRef(symbol)
|
Never,
|
||||||
if !environment.non_unique_symbols.contains(symbol) =>
|
Always(Symbol),
|
||||||
{
|
MustCheck(Symbol),
|
||||||
|
}
|
||||||
|
|
||||||
|
let can_reuse = match rc {
|
||||||
|
ModifyRc::Dec(symbol) | ModifyRc::DecRef(symbol) => {
|
||||||
|
// can only reuse if the symbol is (potentially) unique
|
||||||
|
if environment.non_unique_symbols.contains(symbol) {
|
||||||
|
SymbolIsUnique::Never
|
||||||
|
} else {
|
||||||
|
SymbolIsUnique::MustCheck(*symbol)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ModifyRc::Free(symbol) => {
|
||||||
|
// a free'd symbol is guaranteed to be unique
|
||||||
|
SymbolIsUnique::Always(*symbol)
|
||||||
|
}
|
||||||
|
ModifyRc::Inc(_, _) => {
|
||||||
|
// an incremented symbol is never unique
|
||||||
|
SymbolIsUnique::Never
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ResetOperation {
|
||||||
|
Reset,
|
||||||
|
ResetRef,
|
||||||
|
ClearTagId,
|
||||||
|
Nothing,
|
||||||
|
}
|
||||||
|
|
||||||
|
let reuse_pair = match can_reuse {
|
||||||
|
SymbolIsUnique::MustCheck(symbol) | SymbolIsUnique::Always(symbol) => {
|
||||||
// Get the layout of the symbol from where it is defined.
|
// Get the layout of the symbol from where it is defined.
|
||||||
let layout_option = environment.get_symbol_layout(*symbol);
|
let layout_option = environment.get_symbol_layout(symbol);
|
||||||
|
|
||||||
// If the symbol is defined in the current proc, we can use the layout from the environment.
|
// If the symbol is defined in the current proc, we can use the layout from the environment.
|
||||||
match layout_option.clone() {
|
match layout_option {
|
||||||
LayoutOption::Layout(layout) => {
|
LayoutOption::Layout(layout) => {
|
||||||
match symbol_layout_reusability(
|
match symbol_layout_reusability(
|
||||||
layout_interner,
|
layout_interner,
|
||||||
environment,
|
environment,
|
||||||
symbol,
|
&symbol,
|
||||||
layout,
|
layout,
|
||||||
) {
|
) {
|
||||||
Reuse::Reusable(union_layout) => {
|
Reuse::Reusable(union_layout) => {
|
||||||
|
let (reuse_symbol, reset_op) = match rc {
|
||||||
|
ModifyRc::Dec(_) => (
|
||||||
|
Symbol::new(home, ident_ids.gen_unique()),
|
||||||
|
ResetOperation::Reset,
|
||||||
|
),
|
||||||
|
ModifyRc::DecRef(_) => (
|
||||||
|
Symbol::new(home, ident_ids.gen_unique()),
|
||||||
|
ResetOperation::ResetRef,
|
||||||
|
),
|
||||||
|
ModifyRc::Free(_) => {
|
||||||
|
if union_layout
|
||||||
|
.stores_tag_id_in_pointer(environment.target_info)
|
||||||
|
{
|
||||||
|
(
|
||||||
|
Symbol::new(home, ident_ids.gen_unique()),
|
||||||
|
ResetOperation::ClearTagId,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
(symbol, ResetOperation::Nothing)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
|
||||||
let reuse_token = ReuseToken {
|
let reuse_token = ReuseToken {
|
||||||
symbol: Symbol::new(home, ident_ids.gen_unique()),
|
symbol: reuse_symbol,
|
||||||
update_mode_id: update_mode_ids.next_id(),
|
update_mode_id: update_mode_ids.next_id(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let dec_ref = match rc {
|
let owned_layout = **layout;
|
||||||
ModifyRc::Dec(_) => false,
|
|
||||||
ModifyRc::DecRef(_) => true,
|
|
||||||
_ => unreachable!(),
|
|
||||||
};
|
|
||||||
|
|
||||||
environment.push_reuse_token(
|
environment.push_reuse_token(
|
||||||
arena,
|
arena,
|
||||||
|
@ -432,7 +488,14 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
|
||||||
reuse_token,
|
reuse_token,
|
||||||
layout,
|
layout,
|
||||||
);
|
);
|
||||||
Some((layout, union_layout, *symbol, reuse_token, dec_ref))
|
|
||||||
|
Some((
|
||||||
|
owned_layout,
|
||||||
|
union_layout,
|
||||||
|
symbol,
|
||||||
|
reuse_token,
|
||||||
|
reset_op,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
Reuse::Nonreusable => None,
|
Reuse::Nonreusable => None,
|
||||||
}
|
}
|
||||||
|
@ -440,7 +503,7 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
SymbolIsUnique::Never => {
|
||||||
// We don't need to do anything for an inc or symbols known to be non-unique.
|
// We don't need to do anything for an inc or symbols known to be non-unique.
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -457,7 +520,7 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
|
||||||
);
|
);
|
||||||
|
|
||||||
// If we inserted a reuse token, we need to insert a reset reuse operation if the reuse token is consumed.
|
// If we inserted a reuse token, we need to insert a reset reuse operation if the reuse token is consumed.
|
||||||
if let Some((layout, union_layout, symbol, reuse_token, dec_ref)) = reuse_pair {
|
if let Some((layout, union_layout, symbol, reuse_token, reset_op)) = reuse_pair {
|
||||||
let stack_reuse_token = environment
|
let stack_reuse_token = environment
|
||||||
.peek_reuse_token(&get_reuse_layout_info(layout_interner, union_layout));
|
.peek_reuse_token(&get_reuse_layout_info(layout_interner, union_layout));
|
||||||
|
|
||||||
|
@ -471,29 +534,56 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
|
||||||
_ => {
|
_ => {
|
||||||
// The token we inserted is no longer on the stack, it must have been consumed.
|
// The token we inserted is no longer on the stack, it must have been consumed.
|
||||||
// So we need to insert a reset operation.
|
// So we need to insert a reset operation.
|
||||||
let reset_expr = match dec_ref {
|
match reset_op {
|
||||||
// A decref will be replaced by a resetref.
|
ResetOperation::Reset => {
|
||||||
true => Expr::ResetRef {
|
// a dec will be replaced by a reset.
|
||||||
symbol,
|
let reset_expr = Expr::Reset {
|
||||||
update_mode: reuse_token.update_mode_id,
|
symbol,
|
||||||
},
|
update_mode: reuse_token.update_mode_id,
|
||||||
// And a dec will be replaced by a reset.
|
};
|
||||||
false => Expr::Reset {
|
|
||||||
symbol,
|
|
||||||
update_mode: reuse_token.update_mode_id,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
// If we generate a reuse token, we no longer want to use the drop statement anymore. So we just return the reset expression.
|
return arena.alloc(Stmt::Let(
|
||||||
// TODO verify if this works for both dec and decref.
|
reuse_token.symbol,
|
||||||
// TODO reset probably decrements it's children. So we probably need to create a resetref that only does the token.
|
reset_expr,
|
||||||
return arena.alloc(Stmt::Let(
|
layout,
|
||||||
reuse_token.symbol,
|
new_continuation,
|
||||||
reset_expr,
|
));
|
||||||
// TODO not sure what the layout should be for a reset token. Currently it is the layout of the symbol.
|
}
|
||||||
*layout,
|
ResetOperation::ResetRef => {
|
||||||
new_continuation,
|
// a decref will be replaced by a resetref.
|
||||||
));
|
let reset_expr = Expr::ResetRef {
|
||||||
|
symbol,
|
||||||
|
update_mode: reuse_token.update_mode_id,
|
||||||
|
};
|
||||||
|
|
||||||
|
return arena.alloc(Stmt::Let(
|
||||||
|
reuse_token.symbol,
|
||||||
|
reset_expr,
|
||||||
|
layout,
|
||||||
|
new_continuation,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
ResetOperation::ClearTagId => {
|
||||||
|
let reset_expr = Expr::Call(crate::ir::Call {
|
||||||
|
call_type: crate::ir::CallType::LowLevel {
|
||||||
|
op: LowLevel::PtrClearTagId,
|
||||||
|
update_mode: update_mode_ids.next_id(),
|
||||||
|
},
|
||||||
|
arguments: arena.alloc([symbol]),
|
||||||
|
});
|
||||||
|
|
||||||
|
return arena.alloc(Stmt::Let(
|
||||||
|
reuse_token.symbol,
|
||||||
|
reset_expr,
|
||||||
|
layout,
|
||||||
|
new_continuation,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
ResetOperation::Nothing => {
|
||||||
|
// the reuse token is already in a valid state
|
||||||
|
return new_continuation;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -661,6 +751,7 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
|
||||||
|
|
||||||
// Create a new environment for the body. With everything but the jump reuse tokens. As those should be given by the jump.
|
// Create a new environment for the body. With everything but the jump reuse tokens. As those should be given by the jump.
|
||||||
let mut first_pass_body_environment = ReuseEnvironment {
|
let mut first_pass_body_environment = ReuseEnvironment {
|
||||||
|
target_info: environment.target_info,
|
||||||
symbol_tags: environment.symbol_tags.clone(),
|
symbol_tags: environment.symbol_tags.clone(),
|
||||||
non_unique_symbols: environment.non_unique_symbols.clone(),
|
non_unique_symbols: environment.non_unique_symbols.clone(),
|
||||||
reuse_tokens: max_reuse_token_symbols.clone(),
|
reuse_tokens: max_reuse_token_symbols.clone(),
|
||||||
|
@ -824,6 +915,7 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
|
||||||
let (second_pass_body_environment, second_pass_body) = {
|
let (second_pass_body_environment, second_pass_body) = {
|
||||||
// Create a new environment for the body. With everything but the jump reuse tokens. As those should be given by the jump.
|
// Create a new environment for the body. With everything but the jump reuse tokens. As those should be given by the jump.
|
||||||
let mut body_environment = ReuseEnvironment {
|
let mut body_environment = ReuseEnvironment {
|
||||||
|
target_info: environment.target_info,
|
||||||
symbol_tags: environment.symbol_tags.clone(),
|
symbol_tags: environment.symbol_tags.clone(),
|
||||||
non_unique_symbols: environment.non_unique_symbols.clone(),
|
non_unique_symbols: environment.non_unique_symbols.clone(),
|
||||||
reuse_tokens: used_reuse_tokens.clone(),
|
reuse_tokens: used_reuse_tokens.clone(),
|
||||||
|
@ -889,7 +981,8 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
|
||||||
let mut void_pointer_layout_symbols = Vec::new_in(arena);
|
let mut void_pointer_layout_symbols = Vec::new_in(arena);
|
||||||
|
|
||||||
// See what tokens we can get from the env, if none are available, use a void pointer.
|
// See what tokens we can get from the env, if none are available, use a void pointer.
|
||||||
// We process the tokens in reverse order, so that when we consume the tokens we last added, we consume the tokens that are most likely not to be null.
|
// We process the tokens in reverse order, so that when we consume the tokens we last added,
|
||||||
|
// we consume the tokens that are most likely not to be null.
|
||||||
let tokens = token_layouts_clone
|
let tokens = token_layouts_clone
|
||||||
.iter()
|
.iter()
|
||||||
.rev()
|
.rev()
|
||||||
|
@ -1002,7 +1095,7 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
|
||||||
fn create_ptr_cast(arena: &Bump, symbol: Symbol) -> Expr {
|
fn create_ptr_cast(arena: &Bump, symbol: Symbol) -> Expr {
|
||||||
Expr::Call(crate::ir::Call {
|
Expr::Call(crate::ir::Call {
|
||||||
call_type: crate::ir::CallType::LowLevel {
|
call_type: crate::ir::CallType::LowLevel {
|
||||||
op: roc_module::low_level::LowLevel::PtrCast,
|
op: LowLevel::PtrCast,
|
||||||
update_mode: UpdateModeId::BACKEND_DUMMY,
|
update_mode: UpdateModeId::BACKEND_DUMMY,
|
||||||
},
|
},
|
||||||
arguments: Vec::from_iter_in([symbol], arena).into_bump_slice(),
|
arguments: Vec::from_iter_in([symbol], arena).into_bump_slice(),
|
||||||
|
@ -1029,7 +1122,6 @@ Struct to to check whether two reuse layouts are interchangeable.
|
||||||
*/
|
*/
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||||
struct TokenLayout {
|
struct TokenLayout {
|
||||||
has_tag: bool,
|
|
||||||
size: u32,
|
size: u32,
|
||||||
alignment: u32,
|
alignment: u32,
|
||||||
}
|
}
|
||||||
|
@ -1092,8 +1184,9 @@ enum JoinPointReuseTokens<'a> {
|
||||||
RemainderSecond(Vec<'a, (&'a InLayout<'a>, TokenLayout)>),
|
RemainderSecond(Vec<'a, (&'a InLayout<'a>, TokenLayout)>),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, Clone)]
|
#[derive(Clone)]
|
||||||
struct ReuseEnvironment<'a> {
|
struct ReuseEnvironment<'a> {
|
||||||
|
target_info: TargetInfo,
|
||||||
symbol_tags: MutMap<Symbol, Tag>,
|
symbol_tags: MutMap<Symbol, Tag>,
|
||||||
non_unique_symbols: MutSet<Symbol>,
|
non_unique_symbols: MutSet<Symbol>,
|
||||||
reuse_tokens: ReuseTokens<'a>,
|
reuse_tokens: ReuseTokens<'a>,
|
||||||
|
@ -1322,16 +1415,6 @@ fn get_reuse_layout_info<'a, 'i>(
|
||||||
union_layout: UnionLayout<'a>,
|
union_layout: UnionLayout<'a>,
|
||||||
) -> TokenLayout {
|
) -> TokenLayout {
|
||||||
let (size, alignment) = union_layout.data_size_and_alignment(layout_interner);
|
let (size, alignment) = union_layout.data_size_and_alignment(layout_interner);
|
||||||
let has_tag = match union_layout {
|
|
||||||
UnionLayout::NonRecursive(_) => unreachable!("Non recursive unions should not be reused."),
|
TokenLayout { size, alignment }
|
||||||
// The memory for union layouts that has a tag_id can be reused for new allocations with tag_id.
|
|
||||||
UnionLayout::Recursive(_) | UnionLayout::NullableWrapped { .. } => true,
|
|
||||||
// The memory for union layouts that have no tag_id can be reused for new allocations without tag_id
|
|
||||||
UnionLayout::NonNullableUnwrapped(_) | UnionLayout::NullableUnwrapped { .. } => false,
|
|
||||||
};
|
|
||||||
TokenLayout {
|
|
||||||
has_tag,
|
|
||||||
size,
|
|
||||||
alignment,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,23 +16,22 @@ procedure Test.5 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2):
|
||||||
if Test.53 then
|
if Test.53 then
|
||||||
let Test.32 : [<rnu><null>, C *self *self] = UnionAtIndex (Id 0) (Index 0) Test.29;
|
let Test.32 : [<rnu><null>, C *self *self] = UnionAtIndex (Id 0) (Index 0) Test.29;
|
||||||
let Test.33 : [<rnu><null>, C *self *self] = UnionAtIndex (Id 0) (Index 1) Test.29;
|
let Test.33 : [<rnu><null>, C *self *self] = UnionAtIndex (Id 0) (Index 1) Test.29;
|
||||||
joinpoint #Derived_gen.3 #Derived_gen.7:
|
joinpoint #Derived_gen.3 #Derived_gen.6:
|
||||||
let #Derived_gen.8 : [<rnu>C [<rnu><null>, C *self *self] *self, <null>] = lowlevel PtrCast #Derived_gen.7;
|
let #Derived_gen.7 : [<rnu>C [<rnu><null>, C *self *self] *self, <null>] = lowlevel PtrCast #Derived_gen.6;
|
||||||
let Test.43 : [<rnu>C [<rnu><null>, C *self *self] *self, <null>] = Reuse #Derived_gen.8 UpdateModeId { id: 1 } TagId(1) Test.33 Test.30;
|
let Test.43 : [<rnu>C [<rnu><null>, C *self *self] *self, <null>] = Reuse #Derived_gen.7 UpdateModeId { id: 1 } TagId(1) Test.33 Test.30;
|
||||||
let Test.45 : I64 = 1i64;
|
let Test.45 : I64 = 1i64;
|
||||||
let Test.44 : I64 = CallByName Num.19 Test.31 Test.45;
|
let Test.44 : I64 = CallByName Num.19 Test.31 Test.45;
|
||||||
jump Test.41 Test.32 Test.43 Test.44;
|
jump Test.41 Test.32 Test.43 Test.44;
|
||||||
in
|
in
|
||||||
let #Derived_gen.4 : Int1 = lowlevel RefCountIsUnique Test.29;
|
let #Derived_gen.4 : Int1 = lowlevel RefCountIsUnique Test.29;
|
||||||
if #Derived_gen.4 then
|
if #Derived_gen.4 then
|
||||||
let #Derived_gen.9 : [<rnu><null>, C *self *self] = ResetRef { symbol: Test.29, id: UpdateModeId { id: 2 } };
|
jump #Derived_gen.3 Test.29;
|
||||||
jump #Derived_gen.3 #Derived_gen.9;
|
|
||||||
else
|
else
|
||||||
inc Test.32;
|
inc Test.32;
|
||||||
inc Test.33;
|
inc Test.33;
|
||||||
decref Test.29;
|
decref Test.29;
|
||||||
let #Derived_gen.10 : [<rnu><null>, C *self *self] = NullPointer;
|
let #Derived_gen.8 : [<rnu><null>, C *self *self] = NullPointer;
|
||||||
jump #Derived_gen.3 #Derived_gen.10;
|
jump #Derived_gen.3 #Derived_gen.8;
|
||||||
else
|
else
|
||||||
let Test.48 : U8 = 1i64;
|
let Test.48 : U8 = 1i64;
|
||||||
let Test.49 : U8 = GetTagId Test.30;
|
let Test.49 : U8 = GetTagId Test.30;
|
||||||
|
@ -42,7 +41,7 @@ procedure Test.5 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2):
|
||||||
let Test.36 : [<rnu>C [<rnu><null>, C *self *self] *self, <null>] = UnionAtIndex (Id 1) (Index 1) Test.30;
|
let Test.36 : [<rnu>C [<rnu><null>, C *self *self] *self, <null>] = UnionAtIndex (Id 1) (Index 1) Test.30;
|
||||||
let #Derived_gen.5 : Int1 = lowlevel RefCountIsUnique Test.30;
|
let #Derived_gen.5 : Int1 = lowlevel RefCountIsUnique Test.30;
|
||||||
if #Derived_gen.5 then
|
if #Derived_gen.5 then
|
||||||
decref Test.30;
|
free Test.30;
|
||||||
jump Test.41 Test.35 Test.36 Test.31;
|
jump Test.41 Test.35 Test.36 Test.31;
|
||||||
else
|
else
|
||||||
inc Test.35;
|
inc Test.35;
|
||||||
|
|
|
@ -90,7 +90,7 @@ procedure Test.2 (Test.6):
|
||||||
in
|
in
|
||||||
let #Derived_gen.2 : Int1 = lowlevel RefCountIsUnique Test.6;
|
let #Derived_gen.2 : Int1 = lowlevel RefCountIsUnique Test.6;
|
||||||
if #Derived_gen.2 then
|
if #Derived_gen.2 then
|
||||||
decref Test.6;
|
free Test.6;
|
||||||
jump #Derived_gen.1;
|
jump #Derived_gen.1;
|
||||||
else
|
else
|
||||||
inc Test.7;
|
inc Test.7;
|
||||||
|
@ -108,7 +108,7 @@ procedure Test.2 (Test.6):
|
||||||
in
|
in
|
||||||
let #Derived_gen.4 : Int1 = lowlevel RefCountIsUnique Test.6;
|
let #Derived_gen.4 : Int1 = lowlevel RefCountIsUnique Test.6;
|
||||||
if #Derived_gen.4 then
|
if #Derived_gen.4 then
|
||||||
decref Test.6;
|
free Test.6;
|
||||||
jump #Derived_gen.3;
|
jump #Derived_gen.3;
|
||||||
else
|
else
|
||||||
inc Test.9;
|
inc Test.9;
|
||||||
|
|
|
@ -87,7 +87,7 @@ procedure Test.11 (#Derived_gen.7, #Derived_gen.8):
|
||||||
in
|
in
|
||||||
let #Derived_gen.15 : Int1 = lowlevel RefCountIsUnique #Attr.12;
|
let #Derived_gen.15 : Int1 = lowlevel RefCountIsUnique #Attr.12;
|
||||||
if #Derived_gen.15 then
|
if #Derived_gen.15 then
|
||||||
decref #Attr.12;
|
free #Attr.12;
|
||||||
jump #Derived_gen.14;
|
jump #Derived_gen.14;
|
||||||
else
|
else
|
||||||
inc Test.7;
|
inc Test.7;
|
||||||
|
@ -155,7 +155,7 @@ procedure Test.9 (Test.10, #Attr.12):
|
||||||
in
|
in
|
||||||
let #Derived_gen.13 : Int1 = lowlevel RefCountIsUnique #Attr.12;
|
let #Derived_gen.13 : Int1 = lowlevel RefCountIsUnique #Attr.12;
|
||||||
if #Derived_gen.13 then
|
if #Derived_gen.13 then
|
||||||
decref #Attr.12;
|
free #Attr.12;
|
||||||
jump #Derived_gen.12;
|
jump #Derived_gen.12;
|
||||||
else
|
else
|
||||||
inc Test.7;
|
inc Test.7;
|
||||||
|
|
|
@ -15,7 +15,7 @@ procedure Test.2 (#Derived_gen.0):
|
||||||
let Test.5 : [<rnu><null>, C *self] = UnionAtIndex (Id 0) (Index 0) Test.7;
|
let Test.5 : [<rnu><null>, C *self] = UnionAtIndex (Id 0) (Index 0) Test.7;
|
||||||
let #Derived_gen.1 : Int1 = lowlevel RefCountIsUnique Test.7;
|
let #Derived_gen.1 : Int1 = lowlevel RefCountIsUnique Test.7;
|
||||||
if #Derived_gen.1 then
|
if #Derived_gen.1 then
|
||||||
decref Test.7;
|
free Test.7;
|
||||||
jump Test.13 Test.5;
|
jump Test.13 Test.5;
|
||||||
else
|
else
|
||||||
inc Test.5;
|
inc Test.5;
|
||||||
|
|
|
@ -116,7 +116,7 @@ procedure Test.1 (#Derived_gen.0):
|
||||||
in
|
in
|
||||||
let #Derived_gen.7 : Int1 = lowlevel RefCountIsUnique Test.49;
|
let #Derived_gen.7 : Int1 = lowlevel RefCountIsUnique Test.49;
|
||||||
if #Derived_gen.7 then
|
if #Derived_gen.7 then
|
||||||
decref Test.49;
|
free Test.49;
|
||||||
jump #Derived_gen.6;
|
jump #Derived_gen.6;
|
||||||
else
|
else
|
||||||
decref Test.49;
|
decref Test.49;
|
||||||
|
@ -161,7 +161,7 @@ procedure Test.1 (#Derived_gen.0):
|
||||||
in
|
in
|
||||||
let #Derived_gen.9 : Int1 = lowlevel RefCountIsUnique Test.51;
|
let #Derived_gen.9 : Int1 = lowlevel RefCountIsUnique Test.51;
|
||||||
if #Derived_gen.9 then
|
if #Derived_gen.9 then
|
||||||
decref Test.51;
|
free Test.51;
|
||||||
jump #Derived_gen.8;
|
jump #Derived_gen.8;
|
||||||
else
|
else
|
||||||
inc Test.14;
|
inc Test.14;
|
||||||
|
|
|
@ -22,27 +22,26 @@ procedure Test.2 (#Derived_gen.0, #Derived_gen.1):
|
||||||
else
|
else
|
||||||
let Test.7 : I64 = UnionAtIndex (Id 0) (Index 0) Test.4;
|
let Test.7 : I64 = UnionAtIndex (Id 0) (Index 0) Test.4;
|
||||||
let Test.8 : [<rnu><null>, C I64 *self] = UnionAtIndex (Id 0) (Index 1) Test.4;
|
let Test.8 : [<rnu><null>, C I64 *self] = UnionAtIndex (Id 0) (Index 1) Test.4;
|
||||||
joinpoint #Derived_gen.12 #Derived_gen.15:
|
joinpoint #Derived_gen.12 #Derived_gen.14:
|
||||||
let Test.19 : Int1 = CallByName Num.31 Test.7;
|
let Test.19 : Int1 = CallByName Num.31 Test.7;
|
||||||
if Test.19 then
|
if Test.19 then
|
||||||
let #Derived_gen.9 : [<rnu><null>, C I64 *self] = NullPointer;
|
let #Derived_gen.9 : [<rnu><null>, C I64 *self] = NullPointer;
|
||||||
let Test.20 : [<rnu><null>, C I64 *self] = Reuse #Derived_gen.15 UpdateModeId { id: 1 } TagId(0) Test.7 #Derived_gen.9;
|
let Test.20 : [<rnu><null>, C I64 *self] = Reuse #Derived_gen.14 UpdateModeId { id: 1 } TagId(0) Test.7 #Derived_gen.9;
|
||||||
let #Derived_gen.10 : Ptr([<rnu><null>, C I64 *self]) = UnionFieldPtrAtIndex (Id 0) (Index 1) Test.20;
|
let #Derived_gen.10 : Ptr([<rnu><null>, C I64 *self]) = UnionFieldPtrAtIndex (Id 0) (Index 1) Test.20;
|
||||||
let #Derived_gen.11 : {} = lowlevel PtrStore #Derived_gen.5 Test.20;
|
let #Derived_gen.11 : {} = lowlevel PtrStore #Derived_gen.5 Test.20;
|
||||||
jump #Derived_gen.4 Test.8 Test.5 #Derived_gen.10 #Derived_gen.6;
|
jump #Derived_gen.4 Test.8 Test.5 #Derived_gen.10 #Derived_gen.6;
|
||||||
else
|
else
|
||||||
decref #Derived_gen.15;
|
decref #Derived_gen.14;
|
||||||
jump #Derived_gen.4 Test.8 Test.5 #Derived_gen.5 #Derived_gen.6;
|
jump #Derived_gen.4 Test.8 Test.5 #Derived_gen.5 #Derived_gen.6;
|
||||||
in
|
in
|
||||||
let #Derived_gen.13 : Int1 = lowlevel RefCountIsUnique Test.4;
|
let #Derived_gen.13 : Int1 = lowlevel RefCountIsUnique Test.4;
|
||||||
if #Derived_gen.13 then
|
if #Derived_gen.13 then
|
||||||
let #Derived_gen.16 : [<rnu><null>, C I64 *self] = ResetRef { symbol: Test.4, id: UpdateModeId { id: 2 } };
|
jump #Derived_gen.12 Test.4;
|
||||||
jump #Derived_gen.12 #Derived_gen.16;
|
|
||||||
else
|
else
|
||||||
inc Test.8;
|
inc Test.8;
|
||||||
decref Test.4;
|
decref Test.4;
|
||||||
let #Derived_gen.17 : [<rnu><null>, C I64 *self] = NullPointer;
|
let #Derived_gen.15 : [<rnu><null>, C I64 *self] = NullPointer;
|
||||||
jump #Derived_gen.12 #Derived_gen.17;
|
jump #Derived_gen.12 #Derived_gen.15;
|
||||||
in
|
in
|
||||||
jump #Derived_gen.4 #Derived_gen.0 #Derived_gen.1 #Derived_gen.2 #Derived_gen.2;
|
jump #Derived_gen.4 #Derived_gen.0 #Derived_gen.1 #Derived_gen.2 #Derived_gen.2;
|
||||||
|
|
||||||
|
|
|
@ -22,23 +22,22 @@ procedure Test.2 (#Derived_gen.0, #Derived_gen.1):
|
||||||
else
|
else
|
||||||
let Test.7 : I64 = UnionAtIndex (Id 0) (Index 0) Test.5;
|
let Test.7 : I64 = UnionAtIndex (Id 0) (Index 0) Test.5;
|
||||||
let Test.8 : [<rnu><null>, C I64 *self] = UnionAtIndex (Id 0) (Index 1) Test.5;
|
let Test.8 : [<rnu><null>, C I64 *self] = UnionAtIndex (Id 0) (Index 1) Test.5;
|
||||||
joinpoint #Derived_gen.12 #Derived_gen.15:
|
joinpoint #Derived_gen.12 #Derived_gen.14:
|
||||||
let Test.20 : I64 = CallByName Test.10 Test.7;
|
let Test.20 : I64 = CallByName Test.10 Test.7;
|
||||||
let #Derived_gen.9 : [<rnu><null>, C I64 *self] = NullPointer;
|
let #Derived_gen.9 : [<rnu><null>, C I64 *self] = NullPointer;
|
||||||
let Test.19 : [<rnu><null>, C I64 *self] = Reuse #Derived_gen.15 UpdateModeId { id: 1 } TagId(0) Test.20 #Derived_gen.9;
|
let Test.19 : [<rnu><null>, C I64 *self] = Reuse #Derived_gen.14 UpdateModeId { id: 1 } TagId(0) Test.20 #Derived_gen.9;
|
||||||
let #Derived_gen.10 : Ptr([<rnu><null>, C I64 *self]) = UnionFieldPtrAtIndex (Id 0) (Index 1) Test.19;
|
let #Derived_gen.10 : Ptr([<rnu><null>, C I64 *self]) = UnionFieldPtrAtIndex (Id 0) (Index 1) Test.19;
|
||||||
let #Derived_gen.11 : {} = lowlevel PtrStore #Derived_gen.5 Test.19;
|
let #Derived_gen.11 : {} = lowlevel PtrStore #Derived_gen.5 Test.19;
|
||||||
jump #Derived_gen.4 Test.4 Test.8 #Derived_gen.10 #Derived_gen.6;
|
jump #Derived_gen.4 Test.4 Test.8 #Derived_gen.10 #Derived_gen.6;
|
||||||
in
|
in
|
||||||
let #Derived_gen.13 : Int1 = lowlevel RefCountIsUnique Test.5;
|
let #Derived_gen.13 : Int1 = lowlevel RefCountIsUnique Test.5;
|
||||||
if #Derived_gen.13 then
|
if #Derived_gen.13 then
|
||||||
let #Derived_gen.16 : [<rnu><null>, C I64 *self] = ResetRef { symbol: Test.5, id: UpdateModeId { id: 2 } };
|
jump #Derived_gen.12 Test.5;
|
||||||
jump #Derived_gen.12 #Derived_gen.16;
|
|
||||||
else
|
else
|
||||||
inc Test.8;
|
inc Test.8;
|
||||||
decref Test.5;
|
decref Test.5;
|
||||||
let #Derived_gen.17 : [<rnu><null>, C I64 *self] = NullPointer;
|
let #Derived_gen.15 : [<rnu><null>, C I64 *self] = NullPointer;
|
||||||
jump #Derived_gen.12 #Derived_gen.17;
|
jump #Derived_gen.12 #Derived_gen.15;
|
||||||
in
|
in
|
||||||
jump #Derived_gen.4 #Derived_gen.0 #Derived_gen.1 #Derived_gen.2 #Derived_gen.2;
|
jump #Derived_gen.4 #Derived_gen.0 #Derived_gen.1 #Derived_gen.2 #Derived_gen.2;
|
||||||
|
|
||||||
|
|
|
@ -13,19 +13,18 @@ procedure Test.3 (#Derived_gen.0, #Derived_gen.1):
|
||||||
else
|
else
|
||||||
let Test.9 : I64 = UnionAtIndex (Id 0) (Index 0) Test.8;
|
let Test.9 : I64 = UnionAtIndex (Id 0) (Index 0) Test.8;
|
||||||
let Test.10 : [<rnu><null>, C I64 *self] = UnionAtIndex (Id 0) (Index 1) Test.8;
|
let Test.10 : [<rnu><null>, C I64 *self] = UnionAtIndex (Id 0) (Index 1) Test.8;
|
||||||
joinpoint #Derived_gen.2 #Derived_gen.5:
|
joinpoint #Derived_gen.2 #Derived_gen.4:
|
||||||
let Test.21 : [<rnu><null>, C I64 *self] = Reuse #Derived_gen.5 UpdateModeId { id: 1 } TagId(0) Test.9 Test.7;
|
let Test.21 : [<rnu><null>, C I64 *self] = Reuse #Derived_gen.4 UpdateModeId { id: 1 } TagId(0) Test.9 Test.7;
|
||||||
jump Test.18 Test.21 Test.10;
|
jump Test.18 Test.21 Test.10;
|
||||||
in
|
in
|
||||||
let #Derived_gen.3 : Int1 = lowlevel RefCountIsUnique Test.8;
|
let #Derived_gen.3 : Int1 = lowlevel RefCountIsUnique Test.8;
|
||||||
if #Derived_gen.3 then
|
if #Derived_gen.3 then
|
||||||
let #Derived_gen.6 : [<rnu><null>, C I64 *self] = ResetRef { symbol: Test.8, id: UpdateModeId { id: 2 } };
|
jump #Derived_gen.2 Test.8;
|
||||||
jump #Derived_gen.2 #Derived_gen.6;
|
|
||||||
else
|
else
|
||||||
inc Test.10;
|
inc Test.10;
|
||||||
decref Test.8;
|
decref Test.8;
|
||||||
let #Derived_gen.7 : [<rnu><null>, C I64 *self] = NullPointer;
|
let #Derived_gen.5 : [<rnu><null>, C I64 *self] = NullPointer;
|
||||||
jump #Derived_gen.2 #Derived_gen.7;
|
jump #Derived_gen.2 #Derived_gen.5;
|
||||||
in
|
in
|
||||||
jump Test.18 #Derived_gen.0 #Derived_gen.1;
|
jump Test.18 #Derived_gen.0 #Derived_gen.1;
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ procedure Test.0 ():
|
||||||
let #Derived_gen.1 : Int1 = lowlevel RefCountIsUnique Test.2;
|
let #Derived_gen.1 : Int1 = lowlevel RefCountIsUnique Test.2;
|
||||||
if #Derived_gen.1 then
|
if #Derived_gen.1 then
|
||||||
dec Test.13;
|
dec Test.13;
|
||||||
decref Test.2;
|
free Test.2;
|
||||||
jump #Derived_gen.0;
|
jump #Derived_gen.0;
|
||||||
else
|
else
|
||||||
decref Test.2;
|
decref Test.2;
|
||||||
|
|
|
@ -22,7 +22,7 @@ procedure Test.0 ():
|
||||||
in
|
in
|
||||||
let #Derived_gen.1 : Int1 = lowlevel RefCountIsUnique Test.2;
|
let #Derived_gen.1 : Int1 = lowlevel RefCountIsUnique Test.2;
|
||||||
if #Derived_gen.1 then
|
if #Derived_gen.1 then
|
||||||
decref Test.2;
|
free Test.2;
|
||||||
jump #Derived_gen.0;
|
jump #Derived_gen.0;
|
||||||
else
|
else
|
||||||
inc Test.12;
|
inc Test.12;
|
||||||
|
|
|
@ -37,7 +37,7 @@ procedure Test.0 ():
|
||||||
let #Derived_gen.1 : Int1 = lowlevel RefCountIsUnique Test.15;
|
let #Derived_gen.1 : Int1 = lowlevel RefCountIsUnique Test.15;
|
||||||
if #Derived_gen.1 then
|
if #Derived_gen.1 then
|
||||||
dec Test.16;
|
dec Test.16;
|
||||||
decref Test.15;
|
free Test.15;
|
||||||
jump #Derived_gen.0;
|
jump #Derived_gen.0;
|
||||||
else
|
else
|
||||||
decref Test.15;
|
decref Test.15;
|
||||||
|
|
|
@ -30,13 +30,13 @@ procedure Test.3 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2):
|
||||||
let Test.18 : I64 = UnionAtIndex (Id 1) (Index 1) Test.9;
|
let Test.18 : I64 = UnionAtIndex (Id 1) (Index 1) Test.9;
|
||||||
let Test.19 : [<rnu>C *self I64 *self I32 Int1, <null>] = UnionAtIndex (Id 1) (Index 2) Test.9;
|
let Test.19 : [<rnu>C *self I64 *self I32 Int1, <null>] = UnionAtIndex (Id 1) (Index 2) Test.9;
|
||||||
let Test.17 : I32 = UnionAtIndex (Id 1) (Index 3) Test.9;
|
let Test.17 : I32 = UnionAtIndex (Id 1) (Index 3) Test.9;
|
||||||
joinpoint #Derived_gen.114 #Derived_gen.119:
|
joinpoint #Derived_gen.114 #Derived_gen.118:
|
||||||
let Test.179 : Int1 = CallByName Num.22 Test.10 Test.17;
|
let Test.179 : Int1 = CallByName Num.22 Test.10 Test.17;
|
||||||
if Test.179 then
|
if Test.179 then
|
||||||
joinpoint Test.238 #Derived_gen.181:
|
joinpoint Test.238 #Derived_gen.166:
|
||||||
let Test.232 : Int1 = false;
|
let Test.232 : Int1 = false;
|
||||||
let #Derived_gen.10 : [<rnu>C *self I64 *self I32 Int1, <null>] = NullPointer;
|
let #Derived_gen.10 : [<rnu>C *self I64 *self I32 Int1, <null>] = NullPointer;
|
||||||
let Test.231 : [<rnu>C *self I64 *self I32 Int1, <null>] = Reuse #Derived_gen.181 UpdateModeId { id: 56 } TagId(1) #Derived_gen.10 Test.18 Test.19 Test.17 Test.232;
|
let Test.231 : [<rnu>C *self I64 *self I32 Int1, <null>] = Reuse #Derived_gen.166 UpdateModeId { id: 56 } TagId(1) #Derived_gen.10 Test.18 Test.19 Test.17 Test.232;
|
||||||
let #Derived_gen.11 : Ptr([<rnu>C *self I64 *self I32 Int1, <null>]) = UnionFieldPtrAtIndex (Id 1) (Index 0) Test.231;
|
let #Derived_gen.11 : Ptr([<rnu>C *self I64 *self I32 Int1, <null>]) = UnionFieldPtrAtIndex (Id 1) (Index 0) Test.231;
|
||||||
let #Derived_gen.12 : {} = lowlevel PtrStore #Derived_gen.6 Test.231;
|
let #Derived_gen.12 : {} = lowlevel PtrStore #Derived_gen.6 Test.231;
|
||||||
jump #Derived_gen.5 Test.16 Test.10 Test.11 #Derived_gen.11 #Derived_gen.7;
|
jump #Derived_gen.5 Test.16 Test.10 Test.11 #Derived_gen.11 #Derived_gen.7;
|
||||||
|
@ -50,7 +50,7 @@ procedure Test.3 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2):
|
||||||
let Test.239 : Int1 = lowlevel Eq Test.235 Test.234;
|
let Test.239 : Int1 = lowlevel Eq Test.235 Test.234;
|
||||||
if Test.239 then
|
if Test.239 then
|
||||||
let Test.180 : [<rnu>C *self I64 *self I32 Int1, <null>] = CallByName Test.3 Test.16 Test.10 Test.11;
|
let Test.180 : [<rnu>C *self I64 *self I32 Int1, <null>] = CallByName Test.3 Test.16 Test.10 Test.11;
|
||||||
joinpoint Test.199 #Derived_gen.208:
|
joinpoint Test.199 #Derived_gen.187:
|
||||||
let Test.198 : [<rnu>C *self I64 *self I32 Int1, <null>] = UnionAtIndex (Id 1) (Index 0) Test.180;
|
let Test.198 : [<rnu>C *self I64 *self I32 Int1, <null>] = UnionAtIndex (Id 1) (Index 0) Test.180;
|
||||||
let Test.20 : [<rnu>C *self I64 *self I32 Int1, <null>] = UnionAtIndex (Id 1) (Index 0) Test.198;
|
let Test.20 : [<rnu>C *self I64 *self I32 Int1, <null>] = UnionAtIndex (Id 1) (Index 0) Test.198;
|
||||||
inc Test.20;
|
inc Test.20;
|
||||||
|
@ -61,57 +61,55 @@ procedure Test.3 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2):
|
||||||
let Test.25 : I64 = UnionAtIndex (Id 1) (Index 1) Test.180;
|
let Test.25 : I64 = UnionAtIndex (Id 1) (Index 1) Test.180;
|
||||||
let Test.26 : [<rnu>C *self I64 *self I32 Int1, <null>] = UnionAtIndex (Id 1) (Index 2) Test.180;
|
let Test.26 : [<rnu>C *self I64 *self I32 Int1, <null>] = UnionAtIndex (Id 1) (Index 2) Test.180;
|
||||||
let Test.24 : I32 = UnionAtIndex (Id 1) (Index 3) Test.180;
|
let Test.24 : I32 = UnionAtIndex (Id 1) (Index 3) Test.180;
|
||||||
joinpoint #Derived_gen.72 #Derived_gen.211 #Derived_gen.212 #Derived_gen.213:
|
joinpoint #Derived_gen.72 #Derived_gen.189 #Derived_gen.190 #Derived_gen.191:
|
||||||
let Test.186 : Int1 = false;
|
let Test.186 : Int1 = false;
|
||||||
let Test.183 : [<rnu>C *self I64 *self I32 Int1, <null>] = Reuse #Derived_gen.213 UpdateModeId { id: 85 } TagId(1) Test.20 Test.22 Test.23 Test.21 Test.186;
|
let Test.183 : [<rnu>C *self I64 *self I32 Int1, <null>] = Reuse #Derived_gen.191 UpdateModeId { id: 85 } TagId(1) Test.20 Test.22 Test.23 Test.21 Test.186;
|
||||||
let Test.185 : Int1 = false;
|
let Test.185 : Int1 = false;
|
||||||
let Test.184 : [<rnu>C *self I64 *self I32 Int1, <null>] = Reuse #Derived_gen.212 UpdateModeId { id: 84 } TagId(1) Test.26 Test.18 Test.19 Test.17 Test.185;
|
let Test.184 : [<rnu>C *self I64 *self I32 Int1, <null>] = Reuse #Derived_gen.190 UpdateModeId { id: 84 } TagId(1) Test.26 Test.18 Test.19 Test.17 Test.185;
|
||||||
let Test.182 : Int1 = true;
|
let Test.182 : Int1 = true;
|
||||||
let Test.181 : [<rnu>C *self I64 *self I32 Int1, <null>] = Reuse #Derived_gen.211 UpdateModeId { id: 83 } TagId(1) Test.183 Test.25 Test.184 Test.24 Test.182;
|
let Test.181 : [<rnu>C *self I64 *self I32 Int1, <null>] = Reuse #Derived_gen.189 UpdateModeId { id: 83 } TagId(1) Test.183 Test.25 Test.184 Test.24 Test.182;
|
||||||
let #Derived_gen.14 : {} = lowlevel PtrStore #Derived_gen.6 Test.181;
|
let #Derived_gen.14 : {} = lowlevel PtrStore #Derived_gen.6 Test.181;
|
||||||
let #Derived_gen.13 : [<rnu>C *self I64 *self I32 Int1, <null>] = lowlevel PtrLoad #Derived_gen.7;
|
let #Derived_gen.13 : [<rnu>C *self I64 *self I32 Int1, <null>] = lowlevel PtrLoad #Derived_gen.7;
|
||||||
ret #Derived_gen.13;
|
ret #Derived_gen.13;
|
||||||
in
|
in
|
||||||
let #Derived_gen.73 : Int1 = lowlevel RefCountIsUnique Test.180;
|
let #Derived_gen.73 : Int1 = lowlevel RefCountIsUnique Test.180;
|
||||||
if #Derived_gen.73 then
|
if #Derived_gen.73 then
|
||||||
let #Derived_gen.214 : [<rnu>C *self I64 *self I32 Int1, <null>] = Reset { symbol: Test.198, id: UpdateModeId { id: 86 } };
|
let #Derived_gen.192 : [<rnu>C *self I64 *self I32 Int1, <null>] = Reset { symbol: Test.198, id: UpdateModeId { id: 86 } };
|
||||||
let #Derived_gen.215 : [<rnu>C *self I64 *self I32 Int1, <null>] = ResetRef { symbol: Test.180, id: UpdateModeId { id: 87 } };
|
jump #Derived_gen.72 #Derived_gen.187 #Derived_gen.192 Test.180;
|
||||||
jump #Derived_gen.72 #Derived_gen.208 #Derived_gen.214 #Derived_gen.215;
|
|
||||||
else
|
else
|
||||||
inc Test.26;
|
inc Test.26;
|
||||||
decref Test.180;
|
decref Test.180;
|
||||||
let #Derived_gen.216 : [<rnu>C *self I64 *self I32 Int1, <null>] = NullPointer;
|
let #Derived_gen.193 : [<rnu>C *self I64 *self I32 Int1, <null>] = NullPointer;
|
||||||
jump #Derived_gen.72 #Derived_gen.216 #Derived_gen.216 #Derived_gen.208;
|
jump #Derived_gen.72 #Derived_gen.193 #Derived_gen.193 #Derived_gen.187;
|
||||||
in
|
in
|
||||||
let Test.228 : U8 = 1i64;
|
let Test.228 : U8 = 1i64;
|
||||||
let Test.229 : U8 = GetTagId Test.180;
|
let Test.229 : U8 = GetTagId Test.180;
|
||||||
let Test.230 : Int1 = lowlevel Eq Test.228 Test.229;
|
let Test.230 : Int1 = lowlevel Eq Test.228 Test.229;
|
||||||
if Test.230 then
|
if Test.230 then
|
||||||
joinpoint Test.225 #Derived_gen.226:
|
joinpoint Test.225 #Derived_gen.201:
|
||||||
joinpoint Test.216 #Derived_gen.227:
|
joinpoint Test.216 #Derived_gen.202:
|
||||||
let Test.46 : [<rnu>C *self I64 *self I32 Int1, <null>] = UnionAtIndex (Id 1) (Index 0) Test.180;
|
let Test.46 : [<rnu>C *self I64 *self I32 Int1, <null>] = UnionAtIndex (Id 1) (Index 0) Test.180;
|
||||||
let Test.48 : I64 = UnionAtIndex (Id 1) (Index 1) Test.180;
|
let Test.48 : I64 = UnionAtIndex (Id 1) (Index 1) Test.180;
|
||||||
let Test.49 : [<rnu>C *self I64 *self I32 Int1, <null>] = UnionAtIndex (Id 1) (Index 2) Test.180;
|
let Test.49 : [<rnu>C *self I64 *self I32 Int1, <null>] = UnionAtIndex (Id 1) (Index 2) Test.180;
|
||||||
let Test.47 : I32 = UnionAtIndex (Id 1) (Index 3) Test.180;
|
let Test.47 : I32 = UnionAtIndex (Id 1) (Index 3) Test.180;
|
||||||
joinpoint #Derived_gen.66 #Derived_gen.229 #Derived_gen.230:
|
joinpoint #Derived_gen.66 #Derived_gen.203 #Derived_gen.204:
|
||||||
let Test.196 : Int1 = true;
|
let Test.196 : Int1 = true;
|
||||||
let Test.195 : [<rnu>C *self I64 *self I32 Int1, <null>] = Reuse #Derived_gen.230 UpdateModeId { id: 100 } TagId(1) Test.46 Test.48 Test.49 Test.47 Test.196;
|
let Test.195 : [<rnu>C *self I64 *self I32 Int1, <null>] = Reuse #Derived_gen.204 UpdateModeId { id: 100 } TagId(1) Test.46 Test.48 Test.49 Test.47 Test.196;
|
||||||
let Test.194 : Int1 = false;
|
let Test.194 : Int1 = false;
|
||||||
let Test.193 : [<rnu>C *self I64 *self I32 Int1, <null>] = Reuse #Derived_gen.229 UpdateModeId { id: 99 } TagId(1) Test.195 Test.18 Test.19 Test.17 Test.194;
|
let Test.193 : [<rnu>C *self I64 *self I32 Int1, <null>] = Reuse #Derived_gen.203 UpdateModeId { id: 99 } TagId(1) Test.195 Test.18 Test.19 Test.17 Test.194;
|
||||||
let #Derived_gen.16 : {} = lowlevel PtrStore #Derived_gen.6 Test.193;
|
let #Derived_gen.16 : {} = lowlevel PtrStore #Derived_gen.6 Test.193;
|
||||||
let #Derived_gen.15 : [<rnu>C *self I64 *self I32 Int1, <null>] = lowlevel PtrLoad #Derived_gen.7;
|
let #Derived_gen.15 : [<rnu>C *self I64 *self I32 Int1, <null>] = lowlevel PtrLoad #Derived_gen.7;
|
||||||
ret #Derived_gen.15;
|
ret #Derived_gen.15;
|
||||||
in
|
in
|
||||||
let #Derived_gen.67 : Int1 = lowlevel RefCountIsUnique Test.180;
|
let #Derived_gen.67 : Int1 = lowlevel RefCountIsUnique Test.180;
|
||||||
if #Derived_gen.67 then
|
if #Derived_gen.67 then
|
||||||
let #Derived_gen.231 : [<rnu>C *self I64 *self I32 Int1, <null>] = ResetRef { symbol: Test.180, id: UpdateModeId { id: 101 } };
|
jump #Derived_gen.66 #Derived_gen.202 Test.180;
|
||||||
jump #Derived_gen.66 #Derived_gen.227 #Derived_gen.231;
|
|
||||||
else
|
else
|
||||||
inc Test.46;
|
inc Test.46;
|
||||||
inc Test.49;
|
inc Test.49;
|
||||||
decref Test.180;
|
decref Test.180;
|
||||||
let #Derived_gen.232 : [<rnu>C *self I64 *self I32 Int1, <null>] = NullPointer;
|
let #Derived_gen.205 : [<rnu>C *self I64 *self I32 Int1, <null>] = NullPointer;
|
||||||
jump #Derived_gen.66 #Derived_gen.232 #Derived_gen.227;
|
jump #Derived_gen.66 #Derived_gen.205 #Derived_gen.202;
|
||||||
in
|
in
|
||||||
let Test.213 : [<rnu>C *self I64 *self I32 Int1, <null>] = UnionAtIndex (Id 1) (Index 0) Test.180;
|
let Test.213 : [<rnu>C *self I64 *self I32 Int1, <null>] = UnionAtIndex (Id 1) (Index 0) Test.180;
|
||||||
let Test.214 : U8 = 1i64;
|
let Test.214 : U8 = 1i64;
|
||||||
|
@ -123,11 +121,11 @@ procedure Test.3 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2):
|
||||||
let Test.212 : Int1 = true;
|
let Test.212 : Int1 = true;
|
||||||
let Test.217 : Int1 = lowlevel Eq Test.212 Test.211;
|
let Test.217 : Int1 = lowlevel Eq Test.212 Test.211;
|
||||||
if Test.217 then
|
if Test.217 then
|
||||||
jump Test.199 #Derived_gen.226;
|
jump Test.199 #Derived_gen.201;
|
||||||
else
|
else
|
||||||
jump Test.216 #Derived_gen.226;
|
jump Test.216 #Derived_gen.201;
|
||||||
else
|
else
|
||||||
jump Test.216 #Derived_gen.226;
|
jump Test.216 #Derived_gen.201;
|
||||||
in
|
in
|
||||||
let Test.222 : [<rnu>C *self I64 *self I32 Int1, <null>] = UnionAtIndex (Id 1) (Index 2) Test.180;
|
let Test.222 : [<rnu>C *self I64 *self I32 Int1, <null>] = UnionAtIndex (Id 1) (Index 2) Test.180;
|
||||||
let Test.223 : U8 = 1i64;
|
let Test.223 : U8 = 1i64;
|
||||||
|
@ -139,7 +137,7 @@ procedure Test.3 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2):
|
||||||
let Test.221 : Int1 = true;
|
let Test.221 : Int1 = true;
|
||||||
let Test.226 : Int1 = lowlevel Eq Test.221 Test.220;
|
let Test.226 : Int1 = lowlevel Eq Test.221 Test.220;
|
||||||
if Test.226 then
|
if Test.226 then
|
||||||
joinpoint Test.207 #Derived_gen.233:
|
joinpoint Test.207 #Derived_gen.206:
|
||||||
let Test.33 : [<rnu>C *self I64 *self I32 Int1, <null>] = UnionAtIndex (Id 1) (Index 0) Test.180;
|
let Test.33 : [<rnu>C *self I64 *self I32 Int1, <null>] = UnionAtIndex (Id 1) (Index 0) Test.180;
|
||||||
let Test.35 : I64 = UnionAtIndex (Id 1) (Index 1) Test.180;
|
let Test.35 : I64 = UnionAtIndex (Id 1) (Index 1) Test.180;
|
||||||
let Test.200 : [<rnu>C *self I64 *self I32 Int1, <null>] = UnionAtIndex (Id 1) (Index 2) Test.180;
|
let Test.200 : [<rnu>C *self I64 *self I32 Int1, <null>] = UnionAtIndex (Id 1) (Index 2) Test.180;
|
||||||
|
@ -150,27 +148,26 @@ procedure Test.3 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2):
|
||||||
inc Test.39;
|
inc Test.39;
|
||||||
let Test.37 : I32 = UnionAtIndex (Id 1) (Index 3) Test.200;
|
let Test.37 : I32 = UnionAtIndex (Id 1) (Index 3) Test.200;
|
||||||
let Test.34 : I32 = UnionAtIndex (Id 1) (Index 3) Test.180;
|
let Test.34 : I32 = UnionAtIndex (Id 1) (Index 3) Test.180;
|
||||||
joinpoint #Derived_gen.70 #Derived_gen.236 #Derived_gen.237 #Derived_gen.238:
|
joinpoint #Derived_gen.70 #Derived_gen.208 #Derived_gen.209 #Derived_gen.210:
|
||||||
let Test.192 : Int1 = false;
|
let Test.192 : Int1 = false;
|
||||||
let Test.189 : [<rnu>C *self I64 *self I32 Int1, <null>] = Reuse #Derived_gen.238 UpdateModeId { id: 107 } TagId(1) Test.33 Test.35 Test.36 Test.34 Test.192;
|
let Test.189 : [<rnu>C *self I64 *self I32 Int1, <null>] = Reuse #Derived_gen.210 UpdateModeId { id: 107 } TagId(1) Test.33 Test.35 Test.36 Test.34 Test.192;
|
||||||
let Test.191 : Int1 = false;
|
let Test.191 : Int1 = false;
|
||||||
let Test.190 : [<rnu>C *self I64 *self I32 Int1, <null>] = Reuse #Derived_gen.237 UpdateModeId { id: 106 } TagId(1) Test.39 Test.18 Test.19 Test.17 Test.191;
|
let Test.190 : [<rnu>C *self I64 *self I32 Int1, <null>] = Reuse #Derived_gen.209 UpdateModeId { id: 106 } TagId(1) Test.39 Test.18 Test.19 Test.17 Test.191;
|
||||||
let Test.188 : Int1 = true;
|
let Test.188 : Int1 = true;
|
||||||
let Test.187 : [<rnu>C *self I64 *self I32 Int1, <null>] = Reuse #Derived_gen.236 UpdateModeId { id: 105 } TagId(1) Test.189 Test.38 Test.190 Test.37 Test.188;
|
let Test.187 : [<rnu>C *self I64 *self I32 Int1, <null>] = Reuse #Derived_gen.208 UpdateModeId { id: 105 } TagId(1) Test.189 Test.38 Test.190 Test.37 Test.188;
|
||||||
let #Derived_gen.18 : {} = lowlevel PtrStore #Derived_gen.6 Test.187;
|
let #Derived_gen.18 : {} = lowlevel PtrStore #Derived_gen.6 Test.187;
|
||||||
let #Derived_gen.17 : [<rnu>C *self I64 *self I32 Int1, <null>] = lowlevel PtrLoad #Derived_gen.7;
|
let #Derived_gen.17 : [<rnu>C *self I64 *self I32 Int1, <null>] = lowlevel PtrLoad #Derived_gen.7;
|
||||||
ret #Derived_gen.17;
|
ret #Derived_gen.17;
|
||||||
in
|
in
|
||||||
let #Derived_gen.71 : Int1 = lowlevel RefCountIsUnique Test.180;
|
let #Derived_gen.71 : Int1 = lowlevel RefCountIsUnique Test.180;
|
||||||
if #Derived_gen.71 then
|
if #Derived_gen.71 then
|
||||||
let #Derived_gen.239 : [<rnu>C *self I64 *self I32 Int1, <null>] = Reset { symbol: Test.200, id: UpdateModeId { id: 108 } };
|
let #Derived_gen.211 : [<rnu>C *self I64 *self I32 Int1, <null>] = Reset { symbol: Test.200, id: UpdateModeId { id: 108 } };
|
||||||
let #Derived_gen.240 : [<rnu>C *self I64 *self I32 Int1, <null>] = ResetRef { symbol: Test.180, id: UpdateModeId { id: 109 } };
|
jump #Derived_gen.70 #Derived_gen.206 #Derived_gen.211 Test.180;
|
||||||
jump #Derived_gen.70 #Derived_gen.233 #Derived_gen.239 #Derived_gen.240;
|
|
||||||
else
|
else
|
||||||
inc Test.33;
|
inc Test.33;
|
||||||
decref Test.180;
|
decref Test.180;
|
||||||
let #Derived_gen.241 : [<rnu>C *self I64 *self I32 Int1, <null>] = NullPointer;
|
let #Derived_gen.212 : [<rnu>C *self I64 *self I32 Int1, <null>] = NullPointer;
|
||||||
jump #Derived_gen.70 #Derived_gen.241 #Derived_gen.241 #Derived_gen.233;
|
jump #Derived_gen.70 #Derived_gen.212 #Derived_gen.212 #Derived_gen.206;
|
||||||
in
|
in
|
||||||
let Test.204 : [<rnu>C *self I64 *self I32 Int1, <null>] = UnionAtIndex (Id 1) (Index 0) Test.180;
|
let Test.204 : [<rnu>C *self I64 *self I32 Int1, <null>] = UnionAtIndex (Id 1) (Index 0) Test.180;
|
||||||
let Test.205 : U8 = 1i64;
|
let Test.205 : U8 = 1i64;
|
||||||
|
@ -182,33 +179,33 @@ procedure Test.3 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2):
|
||||||
let Test.203 : Int1 = true;
|
let Test.203 : Int1 = true;
|
||||||
let Test.208 : Int1 = lowlevel Eq Test.203 Test.202;
|
let Test.208 : Int1 = lowlevel Eq Test.203 Test.202;
|
||||||
if Test.208 then
|
if Test.208 then
|
||||||
jump Test.199 #Derived_gen.119;
|
jump Test.199 #Derived_gen.118;
|
||||||
else
|
else
|
||||||
jump Test.207 #Derived_gen.119;
|
jump Test.207 #Derived_gen.118;
|
||||||
else
|
else
|
||||||
jump Test.207 #Derived_gen.119;
|
jump Test.207 #Derived_gen.118;
|
||||||
else
|
else
|
||||||
jump Test.225 #Derived_gen.119;
|
jump Test.225 #Derived_gen.118;
|
||||||
else
|
else
|
||||||
jump Test.225 #Derived_gen.119;
|
jump Test.225 #Derived_gen.118;
|
||||||
else
|
else
|
||||||
decref #Derived_gen.119;
|
decref #Derived_gen.118;
|
||||||
dec Test.19;
|
dec Test.19;
|
||||||
let Test.197 : [<rnu>C *self I64 *self I32 Int1, <null>] = TagId(0) ;
|
let Test.197 : [<rnu>C *self I64 *self I32 Int1, <null>] = TagId(0) ;
|
||||||
let #Derived_gen.20 : {} = lowlevel PtrStore #Derived_gen.6 Test.197;
|
let #Derived_gen.20 : {} = lowlevel PtrStore #Derived_gen.6 Test.197;
|
||||||
let #Derived_gen.19 : [<rnu>C *self I64 *self I32 Int1, <null>] = lowlevel PtrLoad #Derived_gen.7;
|
let #Derived_gen.19 : [<rnu>C *self I64 *self I32 Int1, <null>] = lowlevel PtrLoad #Derived_gen.7;
|
||||||
ret #Derived_gen.19;
|
ret #Derived_gen.19;
|
||||||
else
|
else
|
||||||
jump Test.238 #Derived_gen.119;
|
jump Test.238 #Derived_gen.118;
|
||||||
else
|
else
|
||||||
jump Test.238 #Derived_gen.119;
|
jump Test.238 #Derived_gen.118;
|
||||||
else
|
else
|
||||||
let Test.117 : Int1 = CallByName Num.24 Test.10 Test.17;
|
let Test.117 : Int1 = CallByName Num.24 Test.10 Test.17;
|
||||||
if Test.117 then
|
if Test.117 then
|
||||||
joinpoint Test.176 #Derived_gen.333:
|
joinpoint Test.176 #Derived_gen.288:
|
||||||
let Test.170 : Int1 = false;
|
let Test.170 : Int1 = false;
|
||||||
let #Derived_gen.21 : [<rnu>C *self I64 *self I32 Int1, <null>] = NullPointer;
|
let #Derived_gen.21 : [<rnu>C *self I64 *self I32 Int1, <null>] = NullPointer;
|
||||||
let Test.169 : [<rnu>C *self I64 *self I32 Int1, <null>] = Reuse #Derived_gen.333 UpdateModeId { id: 196 } TagId(1) Test.16 Test.18 #Derived_gen.21 Test.17 Test.170;
|
let Test.169 : [<rnu>C *self I64 *self I32 Int1, <null>] = Reuse #Derived_gen.288 UpdateModeId { id: 196 } TagId(1) Test.16 Test.18 #Derived_gen.21 Test.17 Test.170;
|
||||||
let #Derived_gen.22 : Ptr([<rnu>C *self I64 *self I32 Int1, <null>]) = UnionFieldPtrAtIndex (Id 1) (Index 2) Test.169;
|
let #Derived_gen.22 : Ptr([<rnu>C *self I64 *self I32 Int1, <null>]) = UnionFieldPtrAtIndex (Id 1) (Index 2) Test.169;
|
||||||
let #Derived_gen.23 : {} = lowlevel PtrStore #Derived_gen.6 Test.169;
|
let #Derived_gen.23 : {} = lowlevel PtrStore #Derived_gen.6 Test.169;
|
||||||
jump #Derived_gen.5 Test.19 Test.10 Test.11 #Derived_gen.22 #Derived_gen.7;
|
jump #Derived_gen.5 Test.19 Test.10 Test.11 #Derived_gen.22 #Derived_gen.7;
|
||||||
|
@ -222,9 +219,9 @@ procedure Test.3 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2):
|
||||||
let Test.177 : Int1 = lowlevel Eq Test.173 Test.172;
|
let Test.177 : Int1 = lowlevel Eq Test.173 Test.172;
|
||||||
if Test.177 then
|
if Test.177 then
|
||||||
inc Test.19;
|
inc Test.19;
|
||||||
let #Derived_gen.334 : [<rnu>C *self I64 *self I32 Int1, <null>] = Reset { symbol: Test.16, id: UpdateModeId { id: 197 } };
|
let #Derived_gen.289 : [<rnu>C *self I64 *self I32 Int1, <null>] = Reset { symbol: Test.16, id: UpdateModeId { id: 197 } };
|
||||||
let Test.118 : [<rnu>C *self I64 *self I32 Int1, <null>] = CallByName Test.3 Test.19 Test.10 Test.11;
|
let Test.118 : [<rnu>C *self I64 *self I32 Int1, <null>] = CallByName Test.3 Test.19 Test.10 Test.11;
|
||||||
joinpoint Test.137 #Derived_gen.374 #Derived_gen.375:
|
joinpoint Test.137 #Derived_gen.322 #Derived_gen.323:
|
||||||
let Test.136 : [<rnu>C *self I64 *self I32 Int1, <null>] = UnionAtIndex (Id 1) (Index 0) Test.118;
|
let Test.136 : [<rnu>C *self I64 *self I32 Int1, <null>] = UnionAtIndex (Id 1) (Index 0) Test.118;
|
||||||
let Test.57 : [<rnu>C *self I64 *self I32 Int1, <null>] = UnionAtIndex (Id 1) (Index 0) Test.136;
|
let Test.57 : [<rnu>C *self I64 *self I32 Int1, <null>] = UnionAtIndex (Id 1) (Index 0) Test.136;
|
||||||
inc Test.57;
|
inc Test.57;
|
||||||
|
@ -235,58 +232,56 @@ procedure Test.3 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2):
|
||||||
let Test.62 : I64 = UnionAtIndex (Id 1) (Index 1) Test.118;
|
let Test.62 : I64 = UnionAtIndex (Id 1) (Index 1) Test.118;
|
||||||
let Test.63 : [<rnu>C *self I64 *self I32 Int1, <null>] = UnionAtIndex (Id 1) (Index 2) Test.118;
|
let Test.63 : [<rnu>C *self I64 *self I32 Int1, <null>] = UnionAtIndex (Id 1) (Index 2) Test.118;
|
||||||
let Test.61 : I32 = UnionAtIndex (Id 1) (Index 3) Test.118;
|
let Test.61 : I32 = UnionAtIndex (Id 1) (Index 3) Test.118;
|
||||||
joinpoint #Derived_gen.112 #Derived_gen.379 #Derived_gen.380 #Derived_gen.381:
|
joinpoint #Derived_gen.112 #Derived_gen.326 #Derived_gen.327 #Derived_gen.328:
|
||||||
let Test.124 : Int1 = false;
|
let Test.124 : Int1 = false;
|
||||||
let Test.121 : [<rnu>C *self I64 *self I32 Int1, <null>] = Reuse #Derived_gen.381 UpdateModeId { id: 242 } TagId(1) Test.57 Test.59 Test.60 Test.58 Test.124;
|
let Test.121 : [<rnu>C *self I64 *self I32 Int1, <null>] = Reuse #Derived_gen.328 UpdateModeId { id: 242 } TagId(1) Test.57 Test.59 Test.60 Test.58 Test.124;
|
||||||
let Test.123 : Int1 = false;
|
let Test.123 : Int1 = false;
|
||||||
let Test.122 : [<rnu>C *self I64 *self I32 Int1, <null>] = Reuse #Derived_gen.380 UpdateModeId { id: 241 } TagId(1) Test.63 Test.18 Test.19 Test.17 Test.123;
|
let Test.122 : [<rnu>C *self I64 *self I32 Int1, <null>] = Reuse #Derived_gen.327 UpdateModeId { id: 241 } TagId(1) Test.63 Test.18 Test.19 Test.17 Test.123;
|
||||||
let Test.120 : Int1 = true;
|
let Test.120 : Int1 = true;
|
||||||
let Test.119 : [<rnu>C *self I64 *self I32 Int1, <null>] = Reuse #Derived_gen.379 UpdateModeId { id: 240 } TagId(1) Test.121 Test.62 Test.122 Test.61 Test.120;
|
let Test.119 : [<rnu>C *self I64 *self I32 Int1, <null>] = Reuse #Derived_gen.326 UpdateModeId { id: 240 } TagId(1) Test.121 Test.62 Test.122 Test.61 Test.120;
|
||||||
let #Derived_gen.25 : {} = lowlevel PtrStore #Derived_gen.6 Test.119;
|
let #Derived_gen.25 : {} = lowlevel PtrStore #Derived_gen.6 Test.119;
|
||||||
let #Derived_gen.24 : [<rnu>C *self I64 *self I32 Int1, <null>] = lowlevel PtrLoad #Derived_gen.7;
|
let #Derived_gen.24 : [<rnu>C *self I64 *self I32 Int1, <null>] = lowlevel PtrLoad #Derived_gen.7;
|
||||||
ret #Derived_gen.24;
|
ret #Derived_gen.24;
|
||||||
in
|
in
|
||||||
let #Derived_gen.113 : Int1 = lowlevel RefCountIsUnique Test.118;
|
let #Derived_gen.113 : Int1 = lowlevel RefCountIsUnique Test.118;
|
||||||
if #Derived_gen.113 then
|
if #Derived_gen.113 then
|
||||||
decref #Derived_gen.374;
|
decref #Derived_gen.322;
|
||||||
let #Derived_gen.382 : [<rnu>C *self I64 *self I32 Int1, <null>] = Reset { symbol: Test.136, id: UpdateModeId { id: 243 } };
|
let #Derived_gen.329 : [<rnu>C *self I64 *self I32 Int1, <null>] = Reset { symbol: Test.136, id: UpdateModeId { id: 243 } };
|
||||||
let #Derived_gen.383 : [<rnu>C *self I64 *self I32 Int1, <null>] = ResetRef { symbol: Test.118, id: UpdateModeId { id: 244 } };
|
jump #Derived_gen.112 #Derived_gen.323 #Derived_gen.329 Test.118;
|
||||||
jump #Derived_gen.112 #Derived_gen.375 #Derived_gen.382 #Derived_gen.383;
|
|
||||||
else
|
else
|
||||||
inc Test.63;
|
inc Test.63;
|
||||||
decref Test.118;
|
decref Test.118;
|
||||||
let #Derived_gen.384 : [<rnu>C *self I64 *self I32 Int1, <null>] = NullPointer;
|
let #Derived_gen.330 : [<rnu>C *self I64 *self I32 Int1, <null>] = NullPointer;
|
||||||
jump #Derived_gen.112 #Derived_gen.384 #Derived_gen.374 #Derived_gen.375;
|
jump #Derived_gen.112 #Derived_gen.330 #Derived_gen.322 #Derived_gen.323;
|
||||||
in
|
in
|
||||||
let Test.166 : U8 = 1i64;
|
let Test.166 : U8 = 1i64;
|
||||||
let Test.167 : U8 = GetTagId Test.118;
|
let Test.167 : U8 = GetTagId Test.118;
|
||||||
let Test.168 : Int1 = lowlevel Eq Test.166 Test.167;
|
let Test.168 : Int1 = lowlevel Eq Test.166 Test.167;
|
||||||
if Test.168 then
|
if Test.168 then
|
||||||
joinpoint Test.163 #Derived_gen.396 #Derived_gen.397:
|
joinpoint Test.163 #Derived_gen.340 #Derived_gen.341:
|
||||||
joinpoint Test.154 #Derived_gen.398 #Derived_gen.399:
|
joinpoint Test.154 #Derived_gen.342 #Derived_gen.343:
|
||||||
let Test.83 : [<rnu>C *self I64 *self I32 Int1, <null>] = UnionAtIndex (Id 1) (Index 0) Test.118;
|
let Test.83 : [<rnu>C *self I64 *self I32 Int1, <null>] = UnionAtIndex (Id 1) (Index 0) Test.118;
|
||||||
let Test.85 : I64 = UnionAtIndex (Id 1) (Index 1) Test.118;
|
let Test.85 : I64 = UnionAtIndex (Id 1) (Index 1) Test.118;
|
||||||
let Test.86 : [<rnu>C *self I64 *self I32 Int1, <null>] = UnionAtIndex (Id 1) (Index 2) Test.118;
|
let Test.86 : [<rnu>C *self I64 *self I32 Int1, <null>] = UnionAtIndex (Id 1) (Index 2) Test.118;
|
||||||
let Test.84 : I32 = UnionAtIndex (Id 1) (Index 3) Test.118;
|
let Test.84 : I32 = UnionAtIndex (Id 1) (Index 3) Test.118;
|
||||||
joinpoint #Derived_gen.102 #Derived_gen.402 #Derived_gen.403:
|
joinpoint #Derived_gen.102 #Derived_gen.345 #Derived_gen.346:
|
||||||
let Test.134 : Int1 = true;
|
let Test.134 : Int1 = true;
|
||||||
let Test.133 : [<rnu>C *self I64 *self I32 Int1, <null>] = Reuse #Derived_gen.403 UpdateModeId { id: 262 } TagId(1) Test.83 Test.85 Test.86 Test.84 Test.134;
|
let Test.133 : [<rnu>C *self I64 *self I32 Int1, <null>] = Reuse #Derived_gen.346 UpdateModeId { id: 262 } TagId(1) Test.83 Test.85 Test.86 Test.84 Test.134;
|
||||||
let Test.132 : Int1 = false;
|
let Test.132 : Int1 = false;
|
||||||
let Test.131 : [<rnu>C *self I64 *self I32 Int1, <null>] = Reuse #Derived_gen.402 UpdateModeId { id: 261 } TagId(1) Test.133 Test.18 Test.19 Test.17 Test.132;
|
let Test.131 : [<rnu>C *self I64 *self I32 Int1, <null>] = Reuse #Derived_gen.345 UpdateModeId { id: 261 } TagId(1) Test.133 Test.18 Test.19 Test.17 Test.132;
|
||||||
let #Derived_gen.27 : {} = lowlevel PtrStore #Derived_gen.6 Test.131;
|
let #Derived_gen.27 : {} = lowlevel PtrStore #Derived_gen.6 Test.131;
|
||||||
let #Derived_gen.26 : [<rnu>C *self I64 *self I32 Int1, <null>] = lowlevel PtrLoad #Derived_gen.7;
|
let #Derived_gen.26 : [<rnu>C *self I64 *self I32 Int1, <null>] = lowlevel PtrLoad #Derived_gen.7;
|
||||||
ret #Derived_gen.26;
|
ret #Derived_gen.26;
|
||||||
in
|
in
|
||||||
let #Derived_gen.103 : Int1 = lowlevel RefCountIsUnique Test.118;
|
let #Derived_gen.103 : Int1 = lowlevel RefCountIsUnique Test.118;
|
||||||
if #Derived_gen.103 then
|
if #Derived_gen.103 then
|
||||||
decref #Derived_gen.398;
|
decref #Derived_gen.342;
|
||||||
let #Derived_gen.404 : [<rnu>C *self I64 *self I32 Int1, <null>] = ResetRef { symbol: Test.118, id: UpdateModeId { id: 263 } };
|
jump #Derived_gen.102 #Derived_gen.343 Test.118;
|
||||||
jump #Derived_gen.102 #Derived_gen.399 #Derived_gen.404;
|
|
||||||
else
|
else
|
||||||
inc Test.83;
|
inc Test.83;
|
||||||
inc Test.86;
|
inc Test.86;
|
||||||
decref Test.118;
|
decref Test.118;
|
||||||
jump #Derived_gen.102 #Derived_gen.398 #Derived_gen.399;
|
jump #Derived_gen.102 #Derived_gen.342 #Derived_gen.343;
|
||||||
in
|
in
|
||||||
let Test.151 : [<rnu>C *self I64 *self I32 Int1, <null>] = UnionAtIndex (Id 1) (Index 0) Test.118;
|
let Test.151 : [<rnu>C *self I64 *self I32 Int1, <null>] = UnionAtIndex (Id 1) (Index 0) Test.118;
|
||||||
let Test.152 : U8 = 1i64;
|
let Test.152 : U8 = 1i64;
|
||||||
|
@ -298,11 +293,11 @@ procedure Test.3 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2):
|
||||||
let Test.150 : Int1 = true;
|
let Test.150 : Int1 = true;
|
||||||
let Test.155 : Int1 = lowlevel Eq Test.150 Test.149;
|
let Test.155 : Int1 = lowlevel Eq Test.150 Test.149;
|
||||||
if Test.155 then
|
if Test.155 then
|
||||||
jump Test.137 #Derived_gen.396 #Derived_gen.397;
|
jump Test.137 #Derived_gen.340 #Derived_gen.341;
|
||||||
else
|
else
|
||||||
jump Test.154 #Derived_gen.396 #Derived_gen.397;
|
jump Test.154 #Derived_gen.340 #Derived_gen.341;
|
||||||
else
|
else
|
||||||
jump Test.154 #Derived_gen.396 #Derived_gen.397;
|
jump Test.154 #Derived_gen.340 #Derived_gen.341;
|
||||||
in
|
in
|
||||||
let Test.160 : [<rnu>C *self I64 *self I32 Int1, <null>] = UnionAtIndex (Id 1) (Index 2) Test.118;
|
let Test.160 : [<rnu>C *self I64 *self I32 Int1, <null>] = UnionAtIndex (Id 1) (Index 2) Test.118;
|
||||||
let Test.161 : U8 = 1i64;
|
let Test.161 : U8 = 1i64;
|
||||||
|
@ -314,7 +309,7 @@ procedure Test.3 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2):
|
||||||
let Test.159 : Int1 = true;
|
let Test.159 : Int1 = true;
|
||||||
let Test.164 : Int1 = lowlevel Eq Test.159 Test.158;
|
let Test.164 : Int1 = lowlevel Eq Test.159 Test.158;
|
||||||
if Test.164 then
|
if Test.164 then
|
||||||
joinpoint Test.145 #Derived_gen.405 #Derived_gen.406:
|
joinpoint Test.145 #Derived_gen.347 #Derived_gen.348:
|
||||||
let Test.70 : [<rnu>C *self I64 *self I32 Int1, <null>] = UnionAtIndex (Id 1) (Index 0) Test.118;
|
let Test.70 : [<rnu>C *self I64 *self I32 Int1, <null>] = UnionAtIndex (Id 1) (Index 0) Test.118;
|
||||||
let Test.72 : I64 = UnionAtIndex (Id 1) (Index 1) Test.118;
|
let Test.72 : I64 = UnionAtIndex (Id 1) (Index 1) Test.118;
|
||||||
let Test.138 : [<rnu>C *self I64 *self I32 Int1, <null>] = UnionAtIndex (Id 1) (Index 2) Test.118;
|
let Test.138 : [<rnu>C *self I64 *self I32 Int1, <null>] = UnionAtIndex (Id 1) (Index 2) Test.118;
|
||||||
|
@ -325,28 +320,27 @@ procedure Test.3 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2):
|
||||||
inc Test.76;
|
inc Test.76;
|
||||||
let Test.74 : I32 = UnionAtIndex (Id 1) (Index 3) Test.138;
|
let Test.74 : I32 = UnionAtIndex (Id 1) (Index 3) Test.138;
|
||||||
let Test.71 : I32 = UnionAtIndex (Id 1) (Index 3) Test.118;
|
let Test.71 : I32 = UnionAtIndex (Id 1) (Index 3) Test.118;
|
||||||
joinpoint #Derived_gen.106 #Derived_gen.410 #Derived_gen.411 #Derived_gen.412:
|
joinpoint #Derived_gen.106 #Derived_gen.351 #Derived_gen.352 #Derived_gen.353:
|
||||||
let Test.130 : Int1 = false;
|
let Test.130 : Int1 = false;
|
||||||
let Test.127 : [<rnu>C *self I64 *self I32 Int1, <null>] = Reuse #Derived_gen.412 UpdateModeId { id: 271 } TagId(1) Test.70 Test.72 Test.73 Test.71 Test.130;
|
let Test.127 : [<rnu>C *self I64 *self I32 Int1, <null>] = Reuse #Derived_gen.353 UpdateModeId { id: 271 } TagId(1) Test.70 Test.72 Test.73 Test.71 Test.130;
|
||||||
let Test.129 : Int1 = false;
|
let Test.129 : Int1 = false;
|
||||||
let Test.128 : [<rnu>C *self I64 *self I32 Int1, <null>] = Reuse #Derived_gen.411 UpdateModeId { id: 270 } TagId(1) Test.76 Test.18 Test.19 Test.17 Test.129;
|
let Test.128 : [<rnu>C *self I64 *self I32 Int1, <null>] = Reuse #Derived_gen.352 UpdateModeId { id: 270 } TagId(1) Test.76 Test.18 Test.19 Test.17 Test.129;
|
||||||
let Test.126 : Int1 = true;
|
let Test.126 : Int1 = true;
|
||||||
let Test.125 : [<rnu>C *self I64 *self I32 Int1, <null>] = Reuse #Derived_gen.410 UpdateModeId { id: 269 } TagId(1) Test.127 Test.75 Test.128 Test.74 Test.126;
|
let Test.125 : [<rnu>C *self I64 *self I32 Int1, <null>] = Reuse #Derived_gen.351 UpdateModeId { id: 269 } TagId(1) Test.127 Test.75 Test.128 Test.74 Test.126;
|
||||||
let #Derived_gen.29 : {} = lowlevel PtrStore #Derived_gen.6 Test.125;
|
let #Derived_gen.29 : {} = lowlevel PtrStore #Derived_gen.6 Test.125;
|
||||||
let #Derived_gen.28 : [<rnu>C *self I64 *self I32 Int1, <null>] = lowlevel PtrLoad #Derived_gen.7;
|
let #Derived_gen.28 : [<rnu>C *self I64 *self I32 Int1, <null>] = lowlevel PtrLoad #Derived_gen.7;
|
||||||
ret #Derived_gen.28;
|
ret #Derived_gen.28;
|
||||||
in
|
in
|
||||||
let #Derived_gen.107 : Int1 = lowlevel RefCountIsUnique Test.118;
|
let #Derived_gen.107 : Int1 = lowlevel RefCountIsUnique Test.118;
|
||||||
if #Derived_gen.107 then
|
if #Derived_gen.107 then
|
||||||
decref #Derived_gen.405;
|
decref #Derived_gen.347;
|
||||||
let #Derived_gen.413 : [<rnu>C *self I64 *self I32 Int1, <null>] = Reset { symbol: Test.138, id: UpdateModeId { id: 272 } };
|
let #Derived_gen.354 : [<rnu>C *self I64 *self I32 Int1, <null>] = Reset { symbol: Test.138, id: UpdateModeId { id: 272 } };
|
||||||
let #Derived_gen.414 : [<rnu>C *self I64 *self I32 Int1, <null>] = ResetRef { symbol: Test.118, id: UpdateModeId { id: 273 } };
|
jump #Derived_gen.106 #Derived_gen.348 #Derived_gen.354 Test.118;
|
||||||
jump #Derived_gen.106 #Derived_gen.406 #Derived_gen.413 #Derived_gen.414;
|
|
||||||
else
|
else
|
||||||
inc Test.70;
|
inc Test.70;
|
||||||
decref Test.118;
|
decref Test.118;
|
||||||
let #Derived_gen.415 : [<rnu>C *self I64 *self I32 Int1, <null>] = NullPointer;
|
let #Derived_gen.355 : [<rnu>C *self I64 *self I32 Int1, <null>] = NullPointer;
|
||||||
jump #Derived_gen.106 #Derived_gen.415 #Derived_gen.405 #Derived_gen.406;
|
jump #Derived_gen.106 #Derived_gen.355 #Derived_gen.347 #Derived_gen.348;
|
||||||
in
|
in
|
||||||
let Test.142 : [<rnu>C *self I64 *self I32 Int1, <null>] = UnionAtIndex (Id 1) (Index 0) Test.118;
|
let Test.142 : [<rnu>C *self I64 *self I32 Int1, <null>] = UnionAtIndex (Id 1) (Index 0) Test.118;
|
||||||
let Test.143 : U8 = 1i64;
|
let Test.143 : U8 = 1i64;
|
||||||
|
@ -358,18 +352,18 @@ procedure Test.3 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2):
|
||||||
let Test.141 : Int1 = true;
|
let Test.141 : Int1 = true;
|
||||||
let Test.146 : Int1 = lowlevel Eq Test.141 Test.140;
|
let Test.146 : Int1 = lowlevel Eq Test.141 Test.140;
|
||||||
if Test.146 then
|
if Test.146 then
|
||||||
jump Test.137 #Derived_gen.119 #Derived_gen.334;
|
jump Test.137 #Derived_gen.118 #Derived_gen.289;
|
||||||
else
|
else
|
||||||
jump Test.145 #Derived_gen.119 #Derived_gen.334;
|
jump Test.145 #Derived_gen.118 #Derived_gen.289;
|
||||||
else
|
else
|
||||||
jump Test.145 #Derived_gen.119 #Derived_gen.334;
|
jump Test.145 #Derived_gen.118 #Derived_gen.289;
|
||||||
else
|
else
|
||||||
jump Test.163 #Derived_gen.119 #Derived_gen.334;
|
jump Test.163 #Derived_gen.118 #Derived_gen.289;
|
||||||
else
|
else
|
||||||
jump Test.163 #Derived_gen.119 #Derived_gen.334;
|
jump Test.163 #Derived_gen.118 #Derived_gen.289;
|
||||||
else
|
else
|
||||||
decref #Derived_gen.334;
|
decref #Derived_gen.289;
|
||||||
decref #Derived_gen.119;
|
decref #Derived_gen.118;
|
||||||
joinpoint #Derived_gen.108:
|
joinpoint #Derived_gen.108:
|
||||||
let Test.135 : [<rnu>C *self I64 *self I32 Int1, <null>] = TagId(0) ;
|
let Test.135 : [<rnu>C *self I64 *self I32 Int1, <null>] = TagId(0) ;
|
||||||
let #Derived_gen.31 : {} = lowlevel PtrStore #Derived_gen.6 Test.135;
|
let #Derived_gen.31 : {} = lowlevel PtrStore #Derived_gen.6 Test.135;
|
||||||
|
@ -382,43 +376,42 @@ procedure Test.3 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2):
|
||||||
dec #Derived_gen.110;
|
dec #Derived_gen.110;
|
||||||
let #Derived_gen.109 : [<rnu>C *self I64 *self I32 Int1, <null>] = UnionAtIndex (Id 1) (Index 2) Test.19;
|
let #Derived_gen.109 : [<rnu>C *self I64 *self I32 Int1, <null>] = UnionAtIndex (Id 1) (Index 2) Test.19;
|
||||||
dec #Derived_gen.109;
|
dec #Derived_gen.109;
|
||||||
decref Test.19;
|
free Test.19;
|
||||||
jump #Derived_gen.108;
|
jump #Derived_gen.108;
|
||||||
else
|
else
|
||||||
decref Test.19;
|
decref Test.19;
|
||||||
jump #Derived_gen.108;
|
jump #Derived_gen.108;
|
||||||
else
|
else
|
||||||
jump Test.176 #Derived_gen.119;
|
jump Test.176 #Derived_gen.118;
|
||||||
else
|
else
|
||||||
jump Test.176 #Derived_gen.119;
|
jump Test.176 #Derived_gen.118;
|
||||||
else
|
else
|
||||||
let Test.116 : Int1 = false;
|
let Test.116 : Int1 = false;
|
||||||
let Test.115 : [<rnu>C *self I64 *self I32 Int1, <null>] = Reuse #Derived_gen.119 UpdateModeId { id: 1 } TagId(1) Test.16 Test.11 Test.19 Test.10 Test.116;
|
let Test.115 : [<rnu>C *self I64 *self I32 Int1, <null>] = Reuse #Derived_gen.118 UpdateModeId { id: 1 } TagId(1) Test.16 Test.11 Test.19 Test.10 Test.116;
|
||||||
let #Derived_gen.33 : {} = lowlevel PtrStore #Derived_gen.6 Test.115;
|
let #Derived_gen.33 : {} = lowlevel PtrStore #Derived_gen.6 Test.115;
|
||||||
let #Derived_gen.32 : [<rnu>C *self I64 *self I32 Int1, <null>] = lowlevel PtrLoad #Derived_gen.7;
|
let #Derived_gen.32 : [<rnu>C *self I64 *self I32 Int1, <null>] = lowlevel PtrLoad #Derived_gen.7;
|
||||||
ret #Derived_gen.32;
|
ret #Derived_gen.32;
|
||||||
in
|
in
|
||||||
let #Derived_gen.115 : Int1 = lowlevel RefCountIsUnique Test.9;
|
let #Derived_gen.115 : Int1 = lowlevel RefCountIsUnique Test.9;
|
||||||
if #Derived_gen.115 then
|
if #Derived_gen.115 then
|
||||||
let #Derived_gen.424 : [<rnu>C *self I64 *self I32 Int1, <null>] = ResetRef { symbol: Test.9, id: UpdateModeId { id: 282 } };
|
jump #Derived_gen.114 Test.9;
|
||||||
jump #Derived_gen.114 #Derived_gen.424;
|
|
||||||
else
|
else
|
||||||
inc Test.16;
|
inc Test.16;
|
||||||
inc Test.19;
|
inc Test.19;
|
||||||
decref Test.9;
|
decref Test.9;
|
||||||
let #Derived_gen.425 : [<rnu>C *self I64 *self I32 Int1, <null>] = NullPointer;
|
let #Derived_gen.363 : [<rnu>C *self I64 *self I32 Int1, <null>] = NullPointer;
|
||||||
jump #Derived_gen.114 #Derived_gen.425;
|
jump #Derived_gen.114 #Derived_gen.363;
|
||||||
else
|
else
|
||||||
let Test.96 : [<rnu>C *self I64 *self I32 Int1, <null>] = UnionAtIndex (Id 1) (Index 0) Test.9;
|
let Test.96 : [<rnu>C *self I64 *self I32 Int1, <null>] = UnionAtIndex (Id 1) (Index 0) Test.9;
|
||||||
let Test.98 : I64 = UnionAtIndex (Id 1) (Index 1) Test.9;
|
let Test.98 : I64 = UnionAtIndex (Id 1) (Index 1) Test.9;
|
||||||
let Test.99 : [<rnu>C *self I64 *self I32 Int1, <null>] = UnionAtIndex (Id 1) (Index 2) Test.9;
|
let Test.99 : [<rnu>C *self I64 *self I32 Int1, <null>] = UnionAtIndex (Id 1) (Index 2) Test.9;
|
||||||
let Test.97 : I32 = UnionAtIndex (Id 1) (Index 3) Test.9;
|
let Test.97 : I32 = UnionAtIndex (Id 1) (Index 3) Test.9;
|
||||||
joinpoint #Derived_gen.116 #Derived_gen.427:
|
joinpoint #Derived_gen.116 #Derived_gen.364:
|
||||||
let Test.247 : Int1 = CallByName Num.22 Test.10 Test.97;
|
let Test.247 : Int1 = CallByName Num.22 Test.10 Test.97;
|
||||||
if Test.247 then
|
if Test.247 then
|
||||||
let Test.249 : Int1 = true;
|
let Test.249 : Int1 = true;
|
||||||
let #Derived_gen.34 : [<rnu>C *self I64 *self I32 Int1, <null>] = NullPointer;
|
let #Derived_gen.34 : [<rnu>C *self I64 *self I32 Int1, <null>] = NullPointer;
|
||||||
let Test.248 : [<rnu>C *self I64 *self I32 Int1, <null>] = Reuse #Derived_gen.427 UpdateModeId { id: 284 } TagId(1) #Derived_gen.34 Test.98 Test.99 Test.97 Test.249;
|
let Test.248 : [<rnu>C *self I64 *self I32 Int1, <null>] = Reuse #Derived_gen.364 UpdateModeId { id: 284 } TagId(1) #Derived_gen.34 Test.98 Test.99 Test.97 Test.249;
|
||||||
let #Derived_gen.35 : Ptr([<rnu>C *self I64 *self I32 Int1, <null>]) = UnionFieldPtrAtIndex (Id 1) (Index 0) Test.248;
|
let #Derived_gen.35 : Ptr([<rnu>C *self I64 *self I32 Int1, <null>]) = UnionFieldPtrAtIndex (Id 1) (Index 0) Test.248;
|
||||||
let #Derived_gen.36 : {} = lowlevel PtrStore #Derived_gen.6 Test.248;
|
let #Derived_gen.36 : {} = lowlevel PtrStore #Derived_gen.6 Test.248;
|
||||||
jump #Derived_gen.5 Test.96 Test.10 Test.11 #Derived_gen.35 #Derived_gen.7;
|
jump #Derived_gen.5 Test.96 Test.10 Test.11 #Derived_gen.35 #Derived_gen.7;
|
||||||
|
@ -427,27 +420,26 @@ procedure Test.3 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2):
|
||||||
if Test.243 then
|
if Test.243 then
|
||||||
let Test.245 : Int1 = true;
|
let Test.245 : Int1 = true;
|
||||||
let #Derived_gen.37 : [<rnu>C *self I64 *self I32 Int1, <null>] = NullPointer;
|
let #Derived_gen.37 : [<rnu>C *self I64 *self I32 Int1, <null>] = NullPointer;
|
||||||
let Test.244 : [<rnu>C *self I64 *self I32 Int1, <null>] = Reuse #Derived_gen.427 UpdateModeId { id: 284 } TagId(1) Test.96 Test.98 #Derived_gen.37 Test.97 Test.245;
|
let Test.244 : [<rnu>C *self I64 *self I32 Int1, <null>] = Reuse #Derived_gen.364 UpdateModeId { id: 284 } TagId(1) Test.96 Test.98 #Derived_gen.37 Test.97 Test.245;
|
||||||
let #Derived_gen.38 : Ptr([<rnu>C *self I64 *self I32 Int1, <null>]) = UnionFieldPtrAtIndex (Id 1) (Index 2) Test.244;
|
let #Derived_gen.38 : Ptr([<rnu>C *self I64 *self I32 Int1, <null>]) = UnionFieldPtrAtIndex (Id 1) (Index 2) Test.244;
|
||||||
let #Derived_gen.39 : {} = lowlevel PtrStore #Derived_gen.6 Test.244;
|
let #Derived_gen.39 : {} = lowlevel PtrStore #Derived_gen.6 Test.244;
|
||||||
jump #Derived_gen.5 Test.99 Test.10 Test.11 #Derived_gen.38 #Derived_gen.7;
|
jump #Derived_gen.5 Test.99 Test.10 Test.11 #Derived_gen.38 #Derived_gen.7;
|
||||||
else
|
else
|
||||||
let Test.242 : Int1 = true;
|
let Test.242 : Int1 = true;
|
||||||
let Test.241 : [<rnu>C *self I64 *self I32 Int1, <null>] = Reuse #Derived_gen.427 UpdateModeId { id: 284 } TagId(1) Test.96 Test.11 Test.99 Test.10 Test.242;
|
let Test.241 : [<rnu>C *self I64 *self I32 Int1, <null>] = Reuse #Derived_gen.364 UpdateModeId { id: 284 } TagId(1) Test.96 Test.11 Test.99 Test.10 Test.242;
|
||||||
let #Derived_gen.41 : {} = lowlevel PtrStore #Derived_gen.6 Test.241;
|
let #Derived_gen.41 : {} = lowlevel PtrStore #Derived_gen.6 Test.241;
|
||||||
let #Derived_gen.40 : [<rnu>C *self I64 *self I32 Int1, <null>] = lowlevel PtrLoad #Derived_gen.7;
|
let #Derived_gen.40 : [<rnu>C *self I64 *self I32 Int1, <null>] = lowlevel PtrLoad #Derived_gen.7;
|
||||||
ret #Derived_gen.40;
|
ret #Derived_gen.40;
|
||||||
in
|
in
|
||||||
let #Derived_gen.117 : Int1 = lowlevel RefCountIsUnique Test.9;
|
let #Derived_gen.117 : Int1 = lowlevel RefCountIsUnique Test.9;
|
||||||
if #Derived_gen.117 then
|
if #Derived_gen.117 then
|
||||||
let #Derived_gen.428 : [<rnu>C *self I64 *self I32 Int1, <null>] = ResetRef { symbol: Test.9, id: UpdateModeId { id: 285 } };
|
jump #Derived_gen.116 Test.9;
|
||||||
jump #Derived_gen.116 #Derived_gen.428;
|
|
||||||
else
|
else
|
||||||
inc Test.96;
|
inc Test.96;
|
||||||
inc Test.99;
|
inc Test.99;
|
||||||
decref Test.9;
|
decref Test.9;
|
||||||
let #Derived_gen.429 : [<rnu>C *self I64 *self I32 Int1, <null>] = NullPointer;
|
let #Derived_gen.365 : [<rnu>C *self I64 *self I32 Int1, <null>] = NullPointer;
|
||||||
jump #Derived_gen.116 #Derived_gen.429;
|
jump #Derived_gen.116 #Derived_gen.365;
|
||||||
in
|
in
|
||||||
jump #Derived_gen.5 #Derived_gen.0 #Derived_gen.1 #Derived_gen.2 #Derived_gen.3 #Derived_gen.3;
|
jump #Derived_gen.5 #Derived_gen.0 #Derived_gen.1 #Derived_gen.2 #Derived_gen.3 #Derived_gen.3;
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ procedure Test.6 (Test.16, #Attr.12):
|
||||||
in
|
in
|
||||||
let #Derived_gen.3 : Int1 = lowlevel RefCountIsUnique #Attr.12;
|
let #Derived_gen.3 : Int1 = lowlevel RefCountIsUnique #Attr.12;
|
||||||
if #Derived_gen.3 then
|
if #Derived_gen.3 then
|
||||||
decref #Attr.12;
|
free #Attr.12;
|
||||||
jump #Derived_gen.2;
|
jump #Derived_gen.2;
|
||||||
else
|
else
|
||||||
decref #Attr.12;
|
decref #Attr.12;
|
||||||
|
|
|
@ -54,7 +54,7 @@ procedure Test.4 (#Derived_gen.2, #Derived_gen.3):
|
||||||
in
|
in
|
||||||
let #Derived_gen.5 : Int1 = lowlevel RefCountIsUnique #Attr.12;
|
let #Derived_gen.5 : Int1 = lowlevel RefCountIsUnique #Attr.12;
|
||||||
if #Derived_gen.5 then
|
if #Derived_gen.5 then
|
||||||
decref #Attr.12;
|
free #Attr.12;
|
||||||
jump #Derived_gen.4;
|
jump #Derived_gen.4;
|
||||||
else
|
else
|
||||||
inc Test.3;
|
inc Test.3;
|
||||||
|
|
|
@ -10,7 +10,7 @@ procedure Test.11 (Test.29, #Attr.12):
|
||||||
let Test.10 : {} = UnionAtIndex (Id 0) (Index 0) #Attr.12;
|
let Test.10 : {} = UnionAtIndex (Id 0) (Index 0) #Attr.12;
|
||||||
let #Derived_gen.9 : Int1 = lowlevel RefCountIsUnique #Attr.12;
|
let #Derived_gen.9 : Int1 = lowlevel RefCountIsUnique #Attr.12;
|
||||||
if #Derived_gen.9 then
|
if #Derived_gen.9 then
|
||||||
decref #Attr.12;
|
free #Attr.12;
|
||||||
ret Test.10;
|
ret Test.10;
|
||||||
else
|
else
|
||||||
decref #Attr.12;
|
decref #Attr.12;
|
||||||
|
@ -40,7 +40,7 @@ procedure Test.14 (#Derived_gen.2, #Derived_gen.3):
|
||||||
in
|
in
|
||||||
let #Derived_gen.11 : Int1 = lowlevel RefCountIsUnique #Attr.12;
|
let #Derived_gen.11 : Int1 = lowlevel RefCountIsUnique #Attr.12;
|
||||||
if #Derived_gen.11 then
|
if #Derived_gen.11 then
|
||||||
decref #Attr.12;
|
free #Attr.12;
|
||||||
jump #Derived_gen.10;
|
jump #Derived_gen.10;
|
||||||
else
|
else
|
||||||
decref #Attr.12;
|
decref #Attr.12;
|
||||||
|
|
|
@ -39,7 +39,7 @@ procedure Test.2 (Test.9, Test.10):
|
||||||
let #Derived_gen.5 : Int1 = lowlevel RefCountIsUnique Test.9;
|
let #Derived_gen.5 : Int1 = lowlevel RefCountIsUnique Test.9;
|
||||||
if #Derived_gen.5 then
|
if #Derived_gen.5 then
|
||||||
dec Test.11;
|
dec Test.11;
|
||||||
decref Test.9;
|
free Test.9;
|
||||||
jump #Derived_gen.4;
|
jump #Derived_gen.4;
|
||||||
else
|
else
|
||||||
inc Test.12;
|
inc Test.12;
|
||||||
|
@ -65,7 +65,7 @@ procedure Test.3 (Test.17):
|
||||||
if #Derived_gen.3 then
|
if #Derived_gen.3 then
|
||||||
let #Derived_gen.2 : Str = UnionAtIndex (Id 0) (Index 0) Test.17;
|
let #Derived_gen.2 : Str = UnionAtIndex (Id 0) (Index 0) Test.17;
|
||||||
dec #Derived_gen.2;
|
dec #Derived_gen.2;
|
||||||
decref Test.17;
|
free Test.17;
|
||||||
jump #Derived_gen.1;
|
jump #Derived_gen.1;
|
||||||
else
|
else
|
||||||
inc Test.18;
|
inc Test.18;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue