attempt to correct list refcount generation in dev backends

This commit is contained in:
Brendan Hansknecht 2024-07-07 16:16:16 -07:00
parent 94fe0820d5
commit 36bc8bfac4
No known key found for this signature in database
GPG key ID: 0EA784685083E75B
9 changed files with 56 additions and 24 deletions

View file

@ -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!(),

View file

@ -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 =

View file

@ -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,

View file

@ -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")
} }
} }

View file

@ -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")
} }

View file

@ -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!(),

View file

@ -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,29 +1016,38 @@ 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(
//
dec_elem_ptr_stmt(arena.alloc(
// //
is_refcounted_stmt(arena.alloc( is_refcounted_stmt(arena.alloc(
// //
Stmt::Let(rc_list_unit, rc_list_expr, LAYOUT_UNIT, ret_stmt), Stmt::Let(rc_list_unit, rc_list_expr, LAYOUT_UNIT, ret_stmt),
)), )),
)), )),
)),
)) ))
} }
_ => unreachable!(), _ => unreachable!(),

View file

@ -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);
} }

View file

@ -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],