mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-28 06:14:46 +00:00
saved info and added test
This commit is contained in:
parent
9b58c0fb9c
commit
b0705a00ad
8 changed files with 106 additions and 27 deletions
|
@ -18,8 +18,8 @@ use roc_module::symbol::{IdentIds, ModuleId, Symbol};
|
||||||
use roc_target::TargetInfo;
|
use roc_target::TargetInfo;
|
||||||
|
|
||||||
use crate::ir::{
|
use crate::ir::{
|
||||||
BranchInfo, Call, CallType, Expr, JoinPointId, Literal, ModifyRc, Proc, ProcLayout, Stmt,
|
BranchInfo, Call, CallType, Expr, JoinPointId, ListLiteralElement, Literal, ModifyRc, Proc,
|
||||||
UpdateModeId,
|
ProcLayout, Stmt, UpdateModeId,
|
||||||
};
|
};
|
||||||
use crate::layout::{
|
use crate::layout::{
|
||||||
Builtin, InLayout, Layout, LayoutInterner, LayoutRepr, STLayoutInterner, UnionLayout,
|
Builtin, InLayout, Layout, LayoutInterner, LayoutRepr, STLayoutInterner, UnionLayout,
|
||||||
|
@ -104,7 +104,7 @@ fn specialize_drops_stmt<'a, 'i>(
|
||||||
_ => unreachable!("List get should have two arguments"),
|
_ => unreachable!("List get should have two arguments"),
|
||||||
};
|
};
|
||||||
|
|
||||||
environment.add_list_child(*structure, *binding, index);
|
environment.add_list_child_symbol(*structure, *binding, index);
|
||||||
|
|
||||||
alloc_let_with_continuation!(environment)
|
alloc_let_with_continuation!(environment)
|
||||||
}
|
}
|
||||||
|
@ -125,9 +125,46 @@ fn specialize_drops_stmt<'a, 'i>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Expr::Tag { tag_id, .. } => {
|
Expr::Tag {
|
||||||
|
tag_id,
|
||||||
|
arguments: children,
|
||||||
|
..
|
||||||
|
} => {
|
||||||
environment.symbol_tag.insert(*binding, *tag_id);
|
environment.symbol_tag.insert(*binding, *tag_id);
|
||||||
|
|
||||||
|
for (index, child) in children.iter().enumerate() {
|
||||||
|
environment.add_union_child(*binding, *child, *tag_id, index as u64);
|
||||||
|
}
|
||||||
|
|
||||||
|
alloc_let_with_continuation!(environment)
|
||||||
|
}
|
||||||
|
Expr::Struct(children) => {
|
||||||
|
for (index, child) in children.iter().enumerate() {
|
||||||
|
environment.add_struct_child(*binding, *child, index as u64);
|
||||||
|
}
|
||||||
|
|
||||||
|
alloc_let_with_continuation!(environment)
|
||||||
|
}
|
||||||
|
Expr::ExprBox { symbol: child } => {
|
||||||
|
environment.add_box_child(*binding, *child);
|
||||||
|
|
||||||
|
alloc_let_with_continuation!(environment)
|
||||||
|
}
|
||||||
|
Expr::Array {
|
||||||
|
elems: children, ..
|
||||||
|
} => {
|
||||||
|
for (index, child) in
|
||||||
|
children
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.filter_map(|(index, child)| match child {
|
||||||
|
ListLiteralElement::Literal(_) => None,
|
||||||
|
ListLiteralElement::Symbol(s) => Some((index, s)),
|
||||||
|
})
|
||||||
|
{
|
||||||
|
environment.add_list_child(*binding, *child, index as u64);
|
||||||
|
}
|
||||||
|
|
||||||
alloc_let_with_continuation!(environment)
|
alloc_let_with_continuation!(environment)
|
||||||
}
|
}
|
||||||
Expr::StructAtIndex {
|
Expr::StructAtIndex {
|
||||||
|
@ -179,13 +216,10 @@ fn specialize_drops_stmt<'a, 'i>(
|
||||||
}
|
}
|
||||||
alloc_let_with_continuation!(environment)
|
alloc_let_with_continuation!(environment)
|
||||||
}
|
}
|
||||||
Expr::Struct(_)
|
Expr::RuntimeErrorFunction(_)
|
||||||
| Expr::RuntimeErrorFunction(_)
|
|
||||||
| Expr::ExprBox { .. }
|
|
||||||
| Expr::NullPointer
|
| Expr::NullPointer
|
||||||
| Expr::GetTagId { .. }
|
| Expr::GetTagId { .. }
|
||||||
| Expr::EmptyArray
|
| Expr::EmptyArray => {
|
||||||
| Expr::Array { .. } => {
|
|
||||||
// Does nothing relevant to drop specialization. So we can just continue.
|
// Does nothing relevant to drop specialization. So we can just continue.
|
||||||
alloc_let_with_continuation!(environment)
|
alloc_let_with_continuation!(environment)
|
||||||
}
|
}
|
||||||
|
@ -1222,12 +1256,16 @@ impl<'a> DropSpecializationEnvironment<'a> {
|
||||||
.push(child);
|
.push(child);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_list_child(&mut self, parent: Parent, child: Child, index: &Symbol) {
|
fn add_list_child(&mut self, parent: Parent, child: Child, index: u64) {
|
||||||
|
self.list_children
|
||||||
|
.entry(parent)
|
||||||
|
.or_insert_with(|| Vec::new_in(self.arena))
|
||||||
|
.push((child, index));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add_list_child_symbol(&mut self, parent: Parent, child: Child, index: &Symbol) {
|
||||||
if let Some(index) = self.symbol_index.get(index) {
|
if let Some(index) = self.symbol_index.get(index) {
|
||||||
self.list_children
|
self.add_list_child(parent, child, *index)
|
||||||
.entry(parent)
|
|
||||||
.or_insert_with(|| Vec::new_in(self.arena))
|
|
||||||
.push((child, *index));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
procedure Test.0 ():
|
||||||
|
let Test.2 : Str = "value";
|
||||||
|
let Test.3 : {Str, Str} = Struct {Test.2, Test.2};
|
||||||
|
dec Test.2;
|
||||||
|
let Test.4 : Str = "result";
|
||||||
|
ret Test.4;
|
|
@ -832,7 +832,7 @@ procedure Test.3 ():
|
||||||
let Test.7 : Str = "Roc";
|
let Test.7 : Str = "Roc";
|
||||||
let Test.6 : [C [C List U8, C ], C Str] = TagId(1) Test.7;
|
let Test.6 : [C [C List U8, C ], C Str] = TagId(1) Test.7;
|
||||||
let Test.5 : Int1 = CallByName Bool.11 Test.1 Test.6;
|
let Test.5 : Int1 = CallByName Bool.11 Test.1 Test.6;
|
||||||
dec Test.6;
|
dec Test.7;
|
||||||
expect Test.5;
|
expect Test.5;
|
||||||
dec Test.0;
|
dec Test.0;
|
||||||
dec Test.1;
|
dec Test.1;
|
||||||
|
|
|
@ -865,7 +865,7 @@ procedure Test.12 ():
|
||||||
let Test.16 : {List U8, I64} = Struct {Test.17, Test.18};
|
let Test.16 : {List U8, I64} = Struct {Test.17, Test.18};
|
||||||
let Test.15 : [C Str, C {List U8, I64}] = TagId(1) Test.16;
|
let Test.15 : [C Str, C {List U8, I64}] = TagId(1) Test.16;
|
||||||
let Test.14 : Int1 = CallByName Bool.11 Test.10 Test.15;
|
let Test.14 : Int1 = CallByName Bool.11 Test.10 Test.15;
|
||||||
dec Test.15;
|
dec Test.16;
|
||||||
expect Test.14;
|
expect Test.14;
|
||||||
dec Test.10;
|
dec Test.10;
|
||||||
let Test.13 : {} = Struct {};
|
let Test.13 : {} = Struct {};
|
||||||
|
|
|
@ -5,7 +5,8 @@ procedure Test.0 ():
|
||||||
let Test.9 : U64 = 1i64;
|
let Test.9 : U64 = 1i64;
|
||||||
let Test.10 : Int1 = lowlevel Eq Test.8 Test.9;
|
let Test.10 : Int1 = lowlevel Eq Test.8 Test.9;
|
||||||
if Test.10 then
|
if Test.10 then
|
||||||
dec Test.1;
|
dec Test.11;
|
||||||
|
decref Test.1;
|
||||||
let Test.3 : Str = "B";
|
let Test.3 : Str = "B";
|
||||||
ret Test.3;
|
ret Test.3;
|
||||||
else
|
else
|
||||||
|
|
|
@ -5,11 +5,20 @@ procedure Test.0 ():
|
||||||
let Test.2 : [<rnu><null>, C *self] = TagId(0) Test.13;
|
let Test.2 : [<rnu><null>, C *self] = TagId(0) Test.13;
|
||||||
let Test.10 : U8 = 1i64;
|
let Test.10 : U8 = 1i64;
|
||||||
let Test.11 : U8 = GetTagId Test.2;
|
let Test.11 : U8 = GetTagId Test.2;
|
||||||
dec Test.2;
|
joinpoint #Derived_gen.0:
|
||||||
let Test.12 : Int1 = lowlevel Eq Test.10 Test.11;
|
let Test.12 : Int1 = lowlevel Eq Test.10 Test.11;
|
||||||
if Test.12 then
|
if Test.12 then
|
||||||
let Test.8 : I64 = 0i64;
|
let Test.8 : I64 = 0i64;
|
||||||
ret Test.8;
|
ret Test.8;
|
||||||
|
else
|
||||||
|
let Test.9 : I64 = 1i64;
|
||||||
|
ret Test.9;
|
||||||
|
in
|
||||||
|
let #Derived_gen.1 : Int1 = lowlevel RefCountIsUnique Test.2;
|
||||||
|
if #Derived_gen.1 then
|
||||||
|
dec Test.13;
|
||||||
|
decref Test.2;
|
||||||
|
jump #Derived_gen.0;
|
||||||
else
|
else
|
||||||
let Test.9 : I64 = 1i64;
|
decref Test.2;
|
||||||
ret Test.9;
|
jump #Derived_gen.0;
|
||||||
|
|
|
@ -30,6 +30,15 @@ procedure Test.0 ():
|
||||||
let Test.16 : Str = "";
|
let Test.16 : Str = "";
|
||||||
let Test.15 : [<r>C List *self, C Str] = TagId(1) Test.16;
|
let Test.15 : [<r>C List *self, C Str] = TagId(1) Test.16;
|
||||||
let Test.13 : Int1 = CallByName Bool.11 Test.14 Test.15;
|
let Test.13 : Int1 = CallByName Bool.11 Test.14 Test.15;
|
||||||
dec Test.15;
|
joinpoint #Derived_gen.0:
|
||||||
dec Test.14;
|
dec Test.14;
|
||||||
ret Test.13;
|
ret Test.13;
|
||||||
|
in
|
||||||
|
let #Derived_gen.1 : Int1 = lowlevel RefCountIsUnique Test.15;
|
||||||
|
if #Derived_gen.1 then
|
||||||
|
dec Test.16;
|
||||||
|
decref Test.15;
|
||||||
|
jump #Derived_gen.0;
|
||||||
|
else
|
||||||
|
decref Test.15;
|
||||||
|
jump #Derived_gen.0;
|
||||||
|
|
|
@ -3013,3 +3013,19 @@ fn rb_tree_fbip() {
|
||||||
"#
|
"#
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[mono_test]
|
||||||
|
fn drop_specialize_after_struct() {
|
||||||
|
indoc!(
|
||||||
|
r#"
|
||||||
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
|
Tuple a b : { left : a, right : b }
|
||||||
|
|
||||||
|
main =
|
||||||
|
v = "value"
|
||||||
|
t = { left: v, right: v }
|
||||||
|
"result"
|
||||||
|
"#
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue