mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-26 13:29:12 +00:00
attempt to correct list refcount generation in dev backends
This commit is contained in:
parent
94fe0820d5
commit
36bc8bfac4
9 changed files with 56 additions and 24 deletions
|
@ -93,6 +93,7 @@ macro_rules! map_symbol_to_lowlevel_and_arity {
|
|||
LowLevel::RefCountIsUnique => unimplemented!(),
|
||||
LowLevel::ListIncref => unimplemented!(),
|
||||
LowLevel::ListDecref => unimplemented!(),
|
||||
LowLevel::ListElemDecFnPtr => unimplemented!(),
|
||||
|
||||
LowLevel::SetJmp => unimplemented!(),
|
||||
LowLevel::LongJmp => unimplemented!(),
|
||||
|
|
|
@ -2846,7 +2846,7 @@ impl<
|
|||
self.load_layout_refcounted(element_layout, Symbol::DEV_TMP3);
|
||||
|
||||
let inc_elem_fn = self.increment_fn_pointer(element_layout);
|
||||
let dec_elem_fn = self.decrement_fn_pointer(element_layout);
|
||||
let dec_elem_fn = self.decrement_fn_pointer(element_layout, None);
|
||||
|
||||
// input: RocList,
|
||||
// caller: CompareFn,
|
||||
|
@ -2925,7 +2925,7 @@ impl<
|
|||
self.load_layout_refcounted(elem_layout, Symbol::DEV_TMP3);
|
||||
|
||||
let inc_elem_fn = self.increment_fn_pointer(elem_layout);
|
||||
let dec_elem_fn = self.decrement_fn_pointer(elem_layout);
|
||||
let dec_elem_fn = self.decrement_fn_pointer(elem_layout, None);
|
||||
|
||||
// Setup the return location.
|
||||
let base_offset =
|
||||
|
@ -3276,7 +3276,7 @@ impl<
|
|||
self.load_layout_refcounted(elem_layout, Symbol::DEV_TMP4);
|
||||
|
||||
let inc_elem_fn = self.increment_fn_pointer(elem_layout);
|
||||
let dec_elem_fn = self.decrement_fn_pointer(elem_layout);
|
||||
let dec_elem_fn = self.decrement_fn_pointer(elem_layout, None);
|
||||
|
||||
// Setup the return location.
|
||||
let base_offset =
|
||||
|
@ -3387,7 +3387,7 @@ impl<
|
|||
self.load_layout_refcounted(elem_layout, Symbol::DEV_TMP3);
|
||||
|
||||
let inc_elem_fn = self.increment_fn_pointer(elem_layout);
|
||||
let dec_elem_fn = self.decrement_fn_pointer(elem_layout);
|
||||
let dec_elem_fn = self.decrement_fn_pointer(elem_layout, None);
|
||||
|
||||
// Setup the return location.
|
||||
let base_offset =
|
||||
|
|
|
@ -465,12 +465,12 @@ trait Backend<'a> {
|
|||
element_increment
|
||||
}
|
||||
|
||||
fn decrement_fn_pointer(&mut self, layout: InLayout<'a>) -> Symbol {
|
||||
fn decrement_fn_pointer(&mut self, layout: InLayout<'a>, out: Option<Symbol>) -> Symbol {
|
||||
let box_layout = self
|
||||
.interner_mut()
|
||||
.insert_direct_no_semantic(LayoutRepr::Ptr(layout));
|
||||
|
||||
let element_decrement = self.debug_symbol("element_decrement");
|
||||
let element_decrement = out.unwrap_or(self.debug_symbol("element_decrement"));
|
||||
let element_decrement_symbol = self.build_indirect_dec(layout);
|
||||
|
||||
let element_decrement_string = self.lambda_name_to_string(
|
||||
|
@ -1923,7 +1923,7 @@ trait Backend<'a> {
|
|||
list_argument.element_refcounted,
|
||||
start,
|
||||
len,
|
||||
self.decrement_fn_pointer(element_layout),
|
||||
self.decrement_fn_pointer(element_layout, None),
|
||||
];
|
||||
|
||||
let layout_usize = Layout::U64;
|
||||
|
@ -1953,7 +1953,7 @@ trait Backend<'a> {
|
|||
self.load_literal_i8(&update_mode, UpdateMode::Immutable as i8);
|
||||
|
||||
let inc_elem_fn = self.increment_fn_pointer(list_argument.element_layout);
|
||||
let dec_elem_fn = self.decrement_fn_pointer(list_argument.element_layout);
|
||||
let dec_elem_fn = self.decrement_fn_pointer(list_argument.element_layout, None);
|
||||
|
||||
let layout_usize = Layout::U64;
|
||||
|
||||
|
@ -2005,7 +2005,7 @@ trait Backend<'a> {
|
|||
self.load_literal_i8(&update_mode, UpdateMode::Immutable as i8);
|
||||
|
||||
let inc_elem_fn = self.increment_fn_pointer(list_argument.element_layout);
|
||||
let dec_elem_fn = self.decrement_fn_pointer(list_argument.element_layout);
|
||||
let dec_elem_fn = self.decrement_fn_pointer(list_argument.element_layout, None);
|
||||
|
||||
let layout_usize = Layout::U64;
|
||||
|
||||
|
@ -2079,7 +2079,7 @@ trait Backend<'a> {
|
|||
let list_layout = arg_layouts[0];
|
||||
let list_argument = self.list_argument(list_layout);
|
||||
|
||||
let dec_elem_fn = self.decrement_fn_pointer(list_argument.element_layout);
|
||||
let dec_elem_fn = self.decrement_fn_pointer(list_argument.element_layout, None);
|
||||
|
||||
let layout_usize = Layout::U64;
|
||||
|
||||
|
@ -2110,6 +2110,13 @@ trait Backend<'a> {
|
|||
);
|
||||
}
|
||||
|
||||
LowLevel::ListElemDecFnPtr => {
|
||||
let list_layout = arg_layouts[0];
|
||||
let list_argument = self.list_argument(list_layout);
|
||||
|
||||
_ = self.decrement_fn_pointer(list_argument.element_layout, Some(*sym));
|
||||
}
|
||||
|
||||
LowLevel::ListDropAt => {
|
||||
let list = args[0];
|
||||
let drop_index = args[1];
|
||||
|
@ -2123,7 +2130,7 @@ trait Backend<'a> {
|
|||
|
||||
let layout_usize = Layout::U64;
|
||||
let element_increment = self.increment_fn_pointer(element_layout);
|
||||
let element_decrement = self.decrement_fn_pointer(element_layout);
|
||||
let element_decrement = self.decrement_fn_pointer(element_layout, None);
|
||||
|
||||
// list: RocList,
|
||||
// alignment: u32,
|
||||
|
|
|
@ -1411,7 +1411,7 @@ pub(crate) fn run_low_level<'a, 'ctx>(
|
|||
call_bitcode_fn(env, &[], bitcode::UTILS_DICT_PSEUDO_SEED)
|
||||
}
|
||||
|
||||
ListIncref | ListDecref | SetJmp | LongJmp | SetLongJmpBuffer => {
|
||||
ListElemDecFnPtr | ListIncref | ListDecref | SetJmp | LongJmp | SetLongJmpBuffer => {
|
||||
unreachable!("only inserted in dev backend codegen")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -368,6 +368,17 @@ impl<'a> LowLevelCall<'a> {
|
|||
backend.call_host_fn_after_loading_args(bitcode::LIST_DECREF);
|
||||
}
|
||||
|
||||
ListElemDecFnPtr => {
|
||||
let input_list: Symbol = self.arguments[0];
|
||||
let list_layout = backend
|
||||
.layout_interner
|
||||
.get_repr(backend.storage.symbol_layouts[&input_list]);
|
||||
let elem_in_layout = unwrap_list_elem_layout(list_layout);
|
||||
let dec_fn_ptr = build_refcount_element_fn(backend, elem_in_layout, HelperOp::Dec);
|
||||
|
||||
backend.code_builder.i32_const(dec_fn_ptr);
|
||||
}
|
||||
|
||||
ListMap | ListMap2 | ListMap3 | ListMap4 | ListSortWith => {
|
||||
internal_error!("HigherOrder lowlevels should not be handled here")
|
||||
}
|
||||
|
|
|
@ -50,6 +50,7 @@ pub enum LowLevel {
|
|||
ListConcatUtf8,
|
||||
ListIncref,
|
||||
ListDecref,
|
||||
ListElemDecFnPtr,
|
||||
NumAdd,
|
||||
NumAddWrap,
|
||||
NumAddChecked,
|
||||
|
@ -243,6 +244,7 @@ macro_rules! map_symbol_to_lowlevel {
|
|||
LowLevel::RefCountIsUnique => unimplemented!(),
|
||||
LowLevel::ListIncref => unimplemented!(),
|
||||
LowLevel::ListDecref => unimplemented!(),
|
||||
LowLevel::ListElemDecFnPtr => unimplemented!(),
|
||||
|
||||
LowLevel::SetJmp => unimplemented!(),
|
||||
LowLevel::LongJmp => unimplemented!(),
|
||||
|
|
|
@ -953,7 +953,7 @@ fn refcount_list<'a>(
|
|||
ctx: &mut Context<'a>,
|
||||
layout_interner: &mut STLayoutInterner<'a>,
|
||||
element_layout: InLayout<'a>,
|
||||
structure: Symbol,
|
||||
_structure: Symbol,
|
||||
) -> Stmt<'a> {
|
||||
let arena = root.arena;
|
||||
let layout_isize = root.layout_isize;
|
||||
|
@ -1016,27 +1016,36 @@ fn refcount_list<'a>(
|
|||
Expr::Literal(Literal::Int((element_alignment as u128).to_ne_bytes()));
|
||||
let alignment_stmt = |next| Stmt::Let(alignment, alignment_expr, LAYOUT_U32, next);
|
||||
|
||||
// let orig_op = ctx.op;
|
||||
// ctx.op = HelperOp::IndirectDec;
|
||||
// let dec_elem_fn =
|
||||
// root.find_or_create_proc(ident_ids, ctx, layout_interner, element_layout);
|
||||
// ctx.op = orig_op;
|
||||
// TODO: How do I load a proc symbol to a pointer???
|
||||
let dec_elem_ptr = root.create_symbol(ident_ids, "dec_elem_ptr");
|
||||
let dec_elem_ptr_expr = Expr::Call(Call {
|
||||
call_type: CallType::LowLevel {
|
||||
op: LowLevel::ListElemDecFnPtr,
|
||||
update_mode: UpdateModeId::BACKEND_DUMMY,
|
||||
},
|
||||
arguments: root.arena.alloc([list]),
|
||||
});
|
||||
let dec_elem_ptr_stmt =
|
||||
|next| Stmt::Let(dec_elem_ptr, dec_elem_ptr_expr, Layout::OPAQUE_PTR, next);
|
||||
|
||||
let rc_list_expr = Expr::Call(Call {
|
||||
call_type: CallType::LowLevel {
|
||||
op: LowLevel::ListDecref,
|
||||
update_mode: UpdateModeId::BACKEND_DUMMY,
|
||||
},
|
||||
arguments: root.arena.alloc([list, alignment, width, is_refcounted]),
|
||||
arguments: root
|
||||
.arena
|
||||
.alloc([list, alignment, width, is_refcounted, dec_elem_ptr]),
|
||||
});
|
||||
width_stmt(arena.alloc(
|
||||
//
|
||||
alignment_stmt(arena.alloc(
|
||||
//
|
||||
is_refcounted_stmt(arena.alloc(
|
||||
dec_elem_ptr_stmt(arena.alloc(
|
||||
//
|
||||
Stmt::Let(rc_list_unit, rc_list_expr, LAYOUT_UNIT, ret_stmt),
|
||||
is_refcounted_stmt(arena.alloc(
|
||||
//
|
||||
Stmt::Let(rc_list_unit, rc_list_expr, LAYOUT_UNIT, ret_stmt),
|
||||
)),
|
||||
)),
|
||||
)),
|
||||
))
|
||||
|
|
|
@ -1621,8 +1621,8 @@ fn low_level_no_rc(lowlevel: &LowLevel) -> RC {
|
|||
PtrLoad => RC::NoRc,
|
||||
PtrCast => RC::NoRc,
|
||||
|
||||
PtrClearTagId | RefCountIncRcPtr | RefCountDecRcPtr | RefCountIncDataPtr
|
||||
| RefCountDecDataPtr | RefCountIsUnique => {
|
||||
ListElemDecFnPtr | PtrClearTagId | RefCountIncRcPtr | RefCountDecRcPtr
|
||||
| RefCountIncDataPtr | RefCountDecDataPtr | RefCountIsUnique => {
|
||||
unreachable!("Only inserted *after* borrow checking: {:?}", lowlevel);
|
||||
}
|
||||
|
||||
|
|
|
@ -1357,6 +1357,8 @@ pub(crate) fn lowlevel_borrow_signature(op: LowLevel) -> &'static [Ownership] {
|
|||
StrReleaseExcessCapacity => &[OWNED],
|
||||
ListIncref => &[OWNED],
|
||||
ListDecref => &[OWNED],
|
||||
// This doesn't really use the list. It just generates a functions from the layout.
|
||||
ListElemDecFnPtr => &[BORROWED],
|
||||
|
||||
Eq | NotEq => &[BORROWED, BORROWED],
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue