saved info and added test

This commit is contained in:
J.Teeuwissen 2023-05-26 15:56:18 +02:00
parent 9b58c0fb9c
commit b0705a00ad
No known key found for this signature in database
GPG key ID: DB5F7A1ED8D478AD
8 changed files with 106 additions and 27 deletions

View file

@ -18,8 +18,8 @@ use roc_module::symbol::{IdentIds, ModuleId, Symbol};
use roc_target::TargetInfo;
use crate::ir::{
BranchInfo, Call, CallType, Expr, JoinPointId, Literal, ModifyRc, Proc, ProcLayout, Stmt,
UpdateModeId,
BranchInfo, Call, CallType, Expr, JoinPointId, ListLiteralElement, Literal, ModifyRc, Proc,
ProcLayout, Stmt, UpdateModeId,
};
use crate::layout::{
Builtin, InLayout, Layout, LayoutInterner, LayoutRepr, STLayoutInterner, UnionLayout,
@ -104,7 +104,7 @@ fn specialize_drops_stmt<'a, 'i>(
_ => 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)
}
@ -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);
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)
}
Expr::StructAtIndex {
@ -179,13 +216,10 @@ fn specialize_drops_stmt<'a, 'i>(
}
alloc_let_with_continuation!(environment)
}
Expr::Struct(_)
| Expr::RuntimeErrorFunction(_)
| Expr::ExprBox { .. }
Expr::RuntimeErrorFunction(_)
| Expr::NullPointer
| Expr::GetTagId { .. }
| Expr::EmptyArray
| Expr::Array { .. } => {
| Expr::EmptyArray => {
// Does nothing relevant to drop specialization. So we can just continue.
alloc_let_with_continuation!(environment)
}
@ -1222,12 +1256,16 @@ impl<'a> DropSpecializationEnvironment<'a> {
.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) {
self.list_children
.entry(parent)
.or_insert_with(|| Vec::new_in(self.arena))
.push((child, *index));
self.add_list_child(parent, child, *index)
}
}

View file

@ -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;

View file

@ -832,7 +832,7 @@ procedure Test.3 ():
let Test.7 : Str = "Roc";
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;
dec Test.6;
dec Test.7;
expect Test.5;
dec Test.0;
dec Test.1;

View file

@ -865,7 +865,7 @@ procedure Test.12 ():
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.14 : Int1 = CallByName Bool.11 Test.10 Test.15;
dec Test.15;
dec Test.16;
expect Test.14;
dec Test.10;
let Test.13 : {} = Struct {};

View file

@ -5,7 +5,8 @@ procedure Test.0 ():
let Test.9 : U64 = 1i64;
let Test.10 : Int1 = lowlevel Eq Test.8 Test.9;
if Test.10 then
dec Test.1;
dec Test.11;
decref Test.1;
let Test.3 : Str = "B";
ret Test.3;
else

View file

@ -5,11 +5,20 @@ procedure Test.0 ():
let Test.2 : [<rnu><null>, C *self] = TagId(0) Test.13;
let Test.10 : U8 = 1i64;
let Test.11 : U8 = GetTagId Test.2;
dec Test.2;
let Test.12 : Int1 = lowlevel Eq Test.10 Test.11;
if Test.12 then
let Test.8 : I64 = 0i64;
ret Test.8;
joinpoint #Derived_gen.0:
let Test.12 : Int1 = lowlevel Eq Test.10 Test.11;
if Test.12 then
let Test.8 : I64 = 0i64;
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
let Test.9 : I64 = 1i64;
ret Test.9;
decref Test.2;
jump #Derived_gen.0;

View file

@ -30,6 +30,15 @@ procedure Test.0 ():
let Test.16 : Str = "";
let Test.15 : [<r>C List *self, C Str] = TagId(1) Test.16;
let Test.13 : Int1 = CallByName Bool.11 Test.14 Test.15;
dec Test.15;
dec Test.14;
ret Test.13;
joinpoint #Derived_gen.0:
dec Test.14;
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;

View file

@ -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"
"#
)
}