Updated refcount logic

This commit is contained in:
J.Teeuwissen 2023-04-26 17:39:46 +02:00
parent 0fe94cbd90
commit 74f2b0afda
No known key found for this signature in database
GPG key ID: DB5F7A1ED8D478AD
4 changed files with 29 additions and 71 deletions

View file

@ -231,9 +231,9 @@ inline fn decref_ptr_to_refcount(
} }
} }
pub export fn isUnique( pub fn isUnique(
bytes_or_null: ?[*]u8, bytes_or_null: ?[*]u8,
) bool { ) callconv(.C) bool {
var bytes = bytes_or_null orelse return true; var bytes = bytes_or_null orelse return true;
const ptr = @ptrToInt(bytes); const ptr = @ptrToInt(bytes);

View file

@ -1252,8 +1252,15 @@ pub(crate) fn run_low_level<'a, 'ctx, 'env>(
} }
RefCountIsUnique => { RefCountIsUnique => {
arguments!(input); arguments!(data_ptr);
call_bitcode_fn(env, &[input], &bitcode::UTILS_IS_UNIQUE)
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) { Unreachable => match RocReturn::from_layout(env, layout_interner, layout) {

View file

@ -194,11 +194,8 @@ pub fn refcount_reset_proc_body<'a>(
layout: InLayout<'a>, layout: InLayout<'a>,
structure: Symbol, structure: Symbol,
) -> Stmt<'a> { ) -> 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 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) { let union_layout = match layout_interner.get(layout) {
Layout::Union(u) => u, 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 // Whenever we recurse into a child layout we will want to Decrement
ctx.op = HelperOp::Dec; ctx.op = HelperOp::Dec;
ctx.recursive_union = Some(union_layout); 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. // Reset structure is unique. Decrement its children and return a pointer to the allocation.
let then_stmt = { 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_symbol: is_unique,
cond_layout: LAYOUT_BOOL, cond_layout: LAYOUT_BOOL,
branches: root.arena.alloc([(1, BranchInfo::None, then_stmt)]), branches: root.arena.alloc([(1, BranchInfo::None, then_stmt)]),
default_branch: (BranchInfo::None, root.arena.alloc(else_stmt)), default_branch: (BranchInfo::None, root.arena.alloc(else_stmt)),
ret_layout: layout, ret_layout: layout,
}; });
// Uniqueness test Stmt::Let(
let is_unique_stmt = { is_unique,
let_lowlevel( Expr::Call(Call {
root.arena, call_type: CallType::LowLevel {
LAYOUT_BOOL, op: LowLevel::RefCountIsUnique,
is_unique, update_mode: UpdateModeId::BACKEND_DUMMY,
Eq, },
&[rc, refcount_1], arguments: root.arena.alloc([structure]),
root.arena.alloc(if_stmt), }),
) Layout::BOOL,
}; 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
} }
pub fn refcount_resetref_proc_body<'a>( pub fn refcount_resetref_proc_body<'a>(

View file

@ -326,9 +326,7 @@ fn specialize_drops_stmt<'a, 'i>(
symbol, symbol,
continuation, continuation,
), ),
Layout::LambdaSet(_) => { // TODO: lambda sets should not be reachable, yet they are.
unreachable!("lambda sets should not be a runtime layout")
}
// TODO: Implement this with uniqueness checks. // TODO: Implement this with uniqueness checks.
_ => { _ => {
let new_continuation = specialize_drops_stmt( let new_continuation = specialize_drops_stmt(
@ -905,8 +903,8 @@ where
let join = arena.alloc(Stmt::Join { let join = arena.alloc(Stmt::Join {
id: join_id, id: join_id,
parameters: arena.alloc([]), parameters: arena.alloc([]),
body: switch, body: continutation,
remainder: continutation, remainder: switch,
}); });
join join