mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-03 00:24:34 +00:00
emit less MultiTagUnion
This commit is contained in:
parent
5734cce250
commit
cc93da006d
5 changed files with 31 additions and 18 deletions
|
@ -1036,8 +1036,8 @@ fn path_to_expr_help<'a>(
|
||||||
let mut it = instructions.iter().peekable();
|
let mut it = instructions.iter().peekable();
|
||||||
|
|
||||||
while let Some(PathInstruction { index, tag_id }) = it.next() {
|
while let Some(PathInstruction { index, tag_id }) = it.next() {
|
||||||
match Wrapped::opt_from_layout(&layout) {
|
match Wrapped::is_indexable(&layout) {
|
||||||
None => {
|
false => {
|
||||||
// this MUST be an index into a single-element (hence unwrapped) record
|
// this MUST be an index into a single-element (hence unwrapped) record
|
||||||
|
|
||||||
debug_assert_eq!(*index, 0, "{:?}", &layout);
|
debug_assert_eq!(*index, 0, "{:?}", &layout);
|
||||||
|
@ -1063,7 +1063,7 @@ fn path_to_expr_help<'a>(
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Some(wrapped) => {
|
true => {
|
||||||
let index = *index;
|
let index = *index;
|
||||||
|
|
||||||
let (inner_layout, inner_expr) = match layout {
|
let (inner_layout, inner_expr) = match layout {
|
||||||
|
@ -1078,6 +1078,7 @@ fn path_to_expr_help<'a>(
|
||||||
(union_layout.layout_at(*tag_id as u8, index as usize), expr)
|
(union_layout.layout_at(*tag_id as u8, index as usize), expr)
|
||||||
}
|
}
|
||||||
Layout::Struct(field_layouts) => {
|
Layout::Struct(field_layouts) => {
|
||||||
|
let wrapped = Wrapped::opt_from_layout(&layout).unwrap();
|
||||||
debug_assert!(field_layouts.len() > 1);
|
debug_assert!(field_layouts.len() > 1);
|
||||||
debug_assert_eq!(wrapped, Wrapped::RecordOrSingleTagUnion);
|
debug_assert_eq!(wrapped, Wrapped::RecordOrSingleTagUnion);
|
||||||
|
|
||||||
|
|
|
@ -1032,6 +1032,17 @@ impl Wrapped {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_indexable(layout: &Layout<'_>) -> bool {
|
||||||
|
match layout {
|
||||||
|
Layout::Struct(fields) => match fields.len() {
|
||||||
|
_ => true,
|
||||||
|
},
|
||||||
|
|
||||||
|
Layout::Union(variant) => true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn opt_from_layout(layout: &Layout<'_>) -> Option<Self> {
|
pub fn opt_from_layout(layout: &Layout<'_>) -> Option<Self> {
|
||||||
match layout {
|
match layout {
|
||||||
Layout::Struct(fields) => match fields.len() {
|
Layout::Struct(fields) => match fields.len() {
|
||||||
|
@ -1056,6 +1067,7 @@ impl Wrapped {
|
||||||
NonNullableUnwrapped(_) => Some(Wrapped::LikeARoseTree),
|
NonNullableUnwrapped(_) => Some(Wrapped::LikeARoseTree),
|
||||||
|
|
||||||
NullableWrapped { .. } | NullableUnwrapped { .. } => {
|
NullableWrapped { .. } | NullableUnwrapped { .. } => {
|
||||||
|
todo!();
|
||||||
Some(Wrapped::MultiTagUnion)
|
Some(Wrapped::MultiTagUnion)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2133,6 +2145,8 @@ fn specialize_external<'a>(
|
||||||
match closure_layout.layout_for_member(proc_name) {
|
match closure_layout.layout_for_member(proc_name) {
|
||||||
ClosureRepresentation::Union {
|
ClosureRepresentation::Union {
|
||||||
tag_layout: field_layouts,
|
tag_layout: field_layouts,
|
||||||
|
union_layout,
|
||||||
|
tag_id,
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
debug_assert_eq!(field_layouts.len() - 1, captured.len());
|
debug_assert_eq!(field_layouts.len() - 1, captured.len());
|
||||||
|
@ -2143,11 +2157,11 @@ fn specialize_external<'a>(
|
||||||
index += 1;
|
index += 1;
|
||||||
|
|
||||||
// TODO therefore should the wrapped here not be RecordOrSingleTagUnion?
|
// TODO therefore should the wrapped here not be RecordOrSingleTagUnion?
|
||||||
let expr = Expr::AccessAtIndex {
|
let expr = Expr::CoerceToTagId {
|
||||||
index: index as _,
|
tag_id,
|
||||||
field_layouts,
|
|
||||||
structure: Symbol::ARG_CLOSURE,
|
structure: Symbol::ARG_CLOSURE,
|
||||||
wrapped,
|
index: index as _,
|
||||||
|
union_layout,
|
||||||
};
|
};
|
||||||
|
|
||||||
let layout = field_layouts[index];
|
let layout = field_layouts[index];
|
||||||
|
@ -4074,21 +4088,17 @@ fn construct_closure_data<'a>(
|
||||||
tag_layout: _,
|
tag_layout: _,
|
||||||
union_size,
|
union_size,
|
||||||
tag_name,
|
tag_name,
|
||||||
|
union_layout,
|
||||||
} => {
|
} => {
|
||||||
let tag_id_symbol = env.unique_symbol();
|
let tag_id_symbol = env.unique_symbol();
|
||||||
let mut tag_symbols = Vec::with_capacity_in(symbols.len() + 1, env.arena);
|
let mut tag_symbols = Vec::with_capacity_in(symbols.len() + 1, env.arena);
|
||||||
tag_symbols.push(tag_id_symbol);
|
tag_symbols.push(tag_id_symbol);
|
||||||
tag_symbols.extend(symbols);
|
tag_symbols.extend(symbols);
|
||||||
|
|
||||||
let tag_layout = match lambda_set.runtime_representation() {
|
|
||||||
Layout::Union(inner) => inner,
|
|
||||||
_ => unreachable!(),
|
|
||||||
};
|
|
||||||
|
|
||||||
let expr1 = Expr::Literal(Literal::Int(tag_id as i128));
|
let expr1 = Expr::Literal(Literal::Int(tag_id as i128));
|
||||||
let expr2 = Expr::Tag {
|
let expr2 = Expr::Tag {
|
||||||
tag_id,
|
tag_id,
|
||||||
tag_layout,
|
tag_layout: union_layout,
|
||||||
union_size,
|
union_size,
|
||||||
tag_name,
|
tag_name,
|
||||||
arguments: tag_symbols.into_bump_slice(),
|
arguments: tag_symbols.into_bump_slice(),
|
||||||
|
|
|
@ -200,6 +200,7 @@ pub enum ClosureRepresentation<'a> {
|
||||||
tag_name: TagName,
|
tag_name: TagName,
|
||||||
tag_id: u8,
|
tag_id: u8,
|
||||||
union_size: u8,
|
union_size: u8,
|
||||||
|
union_layout: UnionLayout<'a>,
|
||||||
},
|
},
|
||||||
/// the representation is anything but a union
|
/// the representation is anything but a union
|
||||||
Other(Layout<'a>),
|
Other(Layout<'a>),
|
||||||
|
@ -241,6 +242,7 @@ impl<'a> LambdaSet<'a> {
|
||||||
tag_id: index as u8,
|
tag_id: index as u8,
|
||||||
tag_layout: tags[index],
|
tag_layout: tags[index],
|
||||||
tag_name: TagName::Closure(function_symbol),
|
tag_name: TagName::Closure(function_symbol),
|
||||||
|
union_layout: *union,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
UnionLayout::Recursive(_) => todo!("recursive closures"),
|
UnionLayout::Recursive(_) => todo!("recursive closures"),
|
||||||
|
|
|
@ -22,13 +22,13 @@ procedure Test.1 (Test.2, Test.3):
|
||||||
|
|
||||||
|
|
||||||
procedure Test.7 (Test.10, #Attr.12):
|
procedure Test.7 (Test.10, #Attr.12):
|
||||||
let Test.4 = Index 1 #Attr.12;
|
let Test.4 = CoerceToTagId (Id 0) (Index 1) #Attr.12;
|
||||||
let Test.29 = CallByName Num.24 Test.10 Test.4;
|
let Test.29 = CallByName Num.24 Test.10 Test.4;
|
||||||
ret Test.29;
|
ret Test.29;
|
||||||
|
|
||||||
procedure Test.8 (Test.11, #Attr.12):
|
procedure Test.8 (Test.11, #Attr.12):
|
||||||
let Test.6 = Index 2 #Attr.12;
|
let Test.6 = CoerceToTagId (Id 1) (Index 2) #Attr.12;
|
||||||
let Test.5 = Index 1 #Attr.12;
|
let Test.5 = CoerceToTagId (Id 1) (Index 1) #Attr.12;
|
||||||
if Test.6 then
|
if Test.6 then
|
||||||
let Test.24 = CallByName Num.26 Test.11 Test.5;
|
let Test.24 = CallByName Num.26 Test.11 Test.5;
|
||||||
ret Test.24;
|
ret Test.24;
|
||||||
|
|
|
@ -7,12 +7,12 @@ procedure Num.26 (#Attr.2, #Attr.3):
|
||||||
ret Test.21;
|
ret Test.21;
|
||||||
|
|
||||||
procedure Test.6 (Test.8, #Attr.12):
|
procedure Test.6 (Test.8, #Attr.12):
|
||||||
let Test.4 = Index 1 #Attr.12;
|
let Test.4 = CoerceToTagId (Id 0) (Index 1) #Attr.12;
|
||||||
let Test.25 = CallByName Num.24 Test.8 Test.4;
|
let Test.25 = CallByName Num.24 Test.8 Test.4;
|
||||||
ret Test.25;
|
ret Test.25;
|
||||||
|
|
||||||
procedure Test.7 (Test.9, #Attr.12):
|
procedure Test.7 (Test.9, #Attr.12):
|
||||||
let Test.5 = Index 1 #Attr.12;
|
let Test.5 = CoerceToTagId (Id 1) (Index 1) #Attr.12;
|
||||||
let Test.20 = CallByName Num.26 Test.9 Test.5;
|
let Test.20 = CallByName Num.26 Test.9 Test.5;
|
||||||
ret Test.20;
|
ret Test.20;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue