mirror of
https://github.com/roc-lang/roc.git
synced 2025-12-15 21:23:57 +00:00
Introduce the concept of SemanticRepr
This commit is contained in:
parent
c3eeb5e2cc
commit
f100e8753c
17 changed files with 218 additions and 223 deletions
|
|
@ -436,9 +436,7 @@ fn eq_tag_union_help<'a>(
|
|||
if is_non_recursive {
|
||||
compare_ptr_or_value
|
||||
} else {
|
||||
let union_layout = layout_interner.insert(Layout {
|
||||
repr: LayoutRepr::Union(union_layout),
|
||||
});
|
||||
let union_layout = layout_interner.insert_no_semantic(LayoutRepr::Union(union_layout));
|
||||
let loop_params_iter = operands.iter().map(|arg| Param {
|
||||
symbol: *arg,
|
||||
ownership: Ownership::Borrowed,
|
||||
|
|
@ -661,9 +659,7 @@ fn eq_list<'a>(
|
|||
let arena = root.arena;
|
||||
|
||||
// A "Box" layout (heap pointer to a single list element)
|
||||
let box_layout = layout_interner.insert(Layout {
|
||||
repr: LayoutRepr::Boxed(elem_layout),
|
||||
});
|
||||
let box_layout = layout_interner.insert_no_semantic(LayoutRepr::Boxed(elem_layout));
|
||||
|
||||
// Compare lengths
|
||||
|
||||
|
|
|
|||
|
|
@ -290,9 +290,7 @@ impl<'a> CodeGenHelp<'a> {
|
|||
LayoutRepr::RecursivePointer(_)
|
||||
) {
|
||||
let union_layout = ctx.recursive_union.unwrap();
|
||||
layout_interner.insert(Layout {
|
||||
repr: LayoutRepr::Union(union_layout),
|
||||
})
|
||||
layout_interner.insert_no_semantic(LayoutRepr::Union(union_layout))
|
||||
} else {
|
||||
called_layout
|
||||
};
|
||||
|
|
@ -303,9 +301,7 @@ 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(Layout {
|
||||
repr: LayoutRepr::Boxed(arg),
|
||||
});
|
||||
let box_arg = layout_interner.insert_no_semantic(LayoutRepr::Boxed(arg));
|
||||
|
||||
match ctx.op {
|
||||
Dec | DecRef(_) => (LAYOUT_UNIT, self.arena.alloc([arg])),
|
||||
|
|
@ -434,16 +430,12 @@ impl<'a> CodeGenHelp<'a> {
|
|||
}
|
||||
Dec | DecRef(_) | Reset | ResetRef => self.arena.alloc([roc_value]),
|
||||
IndirectInc => {
|
||||
let box_layout = layout_interner.insert(Layout {
|
||||
repr: LayoutRepr::Boxed(layout),
|
||||
});
|
||||
let box_layout = layout_interner.insert_no_semantic(LayoutRepr::Boxed(layout));
|
||||
let inc_amount = (self.layout_isize, ARG_2);
|
||||
self.arena.alloc([(box_layout, ARG_1), inc_amount])
|
||||
}
|
||||
IndirectDec => {
|
||||
let box_layout = layout_interner.insert(Layout {
|
||||
repr: LayoutRepr::Boxed(layout),
|
||||
});
|
||||
let box_layout = layout_interner.insert_no_semantic(LayoutRepr::Boxed(layout));
|
||||
self.arena.alloc([(box_layout, ARG_1)])
|
||||
}
|
||||
Eq => self.arena.alloc([roc_value, (layout, ARG_2)]),
|
||||
|
|
@ -491,9 +483,7 @@ impl<'a> CodeGenHelp<'a> {
|
|||
niche: Niche::NONE,
|
||||
},
|
||||
HelperOp::IndirectInc => {
|
||||
let box_layout = layout_interner.insert(Layout {
|
||||
repr: LayoutRepr::Boxed(layout),
|
||||
});
|
||||
let box_layout = layout_interner.insert_no_semantic(LayoutRepr::Boxed(layout));
|
||||
|
||||
ProcLayout {
|
||||
arguments: self.arena.alloc([box_layout, self.layout_isize]),
|
||||
|
|
@ -502,9 +492,7 @@ impl<'a> CodeGenHelp<'a> {
|
|||
}
|
||||
}
|
||||
HelperOp::IndirectDec => {
|
||||
let box_layout = layout_interner.insert(Layout {
|
||||
repr: LayoutRepr::Boxed(layout),
|
||||
});
|
||||
let box_layout = layout_interner.insert_no_semantic(LayoutRepr::Boxed(layout));
|
||||
|
||||
ProcLayout {
|
||||
arguments: self.arena.alloc([box_layout]),
|
||||
|
|
@ -597,7 +585,7 @@ impl<'a> CodeGenHelp<'a> {
|
|||
// This line is the whole point of the function
|
||||
LayoutRepr::RecursivePointer(_) => LayoutRepr::Union(ctx.recursive_union.unwrap()),
|
||||
};
|
||||
layout_interner.insert(Layout { repr })
|
||||
layout_interner.insert_no_semantic(repr)
|
||||
}
|
||||
|
||||
fn union_tail_recursion_fields(
|
||||
|
|
@ -681,22 +669,16 @@ impl<'a> CallerProc<'a> {
|
|||
};
|
||||
|
||||
let box_capture_layout = if let Some(capture_layout) = capture_layout {
|
||||
layout_interner.insert(Layout {
|
||||
repr: LayoutRepr::Boxed(capture_layout),
|
||||
})
|
||||
layout_interner.insert_no_semantic(LayoutRepr::Boxed(capture_layout))
|
||||
} else {
|
||||
layout_interner.insert(Layout {
|
||||
repr: LayoutRepr::Boxed(Layout::UNIT),
|
||||
})
|
||||
layout_interner.insert_no_semantic(LayoutRepr::Boxed(Layout::UNIT))
|
||||
};
|
||||
|
||||
let box_argument_layout = layout_interner.insert(Layout {
|
||||
repr: LayoutRepr::Boxed(passed_function.argument_layouts[0]),
|
||||
});
|
||||
let box_argument_layout = layout_interner
|
||||
.insert_no_semantic(LayoutRepr::Boxed(passed_function.argument_layouts[0]));
|
||||
|
||||
let box_return_layout = layout_interner.insert(Layout {
|
||||
repr: LayoutRepr::Boxed(passed_function.return_layout),
|
||||
});
|
||||
let box_return_layout =
|
||||
layout_interner.insert_no_semantic(LayoutRepr::Boxed(passed_function.return_layout));
|
||||
|
||||
let proc_layout = ProcLayout {
|
||||
arguments: arena.alloc([box_capture_layout, box_argument_layout, box_return_layout]),
|
||||
|
|
|
|||
|
|
@ -12,8 +12,8 @@ use crate::ir::{
|
|||
BranchInfo, Call, CallType, Expr, JoinPointId, Literal, ModifyRc, Param, Stmt, UpdateModeId,
|
||||
};
|
||||
use crate::layout::{
|
||||
Builtin, InLayout, Layout, LayoutInterner, LayoutRepr, STLayoutInterner, TagIdIntType,
|
||||
UnionLayout,
|
||||
Builtin, InLayout, Layout, LayoutInterner, LayoutRepr, STLayoutInterner, SemanticRepr,
|
||||
TagIdIntType, UnionLayout,
|
||||
};
|
||||
|
||||
use super::{CodeGenHelp, Context, HelperOp};
|
||||
|
|
@ -309,9 +309,7 @@ pub fn refcount_reset_proc_body<'a>(
|
|||
// Whenever we recurse into a child layout we will want to Decrement
|
||||
ctx.op = HelperOp::Dec;
|
||||
ctx.recursive_union = Some(union_layout);
|
||||
let recursion_ptr = layout_interner.insert(Layout {
|
||||
repr: LayoutRepr::RecursivePointer(layout),
|
||||
});
|
||||
let recursion_ptr = layout_interner.insert_no_semantic(LayoutRepr::RecursivePointer(layout));
|
||||
|
||||
// Reset structure is unique. Decrement its children and return a pointer to the allocation.
|
||||
let then_stmt = {
|
||||
|
|
@ -493,9 +491,7 @@ pub fn refcount_resetref_proc_body<'a>(
|
|||
// Whenever we recurse into a child layout we will want to Decrement
|
||||
ctx.op = HelperOp::Dec;
|
||||
ctx.recursive_union = Some(union_layout);
|
||||
let recursion_ptr = layout_interner.insert(Layout {
|
||||
repr: LayoutRepr::RecursivePointer(layout),
|
||||
});
|
||||
let recursion_ptr = layout_interner.insert_no_semantic(LayoutRepr::RecursivePointer(layout));
|
||||
|
||||
// Reset structure is unique. Return a pointer to the allocation.
|
||||
let then_stmt = Stmt::Ret(addr);
|
||||
|
|
@ -866,9 +862,7 @@ fn refcount_list<'a>(
|
|||
let arena = root.arena;
|
||||
|
||||
// A "Box" layout (heap pointer to a single list element)
|
||||
let box_layout = layout_interner.insert(Layout {
|
||||
repr: LayoutRepr::Boxed(elem_layout),
|
||||
});
|
||||
let box_layout = layout_interner.insert_no_semantic(LayoutRepr::Boxed(elem_layout));
|
||||
|
||||
//
|
||||
// Check if the list is empty
|
||||
|
|
@ -1489,8 +1483,10 @@ fn refcount_union_rec<'a>(
|
|||
};
|
||||
|
||||
let rc_structure_stmt = {
|
||||
// TODO(deref-layout)
|
||||
let alignment = Layout {
|
||||
repr: LayoutRepr::Union(union_layout),
|
||||
semantic: SemanticRepr::None,
|
||||
}
|
||||
.allocation_alignment_bytes(layout_interner, root.target_info);
|
||||
let ret_stmt = rc_return_stmt(root, ident_ids, ctx);
|
||||
|
|
@ -1548,9 +1544,7 @@ fn refcount_union_tailrec<'a>(
|
|||
let tailrec_loop = JoinPointId(root.create_symbol(ident_ids, "tailrec_loop"));
|
||||
let current = root.create_symbol(ident_ids, "current");
|
||||
let next_ptr = root.create_symbol(ident_ids, "next_ptr");
|
||||
let layout = layout_interner.insert(Layout {
|
||||
repr: LayoutRepr::Union(union_layout),
|
||||
});
|
||||
let layout = layout_interner.insert_no_semantic(LayoutRepr::Union(union_layout));
|
||||
|
||||
let tag_id_layout = union_layout.tag_id_layout();
|
||||
|
||||
|
|
@ -1695,9 +1689,7 @@ fn refcount_union_tailrec<'a>(
|
|||
let jump_with_null_ptr = Stmt::Let(
|
||||
null_pointer,
|
||||
Expr::NullPointer,
|
||||
layout_interner.insert(Layout {
|
||||
repr: LayoutRepr::Union(union_layout),
|
||||
}),
|
||||
layout_interner.insert_no_semantic(LayoutRepr::Union(union_layout)),
|
||||
root.arena.alloc(Stmt::Jump(
|
||||
jp_modify_union,
|
||||
root.arena.alloc([null_pointer]),
|
||||
|
|
@ -1741,9 +1733,7 @@ fn refcount_union_tailrec<'a>(
|
|||
));
|
||||
|
||||
let loop_init = Stmt::Jump(tailrec_loop, root.arena.alloc([initial_structure]));
|
||||
let union_layout = layout_interner.insert(Layout {
|
||||
repr: LayoutRepr::Union(union_layout),
|
||||
});
|
||||
let union_layout = layout_interner.insert_no_semantic(LayoutRepr::Union(union_layout));
|
||||
let loop_param = Param {
|
||||
symbol: current,
|
||||
ownership: Ownership::Borrowed,
|
||||
|
|
|
|||
|
|
@ -398,9 +398,9 @@ impl<'a, 'r> Ctx<'a, 'r> {
|
|||
tag_id,
|
||||
arguments,
|
||||
} => {
|
||||
let interned_layout = self.interner.insert(Layout {
|
||||
repr: LayoutRepr::Union(tag_layout),
|
||||
});
|
||||
let interned_layout = self
|
||||
.interner
|
||||
.insert_no_semantic(LayoutRepr::Union(tag_layout));
|
||||
self.check_tag_expr(interned_layout, tag_layout, tag_id, arguments);
|
||||
Some(interned_layout)
|
||||
}
|
||||
|
|
@ -438,9 +438,10 @@ impl<'a, 'r> Ctx<'a, 'r> {
|
|||
}
|
||||
}
|
||||
}
|
||||
Some(self.interner.insert(Layout {
|
||||
repr: LayoutRepr::Builtin(Builtin::List(*elem_layout)),
|
||||
}))
|
||||
Some(
|
||||
self.interner
|
||||
.insert_no_semantic(LayoutRepr::Builtin(Builtin::List(*elem_layout))),
|
||||
)
|
||||
}
|
||||
Expr::EmptyArray => {
|
||||
// TODO don't know what the element layout is
|
||||
|
|
@ -448,9 +449,7 @@ impl<'a, 'r> Ctx<'a, 'r> {
|
|||
}
|
||||
&Expr::ExprBox { symbol } => self.with_sym_layout(symbol, |ctx, _def_line, layout| {
|
||||
let inner = layout;
|
||||
Some(ctx.interner.insert(Layout {
|
||||
repr: LayoutRepr::Boxed(inner),
|
||||
}))
|
||||
Some(ctx.interner.insert_no_semantic(LayoutRepr::Boxed(inner)))
|
||||
}),
|
||||
&Expr::ExprUnbox { symbol } => self.with_sym_layout(symbol, |ctx, def_line, layout| {
|
||||
let layout = ctx.resolve(layout);
|
||||
|
|
@ -470,9 +469,9 @@ impl<'a, 'r> Ctx<'a, 'r> {
|
|||
tag_id: _,
|
||||
arguments: _,
|
||||
} => {
|
||||
let union = self.interner.insert(Layout {
|
||||
repr: LayoutRepr::Union(tag_layout),
|
||||
});
|
||||
let union = self
|
||||
.interner
|
||||
.insert_no_semantic(LayoutRepr::Union(tag_layout));
|
||||
self.check_sym_layout(symbol, union, UseKind::TagReuse);
|
||||
// TODO also check update arguments
|
||||
Some(union)
|
||||
|
|
@ -528,9 +527,9 @@ impl<'a, 'r> Ctx<'a, 'r> {
|
|||
tag_id: u16,
|
||||
index: u64,
|
||||
) -> Option<InLayout<'a>> {
|
||||
let union = self.interner.insert(Layout {
|
||||
repr: LayoutRepr::Union(union_layout),
|
||||
});
|
||||
let union = self
|
||||
.interner
|
||||
.insert_no_semantic(LayoutRepr::Union(union_layout));
|
||||
self.with_sym_layout(structure, |ctx, def_line, _layout| {
|
||||
ctx.check_sym_layout(structure, union, UseKind::TagExpr);
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use crate::ir::literal::{make_num_literal, IntOrFloatValue};
|
|||
use crate::layout::{
|
||||
self, Builtin, ClosureCallOptions, ClosureRepresentation, EnumDispatch, InLayout, LambdaName,
|
||||
LambdaSet, Layout, LayoutCache, LayoutInterner, LayoutProblem, LayoutRepr, Niche,
|
||||
RawFunctionLayout, TLLayoutInterner, TagIdIntType, UnionLayout, WrappedVariant,
|
||||
RawFunctionLayout, SemanticRepr, TLLayoutInterner, TagIdIntType, UnionLayout, WrappedVariant,
|
||||
};
|
||||
use bumpalo::collections::{CollectIn, Vec};
|
||||
use bumpalo::Bump;
|
||||
|
|
@ -4624,16 +4624,14 @@ pub fn with_hole<'a>(
|
|||
match opt_elem_layout {
|
||||
Ok(elem_layout) => {
|
||||
let expr = Expr::EmptyArray;
|
||||
let list_layout = layout_cache.put_in(Layout {
|
||||
repr: LayoutRepr::Builtin(Builtin::List(elem_layout)),
|
||||
});
|
||||
let list_layout = layout_cache
|
||||
.put_in_no_semantic(LayoutRepr::Builtin(Builtin::List(elem_layout)));
|
||||
Stmt::Let(assigned, expr, list_layout, hole)
|
||||
}
|
||||
Err(LayoutProblem::UnresolvedTypeVar(_)) => {
|
||||
let expr = Expr::EmptyArray;
|
||||
let list_layout = layout_cache.put_in(Layout {
|
||||
repr: LayoutRepr::Builtin(Builtin::List(Layout::VOID)),
|
||||
});
|
||||
let list_layout = layout_cache
|
||||
.put_in_no_semantic(LayoutRepr::Builtin(Builtin::List(Layout::VOID)));
|
||||
Stmt::Let(assigned, expr, list_layout, hole)
|
||||
}
|
||||
Err(LayoutProblem::Erroneous) => panic!("list element is error type"),
|
||||
|
|
@ -4679,9 +4677,8 @@ pub fn with_hole<'a>(
|
|||
elems: elements.into_bump_slice(),
|
||||
};
|
||||
|
||||
let list_layout = layout_cache.put_in(Layout {
|
||||
repr: LayoutRepr::Builtin(Builtin::List(elem_layout)),
|
||||
});
|
||||
let list_layout =
|
||||
layout_cache.put_in_no_semantic(LayoutRepr::Builtin(Builtin::List(elem_layout)));
|
||||
|
||||
let stmt = Stmt::Let(assigned, expr, list_layout, hole);
|
||||
|
||||
|
|
@ -6277,9 +6274,7 @@ fn convert_tag_union<'a>(
|
|||
}
|
||||
};
|
||||
|
||||
let union_layout = layout_cache.put_in(Layout {
|
||||
repr: LayoutRepr::Union(union_layout),
|
||||
});
|
||||
let union_layout = layout_cache.put_in_no_semantic(LayoutRepr::Union(union_layout));
|
||||
|
||||
let stmt = Stmt::Let(assigned, tag, union_layout, hole);
|
||||
let iter = field_symbols_temp
|
||||
|
|
@ -7818,9 +7813,7 @@ fn specialize_symbol<'a>(
|
|||
let layout = match raw {
|
||||
RawFunctionLayout::ZeroArgumentThunk(layout) => layout,
|
||||
RawFunctionLayout::Function(_, lambda_set, _) => layout_cache
|
||||
.put_in(Layout {
|
||||
repr: LayoutRepr::LambdaSet(lambda_set),
|
||||
}),
|
||||
.put_in_no_semantic(LayoutRepr::LambdaSet(lambda_set)),
|
||||
};
|
||||
|
||||
let raw = RawFunctionLayout::ZeroArgumentThunk(layout);
|
||||
|
|
@ -9829,6 +9822,7 @@ where
|
|||
let interned_unboxed_struct_layout = layout_interner.insert(*unboxed_struct_layout);
|
||||
let boxed_struct_layout = Layout {
|
||||
repr: LayoutRepr::Boxed(interned_unboxed_struct_layout),
|
||||
semantic: SemanticRepr::None,
|
||||
};
|
||||
let boxed_struct_layout = layout_interner.insert(boxed_struct_layout);
|
||||
let mut answer = bumpalo::collections::Vec::with_capacity_in(field_layouts.len(), arena);
|
||||
|
|
@ -9942,6 +9936,7 @@ where
|
|||
let interned = layout_interner.insert(*unboxed_struct_layout);
|
||||
let boxed_struct_layout = Layout {
|
||||
repr: LayoutRepr::Boxed(interned),
|
||||
semantic: SemanticRepr::None,
|
||||
};
|
||||
let boxed_struct_layout = layout_interner.insert(boxed_struct_layout);
|
||||
let mut answer = bumpalo::collections::Vec::with_capacity_in(field_layouts.len(), arena);
|
||||
|
|
|
|||
|
|
@ -1554,9 +1554,7 @@ fn store_tag_pattern<'a>(
|
|||
|
||||
if let LayoutRepr::RecursivePointer(_) = layout_cache.get_in(arg_layout).repr {
|
||||
// TODO(recursive-layouts): fix after disjoint rec ptrs
|
||||
arg_layout = layout_cache.put_in(Layout {
|
||||
repr: LayoutRepr::Union(union_layout),
|
||||
});
|
||||
arg_layout = layout_cache.put_in_no_semantic(LayoutRepr::Union(union_layout));
|
||||
}
|
||||
|
||||
let load = Expr::UnionAtIndex {
|
||||
|
|
|
|||
|
|
@ -27,25 +27,27 @@ use std::hash::{Hash, Hasher};
|
|||
use ven_pretty::{DocAllocator, DocBuilder};
|
||||
|
||||
mod intern;
|
||||
mod semantic;
|
||||
pub use intern::{
|
||||
GlobalLayoutInterner, InLayout, LayoutInterner, STLayoutInterner, TLLayoutInterner,
|
||||
};
|
||||
pub use semantic::SemanticRepr;
|
||||
|
||||
// if your changes cause this number to go down, great!
|
||||
// please change it to the lower number.
|
||||
// if it went up, maybe check that the change is really required
|
||||
roc_error_macros::assert_sizeof_aarch64!(Builtin, 2 * 8);
|
||||
roc_error_macros::assert_sizeof_aarch64!(Layout, 6 * 8);
|
||||
roc_error_macros::assert_sizeof_aarch64!(Layout, 8 * 8);
|
||||
roc_error_macros::assert_sizeof_aarch64!(UnionLayout, 3 * 8);
|
||||
roc_error_macros::assert_sizeof_aarch64!(LambdaSet, 5 * 8);
|
||||
|
||||
roc_error_macros::assert_sizeof_wasm!(Builtin, 2 * 4);
|
||||
roc_error_macros::assert_sizeof_wasm!(Layout, 6 * 4);
|
||||
roc_error_macros::assert_sizeof_wasm!(Layout, 8 * 4);
|
||||
roc_error_macros::assert_sizeof_wasm!(UnionLayout, 3 * 4);
|
||||
roc_error_macros::assert_sizeof_wasm!(LambdaSet, 5 * 4);
|
||||
|
||||
roc_error_macros::assert_sizeof_default!(Builtin, 2 * 8);
|
||||
roc_error_macros::assert_sizeof_default!(Layout, 6 * 8);
|
||||
roc_error_macros::assert_sizeof_default!(Layout, 8 * 8);
|
||||
roc_error_macros::assert_sizeof_default!(UnionLayout, 3 * 8);
|
||||
roc_error_macros::assert_sizeof_default!(LambdaSet, 5 * 8);
|
||||
|
||||
|
|
@ -330,6 +332,9 @@ impl<'a> LayoutCache<'a> {
|
|||
pub fn put_in(&mut self, layout: Layout<'a>) -> InLayout<'a> {
|
||||
self.interner.insert(layout)
|
||||
}
|
||||
pub fn put_in_no_semantic(&mut self, repr: LayoutRepr<'a>) -> InLayout<'a> {
|
||||
self.interner.insert_no_semantic(repr)
|
||||
}
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
pub fn statistics(&self) -> (CacheStatistics, CacheStatistics) {
|
||||
|
|
@ -684,6 +689,7 @@ impl FieldOrderHash {
|
|||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
pub struct Layout<'a> {
|
||||
pub repr: LayoutRepr<'a>,
|
||||
pub semantic: SemanticRepr<'a>,
|
||||
}
|
||||
|
||||
/// Types for code gen must be monomorphic. No type variables allowed!
|
||||
|
|
@ -912,9 +918,7 @@ impl<'a> UnionLayout<'a> {
|
|||
|
||||
// TODO(recursive-layouts): simplify after we have disjoint recursive pointers
|
||||
if let LayoutRepr::RecursivePointer(_) = interner.get(result).repr {
|
||||
interner.insert(Layout {
|
||||
repr: LayoutRepr::Union(self),
|
||||
})
|
||||
interner.insert_no_semantic(LayoutRepr::Union(self))
|
||||
} else {
|
||||
result
|
||||
}
|
||||
|
|
@ -2819,6 +2823,7 @@ impl<'a> Layout<'a> {
|
|||
}
|
||||
|
||||
/// Used to build a `Layout::Struct` where the field name order is irrelevant.
|
||||
// TODO: to be eliminated once we have SemanticRepr playing a role.
|
||||
pub fn struct_no_name_order(field_layouts: &'a [InLayout]) -> Self {
|
||||
if field_layouts.is_empty() {
|
||||
Self::UNIT_NAKED
|
||||
|
|
@ -2828,6 +2833,7 @@ impl<'a> Layout<'a> {
|
|||
field_layouts,
|
||||
field_order_hash: FieldOrderHash::IRRELEVANT_NON_ZERO_FIELD_HASH,
|
||||
},
|
||||
semantic: SemanticRepr::None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3170,6 +3176,7 @@ fn layout_from_flat_type<'a>(
|
|||
cached!(Layout::from_var(env, inner_var), criteria, env.subs);
|
||||
let boxed_layout = env.cache.put_in(Layout {
|
||||
repr: LayoutRepr::Boxed(inner_layout),
|
||||
semantic: SemanticRepr::None,
|
||||
});
|
||||
|
||||
Cacheable(Ok(boxed_layout), criteria)
|
||||
|
|
@ -3255,6 +3262,7 @@ fn layout_from_flat_type<'a>(
|
|||
field_order_hash,
|
||||
field_layouts: layouts.into_bump_slice(),
|
||||
},
|
||||
semantic: SemanticRepr::None,
|
||||
};
|
||||
|
||||
Ok(env.cache.put_in(struct_layout))
|
||||
|
|
@ -3304,6 +3312,7 @@ fn layout_from_flat_type<'a>(
|
|||
field_order_hash,
|
||||
field_layouts: layouts.into_bump_slice(),
|
||||
},
|
||||
semantic: SemanticRepr::None,
|
||||
};
|
||||
|
||||
Ok(env.cache.put_in(struct_layout))
|
||||
|
|
@ -4160,6 +4169,7 @@ where
|
|||
repr: LayoutRepr::Union(UnionLayout::NonRecursive(
|
||||
tag_layouts.into_bump_slice(),
|
||||
)),
|
||||
semantic: SemanticRepr::None,
|
||||
};
|
||||
env.cache.put_in(layout)
|
||||
}
|
||||
|
|
@ -4275,12 +4285,14 @@ where
|
|||
env.arena,
|
||||
Layout {
|
||||
repr: LayoutRepr::Union(union_layout),
|
||||
semantic: SemanticRepr::None,
|
||||
},
|
||||
)
|
||||
} else {
|
||||
// There are no naked recursion pointers, so we can insert the layout as-is.
|
||||
env.cache.interner.insert(Layout {
|
||||
repr: LayoutRepr::Union(union_layout),
|
||||
semantic: SemanticRepr::None,
|
||||
})
|
||||
};
|
||||
|
||||
|
|
@ -4416,6 +4428,7 @@ pub(crate) fn list_layout_from_elem<'a>(
|
|||
|
||||
let list_layout = env.cache.put_in(Layout {
|
||||
repr: LayoutRepr::Builtin(Builtin::List(element_layout)),
|
||||
semantic: SemanticRepr::None,
|
||||
});
|
||||
|
||||
Cacheable(Ok(list_layout), criteria)
|
||||
|
|
@ -4593,11 +4606,13 @@ mod test {
|
|||
let a = &[Layout::UNIT] as &[_];
|
||||
let b = &[interner.insert(Layout {
|
||||
repr: LayoutRepr::LambdaSet(lambda_set),
|
||||
semantic: SemanticRepr::None,
|
||||
})] as &[_];
|
||||
let tt = [a, b];
|
||||
|
||||
let layout = Layout {
|
||||
repr: LayoutRepr::Union(UnionLayout::NonRecursive(&tt)),
|
||||
semantic: SemanticRepr::None,
|
||||
};
|
||||
|
||||
let target_info = TargetInfo::default_x86_64();
|
||||
|
|
@ -4611,12 +4626,14 @@ mod test {
|
|||
|
||||
let ok_tag = &[interner.insert(Layout {
|
||||
repr: LayoutRepr::Builtin(Builtin::Int(IntWidth::U32)),
|
||||
semantic: SemanticRepr::None,
|
||||
})];
|
||||
let err_tag = &[Layout::UNIT];
|
||||
let tags = [ok_tag as &[_], err_tag as &[_]];
|
||||
let union_layout = UnionLayout::NonRecursive(&tags as &[_]);
|
||||
let layout = Layout {
|
||||
repr: LayoutRepr::Union(union_layout),
|
||||
semantic: SemanticRepr::None,
|
||||
};
|
||||
|
||||
let target_info = TargetInfo::default_x86_64();
|
||||
|
|
|
|||
|
|
@ -14,7 +14,10 @@ use roc_target::TargetInfo;
|
|||
|
||||
use crate::layout::LayoutRepr;
|
||||
|
||||
use super::{Builtin, FieldOrderHash, LambdaSet, Layout, SeenRecPtrs, UnionLayout};
|
||||
use super::{
|
||||
semantic::SemaRecord, Builtin, FieldOrderHash, LambdaSet, Layout, SeenRecPtrs, SemanticRepr,
|
||||
UnionLayout,
|
||||
};
|
||||
|
||||
macro_rules! cache_interned_layouts {
|
||||
($($i:literal, $name:ident, $vis:vis, $layout:expr)*; $total_constants:literal) => {
|
||||
|
|
@ -47,26 +50,35 @@ macro_rules! cache_interned_layouts {
|
|||
}
|
||||
}
|
||||
|
||||
macro_rules! nosema {
|
||||
($r:expr) => {
|
||||
Layout {
|
||||
repr: $r,
|
||||
semantic: SemanticRepr::None,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
cache_interned_layouts! {
|
||||
0, VOID, pub, Layout::VOID_NAKED
|
||||
1, UNIT, pub, Layout::UNIT_NAKED
|
||||
2, BOOL, pub, Layout{ repr: LayoutRepr::Builtin(Builtin::Bool) }
|
||||
3, U8, pub, Layout{ repr: LayoutRepr::Builtin(Builtin::Int(IntWidth::U8)) }
|
||||
4, U16, pub, Layout{ repr: LayoutRepr::Builtin(Builtin::Int(IntWidth::U16)) }
|
||||
5, U32, pub, Layout{ repr: LayoutRepr::Builtin(Builtin::Int(IntWidth::U32)) }
|
||||
6, U64, pub, Layout{ repr: LayoutRepr::Builtin(Builtin::Int(IntWidth::U64)) }
|
||||
7, U128, pub, Layout{ repr: LayoutRepr::Builtin(Builtin::Int(IntWidth::U128)) }
|
||||
8, I8, pub, Layout{ repr: LayoutRepr::Builtin(Builtin::Int(IntWidth::I8)) }
|
||||
9, I16, pub, Layout{ repr: LayoutRepr::Builtin(Builtin::Int(IntWidth::I16)) }
|
||||
10, I32, pub, Layout{ repr: LayoutRepr::Builtin(Builtin::Int(IntWidth::I32)) }
|
||||
11, I64, pub, Layout{ repr: LayoutRepr::Builtin(Builtin::Int(IntWidth::I64)) }
|
||||
12, I128, pub, Layout{ repr: LayoutRepr::Builtin(Builtin::Int(IntWidth::I128)) }
|
||||
13, F32, pub, Layout{ repr: LayoutRepr::Builtin(Builtin::Float(FloatWidth::F32)) }
|
||||
14, F64, pub, Layout{ repr: LayoutRepr::Builtin(Builtin::Float(FloatWidth::F64)) }
|
||||
15, DEC, pub, Layout{ repr: LayoutRepr::Builtin(Builtin::Decimal) }
|
||||
16, STR, pub, Layout{ repr: LayoutRepr::Builtin(Builtin::Str) }
|
||||
17, OPAQUE_PTR, pub, Layout{ repr: LayoutRepr::Boxed(Layout::VOID) }
|
||||
18, NAKED_RECURSIVE_PTR, pub(super), Layout{ repr: LayoutRepr::RecursivePointer(Layout::VOID) }
|
||||
2, BOOL, pub, nosema!(LayoutRepr::Builtin(Builtin::Bool))
|
||||
3, U8, pub, nosema!(LayoutRepr::Builtin(Builtin::Int(IntWidth::U8)))
|
||||
4, U16, pub, nosema!(LayoutRepr::Builtin(Builtin::Int(IntWidth::U16)))
|
||||
5, U32, pub, nosema!(LayoutRepr::Builtin(Builtin::Int(IntWidth::U32)))
|
||||
6, U64, pub, nosema!(LayoutRepr::Builtin(Builtin::Int(IntWidth::U64)))
|
||||
7, U128, pub, nosema!(LayoutRepr::Builtin(Builtin::Int(IntWidth::U128)))
|
||||
8, I8, pub, nosema!(LayoutRepr::Builtin(Builtin::Int(IntWidth::I8)))
|
||||
9, I16, pub, nosema!(LayoutRepr::Builtin(Builtin::Int(IntWidth::I16)))
|
||||
10, I32, pub, nosema!(LayoutRepr::Builtin(Builtin::Int(IntWidth::I32)))
|
||||
11, I64, pub, nosema!(LayoutRepr::Builtin(Builtin::Int(IntWidth::I64)))
|
||||
12, I128, pub, nosema!(LayoutRepr::Builtin(Builtin::Int(IntWidth::I128)))
|
||||
13, F32, pub, nosema!(LayoutRepr::Builtin(Builtin::Float(FloatWidth::F32)))
|
||||
14, F64, pub, nosema!(LayoutRepr::Builtin(Builtin::Float(FloatWidth::F64)))
|
||||
15, DEC, pub, nosema!(LayoutRepr::Builtin(Builtin::Decimal))
|
||||
16, STR, pub, nosema!(LayoutRepr::Builtin(Builtin::Str))
|
||||
17, OPAQUE_PTR, pub, nosema!(LayoutRepr::Boxed(Layout::VOID))
|
||||
18, NAKED_RECURSIVE_PTR, pub(super), nosema!(LayoutRepr::RecursivePointer(Layout::VOID))
|
||||
|
||||
; 19
|
||||
}
|
||||
|
|
@ -111,12 +123,14 @@ impl_to_from_int_width! {
|
|||
impl<'a> Layout<'a> {
|
||||
pub(super) const VOID_NAKED: Self = Layout {
|
||||
repr: LayoutRepr::Union(UnionLayout::NonRecursive(&[])),
|
||||
semantic: SemanticRepr::None,
|
||||
};
|
||||
pub(super) const UNIT_NAKED: Self = Layout {
|
||||
repr: LayoutRepr::Struct {
|
||||
field_layouts: &[],
|
||||
field_order_hash: FieldOrderHash::ZERO_FIELD_HASH,
|
||||
},
|
||||
semantic: SemanticRepr::Record(SemaRecord::new(&[])),
|
||||
};
|
||||
|
||||
pub const fn float_width(w: FloatWidth) -> InLayout<'static> {
|
||||
|
|
@ -144,6 +158,15 @@ pub trait LayoutInterner<'a>: Sized {
|
|||
// allocations when values already have interned representations.
|
||||
fn insert(&mut self, value: Layout<'a>) -> InLayout<'a>;
|
||||
|
||||
/// Interns a value with no semantic representation, returning its interned representation.
|
||||
/// If the value has been interned before, the old interned representation will be re-used.
|
||||
fn insert_no_semantic(&mut self, repr: LayoutRepr<'a>) -> InLayout<'a> {
|
||||
self.insert(Layout {
|
||||
repr,
|
||||
semantic: SemanticRepr::None,
|
||||
})
|
||||
}
|
||||
|
||||
/// Creates a [LambdaSet], including caching the [LayoutRepr::LambdaSet] representation of the
|
||||
/// lambda set onto itself.
|
||||
fn insert_lambda_set(
|
||||
|
|
@ -648,6 +671,7 @@ impl<'a> GlobalLayoutInterner<'a> {
|
|||
};
|
||||
let lambda_set_layout = Layout {
|
||||
repr: LayoutRepr::LambdaSet(full_lambda_set),
|
||||
semantic: SemanticRepr::None,
|
||||
};
|
||||
|
||||
vec[slot.0] = lambda_set_layout;
|
||||
|
|
@ -954,9 +978,13 @@ macro_rules! st_impl {
|
|||
representation,
|
||||
full_layout: slot,
|
||||
};
|
||||
self.vec[slot.0] = Layout { repr: LayoutRepr::LambdaSet(lambda_set) };
|
||||
let lay = Layout {
|
||||
repr: LayoutRepr::LambdaSet(lambda_set),
|
||||
semantic: SemanticRepr::None
|
||||
};
|
||||
self.vec[slot.0] = lay;
|
||||
|
||||
let _old = self.map.insert(Layout { repr: LayoutRepr::LambdaSet(lambda_set) }, slot);
|
||||
let _old = self.map.insert(lay, slot);
|
||||
debug_assert!(_old.is_none());
|
||||
|
||||
let _old = self.normalized_lambda_set_map
|
||||
|
|
@ -1012,7 +1040,7 @@ mod reify {
|
|||
use bumpalo::{collections::Vec, Bump};
|
||||
use roc_module::symbol::Symbol;
|
||||
|
||||
use crate::layout::{Builtin, LambdaSet, Layout, LayoutRepr, UnionLayout};
|
||||
use crate::layout::{Builtin, LambdaSet, Layout, LayoutRepr, SemanticRepr, UnionLayout};
|
||||
|
||||
use super::{InLayout, LayoutInterner, NeedsRecursionPointerFixup};
|
||||
|
||||
|
|
@ -1045,7 +1073,10 @@ mod reify {
|
|||
LayoutRepr::RecursivePointer(if l == Layout::VOID { slot } else { l })
|
||||
}
|
||||
};
|
||||
Layout { repr }
|
||||
Layout {
|
||||
repr,
|
||||
semantic: SemanticRepr::None,
|
||||
}
|
||||
}
|
||||
|
||||
fn reify_layout<'a>(
|
||||
|
|
@ -1481,7 +1512,7 @@ mod insert_lambda_set {
|
|||
use roc_module::symbol::Symbol;
|
||||
use roc_target::TargetInfo;
|
||||
|
||||
use crate::layout::{LambdaSet, Layout, LayoutRepr};
|
||||
use crate::layout::{LambdaSet, Layout, LayoutRepr, SemanticRepr};
|
||||
|
||||
use super::{GlobalLayoutInterner, InLayout, LayoutInterner, NeedsRecursionPointerFixup};
|
||||
|
||||
|
|
@ -1525,6 +1556,7 @@ mod insert_lambda_set {
|
|||
interner.insert_lambda_set(arena, TEST_ARGS, TEST_RET, TEST_SET, FIXUP, Layout::UNIT);
|
||||
let lambda_set_layout_in = interner.insert(Layout {
|
||||
repr: LayoutRepr::LambdaSet(lambda_set),
|
||||
semantic: SemanticRepr::None,
|
||||
});
|
||||
assert_eq!(lambda_set.full_layout, lambda_set_layout_in);
|
||||
}
|
||||
|
|
@ -1574,7 +1606,7 @@ mod insert_recursive_layout {
|
|||
use bumpalo::Bump;
|
||||
use roc_target::TargetInfo;
|
||||
|
||||
use crate::layout::{Builtin, InLayout, Layout, LayoutRepr, UnionLayout};
|
||||
use crate::layout::{Builtin, InLayout, Layout, LayoutRepr, SemanticRepr, UnionLayout};
|
||||
|
||||
use super::{GlobalLayoutInterner, LayoutInterner};
|
||||
|
||||
|
|
@ -1583,6 +1615,7 @@ mod insert_recursive_layout {
|
|||
fn make_layout<'a>(arena: &'a Bump, interner: &mut impl LayoutInterner<'a>) -> Layout<'a> {
|
||||
let list_rec = Layout {
|
||||
repr: LayoutRepr::Builtin(Builtin::List(Layout::NAKED_RECURSIVE_PTR)),
|
||||
semantic: SemanticRepr::None,
|
||||
};
|
||||
let repr = LayoutRepr::Union(UnionLayout::Recursive(&*arena.alloc([
|
||||
&*arena.alloc([interner.insert(list_rec)]),
|
||||
|
|
@ -1590,7 +1623,10 @@ mod insert_recursive_layout {
|
|||
&*arena.alloc([Layout::NAKED_RECURSIVE_PTR]),
|
||||
))]),
|
||||
])));
|
||||
Layout { repr }
|
||||
Layout {
|
||||
repr,
|
||||
semantic: SemanticRepr::None,
|
||||
}
|
||||
}
|
||||
|
||||
fn get_rec_ptr_index<'a>(interner: &impl LayoutInterner<'a>, layout: InLayout<'a>) -> usize {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue