diff --git a/crates/compiler/builtins/bitcode/src/utils.zig b/crates/compiler/builtins/bitcode/src/utils.zig index 79ae4200fa..27cf111f16 100644 --- a/crates/compiler/builtins/bitcode/src/utils.zig +++ b/crates/compiler/builtins/bitcode/src/utils.zig @@ -231,9 +231,9 @@ inline fn decref_ptr_to_refcount( } } -pub export fn isUnique( +pub fn isUnique( bytes_or_null: ?[*]u8, -) bool { +) callconv(.C) bool { var bytes = bytes_or_null orelse return true; const ptr = @ptrToInt(bytes); diff --git a/crates/compiler/gen_llvm/src/llvm/lowlevel.rs b/crates/compiler/gen_llvm/src/llvm/lowlevel.rs index d57253de2a..9883cce585 100644 --- a/crates/compiler/gen_llvm/src/llvm/lowlevel.rs +++ b/crates/compiler/gen_llvm/src/llvm/lowlevel.rs @@ -1252,8 +1252,15 @@ pub(crate) fn run_low_level<'a, 'ctx, 'env>( } RefCountIsUnique => { - arguments!(input); - call_bitcode_fn(env, &[input], &bitcode::UTILS_IS_UNIQUE) + arguments!(data_ptr); + + let ptr = env.builder.build_pointer_cast( + data_ptr.into_pointer_value(), + env.context.i8_type().ptr_type(AddressSpace::default()), + "cast_to_i8_ptr", + ); + + call_bitcode_fn(env, &[ptr.into()], &bitcode::UTILS_IS_UNIQUE) } Unreachable => match RocReturn::from_layout(env, layout_interner, layout) { diff --git a/crates/compiler/mono/src/code_gen_help/refcount.rs b/crates/compiler/mono/src/code_gen_help/refcount.rs index 1bac15153e..4d35b879c0 100644 --- a/crates/compiler/mono/src/code_gen_help/refcount.rs +++ b/crates/compiler/mono/src/code_gen_help/refcount.rs @@ -194,11 +194,8 @@ pub fn refcount_reset_proc_body<'a>( layout: InLayout<'a>, structure: Symbol, ) -> Stmt<'a> { - let rc_ptr = root.create_symbol(ident_ids, "rc_ptr"); - let rc = root.create_symbol(ident_ids, "rc"); - let refcount_1 = root.create_symbol(ident_ids, "refcount_1"); - let is_unique = root.create_symbol(ident_ids, "is_unique"); let addr = root.create_symbol(ident_ids, "addr"); + let is_unique = root.create_symbol(ident_ids, "is_unique"); let union_layout = match layout_interner.get(layout) { Layout::Union(u) => u, @@ -208,7 +205,6 @@ pub fn refcount_reset_proc_body<'a>( // Whenever we recurse into a child layout we will want to Decrement ctx.op = HelperOp::Dec; ctx.recursive_union = Some(union_layout); - let recursion_ptr = layout_interner.insert(Layout::RecursivePointer(layout)); // Reset structure is unique. Decrement its children and return a pointer to the allocation. let then_stmt = { @@ -313,69 +309,26 @@ pub fn refcount_reset_proc_body<'a>( )) }; - let if_stmt = Stmt::Switch { + let if_stmt = root.arena.alloc(Stmt::Switch { cond_symbol: is_unique, cond_layout: LAYOUT_BOOL, branches: root.arena.alloc([(1, BranchInfo::None, then_stmt)]), default_branch: (BranchInfo::None, root.arena.alloc(else_stmt)), ret_layout: layout, - }; + }); - // Uniqueness test - let is_unique_stmt = { - let_lowlevel( - root.arena, - LAYOUT_BOOL, - is_unique, - Eq, - &[rc, refcount_1], - root.arena.alloc(if_stmt), - ) - }; - - // Constant for unique refcount - let refcount_1_encoded = match root.target_info.ptr_width() { - PtrWidth::Bytes4 => i32::MIN as i128, - PtrWidth::Bytes8 => i64::MIN as i128, - } - .to_ne_bytes(); - let refcount_1_expr = Expr::Literal(Literal::Int(refcount_1_encoded)); - let refcount_1_stmt = Stmt::Let( - refcount_1, - refcount_1_expr, - root.layout_isize, - root.arena.alloc(is_unique_stmt), - ); - - // Refcount value - let rc_expr = Expr::UnionAtIndex { - structure: rc_ptr, - tag_id: 0, - union_layout: root.union_refcount, - index: 0, - }; - let rc_stmt = Stmt::Let( - rc, - rc_expr, - root.layout_isize, - root.arena.alloc(refcount_1_stmt), - ); - - // Refcount pointer - let rc_ptr_stmt = { - rc_ptr_from_data_ptr_help( - root, - ident_ids, - structure, - rc_ptr, - union_layout.stores_tag_id_in_pointer(root.target_info), - root.arena.alloc(rc_stmt), - addr, - recursion_ptr, - ) - }; - - rc_ptr_stmt + Stmt::Let( + is_unique, + Expr::Call(Call { + call_type: CallType::LowLevel { + op: LowLevel::RefCountIsUnique, + update_mode: UpdateModeId::BACKEND_DUMMY, + }, + arguments: root.arena.alloc([structure]), + }), + Layout::BOOL, + if_stmt, + ) } pub fn refcount_resetref_proc_body<'a>( diff --git a/crates/compiler/mono/src/drop_specialization.rs b/crates/compiler/mono/src/drop_specialization.rs index 00e7d0e368..f5e76f457c 100644 --- a/crates/compiler/mono/src/drop_specialization.rs +++ b/crates/compiler/mono/src/drop_specialization.rs @@ -326,9 +326,7 @@ fn specialize_drops_stmt<'a, 'i>( symbol, continuation, ), - Layout::LambdaSet(_) => { - unreachable!("lambda sets should not be a runtime layout") - } + // TODO: lambda sets should not be reachable, yet they are. // TODO: Implement this with uniqueness checks. _ => { let new_continuation = specialize_drops_stmt( @@ -905,8 +903,8 @@ where let join = arena.alloc(Stmt::Join { id: join_id, parameters: arena.alloc([]), - body: switch, - remainder: continutation, + body: continutation, + remainder: switch, }); join