Skip to content

Commit

Permalink
Fix #428 (#429)
Browse files Browse the repository at this point in the history
  • Loading branch information
pschachte authored Dec 9, 2023
1 parent 63c971d commit 7b495e0
Show file tree
Hide file tree
Showing 31 changed files with 306 additions and 170 deletions.
25 changes: 15 additions & 10 deletions src/Unbranch.hs
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,10 @@ unbranchProc' proc = do
let params' = selectDetism id addTestOutParam detism
$ contentApply unbranchParam <$> params
let stmts = selectDetism body (body++[move boolTrue testOutExp]) detism
let impurity = procImpurity proc
let proto' = proto {procProtoParams = params'}
(body',tmpCtr',newProcs) <-
unbranchBody name tmpCtr params' detism stmts
unbranchBody name tmpCtr params' detism impurity stmts
let proc' = proc { procProto = proto'
, procDetism = selectDetism detism Det detism
, procImpln = ProcDefSrc body'
Expand All @@ -130,10 +131,11 @@ unbranchProc' proc = do

-- |Eliminate loops and ensure that Conds only appear as the final
-- statement of a body.
unbranchBody :: ProcName -> Int -> [Placed Param] -> Determinism
unbranchBody :: ProcName -> Int -> [Placed Param] -> Determinism -> Impurity
-> [Placed Stmt] -> Compiler ([Placed Stmt],Int,[ProcDef])
unbranchBody name tmpCtr params detism body = do
let unbrancher = initUnbrancherState Nothing tmpCtr detism params name
unbranchBody name tmpCtr params detism impurity body = do
let unbrancher =
initUnbrancherState Nothing tmpCtr detism impurity params name
let outparams = brOutParams unbrancher
let outvars = brOutArgs unbrancher
let stmts = body
Expand Down Expand Up @@ -219,6 +221,7 @@ data UnbrancherState = Unbrancher {
-- the current SemiDet context (and so must be
-- saved if they are reassigned)
brDetism :: Determinism, -- ^The determinism of the current context
brImpurity :: Impurity, -- ^The impurity of the enclosing proc
brAlternate :: [Placed Stmt], -- ^Code to execute in case of failure
brSense :: Bool, -- ^True iff execute brAlternate on failure
brProcName :: ProcName -- ^The name of the proc being unbranched
Expand All @@ -231,9 +234,9 @@ data LoopInfo = LoopInfo {
} deriving (Eq)


initUnbrancherState :: Maybe LoopInfo -> Int -> Determinism -> [Placed Param]
-> ProcName -> UnbrancherState
initUnbrancherState loopinfo tmpCtr detism params =
initUnbrancherState :: Maybe LoopInfo -> Int -> Determinism -> Impurity
-> [Placed Param] -> ProcName -> UnbrancherState
initUnbrancherState loopinfo tmpCtr detism impurity params =
let defined = inputParams $ content <$> params
outParams = [unbranchParam (Param nm ty ParamOut ft) `maybePlace` pos
| (Param nm ty fl ft, pos) <- unPlace <$> params
Expand All @@ -246,7 +249,8 @@ initUnbrancherState loopinfo tmpCtr detism params =
, flowsOut fl && flowsIn fl]
alt = selectDetism [] [move boolFalse testOutExp] detism
in Unbrancher loopinfo defined tmpCtr outParams outArgs
(Set.fromList inOuts) [] Map.empty Set.empty detism alt True
(Set.fromList inOuts) [] Map.empty Set.empty detism impurity
alt True


-- | Add the specified variable to the symbol table
Expand Down Expand Up @@ -308,14 +312,15 @@ newProcName name = lift . genProcName . (`specialName2` name) =<< gets brProcNam


-- |Create, unbranch, and record a new proc with the specified proto,
-- determinism and body.
-- determinism and body. Takes its impurity from the parent proc.
genProc :: ProcProto -> Determinism -> [Placed Stmt] -> Unbrancher ()
genProc proto detism stmts = do
let name = procProtoName proto
tmpCtr <- gets brTempCtr
impurity <- gets brImpurity
-- call site count will be refilled later
let procDef = ProcDef name proto (ProcDefSrc stmts) Nothing tmpCtr 0
Map.empty Private detism MayInline Pure GeneratedProc
Map.empty Private detism MayInline impurity GeneratedProc
NoSuperproc Map.empty
logUnbranch $ "Generating fresh " ++ show detism ++ " proc:"
++ showProcDef 8 procDef
Expand Down
4 changes: 2 additions & 2 deletions test-cases/complex/exp/testcase_multi_specz-drone.exp
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ module top-level code > public {semipure} (0 calls)



proc #cont#1 > (2 calls)
proc #cont#1 > {semipure} (2 calls)
0: drone.#cont#1<0>
#cont#1()<{<<wybe.io.io>>}; {<<wybe.io.io>>}; {}>:
AliasPairs: []
Expand Down Expand Up @@ -888,7 +888,7 @@ module top-level code > public {semipure} (0 calls)



proc #cont#1 > (2 calls)
proc #cont#1 > {semipure} (2 calls)
0: drone.#cont#1<0>
#cont#1()<{<<wybe.io.io>>}; {<<wybe.io.io>>}; {}>:
AliasPairs: []
Expand Down
1 change: 1 addition & 0 deletions test-cases/execution/semipure_continuation.exp
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
321
Empty file.
19 changes: 19 additions & 0 deletions test-cases/execution/semipure_continuation.wybe
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
use logging
def {noinline} do_nothing {
pass
}

def {semipure} foo(x:int) {
if {
x ~= 0 ::
do_nothing
}
if {
x ~= 0 ::
!logmsg(x)
!foo(x-1)
}
}

!foo(3)
!lognl
4 changes: 2 additions & 2 deletions test-cases/final-dump/afterbreak.exp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ module top-level code > public {inline,semipure} (0 calls)
afterbreak.#cont#1<0>(1:wybe.int)<{<<wybe.io.io>>}; {<<wybe.io.io>>}; {}> #0 @afterbreak:nn:nn


proc #cont#1 > (2 calls)
proc #cont#1 > {semipure} (2 calls)
0: afterbreak.#cont#1<0>
#cont#1(x##0:wybe.int)<{<<wybe.io.io>>}; {<<wybe.io.io>>}; {}>:
AliasPairs: []
Expand All @@ -36,7 +36,7 @@ proc #cont#1 > (2 calls)



proc #cont#2 > {inline} (1 calls)
proc #cont#2 > {inline,semipure} (1 calls)
0: afterbreak.#cont#2<0>
#cont#2([x##0:wybe.int], y##0:wybe.int)<{<<wybe.io.io>>}; {<<wybe.io.io>>}; {}>:
AliasPairs: []
Expand Down
2 changes: 1 addition & 1 deletion test-cases/final-dump/alias_fork2.exp
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ module top-level code > public {semipure} (0 calls)



proc #cont#1 > (2 calls)
proc #cont#1 > {semipure} (2 calls)
0: alias_fork2.#cont#1<0>
#cont#1(t##0:mytree.tree, t1##0:mytree.tree)<{<<wybe.io.io>>}; {<<wybe.io.io>>}; {}>:
AliasPairs: []
Expand Down
6 changes: 3 additions & 3 deletions test-cases/final-dump/anon_field.exp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ module top-level code > public {semipure} (0 calls)



proc #cont#1 > (2 calls)
proc #cont#1 > {semipure} (2 calls)
0: anon_field.#cont#1<0>
#cont#1()<{<<wybe.io.io>>}; {<<wybe.io.io>>}; {}>:
AliasPairs: []
Expand All @@ -69,7 +69,7 @@ proc #cont#1 > (2 calls)



proc #cont#2 > (3 calls)
proc #cont#2 > {semipure} (3 calls)
0: anon_field.#cont#2<0>
#cont#2()<{<<wybe.io.io>>}; {<<wybe.io.io>>}; {}>:
AliasPairs: []
Expand All @@ -96,7 +96,7 @@ proc #cont#2 > (3 calls)



proc #cont#3 > (2 calls)
proc #cont#3 > {semipure} (2 calls)
0: anon_field.#cont#3<0>
#cont#3()<{<<wybe.io.io>>}; {<<wybe.io.io>>}; {}>:
AliasPairs: []
Expand Down
2 changes: 1 addition & 1 deletion test-cases/final-dump/backwards_assign.exp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ module top-level code > public {inline,semipure} (0 calls)
backwards_assign.#cont#1<0>(0:wybe.int)<{<<wybe.io.io>>}; {<<wybe.io.io>>}; {}> #0 @backwards_assign:nn:nn


proc #cont#1 > (2 calls)
proc #cont#1 > {semipure} (2 calls)
0: backwards_assign.#cont#1<0>
#cont#1(i##0:wybe.int)<{<<wybe.io.io>>}; {<<wybe.io.io>>}; {}>:
AliasPairs: []
Expand Down
4 changes: 2 additions & 2 deletions test-cases/final-dump/break_in_loop_in_do.exp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ module top-level code > public {semipure} (0 calls)
foreign lpvm store(~%tmp#7##0:wybe.phantom, <<wybe.io.io>>:wybe.phantom) @io:nn:nn


proc #cont#1 > {inline} (2 calls)
proc #cont#1 > {inline,semipure} (2 calls)
0: break_in_loop_in_do.#cont#1<0>
#cont#1([counter##0:wybe.int])<{<<break_in_loop_in_do.counter>>, <<wybe.io.io>>}; {<<wybe.io.io>>}; {}>:
AliasPairs: []
Expand All @@ -33,7 +33,7 @@ proc #cont#1 > {inline} (2 calls)
foreign lpvm store(~%tmp#8##0:wybe.phantom, <<wybe.io.io>>:wybe.phantom) @io:nn:nn


proc #cont#2 > {inline} (1 calls)
proc #cont#2 > {inline,semipure} (1 calls)
0: break_in_loop_in_do.#cont#2<0>
#cont#2([tmp#0##0:wybe.int], tmp#1##0:wybe.int)<{<<wybe.io.io>>}; {<<break_in_loop_in_do.counter>>, <<wybe.io.io>>}; {}>:
AliasPairs: []
Expand Down
4 changes: 2 additions & 2 deletions test-cases/final-dump/bug214.exp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ module top-level code > public {semipure} (0 calls)
bug214.#cont#2<0>[7477e50a09](~tmp#0##0:bug214.position, ~tmp#1##0:bug214)<{<<wybe.io.io>>}; {<<wybe.io.io>>}; {}> #3 @bug214:nn:nn


proc #cont#1 > {inline} (0 calls)
proc #cont#1 > {inline,semipure} (0 calls)
0: bug214.#cont#1<0>
#cont#1(pos##0:bug214.position, sub##0:bug214)<{<<wybe.io.io>>}; {<<wybe.io.io>>}; {}>:
AliasPairs: []
Expand Down Expand Up @@ -56,7 +56,7 @@ proc #cont#1 > {inline} (0 calls)
foreign lpvm store(~%tmp#38##0:wybe.phantom, <<wybe.io.io>>:wybe.phantom) @io:nn:nn


proc #cont#2 > (3 calls)
proc #cont#2 > {semipure} (3 calls)
0: bug214.#cont#2<0>[7477e50a09]
#cont#2(pos##0:bug214.position, sub##0:bug214)<{<<wybe.io.io>>}; {<<wybe.io.io>>}; {}>:
AliasPairs: []
Expand Down
4 changes: 2 additions & 2 deletions test-cases/final-dump/card.exp
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ module top-level code > public {inline,semipure} (0 calls)
card.#cont#1<0>(~tmp#1##0:wybe.list(card.suit))<{<<wybe.io.io>>}; {<<wybe.io.io>>}; {}> #1 @card:nn:nn


proc #cont#1 > (2 calls)
proc #cont#1 > {semipure} (2 calls)
0: card.#cont#1<0>
#cont#1(tmp#0##0:wybe.list(card.suit))<{<<wybe.io.io>>}; {<<wybe.io.io>>}; {}>:
AliasPairs: []
Expand All @@ -75,7 +75,7 @@ proc #cont#1 > (2 calls)



proc #cont#2 > (2 calls)
proc #cont#2 > {semipure} (2 calls)
0: card.#cont#2<0>
#cont#2(s##0:card.suit, tmp#0##0:wybe.list(card.suit), tmp#2##0:wybe.list(card.rank))<{<<wybe.io.io>>}; {<<wybe.io.io>>}; {}>:
AliasPairs: []
Expand Down
2 changes: 1 addition & 1 deletion test-cases/final-dump/caret.exp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ module top-level code > public {semipure} (0 calls)
caret.#cont#1<0>[410bae77d3](~tmp#27##0:caret.region)<{<<wybe.io.io>>}; {<<wybe.io.io>>}; {}> #8


proc #cont#1 > (2 calls)
proc #cont#1 > {semipure} (2 calls)
0: caret.#cont#1<0>[410bae77d3]
#cont#1(reg##0:caret.region)<{<<wybe.io.io>>}; {<<wybe.io.io>>}; {}>:
AliasPairs: []
Expand Down
2 changes: 1 addition & 1 deletion test-cases/final-dump/det_for.exp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ module top-level code > public {inline,semipure} (0 calls)
det_for.#cont#1<0>(0:wybe.int)<{<<wybe.io.io>>}; {<<wybe.io.io>>}; {}> #0 @det_for:nn:nn


proc #cont#1 > (2 calls)
proc #cont#1 > {semipure} (2 calls)
0: det_for.#cont#1<0>
#cont#1(tmp#0##0:wybe.int)<{<<wybe.io.io>>}; {<<wybe.io.io>>}; {}>:
AliasPairs: []
Expand Down
6 changes: 3 additions & 3 deletions test-cases/final-dump/disjunctive-cond.exp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ module top-level code > public {semipure} (0 calls)
disjunctive-cond.#cont#1<0>(1:wybe.bool, 0:wybe.bool)<{<<wybe.io.io>>}; {<<wybe.io.io>>}; {}> #9


proc #cont#1 > (5 calls)
proc #cont#1 > {semipure} (5 calls)
0: disjunctive-cond.#cont#1<0>
#cont#1(a##0:wybe.bool, b##0:wybe.bool)<{<<wybe.io.io>>}; {<<wybe.io.io>>}; {}>:
AliasPairs: []
Expand Down Expand Up @@ -53,7 +53,7 @@ proc #cont#1 > (5 calls)



proc #cont#2 > (3 calls)
proc #cont#2 > {semipure} (3 calls)
0: disjunctive-cond.#cont#2<0>
#cont#2(a##0:wybe.bool, b##0:wybe.bool)<{<<wybe.io.io>>}; {<<wybe.io.io>>}; {}>:
AliasPairs: []
Expand Down Expand Up @@ -88,7 +88,7 @@ proc #cont#2 > (3 calls)



proc #cont#3 > (7 calls)
proc #cont#3 > {semipure} (7 calls)
0: disjunctive-cond.#cont#3<0>
#cont#3(a##0:wybe.bool, b##0:wybe.bool)<{<<wybe.io.io>>}; {<<wybe.io.io>>}; {}>:
AliasPairs: []
Expand Down
Loading

0 comments on commit 7b495e0

Please sign in to comment.