mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-26 21:39:07 +00:00
use Ptr instead of Boxed in the code-gen-help
This commit is contained in:
parent
cde3615ec2
commit
3b18494ddd
4 changed files with 83 additions and 80 deletions
|
@ -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(
|
||||
//
|
||||
|
|
|
@ -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),
|
||||
])
|
||||
};
|
||||
|
||||
|
|
|
@ -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(
|
||||
//
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue