mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-24 12:32:29 +00:00
Push layout interner further through Layout
This commit is contained in:
parent
ed04c2040a
commit
3b4b1838b8
34 changed files with 1279 additions and 634 deletions
|
@ -629,7 +629,7 @@ fn eq_list<'a>(
|
|||
// let size = literal int
|
||||
let size = root.create_symbol(ident_ids, "size");
|
||||
let size_expr = Expr::Literal(Literal::Int(
|
||||
(elem_layout.stack_size(root.target_info) as i128).to_ne_bytes(),
|
||||
(elem_layout.stack_size(root.layout_interner, root.target_info) as i128).to_ne_bytes(),
|
||||
));
|
||||
let size_stmt = |next| Stmt::Let(size, size_expr, layout_isize, next);
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ use crate::ir::{
|
|||
Call, CallSpecId, CallType, Expr, HostExposedLayouts, JoinPointId, ModifyRc, Proc, ProcLayout,
|
||||
SelfRecursive, Stmt, UpdateModeId,
|
||||
};
|
||||
use crate::layout::{Builtin, CapturesNiche, LambdaName, Layout, UnionLayout};
|
||||
use crate::layout::{Builtin, CapturesNiche, LambdaName, Layout, STLayoutInterner, UnionLayout};
|
||||
|
||||
mod equality;
|
||||
mod refcount;
|
||||
|
@ -73,6 +73,7 @@ pub struct Context<'a> {
|
|||
///
|
||||
pub struct CodeGenHelp<'a> {
|
||||
arena: &'a Bump,
|
||||
layout_interner: &'a STLayoutInterner<'a>,
|
||||
home: ModuleId,
|
||||
target_info: TargetInfo,
|
||||
layout_isize: Layout<'a>,
|
||||
|
@ -82,7 +83,12 @@ pub struct CodeGenHelp<'a> {
|
|||
}
|
||||
|
||||
impl<'a> CodeGenHelp<'a> {
|
||||
pub fn new(arena: &'a Bump, target_info: TargetInfo, home: ModuleId) -> Self {
|
||||
pub fn new(
|
||||
arena: &'a Bump,
|
||||
layout_interner: &'a STLayoutInterner<'a>,
|
||||
target_info: TargetInfo,
|
||||
home: ModuleId,
|
||||
) -> Self {
|
||||
let layout_isize = Layout::isize(target_info);
|
||||
|
||||
// Refcount is a boxed isize. TODO: use the new Box layout when dev backends support it
|
||||
|
@ -90,6 +96,7 @@ impl<'a> CodeGenHelp<'a> {
|
|||
|
||||
CodeGenHelp {
|
||||
arena,
|
||||
layout_interner,
|
||||
home,
|
||||
target_info,
|
||||
layout_isize,
|
||||
|
@ -122,7 +129,7 @@ impl<'a> CodeGenHelp<'a> {
|
|||
modify: &ModifyRc,
|
||||
following: &'a Stmt<'a>,
|
||||
) -> (&'a Stmt<'a>, Vec<'a, (Symbol, ProcLayout<'a>)>) {
|
||||
if !refcount::is_rc_implemented_yet(&layout) {
|
||||
if !refcount::is_rc_implemented_yet(self.layout_interner, &layout) {
|
||||
// Just a warning, so we can decouple backend development from refcounting development.
|
||||
// When we are closer to completion, we can change it to a panic.
|
||||
println!(
|
||||
|
@ -450,7 +457,7 @@ impl<'a> CodeGenHelp<'a> {
|
|||
}
|
||||
|
||||
Layout::LambdaSet(lambda_set) => {
|
||||
self.replace_rec_ptr(ctx, lambda_set.runtime_representation())
|
||||
self.replace_rec_ptr(ctx, lambda_set.runtime_representation(self.layout_interner))
|
||||
}
|
||||
|
||||
// This line is the whole point of the function
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use bumpalo::collections::vec::Vec;
|
||||
use roc_builtins::bitcode::IntWidth;
|
||||
use roc_intern::Interner;
|
||||
use roc_module::low_level::{LowLevel, LowLevel::*};
|
||||
use roc_module::symbol::{IdentIds, Symbol};
|
||||
use roc_target::PtrWidth;
|
||||
|
@ -102,7 +103,7 @@ pub fn refcount_generic<'a>(
|
|||
layout: Layout<'a>,
|
||||
structure: Symbol,
|
||||
) -> Stmt<'a> {
|
||||
debug_assert!(is_rc_implemented_yet(&layout));
|
||||
debug_assert!(is_rc_implemented_yet(root.layout_interner, &layout));
|
||||
|
||||
match layout {
|
||||
Layout::Builtin(Builtin::Int(_) | Builtin::Float(_) | Builtin::Bool | Builtin::Decimal) => {
|
||||
|
@ -121,7 +122,7 @@ pub fn refcount_generic<'a>(
|
|||
refcount_union(root, ident_ids, ctx, union_layout, structure)
|
||||
}
|
||||
Layout::LambdaSet(lambda_set) => {
|
||||
let runtime_layout = lambda_set.runtime_representation();
|
||||
let runtime_layout = lambda_set.runtime_representation(root.layout_interner);
|
||||
refcount_generic(root, ident_ids, ctx, runtime_layout, structure)
|
||||
}
|
||||
Layout::RecursivePointer => unreachable!(
|
||||
|
@ -205,7 +206,8 @@ pub fn refcount_reset_proc_body<'a>(
|
|||
let alloc_addr_stmt = {
|
||||
let alignment = root.create_symbol(ident_ids, "alignment");
|
||||
let alignment_expr = Expr::Literal(Literal::Int(
|
||||
(layout.alignment_bytes(root.target_info) as i128).to_ne_bytes(),
|
||||
(layout.alignment_bytes(root.layout_interner, root.target_info) as i128)
|
||||
.to_ne_bytes(),
|
||||
));
|
||||
let alloc_addr = root.create_symbol(ident_ids, "alloc_addr");
|
||||
let alloc_addr_expr = Expr::Call(Call {
|
||||
|
@ -351,30 +353,37 @@ pub fn refcount_reset_proc_body<'a>(
|
|||
// Check if refcounting is implemented yet. In the long term, this will be deleted.
|
||||
// In the short term, it helps us to skip refcounting and let it leak, so we can make
|
||||
// progress incrementally. Kept in sync with generate_procs using assertions.
|
||||
pub fn is_rc_implemented_yet(layout: &Layout) -> bool {
|
||||
pub fn is_rc_implemented_yet<'a, I>(interner: &I, layout: &Layout<'a>) -> bool
|
||||
where
|
||||
I: Interner<'a, Layout<'a>>,
|
||||
{
|
||||
use UnionLayout::*;
|
||||
|
||||
match layout {
|
||||
Layout::Builtin(Builtin::List(elem_layout)) => is_rc_implemented_yet(elem_layout),
|
||||
Layout::Builtin(Builtin::List(elem_layout)) => is_rc_implemented_yet(interner, elem_layout),
|
||||
Layout::Builtin(_) => true,
|
||||
Layout::Struct { field_layouts, .. } => field_layouts.iter().all(is_rc_implemented_yet),
|
||||
Layout::Struct { field_layouts, .. } => field_layouts
|
||||
.iter()
|
||||
.all(|l| is_rc_implemented_yet(interner, l)),
|
||||
Layout::Union(union_layout) => match union_layout {
|
||||
NonRecursive(tags) => tags
|
||||
.iter()
|
||||
.all(|fields| fields.iter().all(is_rc_implemented_yet)),
|
||||
.all(|fields| fields.iter().all(|l| is_rc_implemented_yet(interner, l))),
|
||||
Recursive(tags) => tags
|
||||
.iter()
|
||||
.all(|fields| fields.iter().all(is_rc_implemented_yet)),
|
||||
NonNullableUnwrapped(fields) => fields.iter().all(is_rc_implemented_yet),
|
||||
.all(|fields| fields.iter().all(|l| is_rc_implemented_yet(interner, l))),
|
||||
NonNullableUnwrapped(fields) => {
|
||||
fields.iter().all(|l| is_rc_implemented_yet(interner, l))
|
||||
}
|
||||
NullableWrapped { other_tags, .. } => other_tags
|
||||
.iter()
|
||||
.all(|fields| fields.iter().all(is_rc_implemented_yet)),
|
||||
NullableUnwrapped { other_fields, .. } => {
|
||||
other_fields.iter().all(is_rc_implemented_yet)
|
||||
}
|
||||
.all(|fields| fields.iter().all(|l| is_rc_implemented_yet(interner, l))),
|
||||
NullableUnwrapped { other_fields, .. } => other_fields
|
||||
.iter()
|
||||
.all(|l| is_rc_implemented_yet(interner, l)),
|
||||
},
|
||||
Layout::LambdaSet(lambda_set) => {
|
||||
is_rc_implemented_yet(&lambda_set.runtime_representation())
|
||||
is_rc_implemented_yet(interner, &lambda_set.runtime_representation(interner))
|
||||
}
|
||||
Layout::RecursivePointer => true,
|
||||
Layout::Boxed(_) => true,
|
||||
|
@ -734,7 +743,7 @@ fn refcount_list<'a>(
|
|||
//
|
||||
|
||||
let rc_ptr = root.create_symbol(ident_ids, "rc_ptr");
|
||||
let alignment = layout.alignment_bytes(root.target_info);
|
||||
let alignment = layout.alignment_bytes(root.layout_interner, root.target_info);
|
||||
|
||||
let ret_stmt = rc_return_stmt(root, ident_ids, ctx);
|
||||
let modify_list = modify_refcount(
|
||||
|
@ -832,7 +841,7 @@ fn refcount_list_elems<'a>(
|
|||
// let size = literal int
|
||||
let elem_size = root.create_symbol(ident_ids, "elem_size");
|
||||
let elem_size_expr = Expr::Literal(Literal::Int(
|
||||
(elem_layout.stack_size(root.target_info) as i128).to_ne_bytes(),
|
||||
(elem_layout.stack_size(root.layout_interner, root.target_info) as i128).to_ne_bytes(),
|
||||
));
|
||||
let elem_size_stmt = |next| Stmt::Let(elem_size, elem_size_expr, layout_isize, next);
|
||||
|
||||
|
@ -981,7 +990,7 @@ fn refcount_struct<'a>(
|
|||
let mut stmt = rc_return_stmt(root, ident_ids, ctx);
|
||||
|
||||
for (i, field_layout) in field_layouts.iter().enumerate().rev() {
|
||||
if field_layout.contains_refcounted() {
|
||||
if field_layout.contains_refcounted(root.layout_interner) {
|
||||
let field_val = root.create_symbol(ident_ids, &format!("field_val_{}", i));
|
||||
let field_val_expr = Expr::StructAtIndex {
|
||||
index: i as u64,
|
||||
|
@ -1221,7 +1230,8 @@ fn refcount_union_rec<'a>(
|
|||
let rc_structure_stmt = {
|
||||
let rc_ptr = root.create_symbol(ident_ids, "rc_ptr");
|
||||
|
||||
let alignment = Layout::Union(union_layout).alignment_bytes(root.target_info);
|
||||
let alignment =
|
||||
Layout::Union(union_layout).alignment_bytes(root.layout_interner, root.target_info);
|
||||
let ret_stmt = rc_return_stmt(root, ident_ids, ctx);
|
||||
let modify_structure_stmt = modify_refcount(
|
||||
root,
|
||||
|
@ -1329,7 +1339,7 @@ fn refcount_union_tailrec<'a>(
|
|||
)
|
||||
};
|
||||
|
||||
let alignment = layout.alignment_bytes(root.target_info);
|
||||
let alignment = layout.alignment_bytes(root.layout_interner, root.target_info);
|
||||
let modify_structure_stmt = modify_refcount(
|
||||
root,
|
||||
ident_ids,
|
||||
|
@ -1487,7 +1497,7 @@ fn refcount_tag_fields<'a>(
|
|||
let mut stmt = following;
|
||||
|
||||
for (i, field_layout) in field_layouts.iter().enumerate().rev() {
|
||||
if field_layout.contains_refcounted() {
|
||||
if field_layout.contains_refcounted(root.layout_interner) {
|
||||
let field_val = root.create_symbol(ident_ids, &format!("field_{}_{}", tag_id, i));
|
||||
let field_val_expr = Expr::UnionAtIndex {
|
||||
union_layout,
|
||||
|
@ -1534,7 +1544,7 @@ fn refcount_boxed<'a>(
|
|||
//
|
||||
|
||||
let rc_ptr = root.create_symbol(ident_ids, "rc_ptr");
|
||||
let alignment = layout.alignment_bytes(root.target_info);
|
||||
let alignment = layout.alignment_bytes(root.layout_interner, root.target_info);
|
||||
let ret_stmt = rc_return_stmt(root, ident_ids, ctx);
|
||||
let modify_outer = modify_refcount(
|
||||
root,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue