mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-04 12:18:19 +00:00
Handle guards that appear multiple times in a compiled decision tree
Suppose we have a when expression ``` 15 if foo -> <b1> b if bar -> <b2> _ -> <b3> ``` that may have a decision tree like ``` 15? \true => foo? \true => <b1> \false => bar? \true => <b2> \false => <b3> \false => bar? \true => <b2> \false => <b3> ``` In this case, the guard "bar?" appears twice in the compiled decision tree. We need to materialize the guard expression in both locations in the compiled tree, which means we cannot as-is stamp a compiled `bar?` twice in each location. The reason is that - the compiled joinpoint for each `bar?` guard needs to have a unique ID - the guard expression might have call which needs unique call spec IDs, or other joins that need unique joinpoint IDs. So, save the expression as we build up the decision tree and materialize the guard each time we need it. In practice the guards should be quite small, so duplicating should be fine. We could avoid duplication, but it's not clear to me how to do that exactly since the branches after the guard might end up being different.
This commit is contained in:
parent
f3ddc254c1
commit
dd55be6142
3 changed files with 160 additions and 43 deletions
|
@ -0,0 +1,51 @@
|
|||
procedure Bool.2 ():
|
||||
let Bool.25 : Int1 = true;
|
||||
ret Bool.25;
|
||||
|
||||
procedure Num.19 (#Attr.2, #Attr.3):
|
||||
let Num.275 : U8 = lowlevel NumAdd #Attr.2 #Attr.3;
|
||||
ret Num.275;
|
||||
|
||||
procedure Test.1 (Test.2):
|
||||
joinpoint Test.12:
|
||||
let Test.9 : U8 = 3i64;
|
||||
ret Test.9;
|
||||
in
|
||||
joinpoint Test.11 Test.10:
|
||||
let Test.8 : U8 = 2i64;
|
||||
let Test.7 : U8 = CallByName Num.19 Test.10 Test.8;
|
||||
ret Test.7;
|
||||
in
|
||||
let Test.22 : U8 = 15i64;
|
||||
let Test.23 : Int1 = lowlevel Eq Test.22 Test.2;
|
||||
if Test.23 then
|
||||
joinpoint Test.17 Test.13:
|
||||
if Test.13 then
|
||||
let Test.6 : U8 = 1i64;
|
||||
ret Test.6;
|
||||
else
|
||||
joinpoint Test.15 Test.14:
|
||||
if Test.14 then
|
||||
jump Test.11 Test.2;
|
||||
else
|
||||
jump Test.12;
|
||||
in
|
||||
let Test.16 : Int1 = CallByName Bool.2;
|
||||
jump Test.15 Test.16;
|
||||
in
|
||||
let Test.18 : Int1 = CallByName Bool.2;
|
||||
jump Test.17 Test.18;
|
||||
else
|
||||
joinpoint Test.20 Test.19:
|
||||
if Test.19 then
|
||||
jump Test.11 Test.2;
|
||||
else
|
||||
jump Test.12;
|
||||
in
|
||||
let Test.21 : Int1 = CallByName Bool.2;
|
||||
jump Test.20 Test.21;
|
||||
|
||||
procedure Test.0 ():
|
||||
let Test.5 : U8 = 46i64;
|
||||
let Test.4 : U8 = CallByName Test.1 Test.5;
|
||||
ret Test.4;
|
Loading…
Add table
Add a link
Reference in a new issue