undo mono unique

This commit is contained in:
J.Teeuwissen 2023-04-26 20:17:19 +02:00
parent 4de6369e6a
commit 804e617497
No known key found for this signature in database
GPG key ID: DB5F7A1ED8D478AD

View file

@ -194,22 +194,24 @@ pub fn refcount_reset_proc_body<'a>(
layout: InLayout<'a>,
structure: Symbol,
) -> Stmt<'a> {
let addr = root.create_symbol(ident_ids, "addr");
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 union_layout = match layout_interner.get(layout) {
Layout::Union(u) => u,
_ => unimplemented!("Reset is only implemented for UnionLayout"),
};
// 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 = {
use UnionLayout::*;
let tag_layouts;
let mut null_id = None;
match union_layout {
@ -237,9 +239,7 @@ pub fn refcount_reset_proc_body<'a>(
tag_layouts = root.arena.alloc([other_fields]);
}
};
let tag_id_layout = union_layout.tag_id_layout();
let tag_id_sym = root.create_symbol(ident_ids, "tag_id");
let tag_id_stmt = |next| {
Stmt::Let(
@ -252,7 +252,6 @@ pub fn refcount_reset_proc_body<'a>(
next,
)
};
let rc_contents_stmt = refcount_union_contents(
root,
ident_ids,
@ -266,13 +265,11 @@ pub fn refcount_reset_proc_body<'a>(
tag_id_layout,
Stmt::Ret(addr),
);
tag_id_stmt(root.arena.alloc(
//
rc_contents_stmt,
))
};
// Reset structure is not unique. Decrement it and return a NULL pointer.
let else_stmt = {
let decrement_unit = root.create_symbol(ident_ids, "decrement_unit");
@ -286,17 +283,14 @@ pub fn refcount_reset_proc_body<'a>(
)
.unwrap();
let decrement_stmt = |next| Stmt::Let(decrement_unit, decrement_expr, LAYOUT_UNIT, next);
// Zero
let zero = root.create_symbol(ident_ids, "zero");
let zero_expr = Expr::Literal(Literal::Int(0i128.to_ne_bytes()));
let zero_stmt = |next| Stmt::Let(zero, zero_expr, root.layout_isize, next);
// Null pointer with union layout
let null = root.create_symbol(ident_ids, "null");
let null_stmt =
|next| let_lowlevel(root.arena, root.layout_isize, null, PtrCast, &[zero], next);
decrement_stmt(root.arena.alloc(
//
zero_stmt(root.arena.alloc(
@ -309,26 +303,69 @@ pub fn refcount_reset_proc_body<'a>(
))
};
let if_stmt = root.arena.alloc(Stmt::Switch {
let if_stmt = 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,
});
};
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,
)
// 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
}
pub fn refcount_resetref_proc_body<'a>(