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() {

View file

@ -15,11 +15,11 @@ use roc_target::TargetInfo;
use super::{Builtin, FieldOrderHash, LambdaSet, Layout, UnionLayout};
macro_rules! cache_interned_layouts {
($($i:literal, $name:ident, $layout:expr)*; $total_constants:literal) => {
($($i:literal, $name:ident, $vis:vis, $layout:expr)*; $total_constants:literal) => {
impl<'a> Layout<'a> {
$(
#[allow(unused)] // for now
pub const $name: InLayout<'static> = unsafe { InLayout::from_index($i) };
$vis const $name: InLayout<'static> = unsafe { InLayout::from_index($i) };
)*
}
@ -46,26 +46,27 @@ macro_rules! cache_interned_layouts {
}
cache_interned_layouts! {
0, VOID, Layout::VOID_NAKED
1, UNIT, Layout::UNIT_NAKED
2, BOOL, Layout::Builtin(Builtin::Bool)
3, U8, Layout::Builtin(Builtin::Int(IntWidth::U8))
4, U16, Layout::Builtin(Builtin::Int(IntWidth::U16))
5, U32, Layout::Builtin(Builtin::Int(IntWidth::U32))
6, U64, Layout::Builtin(Builtin::Int(IntWidth::U64))
7, U128, Layout::Builtin(Builtin::Int(IntWidth::U128))
8, I8, Layout::Builtin(Builtin::Int(IntWidth::I8))
9, I16, Layout::Builtin(Builtin::Int(IntWidth::I16))
10, I32, Layout::Builtin(Builtin::Int(IntWidth::I32))
11, I64, Layout::Builtin(Builtin::Int(IntWidth::I64))
12, I128, Layout::Builtin(Builtin::Int(IntWidth::I128))
13, F32, Layout::Builtin(Builtin::Float(FloatWidth::F32))
14, F64, Layout::Builtin(Builtin::Float(FloatWidth::F64))
15, DEC, Layout::Builtin(Builtin::Decimal)
16, STR, Layout::Builtin(Builtin::Str)
17, RECURSIVE_PTR, Layout::RecursivePointer(Layout::VOID)
0, VOID, pub, Layout::VOID_NAKED
1, UNIT, pub, Layout::UNIT_NAKED
2, BOOL, pub, Layout::Builtin(Builtin::Bool)
3, U8, pub, Layout::Builtin(Builtin::Int(IntWidth::U8))
4, U16, pub, Layout::Builtin(Builtin::Int(IntWidth::U16))
5, U32, pub, Layout::Builtin(Builtin::Int(IntWidth::U32))
6, U64, pub, Layout::Builtin(Builtin::Int(IntWidth::U64))
7, U128, pub, Layout::Builtin(Builtin::Int(IntWidth::U128))
8, I8, pub, Layout::Builtin(Builtin::Int(IntWidth::I8))
9, I16, pub, Layout::Builtin(Builtin::Int(IntWidth::I16))
10, I32, pub, Layout::Builtin(Builtin::Int(IntWidth::I32))
11, I64, pub, Layout::Builtin(Builtin::Int(IntWidth::I64))
12, I128, pub, Layout::Builtin(Builtin::Int(IntWidth::I128))
13, F32, pub, Layout::Builtin(Builtin::Float(FloatWidth::F32))
14, F64, pub, Layout::Builtin(Builtin::Float(FloatWidth::F64))
15, DEC, pub, Layout::Builtin(Builtin::Decimal)
16, STR, pub, Layout::Builtin(Builtin::Str)
17, OPAQUE_PTR, pub, Layout::Boxed(Layout::VOID)
18, NAKED_RECURSIVE_PTR, pub(super), Layout::RecursivePointer(Layout::VOID)
; 18
; 19
}
macro_rules! impl_to_from_int_width {
@ -1011,9 +1012,11 @@ mod insert_recursive_layout {
fn make_layout<'a>(arena: &'a Bump, interner: &mut impl LayoutInterner<'a>) -> Layout<'a> {
Layout::Union(UnionLayout::Recursive(&*arena.alloc([
&*arena.alloc([interner.insert(Layout::Builtin(Builtin::List(Layout::RECURSIVE_PTR)))]),
&*arena.alloc([
interner.insert(Layout::Builtin(Builtin::List(Layout::NAKED_RECURSIVE_PTR))),
]),
&*arena.alloc_slice_fill_iter([interner.insert(Layout::struct_no_name_order(
&*arena.alloc([Layout::RECURSIVE_PTR]),
&*arena.alloc([Layout::NAKED_RECURSIVE_PTR]),
))]),
])))
}