use Ptr instead of Boxed in the code-gen-help

This commit is contained in:
Folkert 2023-06-28 22:35:39 +02:00 committed by Anton-4
parent cde3615ec2
commit 3b18494ddd
4 changed files with 83 additions and 80 deletions

View file

@ -609,8 +609,8 @@ fn eq_boxed<'a>(
let b = root.create_symbol(ident_ids, "b");
let result = root.create_symbol(ident_ids, "result");
let a_expr = Expr::ExprUnbox { symbol: ARG_1 };
let b_expr = Expr::ExprUnbox { symbol: ARG_2 };
let a_expr = Expr::ptr_load(&ARG_1);
let b_expr = Expr::ptr_load(&ARG_2);
let eq_call_expr = root
.call_specialized_op(
ident_ids,
@ -649,8 +649,8 @@ fn eq_boxed<'a>(
/// TODO, ListGetUnsafe no longer increments the refcount, so we can use it here.
/// We can't use `ListGetUnsafe` because it increments the refcount, and we don't want that.
/// Another way to dereference a heap pointer is to use `Expr::UnionAtIndex`.
/// To achieve this we use `PtrCast` to cast the element pointer to a "Box" layout.
/// Then we can increment the Box pointer in a loop, dereferencing it each time.
/// To achieve this we use `PtrCast` to cast the element pointer to a "Ptr" layout.
/// Then we can increment the pointer in a loop, dereferencing it each time.
/// (An alternative approach would be to create a new lowlevel like ListPeekUnsafe.)
fn eq_list<'a>(
root: &mut CodeGenHelp<'a>,
@ -663,8 +663,8 @@ fn eq_list<'a>(
let layout_isize = root.layout_isize;
let arena = root.arena;
// A "Box" layout (heap pointer to a single list element)
let box_layout = layout_interner.insert_direct_no_semantic(LayoutRepr::Boxed(elem_layout));
// A pointer layout (heap pointer to a single list element)
let ptr_layout = layout_interner.insert_direct_no_semantic(LayoutRepr::Ptr(elem_layout));
// Compare lengths
@ -683,16 +683,16 @@ fn eq_list<'a>(
let elements_2 = root.create_symbol(ident_ids, "elements_2");
let elements_1_expr = Expr::StructAtIndex {
index: 0,
field_layouts: root.arena.alloc([box_layout, layout_isize]),
field_layouts: root.arena.alloc([ptr_layout, layout_isize]),
structure: ARG_1,
};
let elements_2_expr = Expr::StructAtIndex {
index: 0,
field_layouts: root.arena.alloc([box_layout, layout_isize]),
field_layouts: root.arena.alloc([ptr_layout, layout_isize]),
structure: ARG_2,
};
let elements_1_stmt = |next| Stmt::Let(elements_1, elements_1_expr, box_layout, next);
let elements_2_stmt = |next| Stmt::Let(elements_2, elements_2_expr, box_layout, next);
let elements_1_stmt = |next| Stmt::Let(elements_1, elements_1_expr, ptr_layout, next);
let elements_2_stmt = |next| Stmt::Let(elements_2, elements_2_expr, ptr_layout, next);
// Cast to integers
let start_1 = root.create_symbol(ident_ids, "start_1");
@ -758,17 +758,17 @@ fn eq_list<'a>(
// if we haven't reached the end yet...
//
// Cast integers to box pointers
let box1 = root.create_symbol(ident_ids, "box1");
let box2 = root.create_symbol(ident_ids, "box2");
let box1_stmt = |next| let_lowlevel(arena, box_layout, box1, PtrCast, &[addr1], next);
let box2_stmt = |next| let_lowlevel(arena, box_layout, box2, PtrCast, &[addr2], next);
// Cast integers to pointers
let ptr1 = root.create_symbol(ident_ids, "ptr1");
let ptr2 = root.create_symbol(ident_ids, "ptr2");
let ptr1_stmt = |next| let_lowlevel(arena, ptr_layout, ptr1, PtrCast, &[addr1], next);
let ptr2_stmt = |next| let_lowlevel(arena, ptr_layout, ptr2, PtrCast, &[addr2], next);
// Dereference the box pointers to get the current elements
// Dereference the pointers to get the current elements
let elem1 = root.create_symbol(ident_ids, "elem1");
let elem2 = root.create_symbol(ident_ids, "elem2");
let elem1_expr = Expr::ExprUnbox { symbol: box1 };
let elem2_expr = Expr::ExprUnbox { symbol: box2 };
let elem1_expr = Expr::ptr_load(arena.alloc(ptr1));
let elem2_expr = Expr::ptr_load(arena.alloc(ptr2));
let elem1_stmt = |next| Stmt::Let(elem1, elem1_expr, elem_layout, next);
let elem2_stmt = |next| Stmt::Let(elem2, elem2_expr, elem_layout, next);
@ -819,9 +819,9 @@ fn eq_list<'a>(
Stmt::Ret(Symbol::BOOL_TRUE),
root.arena.alloc(
//
box1_stmt(root.arena.alloc(
ptr1_stmt(root.arena.alloc(
//
box2_stmt(root.arena.alloc(
ptr2_stmt(root.arena.alloc(
//
elem1_stmt(root.arena.alloc(
//

View file

@ -302,14 +302,14 @@ impl<'a> CodeGenHelp<'a> {
let (ret_layout, arg_layouts): (InLayout<'a>, &'a [InLayout<'a>]) = {
let arg = self.replace_rec_ptr(ctx, layout_interner, layout);
let box_arg = layout_interner.insert_direct_no_semantic(LayoutRepr::Boxed(arg));
let ptr_arg = layout_interner.insert_direct_no_semantic(LayoutRepr::Ptr(arg));
match ctx.op {
Dec | DecRef(_) => (LAYOUT_UNIT, self.arena.alloc([arg])),
Reset | ResetRef => (layout, self.arena.alloc([layout])),
Inc => (LAYOUT_UNIT, self.arena.alloc([arg, self.layout_isize])),
IndirectDec => (LAYOUT_UNIT, arena.alloc([box_arg])),
IndirectInc => (LAYOUT_UNIT, arena.alloc([box_arg, self.layout_isize])),
IndirectDec => (LAYOUT_UNIT, arena.alloc([ptr_arg])),
IndirectInc => (LAYOUT_UNIT, arena.alloc([ptr_arg, self.layout_isize])),
Eq => (LAYOUT_BOOL, self.arena.alloc([arg, arg])),
}
};
@ -431,15 +431,15 @@ impl<'a> CodeGenHelp<'a> {
}
Dec | DecRef(_) | Reset | ResetRef => self.arena.alloc([roc_value]),
IndirectInc => {
let box_layout =
layout_interner.insert_direct_no_semantic(LayoutRepr::Boxed(layout));
let ptr_layout =
layout_interner.insert_direct_no_semantic(LayoutRepr::Ptr(layout));
let inc_amount = (self.layout_isize, ARG_2);
self.arena.alloc([(box_layout, ARG_1), inc_amount])
self.arena.alloc([(ptr_layout, ARG_1), inc_amount])
}
IndirectDec => {
let box_layout =
layout_interner.insert_direct_no_semantic(LayoutRepr::Boxed(layout));
self.arena.alloc([(box_layout, ARG_1)])
let ptr_layout =
layout_interner.insert_direct_no_semantic(LayoutRepr::Ptr(layout));
self.arena.alloc([(ptr_layout, ARG_1)])
}
Eq => self.arena.alloc([roc_value, (layout, ARG_2)]),
}
@ -486,21 +486,19 @@ impl<'a> CodeGenHelp<'a> {
niche: Niche::NONE,
},
HelperOp::IndirectInc => {
let box_layout =
layout_interner.insert_direct_no_semantic(LayoutRepr::Boxed(layout));
let ptr_layout = layout_interner.insert_direct_no_semantic(LayoutRepr::Ptr(layout));
ProcLayout {
arguments: self.arena.alloc([box_layout, self.layout_isize]),
arguments: self.arena.alloc([ptr_layout, self.layout_isize]),
result: LAYOUT_UNIT,
niche: Niche::NONE,
}
}
HelperOp::IndirectDec => {
let box_layout =
layout_interner.insert_direct_no_semantic(LayoutRepr::Boxed(layout));
let ptr_layout = layout_interner.insert_direct_no_semantic(LayoutRepr::Ptr(layout));
ProcLayout {
arguments: self.arena.alloc([box_layout]),
arguments: self.arena.alloc([ptr_layout]),
result: LAYOUT_UNIT,
niche: Niche::NONE,
}
@ -674,20 +672,20 @@ impl<'a> CallerProc<'a> {
op: HelperOp::Eq,
};
let box_capture_layout = if let Some(capture_layout) = capture_layout {
layout_interner.insert_direct_no_semantic(LayoutRepr::Boxed(capture_layout))
let ptr_capture_layout = if let Some(capture_layout) = capture_layout {
layout_interner.insert_direct_no_semantic(LayoutRepr::Ptr(capture_layout))
} else {
layout_interner.insert_direct_no_semantic(LayoutRepr::Boxed(Layout::UNIT))
layout_interner.insert_direct_no_semantic(LayoutRepr::Ptr(Layout::UNIT))
};
let box_argument_layout = layout_interner
.insert_direct_no_semantic(LayoutRepr::Boxed(passed_function.argument_layouts[0]));
let ptr_argument_layout = layout_interner
.insert_direct_no_semantic(LayoutRepr::Ptr(passed_function.argument_layouts[0]));
let box_return_layout = layout_interner
.insert_direct_no_semantic(LayoutRepr::Boxed(passed_function.return_layout));
let ptr_return_layout = layout_interner
.insert_direct_no_semantic(LayoutRepr::Ptr(passed_function.return_layout));
let proc_layout = ProcLayout {
arguments: arena.alloc([box_capture_layout, box_argument_layout, box_return_layout]),
arguments: arena.alloc([ptr_capture_layout, ptr_argument_layout, ptr_return_layout]),
result: Layout::UNIT,
niche: Niche::NONE,
};
@ -697,16 +695,11 @@ impl<'a> CallerProc<'a> {
ctx.new_linker_data.push((proc_symbol, proc_layout));
let unbox_capture = Expr::ExprUnbox {
symbol: Symbol::ARG_1,
};
let load_capture = Expr::ptr_load(arena.alloc(Symbol::ARG_1));
let load_argument = Expr::ptr_load(arena.alloc(Symbol::ARG_2));
let unbox_argument = Expr::ExprUnbox {
symbol: Symbol::ARG_2,
};
let unboxed_capture = Self::create_symbol(home, ident_ids, "unboxed_capture");
let unboxed_argument = Self::create_symbol(home, ident_ids, "unboxed_argument");
let loaded_capture = Self::create_symbol(home, ident_ids, "loaded_capture");
let loaded_argument = Self::create_symbol(home, ident_ids, "loaded_argument");
let call_result = Self::create_symbol(home, ident_ids, "call_result");
let unit_symbol = Self::create_symbol(home, ident_ids, "unit_symbol");
let ignored = Self::create_symbol(home, ident_ids, "ignored");
@ -719,9 +712,9 @@ impl<'a> CallerProc<'a> {
specialization_id: passed_function.specialization_id,
},
arguments: if capture_layout.is_some() {
arena.alloc([unboxed_argument, unboxed_capture])
arena.alloc([loaded_argument, loaded_capture])
} else {
arena.alloc([unboxed_argument])
arena.alloc([loaded_argument])
},
});
@ -734,8 +727,8 @@ impl<'a> CallerProc<'a> {
});
let mut body = Stmt::Let(
unboxed_argument,
unbox_argument,
loaded_argument,
load_argument,
passed_function.argument_layouts[0],
arena.alloc(Stmt::Let(
call_result,
@ -744,7 +737,7 @@ impl<'a> CallerProc<'a> {
arena.alloc(Stmt::Let(
ignored,
ptr_write,
box_return_layout,
ptr_return_layout,
arena.alloc(Stmt::Let(
unit_symbol,
Expr::Struct(&[]),
@ -757,8 +750,8 @@ impl<'a> CallerProc<'a> {
if let Some(capture_layout) = capture_layout {
body = Stmt::Let(
unboxed_capture,
unbox_capture,
loaded_capture,
load_capture,
capture_layout,
arena.alloc(body),
);
@ -766,9 +759,9 @@ impl<'a> CallerProc<'a> {
let args: &'a [(InLayout<'a>, Symbol)] = {
arena.alloc([
(box_capture_layout, ARG_1),
(box_argument_layout, ARG_2),
(box_return_layout, ARG_3),
(ptr_capture_layout, ARG_1),
(ptr_argument_layout, ARG_2),
(ptr_return_layout, ARG_3),
])
};

View file

@ -135,7 +135,7 @@ pub fn refcount_indirect<'a>(
let arena = root.arena;
let unit = root.create_symbol(ident_ids, "unit");
let unboxed = root.create_symbol(ident_ids, "unboxed");
let loaded = root.create_symbol(ident_ids, "loaded");
let indirect_op = ctx.op;
let direct_op = match ctx.op {
@ -147,7 +147,7 @@ pub fn refcount_indirect<'a>(
// we've done the indirection, the inner value shoud be inc- or decremented directly
ctx.op = direct_op;
let mod_args = refcount_args(root, ctx, unboxed);
let mod_args = refcount_args(root, ctx, loaded);
let opt_mod_expr =
root.call_specialized_op(ident_ids, ctx, layout_interner, element_layout, mod_args);
@ -156,8 +156,8 @@ pub fn refcount_indirect<'a>(
if let Some(mod_expr) = opt_mod_expr {
Stmt::Let(
unboxed,
Expr::ExprUnbox { symbol: structure },
loaded,
Expr::ptr_load(arena.alloc(structure)),
element_layout,
arena.alloc(
//
@ -447,7 +447,7 @@ pub fn refcount_reset_proc_body<'a>(
);
// Refcount value
let rc_expr = Expr::ExprUnbox { symbol: rc_ptr };
let rc_expr = Expr::ptr_load(root.arena.alloc(rc_ptr));
let rc_stmt = Stmt::Let(
rc,
@ -572,7 +572,7 @@ pub fn refcount_resetref_proc_body<'a>(
);
// Refcount value
let rc_expr = Expr::ExprUnbox { symbol: rc_ptr };
let rc_expr = Expr::ptr_load(root.arena.alloc(rc_ptr));
let rc_stmt = Stmt::Let(
rc,
@ -968,8 +968,8 @@ fn refcount_list<'a>(
let layout_isize = root.layout_isize;
let arena = root.arena;
// A "Box" layout (heap pointer to a single list element)
let box_layout = layout_interner.insert_direct_no_semantic(LayoutRepr::Boxed(elem_layout));
// A "Ptr" layout (heap pointer to a single list element)
let ptr_layout = layout_interner.insert_direct_no_semantic(LayoutRepr::Ptr(elem_layout));
//
// Check if the list is empty
@ -993,7 +993,7 @@ fn refcount_list<'a>(
// let capacity = StructAtIndex 2 structure
let capacity = root.create_symbol(ident_ids, "capacity");
let list_field_layouts = arena.alloc([box_layout, layout_isize, layout_isize]);
let list_field_layouts = arena.alloc([ptr_layout, layout_isize, layout_isize]);
let capacity_expr = Expr::StructAtIndex {
index: 2,
field_layouts: list_field_layouts,
@ -1017,7 +1017,7 @@ fn refcount_list<'a>(
field_layouts: list_field_layouts,
structure,
};
let first_element_stmt = |next| Stmt::Let(first_element, first_element_expr, box_layout, next);
let first_element_stmt = |next| Stmt::Let(first_element, first_element_expr, ptr_layout, next);
let jp_elements = JoinPointId(root.create_symbol(ident_ids, "jp_elements"));
let data_pointer = root.create_symbol(ident_ids, "data_pointer");
@ -1104,7 +1104,7 @@ fn refcount_list<'a>(
layout_interner,
elem_layout,
LAYOUT_UNIT,
box_layout,
ptr_layout,
len,
first_element_pointer,
modify_list,
@ -1166,7 +1166,7 @@ fn refcount_list_elems<'a>(
layout_interner: &mut STLayoutInterner<'a>,
elem_layout: InLayout<'a>,
ret_layout: InLayout<'a>,
box_layout: InLayout<'a>,
ptr_layout: InLayout<'a>,
length: Symbol,
elements: Symbol,
following: Stmt<'a>,
@ -1224,13 +1224,13 @@ fn refcount_list_elems<'a>(
// if we haven't reached the end yet...
//
// Cast integer to box pointer
let box_ptr = root.create_symbol(ident_ids, "box");
let box_stmt = |next| let_lowlevel(arena, box_layout, box_ptr, PtrCast, &[addr], next);
// Cast integer to pointer
let ptr_symbol = root.create_symbol(ident_ids, "ptr");
let ptr_stmt = |next| let_lowlevel(arena, ptr_layout, ptr_symbol, PtrCast, &[addr], next);
// Dereference the box pointer to get the current element
// Dereference the pointer to get the current element
let elem = root.create_symbol(ident_ids, "elem");
let elem_expr = Expr::ExprUnbox { symbol: box_ptr };
let elem_expr = Expr::ptr_load(arena.alloc(ptr_symbol));
let elem_stmt = |next| Stmt::Let(elem, elem_expr, elem_layout, next);
//
@ -1273,7 +1273,7 @@ fn refcount_list_elems<'a>(
is_end,
ret_layout,
following,
arena.alloc(box_stmt(arena.alloc(
arena.alloc(ptr_stmt(arena.alloc(
//
elem_stmt(arena.alloc(
//