mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-27 05:49:08 +00:00
Push interned layouts as mut throughout the backend, and intern box layouts
This commit is contained in:
parent
dd6a72fc46
commit
7ab7fdfa7b
26 changed files with 769 additions and 375 deletions
|
@ -1,11 +1,12 @@
|
|||
use bumpalo::collections::vec::Vec;
|
||||
use roc_intern::Interner;
|
||||
use roc_module::low_level::LowLevel;
|
||||
use roc_module::symbol::{IdentIds, Symbol};
|
||||
|
||||
use crate::ir::{
|
||||
BranchInfo, Call, CallType, Expr, JoinPointId, Literal, Param, Stmt, UpdateModeId,
|
||||
};
|
||||
use crate::layout::{Builtin, Layout, TagIdIntType, UnionLayout};
|
||||
use crate::layout::{Builtin, InLayout, Layout, STLayoutInterner, TagIdIntType, UnionLayout};
|
||||
|
||||
use super::{let_lowlevel, CodeGenHelp, Context, LAYOUT_BOOL};
|
||||
|
||||
|
@ -16,6 +17,7 @@ pub fn eq_generic<'a>(
|
|||
root: &mut CodeGenHelp<'a>,
|
||||
ident_ids: &mut IdentIds,
|
||||
ctx: &mut Context<'a>,
|
||||
layout_interner: &mut STLayoutInterner<'a>,
|
||||
layout: Layout<'a>,
|
||||
) -> Stmt<'a> {
|
||||
let main_body = match layout {
|
||||
|
@ -28,10 +30,18 @@ pub fn eq_generic<'a>(
|
|||
Layout::Builtin(Builtin::Str) => {
|
||||
unreachable!("No generated helper proc for `==` on Str. Use Zig function.")
|
||||
}
|
||||
Layout::Builtin(Builtin::List(elem_layout)) => eq_list(root, ident_ids, ctx, elem_layout),
|
||||
Layout::Struct { field_layouts, .. } => eq_struct(root, ident_ids, ctx, field_layouts),
|
||||
Layout::Union(union_layout) => eq_tag_union(root, ident_ids, ctx, union_layout),
|
||||
Layout::Boxed(inner_layout) => eq_boxed(root, ident_ids, ctx, inner_layout),
|
||||
Layout::Builtin(Builtin::List(elem_layout)) => {
|
||||
eq_list(root, ident_ids, ctx, layout_interner, elem_layout)
|
||||
}
|
||||
Layout::Struct { field_layouts, .. } => {
|
||||
eq_struct(root, ident_ids, ctx, layout_interner, field_layouts)
|
||||
}
|
||||
Layout::Union(union_layout) => {
|
||||
eq_tag_union(root, ident_ids, ctx, layout_interner, union_layout)
|
||||
}
|
||||
Layout::Boxed(inner_layout) => {
|
||||
eq_boxed(root, ident_ids, ctx, layout_interner, inner_layout)
|
||||
}
|
||||
Layout::LambdaSet(_) => unreachable!("`==` is not defined on functions"),
|
||||
Layout::RecursivePointer => {
|
||||
unreachable!(
|
||||
|
@ -129,6 +139,7 @@ fn eq_struct<'a>(
|
|||
root: &mut CodeGenHelp<'a>,
|
||||
ident_ids: &mut IdentIds,
|
||||
ctx: &mut Context<'a>,
|
||||
layout_interner: &mut STLayoutInterner<'a>,
|
||||
field_layouts: &'a [Layout<'a>],
|
||||
) -> Stmt<'a> {
|
||||
let mut else_stmt = Stmt::Ret(Symbol::BOOL_TRUE);
|
||||
|
@ -153,6 +164,7 @@ fn eq_struct<'a>(
|
|||
.call_specialized_op(
|
||||
ident_ids,
|
||||
ctx,
|
||||
layout_interner,
|
||||
*layout,
|
||||
root.arena.alloc([field1_sym, field2_sym]),
|
||||
)
|
||||
|
@ -181,6 +193,7 @@ fn eq_tag_union<'a>(
|
|||
root: &mut CodeGenHelp<'a>,
|
||||
ident_ids: &mut IdentIds,
|
||||
ctx: &mut Context<'a>,
|
||||
layout_interner: &mut STLayoutInterner<'a>,
|
||||
union_layout: UnionLayout<'a>,
|
||||
) -> Stmt<'a> {
|
||||
use UnionLayout::*;
|
||||
|
@ -191,13 +204,37 @@ fn eq_tag_union<'a>(
|
|||
}
|
||||
|
||||
let body = match union_layout {
|
||||
NonRecursive(tags) => eq_tag_union_help(root, ident_ids, ctx, union_layout, tags, None),
|
||||
NonRecursive(tags) => eq_tag_union_help(
|
||||
root,
|
||||
ident_ids,
|
||||
ctx,
|
||||
layout_interner,
|
||||
union_layout,
|
||||
tags,
|
||||
None,
|
||||
),
|
||||
|
||||
Recursive(tags) => eq_tag_union_help(root, ident_ids, ctx, union_layout, tags, None),
|
||||
Recursive(tags) => eq_tag_union_help(
|
||||
root,
|
||||
ident_ids,
|
||||
ctx,
|
||||
layout_interner,
|
||||
union_layout,
|
||||
tags,
|
||||
None,
|
||||
),
|
||||
|
||||
NonNullableUnwrapped(field_layouts) => {
|
||||
let tags = root.arena.alloc([field_layouts]);
|
||||
eq_tag_union_help(root, ident_ids, ctx, union_layout, tags, None)
|
||||
eq_tag_union_help(
|
||||
root,
|
||||
ident_ids,
|
||||
ctx,
|
||||
layout_interner,
|
||||
union_layout,
|
||||
tags,
|
||||
None,
|
||||
)
|
||||
}
|
||||
|
||||
NullableWrapped {
|
||||
|
@ -207,6 +244,7 @@ fn eq_tag_union<'a>(
|
|||
root,
|
||||
ident_ids,
|
||||
ctx,
|
||||
layout_interner,
|
||||
union_layout,
|
||||
other_tags,
|
||||
Some(nullable_id),
|
||||
|
@ -219,6 +257,7 @@ fn eq_tag_union<'a>(
|
|||
root,
|
||||
ident_ids,
|
||||
ctx,
|
||||
layout_interner,
|
||||
union_layout,
|
||||
root.arena.alloc([other_fields]),
|
||||
Some(nullable_id as TagIdIntType),
|
||||
|
@ -234,6 +273,7 @@ fn eq_tag_union_help<'a>(
|
|||
root: &mut CodeGenHelp<'a>,
|
||||
ident_ids: &mut IdentIds,
|
||||
ctx: &mut Context<'a>,
|
||||
layout_interner: &mut STLayoutInterner<'a>,
|
||||
union_layout: UnionLayout<'a>,
|
||||
tag_layouts: &'a [&'a [Layout<'a>]],
|
||||
nullable_id: Option<TagIdIntType>,
|
||||
|
@ -314,6 +354,7 @@ fn eq_tag_union_help<'a>(
|
|||
root,
|
||||
ident_ids,
|
||||
ctx,
|
||||
layout_interner,
|
||||
tailrec_loop,
|
||||
union_layout,
|
||||
field_layouts,
|
||||
|
@ -335,6 +376,7 @@ fn eq_tag_union_help<'a>(
|
|||
root,
|
||||
ident_ids,
|
||||
ctx,
|
||||
layout_interner,
|
||||
tailrec_loop,
|
||||
union_layout,
|
||||
tag_layouts.last().unwrap(),
|
||||
|
@ -395,6 +437,7 @@ fn eq_tag_fields<'a>(
|
|||
root: &mut CodeGenHelp<'a>,
|
||||
ident_ids: &mut IdentIds,
|
||||
ctx: &mut Context<'a>,
|
||||
layout_interner: &mut STLayoutInterner<'a>,
|
||||
tailrec_loop: JoinPointId,
|
||||
union_layout: UnionLayout<'a>,
|
||||
field_layouts: &'a [Layout<'a>],
|
||||
|
@ -482,6 +525,7 @@ fn eq_tag_fields<'a>(
|
|||
.call_specialized_op(
|
||||
ident_ids,
|
||||
ctx,
|
||||
layout_interner,
|
||||
*layout,
|
||||
root.arena.alloc([field1_sym, field2_sym]),
|
||||
)
|
||||
|
@ -530,8 +574,11 @@ fn eq_boxed<'a>(
|
|||
root: &mut CodeGenHelp<'a>,
|
||||
ident_ids: &mut IdentIds,
|
||||
ctx: &mut Context<'a>,
|
||||
inner_layout: &'a Layout<'a>,
|
||||
layout_interner: &mut STLayoutInterner<'a>,
|
||||
inner_layout: InLayout<'a>,
|
||||
) -> Stmt<'a> {
|
||||
let inner_layout = layout_interner.get(inner_layout);
|
||||
|
||||
let a = root.create_symbol(ident_ids, "a");
|
||||
let b = root.create_symbol(ident_ids, "b");
|
||||
let result = root.create_symbol(ident_ids, "result");
|
||||
|
@ -539,7 +586,13 @@ fn eq_boxed<'a>(
|
|||
let a_expr = Expr::ExprUnbox { symbol: ARG_1 };
|
||||
let b_expr = Expr::ExprUnbox { symbol: ARG_2 };
|
||||
let eq_call_expr = root
|
||||
.call_specialized_op(ident_ids, ctx, *inner_layout, root.arena.alloc([a, b]))
|
||||
.call_specialized_op(
|
||||
ident_ids,
|
||||
ctx,
|
||||
layout_interner,
|
||||
*inner_layout,
|
||||
root.arena.alloc([a, b]),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
Stmt::Let(
|
||||
|
@ -576,6 +629,7 @@ fn eq_list<'a>(
|
|||
root: &mut CodeGenHelp<'a>,
|
||||
ident_ids: &mut IdentIds,
|
||||
ctx: &mut Context<'a>,
|
||||
layout_interner: &mut STLayoutInterner<'a>,
|
||||
elem_layout: &Layout<'a>,
|
||||
) -> Stmt<'a> {
|
||||
use LowLevel::*;
|
||||
|
@ -629,7 +683,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.layout_interner, root.target_info) as i128).to_ne_bytes(),
|
||||
(elem_layout.stack_size(layout_interner, root.target_info) as i128).to_ne_bytes(),
|
||||
));
|
||||
let size_stmt = |next| Stmt::Let(size, size_expr, layout_isize, next);
|
||||
|
||||
|
@ -703,7 +757,7 @@ fn eq_list<'a>(
|
|||
let eq_elems = root.create_symbol(ident_ids, "eq_elems");
|
||||
let eq_elems_args = root.arena.alloc([elem1, elem2]);
|
||||
let eq_elems_expr = root
|
||||
.call_specialized_op(ident_ids, ctx, *elem_layout, eq_elems_args)
|
||||
.call_specialized_op(ident_ids, ctx, layout_interner, *elem_layout, eq_elems_args)
|
||||
.unwrap();
|
||||
|
||||
let eq_elems_stmt = |next| Stmt::Let(eq_elems, eq_elems_expr, LAYOUT_BOOL, next);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue