check inside a lambda set for whether it is reference counted

This commit is contained in:
Folkert 2023-07-26 20:06:37 +02:00
parent 73ffce0baa
commit 334253f47f
No known key found for this signature in database
GPG key ID: 1F17F6FFD112B97C
7 changed files with 34 additions and 31 deletions

View file

@ -2872,8 +2872,7 @@ pub(crate) fn build_exp_stmt<'a, 'ctx>(
DecRef(symbol) => {
let (value, layout) = scope.load_symbol_and_layout(symbol);
let lay = layout_interner.get_repr(layout);
match lay {
match layout_interner.get_repr(layout) {
LayoutRepr::Builtin(Builtin::Str) => todo!(),
LayoutRepr::Builtin(Builtin::List(element_layout)) => {
debug_assert!(value.is_struct_value());
@ -2883,9 +2882,9 @@ pub(crate) fn build_exp_stmt<'a, 'ctx>(
build_list::decref(env, value.into_struct_value(), alignment);
}
_ if lay.is_refcounted() => {
other_layout if other_layout.is_refcounted(layout_interner) => {
if value.is_pointer_value() {
let value_ptr = match lay {
let value_ptr = match other_layout {
LayoutRepr::Union(union_layout)
if union_layout
.stores_tag_id_in_pointer(env.target_info) =>

View file

@ -1246,7 +1246,7 @@ enum DecOrReuse {
fn fields_need_no_refcounting(interner: &STLayoutInterner, field_layouts: &[InLayout]) -> bool {
!field_layouts.iter().any(|x| {
let x = interner.get_repr(*x);
x.is_refcounted() || x.contains_refcounted(interner)
x.is_refcounted(interner) || x.contains_refcounted(interner)
})
}
@ -1763,7 +1763,7 @@ fn modify_refcount_nonrecursive_help<'a, 'ctx>(
// if none of the fields are or contain anything refcounted, just move on
if !field_layouts.iter().any(|x| {
let x = layout_interner.get_repr(*x);
x.is_refcounted() || x.contains_refcounted(layout_interner)
x.is_refcounted(layout_interner) || x.contains_refcounted(layout_interner)
}) {
continue;
}

View file

@ -365,7 +365,7 @@ impl<'a> LowLevelCall<'a> {
);
// Increment refcount
if self.ret_layout_raw.is_refcounted() {
if self.ret_layout_raw.is_refcounted(backend.layout_interner) {
let inc_fn = backend.get_refcount_fn_index(self.ret_layout, HelperOp::Inc);
backend.code_builder.get_local(elem_local);
backend.code_builder.i32_const(1);

View file

@ -4,7 +4,7 @@ use std::hash::Hash;
use crate::ir::{
Expr, HigherOrderLowLevel, JoinPointId, Param, PassedFunction, Proc, ProcLayout, Stmt,
};
use crate::layout::{InLayout, LayoutInterner, LayoutRepr, STLayoutInterner};
use crate::layout::{InLayout, LayoutInterner, STLayoutInterner};
use bumpalo::collections::Vec;
use bumpalo::Bump;
use roc_collections::all::{MutMap, MutSet};
@ -30,8 +30,8 @@ impl Ownership {
/// For reference-counted types (lists, (big) strings, recursive tags), owning a value
/// means incrementing its reference count. Hence, we prefer borrowing for these types
fn from_layout(layout: &LayoutRepr) -> Self {
match layout.is_refcounted() {
fn from_layout(interner: &STLayoutInterner<'_>, layout: InLayout<'_>) -> Self {
match interner.is_refcounted(layout) {
true => Ownership::Borrowed,
false => Ownership::Owned,
}
@ -266,7 +266,7 @@ impl<'a> ParamMap<'a> {
) -> &'a [Param<'a>] {
Vec::from_iter_in(
ps.iter().map(|p| Param {
ownership: Ownership::from_layout(&interner.get_repr(p.layout)),
ownership: Ownership::from_layout(interner, p.layout),
layout: p.layout,
symbol: p.symbol,
}),
@ -282,7 +282,7 @@ impl<'a> ParamMap<'a> {
) -> &'a [Param<'a>] {
Vec::from_iter_in(
ps.iter().map(|(layout, symbol)| Param {
ownership: Ownership::from_layout(&interner.get_repr(*layout)),
ownership: Ownership::from_layout(interner, *layout),
layout: *layout,
symbol: *symbol,
}),

View file

@ -1046,23 +1046,22 @@ fn refcount_list<'a>(
let modify_list = modify_refcount_stmt(Pointer::ToData(data_pointer));
let is_relevant_op = ctx.op.is_dec() || ctx.op.is_inc();
let modify_elems_and_list =
if is_relevant_op && layout_interner.get_repr(elem_layout).is_refcounted() {
refcount_list_elems(
root,
ident_ids,
ctx,
layout_interner,
elem_layout,
LAYOUT_UNIT,
ptr_layout,
len,
first_element_pointer,
modify_list,
)
} else {
modify_list
};
let modify_elems_and_list = if is_relevant_op && layout_interner.is_refcounted(elem_layout) {
refcount_list_elems(
root,
ident_ids,
ctx,
layout_interner,
elem_layout,
LAYOUT_UNIT,
ptr_layout,
len,
first_element_pointer,
modify_list,
)
} else {
modify_list
};
//
// JoinPoint for slice vs list

View file

@ -2843,7 +2843,10 @@ impl<'a> LayoutRepr<'a> {
}
}
pub fn is_refcounted(&self) -> bool {
pub fn is_refcounted<I>(&self, interner: &I) -> bool
where
I: LayoutInterner<'a>,
{
use self::Builtin::*;
use LayoutRepr::*;
@ -2858,6 +2861,8 @@ impl<'a> LayoutRepr<'a> {
Erased(_) => true,
LambdaSet(lambda_set) => interner.is_refcounted(lambda_set.runtime_representation()),
_ => false,
}
}

View file

@ -228,7 +228,7 @@ pub trait LayoutInterner<'a>: Sized {
}
fn is_refcounted(&self, layout: InLayout<'a>) -> bool {
self.get_repr(layout).is_refcounted()
self.get_repr(layout).is_refcounted(self)
}
fn is_nullable(&self, layout: InLayout<'a>) -> bool {