mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-03 00:24:34 +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::RefCountIsUnique => unimplemented!(),
|
||||||
LowLevel::ListIncref => unimplemented!(),
|
LowLevel::ListIncref => unimplemented!(),
|
||||||
LowLevel::ListDecref => unimplemented!(),
|
LowLevel::ListDecref => unimplemented!(),
|
||||||
|
LowLevel::ListElemDecFnPtr => unimplemented!(),
|
||||||
|
|
||||||
LowLevel::SetJmp => unimplemented!(),
|
LowLevel::SetJmp => unimplemented!(),
|
||||||
LowLevel::LongJmp => unimplemented!(),
|
LowLevel::LongJmp => unimplemented!(),
|
||||||
|
|
|
@ -2846,7 +2846,7 @@ impl<
|
||||||
self.load_layout_refcounted(element_layout, Symbol::DEV_TMP3);
|
self.load_layout_refcounted(element_layout, Symbol::DEV_TMP3);
|
||||||
|
|
||||||
let inc_elem_fn = self.increment_fn_pointer(element_layout);
|
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,
|
// input: RocList,
|
||||||
// caller: CompareFn,
|
// caller: CompareFn,
|
||||||
|
@ -2925,7 +2925,7 @@ impl<
|
||||||
self.load_layout_refcounted(elem_layout, Symbol::DEV_TMP3);
|
self.load_layout_refcounted(elem_layout, Symbol::DEV_TMP3);
|
||||||
|
|
||||||
let inc_elem_fn = self.increment_fn_pointer(elem_layout);
|
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.
|
// Setup the return location.
|
||||||
let base_offset =
|
let base_offset =
|
||||||
|
@ -3276,7 +3276,7 @@ impl<
|
||||||
self.load_layout_refcounted(elem_layout, Symbol::DEV_TMP4);
|
self.load_layout_refcounted(elem_layout, Symbol::DEV_TMP4);
|
||||||
|
|
||||||
let inc_elem_fn = self.increment_fn_pointer(elem_layout);
|
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.
|
// Setup the return location.
|
||||||
let base_offset =
|
let base_offset =
|
||||||
|
@ -3387,7 +3387,7 @@ impl<
|
||||||
self.load_layout_refcounted(elem_layout, Symbol::DEV_TMP3);
|
self.load_layout_refcounted(elem_layout, Symbol::DEV_TMP3);
|
||||||
|
|
||||||
let inc_elem_fn = self.increment_fn_pointer(elem_layout);
|
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.
|
// Setup the return location.
|
||||||
let base_offset =
|
let base_offset =
|
||||||
|
|
|
@ -465,12 +465,12 @@ trait Backend<'a> {
|
||||||
element_increment
|
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
|
let box_layout = self
|
||||||
.interner_mut()
|
.interner_mut()
|
||||||
.insert_direct_no_semantic(LayoutRepr::Ptr(layout));
|
.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_symbol = self.build_indirect_dec(layout);
|
||||||
|
|
||||||
let element_decrement_string = self.lambda_name_to_string(
|
let element_decrement_string = self.lambda_name_to_string(
|
||||||
|
@ -1923,7 +1923,7 @@ trait Backend<'a> {
|
||||||
list_argument.element_refcounted,
|
list_argument.element_refcounted,
|
||||||
start,
|
start,
|
||||||
len,
|
len,
|
||||||
self.decrement_fn_pointer(element_layout),
|
self.decrement_fn_pointer(element_layout, None),
|
||||||
];
|
];
|
||||||
|
|
||||||
let layout_usize = Layout::U64;
|
let layout_usize = Layout::U64;
|
||||||
|
@ -1953,7 +1953,7 @@ trait Backend<'a> {
|
||||||
self.load_literal_i8(&update_mode, UpdateMode::Immutable as i8);
|
self.load_literal_i8(&update_mode, UpdateMode::Immutable as i8);
|
||||||
|
|
||||||
let inc_elem_fn = self.increment_fn_pointer(list_argument.element_layout);
|
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;
|
let layout_usize = Layout::U64;
|
||||||
|
|
||||||
|
@ -2005,7 +2005,7 @@ trait Backend<'a> {
|
||||||
self.load_literal_i8(&update_mode, UpdateMode::Immutable as i8);
|
self.load_literal_i8(&update_mode, UpdateMode::Immutable as i8);
|
||||||
|
|
||||||
let inc_elem_fn = self.increment_fn_pointer(list_argument.element_layout);
|
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;
|
let layout_usize = Layout::U64;
|
||||||
|
|
||||||
|
@ -2079,7 +2079,7 @@ trait Backend<'a> {
|
||||||
let list_layout = arg_layouts[0];
|
let list_layout = arg_layouts[0];
|
||||||
let list_argument = self.list_argument(list_layout);
|
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;
|
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 => {
|
LowLevel::ListDropAt => {
|
||||||
let list = args[0];
|
let list = args[0];
|
||||||
let drop_index = args[1];
|
let drop_index = args[1];
|
||||||
|
@ -2123,7 +2130,7 @@ trait Backend<'a> {
|
||||||
|
|
||||||
let layout_usize = Layout::U64;
|
let layout_usize = Layout::U64;
|
||||||
let element_increment = self.increment_fn_pointer(element_layout);
|
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,
|
// list: RocList,
|
||||||
// alignment: u32,
|
// alignment: u32,
|
||||||
|
|
|
@ -1411,7 +1411,7 @@ pub(crate) fn run_low_level<'a, 'ctx>(
|
||||||
call_bitcode_fn(env, &[], bitcode::UTILS_DICT_PSEUDO_SEED)
|
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")
|
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);
|
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 => {
|
ListMap | ListMap2 | ListMap3 | ListMap4 | ListSortWith => {
|
||||||
internal_error!("HigherOrder lowlevels should not be handled here")
|
internal_error!("HigherOrder lowlevels should not be handled here")
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,6 +50,7 @@ pub enum LowLevel {
|
||||||
ListConcatUtf8,
|
ListConcatUtf8,
|
||||||
ListIncref,
|
ListIncref,
|
||||||
ListDecref,
|
ListDecref,
|
||||||
|
ListElemDecFnPtr,
|
||||||
NumAdd,
|
NumAdd,
|
||||||
NumAddWrap,
|
NumAddWrap,
|
||||||
NumAddChecked,
|
NumAddChecked,
|
||||||
|
@ -243,6 +244,7 @@ macro_rules! map_symbol_to_lowlevel {
|
||||||
LowLevel::RefCountIsUnique => unimplemented!(),
|
LowLevel::RefCountIsUnique => unimplemented!(),
|
||||||
LowLevel::ListIncref => unimplemented!(),
|
LowLevel::ListIncref => unimplemented!(),
|
||||||
LowLevel::ListDecref => unimplemented!(),
|
LowLevel::ListDecref => unimplemented!(),
|
||||||
|
LowLevel::ListElemDecFnPtr => unimplemented!(),
|
||||||
|
|
||||||
LowLevel::SetJmp => unimplemented!(),
|
LowLevel::SetJmp => unimplemented!(),
|
||||||
LowLevel::LongJmp => unimplemented!(),
|
LowLevel::LongJmp => unimplemented!(),
|
||||||
|
|
|
@ -953,7 +953,7 @@ fn refcount_list<'a>(
|
||||||
ctx: &mut Context<'a>,
|
ctx: &mut Context<'a>,
|
||||||
layout_interner: &mut STLayoutInterner<'a>,
|
layout_interner: &mut STLayoutInterner<'a>,
|
||||||
element_layout: InLayout<'a>,
|
element_layout: InLayout<'a>,
|
||||||
structure: Symbol,
|
_structure: Symbol,
|
||||||
) -> Stmt<'a> {
|
) -> Stmt<'a> {
|
||||||
let arena = root.arena;
|
let arena = root.arena;
|
||||||
let layout_isize = root.layout_isize;
|
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()));
|
Expr::Literal(Literal::Int((element_alignment as u128).to_ne_bytes()));
|
||||||
let alignment_stmt = |next| Stmt::Let(alignment, alignment_expr, LAYOUT_U32, next);
|
let alignment_stmt = |next| Stmt::Let(alignment, alignment_expr, LAYOUT_U32, next);
|
||||||
|
|
||||||
// let orig_op = ctx.op;
|
let dec_elem_ptr = root.create_symbol(ident_ids, "dec_elem_ptr");
|
||||||
// ctx.op = HelperOp::IndirectDec;
|
let dec_elem_ptr_expr = Expr::Call(Call {
|
||||||
// let dec_elem_fn =
|
call_type: CallType::LowLevel {
|
||||||
// root.find_or_create_proc(ident_ids, ctx, layout_interner, element_layout);
|
op: LowLevel::ListElemDecFnPtr,
|
||||||
// ctx.op = orig_op;
|
update_mode: UpdateModeId::BACKEND_DUMMY,
|
||||||
// TODO: How do I load a proc symbol to a pointer???
|
},
|
||||||
|
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 {
|
let rc_list_expr = Expr::Call(Call {
|
||||||
call_type: CallType::LowLevel {
|
call_type: CallType::LowLevel {
|
||||||
op: LowLevel::ListDecref,
|
op: LowLevel::ListDecref,
|
||||||
update_mode: UpdateModeId::BACKEND_DUMMY,
|
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(
|
width_stmt(arena.alloc(
|
||||||
//
|
//
|
||||||
alignment_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,
|
PtrLoad => RC::NoRc,
|
||||||
PtrCast => RC::NoRc,
|
PtrCast => RC::NoRc,
|
||||||
|
|
||||||
PtrClearTagId | RefCountIncRcPtr | RefCountDecRcPtr | RefCountIncDataPtr
|
ListElemDecFnPtr | PtrClearTagId | RefCountIncRcPtr | RefCountDecRcPtr
|
||||||
| RefCountDecDataPtr | RefCountIsUnique => {
|
| RefCountIncDataPtr | RefCountDecDataPtr | RefCountIsUnique => {
|
||||||
unreachable!("Only inserted *after* borrow checking: {:?}", lowlevel);
|
unreachable!("Only inserted *after* borrow checking: {:?}", lowlevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1357,6 +1357,8 @@ pub(crate) fn lowlevel_borrow_signature(op: LowLevel) -> &'static [Ownership] {
|
||||||
StrReleaseExcessCapacity => &[OWNED],
|
StrReleaseExcessCapacity => &[OWNED],
|
||||||
ListIncref => &[OWNED],
|
ListIncref => &[OWNED],
|
||||||
ListDecref => &[OWNED],
|
ListDecref => &[OWNED],
|
||||||
|
// This doesn't really use the list. It just generates a functions from the layout.
|
||||||
|
ListElemDecFnPtr => &[BORROWED],
|
||||||
|
|
||||||
Eq | NotEq => &[BORROWED, BORROWED],
|
Eq | NotEq => &[BORROWED, BORROWED],
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue