Eliminate uses of RECURSIVE_PTR directly

This commit is contained in:
Ayaz Hafiz 2023-01-23 16:04:55 -06:00
parent 37d9307fbf
commit 8edbd3b378
No known key found for this signature in database
GPG key ID: 0E2A37416A25EF58
3 changed files with 53 additions and 30 deletions

View file

@ -20,10 +20,6 @@ const LAYOUT_BOOL: InLayout = Layout::BOOL;
const LAYOUT_UNIT: InLayout = Layout::UNIT;
const LAYOUT_U32: InLayout = Layout::U32;
// TODO: Replace usages with root.union_refcount
// TODO(recursive-layouts): update once we have disjoint recursive pointers
const LAYOUT_PTR: InLayout = Layout::RECURSIVE_PTR;
pub fn refcount_stmt<'a>(
root: &mut CodeGenHelp<'a>,
ident_ids: &mut IdentIds,
@ -162,6 +158,7 @@ pub fn refcount_generic<'a>(
ident_ids,
ctx,
layout_interner,
layout,
union_layout,
structure,
),
@ -213,6 +210,7 @@ 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 = {
@ -411,6 +409,7 @@ pub fn refcount_reset_proc_body<'a>(
union_layout.stores_tag_id_in_pointer(root.target_info),
root.arena.alloc(rc_stmt),
addr,
recursion_ptr,
)
};
@ -489,6 +488,7 @@ pub fn rc_ptr_from_data_ptr<'a>(
rc_ptr_sym: Symbol,
mask_lower_bits: bool,
following: &'a Stmt<'a>,
recursive_layout: InLayout<'a>,
) -> Stmt<'a> {
let addr_sym = root.create_symbol(ident_ids, "addr");
rc_ptr_from_data_ptr_help(
@ -499,6 +499,7 @@ pub fn rc_ptr_from_data_ptr<'a>(
mask_lower_bits,
following,
addr_sym,
recursive_layout,
)
}
@ -510,6 +511,7 @@ pub fn rc_ptr_from_data_ptr_help<'a>(
mask_lower_bits: bool,
following: &'a Stmt<'a>,
addr_sym: Symbol,
recursion_ptr: InLayout<'a>,
) -> Stmt<'a> {
use std::ops::Neg;
@ -571,7 +573,7 @@ pub fn rc_ptr_from_data_ptr_help<'a>(
},
arguments: root.arena.alloc([rc_addr_sym]),
});
let cast_stmt = |next| Stmt::Let(rc_ptr_sym, cast_expr, LAYOUT_PTR, next);
let cast_stmt = |next| Stmt::Let(rc_ptr_sym, cast_expr, recursion_ptr, next);
if mask_lower_bits {
as_int_stmt(root.arena.alloc(
@ -664,7 +666,9 @@ fn refcount_str<'a>(
) -> Stmt<'a> {
let string = Symbol::ARG_1;
let layout_isize = root.layout_isize;
let field_layouts = root.arena.alloc([LAYOUT_PTR, layout_isize, layout_isize]);
let field_layouts = root
.arena
.alloc([Layout::OPAQUE_PTR, layout_isize, layout_isize]);
// Get the last word as a signed int
let last_word = root.create_symbol(ident_ids, "last_word");
@ -728,6 +732,7 @@ fn refcount_str<'a>(
//
mod_rc_stmt,
),
Layout::OPAQUE_PTR,
),
));
@ -828,6 +833,7 @@ fn refcount_list<'a>(
rc_ptr,
false,
arena.alloc(modify_list),
Layout::OPAQUE_PTR,
);
let modify_elems_and_list =
@ -1093,6 +1099,7 @@ fn refcount_union<'a>(
ident_ids: &mut IdentIds,
ctx: &mut Context<'a>,
layout_interner: &mut STLayoutInterner<'a>,
layout: InLayout<'a>,
union: UnionLayout<'a>,
structure: Symbol,
) -> Stmt<'a> {
@ -1129,6 +1136,7 @@ fn refcount_union<'a>(
structure,
)
} else {
let recursive_ptr = layout_interner.insert(Layout::RecursivePointer(layout));
refcount_union_rec(
root,
ident_ids,
@ -1137,6 +1145,7 @@ fn refcount_union<'a>(
union,
tags,
None,
recursive_ptr,
structure,
)
}
@ -1148,6 +1157,7 @@ fn refcount_union<'a>(
// a direct RecursionPointer is only possible if there's at least one non-recursive variant.
// This nesting makes it harder to do tail recursion, so we just don't.
let tags = root.arena.alloc([field_layouts]);
let recursive_ptr = layout_interner.insert(Layout::RecursivePointer(layout));
refcount_union_rec(
root,
ident_ids,
@ -1156,6 +1166,7 @@ fn refcount_union<'a>(
union,
tags,
None,
recursive_ptr,
structure,
)
}
@ -1179,6 +1190,7 @@ fn refcount_union<'a>(
structure,
)
} else {
let recursive_ptr = layout_interner.insert(Layout::RecursivePointer(layout));
refcount_union_rec(
root,
ident_ids,
@ -1187,6 +1199,7 @@ fn refcount_union<'a>(
union,
tags,
null_id,
recursive_ptr,
structure,
)
}
@ -1212,6 +1225,7 @@ fn refcount_union<'a>(
structure,
)
} else {
let recursive_ptr = layout_interner.insert(Layout::RecursivePointer(layout));
refcount_union_rec(
root,
ident_ids,
@ -1220,6 +1234,7 @@ fn refcount_union<'a>(
union,
tags,
null_id,
recursive_ptr,
structure,
)
}
@ -1354,6 +1369,7 @@ fn refcount_union_rec<'a>(
union_layout: UnionLayout<'a>,
tag_layouts: &'a [&'a [InLayout<'a>]],
null_id: Option<TagIdIntType>,
recursion_ptr: InLayout<'a>,
structure: Symbol,
) -> Stmt<'a> {
let tag_id_layout = union_layout.tag_id_layout();
@ -1393,6 +1409,7 @@ fn refcount_union_rec<'a>(
rc_ptr,
union_layout.stores_tag_id_in_pointer(root.target_info),
root.arena.alloc(modify_structure_stmt),
recursion_ptr,
)
};
@ -1440,6 +1457,7 @@ fn refcount_union_tailrec<'a>(
let current = root.create_symbol(ident_ids, "current");
let next_ptr = root.create_symbol(ident_ids, "next_ptr");
let layout = layout_interner.insert(Layout::Union(union_layout));
let recursion_ptr = layout_interner.insert(Layout::RecursivePointer(layout));
let tag_id_layout = union_layout.tag_id_layout();
@ -1501,6 +1519,7 @@ fn refcount_union_tailrec<'a>(
rc_ptr,
union_layout.stores_tag_id_in_pointer(root.target_info),
root.arena.alloc(modify_structure_stmt),
recursion_ptr,
)
};
@ -1710,6 +1729,7 @@ fn refcount_boxed<'a>(
rc_ptr,
false,
arena.alloc(modify_outer),
Layout::OPAQUE_PTR,
);
if layout_interner.is_refcounted(inner_layout) && !ctx.op.is_decref() {