{-# LANGUAGE TupleSections #-}
module C.CF ( cfC ) where
import C
import CF
import CF.AL
import Control.Monad.State.Strict (State, evalState, gets, modify, state)
import Data.Bifunctor (first)
import Data.Functor (($>))
import qualified Data.IntMap as IM
import qualified Data.IntSet as IS
import Data.List (uncons)
import qualified Data.Map as M
import Data.Tuple.Extra (second3, snd3, thd3, third3)
type N=Int
type FreshM = State (N, M.Map Label N, M.Map Label [N])
runFreshM :: FreshM a -> a
runFreshM :: forall a. FreshM a -> a
runFreshM = (FreshM a -> (N, Map Label N, Map Label [N]) -> a)
-> (N, Map Label N, Map Label [N]) -> FreshM a -> a
forall a b c. (a -> b -> c) -> b -> a -> c
flip FreshM a -> (N, Map Label N, Map Label [N]) -> a
forall s a. State s a -> s -> a
evalState (N
0, Map Label N
forall a. Monoid a => a
mempty, Map Label [N]
forall a. Monoid a => a
mempty)
cfC :: [CS ()] -> ([N], [CS ControlAnn], IM.IntMap (ControlAnn, Liveness))
cfC :: [CS ()] -> ([N], [CS ControlAnn], IntMap (ControlAnn, Liveness))
cfC [CS ()]
cs = let cfs :: [CS ControlAnn]
cfs = [CS ()] -> [CS ControlAnn]
mkControlFlow [CS ()]
cs in ([CS ControlAnn] -> [N]
inspectOrder [CS ControlAnn]
cfs, [CS ControlAnn]
cfs, [CS ControlAnn] -> IntMap (ControlAnn, Liveness)
initLiveness [CS ControlAnn]
cfs)
mkControlFlow :: [CS ()] -> [CS ControlAnn]
mkControlFlow :: [CS ()] -> [CS ControlAnn]
mkControlFlow [CS ()]
instrs = FreshM [CS ControlAnn] -> [CS ControlAnn]
forall a. FreshM a -> a
runFreshM ([CS ()] -> FreshM ()
brs [CS ()]
instrs FreshM () -> FreshM [CS ControlAnn] -> FreshM [CS ControlAnn]
forall a b.
StateT (N, Map Label N, Map Label [N]) Identity a
-> StateT (N, Map Label N, Map Label [N]) Identity b
-> StateT (N, Map Label N, Map Label [N]) Identity b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> [CS ()] -> FreshM [CS ControlAnn]
addCF [CS ()]
instrs)
getFresh :: FreshM N
getFresh :: FreshM N
getFresh = ((N, Map Label N, Map Label [N])
-> (N, (N, Map Label N, Map Label [N])))
-> FreshM N
forall a.
((N, Map Label N, Map Label [N])
-> (a, (N, Map Label N, Map Label [N])))
-> StateT (N, Map Label N, Map Label [N]) Identity a
forall s (m :: * -> *) a. MonadState s m => (s -> (a, s)) -> m a
state (\(N
i,Map Label N
m0,Map Label [N]
m1) -> (N
i,(N
iN -> N -> N
forall a. Num a => a -> a -> a
+N
1,Map Label N
m0,Map Label [N]
m1)))
fm :: Label -> FreshM N
fm :: Label -> FreshM N
fm Label
l = do {i <- FreshM N
getFresh; br i l $> i}
ll :: Label -> FreshM N
ll :: Label -> FreshM N
ll Label
l = ((N, Map Label N, Map Label [N]) -> N) -> FreshM N
forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets (N -> Label -> Map Label N -> N
forall k a. Ord k => a -> k -> Map k a -> a
M.findWithDefault ([Char] -> N
forall a. HasCallStack => [Char] -> a
error [Char]
"Internal error in control-flow graph: node label not in map.") Label
l (Map Label N -> N)
-> ((N, Map Label N, Map Label [N]) -> Map Label N)
-> (N, Map Label N, Map Label [N])
-> N
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (N, Map Label N, Map Label [N]) -> Map Label N
forall a b c. (a, b, c) -> b
snd3)
lC :: Label -> FreshM [N]
lC :: Label -> FreshM [N]
lC Label
l = ((N, Map Label N, Map Label [N]) -> [N]) -> FreshM [N]
forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets ([N] -> Label -> Map Label [N] -> [N]
forall k a. Ord k => a -> k -> Map k a -> a
M.findWithDefault ([Char] -> [N]
forall a. HasCallStack => [Char] -> a
error [Char]
"Internal error in CF graph: node label not in map.") Label
l (Map Label [N] -> [N])
-> ((N, Map Label N, Map Label [N]) -> Map Label [N])
-> (N, Map Label N, Map Label [N])
-> [N]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (N, Map Label N, Map Label [N]) -> Map Label [N]
forall a b c. (a, b, c) -> c
thd3)
br :: N -> Label -> FreshM ()
br :: N -> Label -> FreshM ()
br N
i Label
l = ((N, Map Label N, Map Label [N])
-> (N, Map Label N, Map Label [N]))
-> FreshM ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify ((Map Label N -> Map Label N)
-> (N, Map Label N, Map Label [N])
-> (N, Map Label N, Map Label [N])
forall b b' a c. (b -> b') -> (a, b, c) -> (a, b', c)
second3 (Label -> N -> Map Label N -> Map Label N
forall k a. Ord k => k -> a -> Map k a -> Map k a
M.insert Label
l N
i))
b3 :: N -> Label -> FreshM ()
b3 :: N -> Label -> FreshM ()
b3 N
i Label
l = ((N, Map Label N, Map Label [N])
-> (N, Map Label N, Map Label [N]))
-> FreshM ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify ((Map Label [N] -> Map Label [N])
-> (N, Map Label N, Map Label [N])
-> (N, Map Label N, Map Label [N])
forall c c' a b. (c -> c') -> (a, b, c) -> (a, b, c')
third3 ((Maybe [N] -> Maybe [N]) -> Label -> Map Label [N] -> Map Label [N]
forall k a.
Ord k =>
(Maybe a -> Maybe a) -> k -> Map k a -> Map k a
M.alter (\Maybe [N]
k -> [N] -> Maybe [N]
forall a. a -> Maybe a
Just([N] -> Maybe [N]) -> [N] -> Maybe [N]
forall a b. (a -> b) -> a -> b
$case Maybe [N]
k of {Maybe [N]
Nothing -> [N
i]; Just [N]
is -> N
iN -> [N] -> [N]
forall a. a -> [a] -> [a]
:[N]
is}) Label
l))
mC :: ([N] -> [N]) -> ControlAnn -> ControlAnn
mC :: ([N] -> [N]) -> ControlAnn -> ControlAnn
mC [N] -> [N]
f (ControlAnn N
l [N]
ds UD
udϵ) = N -> [N] -> UD -> ControlAnn
ControlAnn N
l ([N] -> [N]
f [N]
ds) UD
udϵ
addH :: N -> ControlAnn -> ControlAnn
addH N
n = ([N] -> [N]) -> ControlAnn -> ControlAnn
mC (N
nN -> [N] -> [N]
forall a. a -> [a] -> [a]
:)
unsnoc :: [a] -> ([a], a)
unsnoc :: forall a. [a] -> ([a], a)
unsnoc [a
x] = ([], a
x)
unsnoc (a
x:[a]
xs) = ([a] -> [a]) -> ([a], a) -> ([a], a)
forall a b c. (a -> b) -> (a, c) -> (b, c)
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first (a
xa -> [a] -> [a]
forall a. a -> [a] -> [a]
:) (([a], a) -> ([a], a)) -> ([a], a) -> ([a], a)
forall a b. (a -> b) -> a -> b
$ [a] -> ([a], a)
forall a. [a] -> ([a], a)
unsnoc [a]
xs
unsnoc [a]
_ = [Char] -> ([a], a)
forall a. HasCallStack => [Char] -> a
error [Char]
"Internal error: unsnoc called on empty list."
emptyL :: Liveness
emptyL :: Liveness
emptyL = IntSet -> IntSet -> IntSet -> IntSet -> Liveness
Liveness IntSet
IS.empty IntSet
IS.empty IntSet
IS.empty IntSet
IS.empty
initLiveness :: [CS ControlAnn] -> IM.IntMap (ControlAnn, Liveness)
initLiveness :: [CS ControlAnn] -> IntMap (ControlAnn, Liveness)
initLiveness = [(N, (ControlAnn, Liveness))] -> IntMap (ControlAnn, Liveness)
forall a. [(N, a)] -> IntMap a
IM.fromList ([(N, (ControlAnn, Liveness))] -> IntMap (ControlAnn, Liveness))
-> ([CS ControlAnn] -> [(N, (ControlAnn, Liveness))])
-> [CS ControlAnn]
-> IntMap (ControlAnn, Liveness)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [CS ControlAnn] -> [(N, (ControlAnn, Liveness))]
go where
go :: [CS ControlAnn] -> [(N, (ControlAnn, Liveness))]
go [] = []
go (For ControlAnn
ann Temp
_ CE
_ IRel
_ CE
_ [CS ControlAnn]
ss:[CS ControlAnn]
cs) = (ControlAnn -> N
node ControlAnn
ann, (ControlAnn
ann, Liveness
emptyL))(N, (ControlAnn, Liveness))
-> [(N, (ControlAnn, Liveness))] -> [(N, (ControlAnn, Liveness))]
forall a. a -> [a] -> [a]
:[CS ControlAnn] -> [(N, (ControlAnn, Liveness))]
go [CS ControlAnn]
ss[(N, (ControlAnn, Liveness))]
-> [(N, (ControlAnn, Liveness))] -> [(N, (ControlAnn, Liveness))]
forall a. [a] -> [a] -> [a]
++[CS ControlAnn] -> [(N, (ControlAnn, Liveness))]
go [CS ControlAnn]
cs
go (For1 ControlAnn
ann Temp
_ CE
_ IRel
_ CE
_ [CS ControlAnn]
ss:[CS ControlAnn]
cs) = (ControlAnn -> N
node ControlAnn
ann, (ControlAnn
ann, Liveness
emptyL))(N, (ControlAnn, Liveness))
-> [(N, (ControlAnn, Liveness))] -> [(N, (ControlAnn, Liveness))]
forall a. a -> [a] -> [a]
:[CS ControlAnn] -> [(N, (ControlAnn, Liveness))]
go [CS ControlAnn]
ss[(N, (ControlAnn, Liveness))]
-> [(N, (ControlAnn, Liveness))] -> [(N, (ControlAnn, Liveness))]
forall a. [a] -> [a] -> [a]
++[CS ControlAnn] -> [(N, (ControlAnn, Liveness))]
go [CS ControlAnn]
cs
go (While ControlAnn
ann Temp
_ IRel
_ CE
_ [CS ControlAnn]
ss:[CS ControlAnn]
cs) = (ControlAnn -> N
node ControlAnn
ann, (ControlAnn
ann, Liveness
emptyL))(N, (ControlAnn, Liveness))
-> [(N, (ControlAnn, Liveness))] -> [(N, (ControlAnn, Liveness))]
forall a. a -> [a] -> [a]
:[CS ControlAnn] -> [(N, (ControlAnn, Liveness))]
go [CS ControlAnn]
ss[(N, (ControlAnn, Liveness))]
-> [(N, (ControlAnn, Liveness))] -> [(N, (ControlAnn, Liveness))]
forall a. [a] -> [a] -> [a]
++[CS ControlAnn] -> [(N, (ControlAnn, Liveness))]
go [CS ControlAnn]
cs
go (WT ControlAnn
ann PE
_ [CS ControlAnn]
ss:[CS ControlAnn]
cs) = (ControlAnn -> N
node ControlAnn
ann, (ControlAnn
ann, Liveness
emptyL))(N, (ControlAnn, Liveness))
-> [(N, (ControlAnn, Liveness))] -> [(N, (ControlAnn, Liveness))]
forall a. a -> [a] -> [a]
:[CS ControlAnn] -> [(N, (ControlAnn, Liveness))]
go [CS ControlAnn]
ss[(N, (ControlAnn, Liveness))]
-> [(N, (ControlAnn, Liveness))] -> [(N, (ControlAnn, Liveness))]
forall a. [a] -> [a] -> [a]
++[CS ControlAnn] -> [(N, (ControlAnn, Liveness))]
go [CS ControlAnn]
cs
go (If ControlAnn
ann PE
_ [CS ControlAnn]
ss [CS ControlAnn]
ss':[CS ControlAnn]
cs) = (ControlAnn -> N
node ControlAnn
ann, (ControlAnn
ann, Liveness
emptyL))(N, (ControlAnn, Liveness))
-> [(N, (ControlAnn, Liveness))] -> [(N, (ControlAnn, Liveness))]
forall a. a -> [a] -> [a]
:[CS ControlAnn] -> [(N, (ControlAnn, Liveness))]
go [CS ControlAnn]
ss[(N, (ControlAnn, Liveness))]
-> [(N, (ControlAnn, Liveness))] -> [(N, (ControlAnn, Liveness))]
forall a. [a] -> [a] -> [a]
++[CS ControlAnn] -> [(N, (ControlAnn, Liveness))]
go [CS ControlAnn]
ss'[(N, (ControlAnn, Liveness))]
-> [(N, (ControlAnn, Liveness))] -> [(N, (ControlAnn, Liveness))]
forall a. [a] -> [a] -> [a]
++[CS ControlAnn] -> [(N, (ControlAnn, Liveness))]
go [CS ControlAnn]
cs
go (Ifn't ControlAnn
ann PE
_ [CS ControlAnn]
ss:[CS ControlAnn]
cs) = (ControlAnn -> N
node ControlAnn
ann, (ControlAnn
ann, Liveness
emptyL))(N, (ControlAnn, Liveness))
-> [(N, (ControlAnn, Liveness))] -> [(N, (ControlAnn, Liveness))]
forall a. a -> [a] -> [a]
:[CS ControlAnn] -> [(N, (ControlAnn, Liveness))]
go [CS ControlAnn]
ss[(N, (ControlAnn, Liveness))]
-> [(N, (ControlAnn, Liveness))] -> [(N, (ControlAnn, Liveness))]
forall a. [a] -> [a] -> [a]
++[CS ControlAnn] -> [(N, (ControlAnn, Liveness))]
go [CS ControlAnn]
cs
go (Def ControlAnn
ann Label
_ [CS ControlAnn]
ss:[CS ControlAnn]
cs) = (ControlAnn -> N
node ControlAnn
ann, (ControlAnn
ann, Liveness
emptyL))(N, (ControlAnn, Liveness))
-> [(N, (ControlAnn, Liveness))] -> [(N, (ControlAnn, Liveness))]
forall a. a -> [a] -> [a]
:[CS ControlAnn] -> [(N, (ControlAnn, Liveness))]
go [CS ControlAnn]
ss[(N, (ControlAnn, Liveness))]
-> [(N, (ControlAnn, Liveness))] -> [(N, (ControlAnn, Liveness))]
forall a. [a] -> [a] -> [a]
++[CS ControlAnn] -> [(N, (ControlAnn, Liveness))]
go [CS ControlAnn]
cs
go (CS ControlAnn
c:[CS ControlAnn]
cs) = let x :: ControlAnn
x=CS ControlAnn -> ControlAnn
forall a. CS a -> a
lann CS ControlAnn
c in (ControlAnn -> N
node ControlAnn
x, (ControlAnn
x, Liveness
emptyL))(N, (ControlAnn, Liveness))
-> [(N, (ControlAnn, Liveness))] -> [(N, (ControlAnn, Liveness))]
forall a. a -> [a] -> [a]
:[CS ControlAnn] -> [(N, (ControlAnn, Liveness))]
go [CS ControlAnn]
cs
inspectOrder :: [CS ControlAnn] -> [N]
inspectOrder :: [CS ControlAnn] -> [N]
inspectOrder (For ControlAnn
ann Temp
_ CE
_ IRel
_ CE
_ [CS ControlAnn]
ss:[CS ControlAnn]
cs) = ControlAnn -> N
node ControlAnn
annN -> [N] -> [N]
forall a. a -> [a] -> [a]
:[CS ControlAnn] -> [N]
inspectOrder [CS ControlAnn]
ss[N] -> [N] -> [N]
forall a. [a] -> [a] -> [a]
++[CS ControlAnn] -> [N]
inspectOrder [CS ControlAnn]
cs
inspectOrder (For1 ControlAnn
ann Temp
_ CE
_ IRel
_ CE
_ [CS ControlAnn]
ss:[CS ControlAnn]
cs) = ControlAnn -> N
node ControlAnn
annN -> [N] -> [N]
forall a. a -> [a] -> [a]
:[CS ControlAnn] -> [N]
inspectOrder [CS ControlAnn]
ss[N] -> [N] -> [N]
forall a. [a] -> [a] -> [a]
++[CS ControlAnn] -> [N]
inspectOrder [CS ControlAnn]
cs
inspectOrder (While ControlAnn
ann Temp
_ IRel
_ CE
_ [CS ControlAnn]
ss:[CS ControlAnn]
cs) = ControlAnn -> N
node ControlAnn
annN -> [N] -> [N]
forall a. a -> [a] -> [a]
:[CS ControlAnn] -> [N]
inspectOrder [CS ControlAnn]
ss[N] -> [N] -> [N]
forall a. [a] -> [a] -> [a]
++[CS ControlAnn] -> [N]
inspectOrder [CS ControlAnn]
cs
inspectOrder (WT ControlAnn
ann PE
_ [CS ControlAnn]
ss:[CS ControlAnn]
cs) = ControlAnn -> N
node ControlAnn
annN -> [N] -> [N]
forall a. a -> [a] -> [a]
:[CS ControlAnn] -> [N]
inspectOrder [CS ControlAnn]
ss[N] -> [N] -> [N]
forall a. [a] -> [a] -> [a]
++[CS ControlAnn] -> [N]
inspectOrder [CS ControlAnn]
cs
inspectOrder (If ControlAnn
ann PE
_ [CS ControlAnn]
ss [CS ControlAnn]
ss':[CS ControlAnn]
cs) = ControlAnn -> N
node ControlAnn
annN -> [N] -> [N]
forall a. a -> [a] -> [a]
:[CS ControlAnn] -> [N]
inspectOrder [CS ControlAnn]
ss[N] -> [N] -> [N]
forall a. [a] -> [a] -> [a]
++[CS ControlAnn] -> [N]
inspectOrder [CS ControlAnn]
ss'[N] -> [N] -> [N]
forall a. [a] -> [a] -> [a]
++[CS ControlAnn] -> [N]
inspectOrder [CS ControlAnn]
cs
inspectOrder (Ifn't ControlAnn
ann PE
_ [CS ControlAnn]
ss:[CS ControlAnn]
cs) = ControlAnn -> N
node ControlAnn
annN -> [N] -> [N]
forall a. a -> [a] -> [a]
:[CS ControlAnn] -> [N]
inspectOrder [CS ControlAnn]
ss[N] -> [N] -> [N]
forall a. [a] -> [a] -> [a]
++[CS ControlAnn] -> [N]
inspectOrder [CS ControlAnn]
cs
inspectOrder (Def ControlAnn
ann Label
_ [CS ControlAnn]
ss:[CS ControlAnn]
cs) = ControlAnn -> N
node ControlAnn
annN -> [N] -> [N]
forall a. a -> [a] -> [a]
:[CS ControlAnn] -> [N]
inspectOrder [CS ControlAnn]
ss[N] -> [N] -> [N]
forall a. [a] -> [a] -> [a]
++[CS ControlAnn] -> [N]
inspectOrder [CS ControlAnn]
cs
inspectOrder (CS ControlAnn
c:[CS ControlAnn]
cs) = ControlAnn -> N
node (CS ControlAnn -> ControlAnn
forall a. CS a -> a
lann CS ControlAnn
c)N -> [N] -> [N]
forall a. a -> [a] -> [a]
:[CS ControlAnn] -> [N]
inspectOrder [CS ControlAnn]
cs
inspectOrder [] = []
tieBranch :: N -> ([N] -> [N]) -> [CS ()] -> FreshM ([N] -> [N], [CS ControlAnn])
tieBranch :: N
-> ([N] -> [N]) -> [CS ()] -> FreshM ([N] -> [N], [CS ControlAnn])
tieBranch N
i [N] -> [N]
f [CS ()]
ss = do
preSs <- [CS ()] -> FreshM [CS ControlAnn]
addCF [CS ()]
ss
pure $ case uncons preSs of
Just (CS ControlAnn
i1, [CS ControlAnn]
_) ->
let hi :: N
hi=ControlAnn -> N
node (CS ControlAnn -> ControlAnn
forall a. CS a -> a
lann CS ControlAnn
i1)
([CS ControlAnn]
ss',CS ControlAnn
l) = [CS ControlAnn] -> ([CS ControlAnn], CS ControlAnn)
forall a. [a] -> ([a], a)
unsnoc [CS ControlAnn]
preSs
l' :: CS ControlAnn
l' = (ControlAnn -> ControlAnn) -> CS ControlAnn -> CS ControlAnn
forall a b. (a -> b) -> CS a -> CS b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (([N] -> [N]) -> ControlAnn -> ControlAnn
mC [N] -> [N]
f) CS ControlAnn
l
in ((N
hiN -> [N] -> [N]
forall a. a -> [a] -> [a]
:),) ([CS ControlAnn] -> ([N] -> [N], [CS ControlAnn]))
-> [CS ControlAnn] -> ([N] -> [N], [CS ControlAnn])
forall a b. (a -> b) -> a -> b
$ case [CS ControlAnn] -> Maybe (CS ControlAnn, [CS ControlAnn])
forall a. [a] -> Maybe (a, [a])
uncons [CS ControlAnn]
ss' of
Maybe (CS ControlAnn, [CS ControlAnn])
Nothing -> [CS ControlAnn]
ss'[CS ControlAnn] -> [CS ControlAnn] -> [CS ControlAnn]
forall a. [a] -> [a] -> [a]
++[CS ControlAnn
l']
Just (CS ControlAnn
hh, [CS ControlAnn]
bs) -> let h' :: CS ControlAnn
h' = (ControlAnn -> ControlAnn) -> CS ControlAnn -> CS ControlAnn
forall a b. (a -> b) -> CS a -> CS b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (N -> ControlAnn -> ControlAnn
addH N
i) CS ControlAnn
hh in CS ControlAnn
h'CS ControlAnn -> [CS ControlAnn] -> [CS ControlAnn]
forall a. a -> [a] -> [a]
:[CS ControlAnn]
bs[CS ControlAnn] -> [CS ControlAnn] -> [CS ControlAnn]
forall a. [a] -> [a] -> [a]
++[CS ControlAnn
l']
Maybe (CS ControlAnn, [CS ControlAnn])
Nothing -> ([N] -> [N]
forall a. a -> a
id, [CS ControlAnn]
preSs)
tieBody :: N -> ([N] -> [N]) -> [CS ()] -> FreshM ([N] -> [N], [CS ControlAnn])
tieBody :: N
-> ([N] -> [N]) -> [CS ()] -> FreshM ([N] -> [N], [CS ControlAnn])
tieBody N
h [N] -> [N]
f [CS ()]
ss = do
preSs <- [CS ()] -> FreshM [CS ControlAnn]
addCF [CS ()]
ss
case uncons preSs of
Just (CS ControlAnn
i1, [CS ControlAnn]
_) ->
let hi :: N
hi=ControlAnn -> N
node (CS ControlAnn -> ControlAnn
forall a. CS a -> a
lann CS ControlAnn
i1)
([CS ControlAnn]
ss',CS ControlAnn
l) = [CS ControlAnn] -> ([CS ControlAnn], CS ControlAnn)
forall a. [a] -> ([a], a)
unsnoc [CS ControlAnn]
preSs
l' :: CS ControlAnn
l'=(ControlAnn -> ControlAnn) -> CS ControlAnn -> CS ControlAnn
forall a b. (a -> b) -> CS a -> CS b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (([N] -> [N]) -> ControlAnn -> ControlAnn
mC ((N
hN -> [N] -> [N]
forall a. a -> [a] -> [a]
:)([N] -> [N]) -> ([N] -> [N]) -> [N] -> [N]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.[N] -> [N]
f)) CS ControlAnn
l
ss'' :: [CS ControlAnn]
ss''=[CS ControlAnn]
ss'[CS ControlAnn] -> [CS ControlAnn] -> [CS ControlAnn]
forall a. [a] -> [a] -> [a]
++[CS ControlAnn
l']
in ([N] -> [N], [CS ControlAnn])
-> FreshM ([N] -> [N], [CS ControlAnn])
forall a. a -> StateT (N, Map Label N, Map Label [N]) Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((N
hiN -> [N] -> [N]
forall a. a -> [a] -> [a]
:), [CS ControlAnn]
ss'')
Maybe (CS ControlAnn, [CS ControlAnn])
Nothing -> ([N] -> [N], [CS ControlAnn])
-> FreshM ([N] -> [N], [CS ControlAnn])
forall a. a -> StateT (N, Map Label N, Map Label [N]) Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([N] -> [N]
forall a. a -> a
id, [])
addCF :: [CS ()] -> FreshM [CS ControlAnn]
addCF :: [CS ()] -> FreshM [CS ControlAnn]
addCF [] = [CS ControlAnn] -> FreshM [CS ControlAnn]
forall a. a -> StateT (N, Map Label N, Map Label [N]) Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure []
addCF ((Def ()
_ Label
l [CS ()]
ss):[CS ()]
stmts) = do
i <- Label -> FreshM N
ll Label
l
nextStmts <- addCF stmts
preSs <- addCF ss
case uncons preSs of
Maybe (CS ControlAnn, [CS ControlAnn])
Nothing -> FreshM [CS ControlAnn]
forall a. HasCallStack => a
undefined
Just (CS ControlAnn
h, [CS ControlAnn]
_) ->
let hi :: N
hi=ControlAnn -> N
node (CS ControlAnn -> ControlAnn
forall a. CS a -> a
lann CS ControlAnn
h)
([CS ControlAnn]
ss',CS ControlAnn
lϵ) = [CS ControlAnn] -> ([CS ControlAnn], CS ControlAnn)
forall a. [a] -> ([a], a)
unsnoc [CS ControlAnn]
preSs
in do
l_is <- Label -> FreshM [N]
lC Label
l
let l'= (ControlAnn -> ControlAnn) -> CS ControlAnn -> CS ControlAnn
forall a b. (a -> b) -> CS a -> CS b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (([N] -> [N]) -> ControlAnn -> ControlAnn
mC ([N] -> [N] -> [N]
forall a b. a -> b -> a
const [N]
l_is)) CS ControlAnn
lϵ
ss''=[CS ControlAnn]
ss'[CS ControlAnn] -> [CS ControlAnn] -> [CS ControlAnn]
forall a. [a] -> [a] -> [a]
++[CS ControlAnn
l']
pure (Def (ControlAnn i [hi] (UD IS.empty IS.empty IS.empty IS.empty)) l ss'':nextStmts)
addCF (G ()
_ Label
l Label
r:[CS ()]
stmts) = do
i <- Label -> FreshM N
ll Label
r
nextStmts <- addCF stmts
l_i <- ll l
pure (G (ControlAnn i [l_i] (UD IS.empty IS.empty IS.empty IS.empty)) l r:nextStmts)
addCF ((For ()
_ Temp
t CE
el IRel
c CE
eu [CS ()]
ss):[CS ()]
stmts) = do
i <- FreshM N
getFresh
(f, stmts') <- next stmts
(h, ss') <- tieBody i f ss
pure $ For (ControlAnn i (f (h [])) udϵ) t el c eu ss':stmts'
where
udϵ :: UD
udϵ = IntSet -> IntSet -> IntSet -> IntSet -> UD
UD (CE -> IntSet
uE CE
elIntSet -> IntSet -> IntSet
forall a. Semigroup a => a -> a -> a
<>CE -> IntSet
uE CE
eu) IntSet
IS.empty IntSet
IS.empty IntSet
IS.empty
addCF ((For1 ()
_ Temp
t CE
el IRel
c CE
eu [CS ()]
ss):[CS ()]
stmts) = do
i <- FreshM N
getFresh
(f, stmts') <- next stmts
(h, ss') <- tieBody i f ss
pure $ For1 (ControlAnn i (f (h [])) udϵ) t el c eu ss':stmts'
where
udϵ :: UD
udϵ = IntSet -> IntSet -> IntSet -> IntSet -> UD
UD (CE -> IntSet
uE CE
elIntSet -> IntSet -> IntSet
forall a. Semigroup a => a -> a -> a
<>CE -> IntSet
uE CE
eu) IntSet
IS.empty IntSet
IS.empty IntSet
IS.empty
addCF ((While ()
_ Temp
t IRel
c CE
ed [CS ()]
ss):[CS ()]
stmts) = do
i <- FreshM N
getFresh
(f, stmts') <- next stmts
(h, ss') <- tieBody i f ss
pure $ While (ControlAnn i (f (h [])) udϵ) t c ed ss':stmts'
where
udϵ :: UD
udϵ = IntSet -> IntSet -> IntSet -> IntSet -> UD
UD (CE -> IntSet
uE CE
ed) IntSet
IS.empty IntSet
IS.empty IntSet
IS.empty
addCF ((WT ()
_ PE
t [CS ()]
ss):[CS ()]
stmts) = do
i <- FreshM N
getFresh
(f, stmts') <- next stmts
(h, ss') <- tieBody i f ss
pure $ WT (ControlAnn i (f (h [])) udϵ) t ss':stmts'
where
udϵ :: UD
udϵ = IntSet -> IntSet -> IntSet -> IntSet -> UD
UD IntSet
IS.empty IntSet
IS.empty IntSet
IS.empty IntSet
IS.empty
addCF (If ()
_ PE
p [CS ()]
b0 [CS ()]
b1:[CS ()]
stmts) = do
i <- FreshM N
getFresh
(f, stmts') <- next stmts
(h0, b0') <- tieBranch i f b0
(h1, b1') <- tieBranch i f b1
let fnext = if [CS ()] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [CS ()]
b0 Bool -> Bool -> Bool
|| [CS ()] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [CS ()]
b1 then [N] -> [N]
f else [N] -> [N]
forall a. a -> a
id
pure $ If (ControlAnn i (fnext (h0 (h1 []))) udϵ) p b0' b1':stmts'
where
udϵ :: UD
udϵ = IntSet -> IntSet -> IntSet -> IntSet -> UD
UD (PE -> IntSet
uB PE
p) IntSet
IS.empty IntSet
IS.empty IntSet
IS.empty
addCF (Ifn't ()
_ PE
p [CS ()]
b:[CS ()]
stmts) = do
i <- FreshM N
getFresh
(f, stmts') <- next stmts
(h, b') <- tieBranch i f b
pure $ Ifn't (ControlAnn i (f (h [])) udϵ) p b':stmts'
where
udϵ :: UD
udϵ = IntSet -> IntSet -> IntSet -> IntSet -> UD
UD (PE -> IntSet
uB PE
p) IntSet
IS.empty IntSet
IS.empty IntSet
IS.empty
addCF (CS ()
stmt:[CS ()]
stmts) = do
i <- FreshM N
getFresh
(f, stmts') <- next stmts
pure ((stmt $> ControlAnn i (f []) (UD (uses stmt) IS.empty (defs stmt) IS.empty)):stmts')
uE :: CE -> IS.IntSet
uE :: CE -> IntSet
uE ConstI{} = IntSet
IS.empty
uE LA{} = IntSet
IS.empty
uE (EAt ArrAcc
a) = ArrAcc -> IntSet
uA ArrAcc
a
uE Tmp{} = IntSet
IS.empty
uE (Bin IBin
_ CE
e0 CE
e1) = CE -> IntSet
uE CE
e0IntSet -> IntSet -> IntSet
forall a. Semigroup a => a -> a -> a
<>CE -> IntSet
uE CE
e1
uE (CFloor CFE FTemp Double CE
e0) = CFE FTemp Double CE -> IntSet
forall x. CFE FTemp x CE -> IntSet
uF CFE FTemp Double CE
e0
uE (DP Temp
_ CE
e) = CE -> IntSet
uE CE
e
uF :: CFE FTemp x CE -> IS.IntSet
uF :: forall x. CFE FTemp x CE -> IntSet
uF ConstF{} = IntSet
IS.empty
uF FTmp{} = IntSet
IS.empty
uF (FAt ArrAcc
a) = ArrAcc -> IntSet
uA ArrAcc
a
uF (FUn FUn
_ CFE FTemp x CE
e) = CFE FTemp x CE -> IntSet
forall x. CFE FTemp x CE -> IntSet
uF CFE FTemp x CE
e
uF (FBin FBin
_ CFE FTemp x CE
e0 CFE FTemp x CE
e1) = CFE FTemp x CE -> IntSet
forall x. CFE FTemp x CE -> IntSet
uF CFE FTemp x CE
e0IntSet -> IntSet -> IntSet
forall a. Semigroup a => a -> a -> a
<>CFE FTemp x CE -> IntSet
forall x. CFE FTemp x CE -> IntSet
uF CFE FTemp x CE
e1
uF (IE CE
e) = CE -> IntSet
uE CE
e
m'insert :: Maybe AL -> IntSet -> IntSet
m'insert (Just AL
l) IntSet
a = AL -> IntSet -> IntSet
sinsert AL
l IntSet
a
m'insert Maybe AL
Nothing IntSet
a = IntSet
a
uA :: ArrAcc -> IntSet
uA (ARnk Temp
_ (Just AL
l)) = AL -> IntSet
singleton AL
l
uA (ARnk Temp
_ Maybe AL
Nothing) = IntSet
IS.empty
uA (ADim Temp
_ CE
d Maybe AL
l) = Maybe AL -> IntSet -> IntSet
m'insert Maybe AL
l (IntSet -> IntSet) -> IntSet -> IntSet
forall a b. (a -> b) -> a -> b
$ CE -> IntSet
uE CE
d
uA (TupM Temp
_ (Just AL
l)) = AL -> IntSet
singleton AL
l
uA (TupM Temp
_ Maybe AL
Nothing) = IntSet
IS.empty
uA (AElem Temp
_ CE
r CE
ei Maybe AL
l Int64
_) = Maybe AL -> IntSet -> IntSet
m'insert Maybe AL
l (CE -> IntSet
uE CE
rIntSet -> IntSet -> IntSet
forall a. Semigroup a => a -> a -> a
<>CE -> IntSet
uE CE
ei)
uA (Raw Temp
_ CE
e Maybe AL
l Int64
_) = Maybe AL -> IntSet -> IntSet
m'insert Maybe AL
l (CE -> IntSet
uE CE
e)
uA (At Temp
_ [CE]
ss [CE]
ixs Maybe AL
l Int64
_) = Maybe AL -> IntSet -> IntSet
m'insert Maybe AL
l ((CE -> IntSet) -> [CE] -> IntSet
forall m a. Monoid m => (a -> m) -> [a] -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap CE -> IntSet
uE [CE]
ssIntSet -> IntSet -> IntSet
forall a. Semigroup a => a -> a -> a
<>(CE -> IntSet) -> [CE] -> IntSet
forall m a. Monoid m => (a -> m) -> [a] -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap CE -> IntSet
uE [CE]
ixs)
uses :: CS a -> IS.IntSet
uses :: forall a. CS a -> IntSet
uses (Ma a
_ AL
_ Temp
_ CE
r CE
n Int64
_) = CE -> IntSet
uE CE
rIntSet -> IntSet -> IntSet
forall a. Semigroup a => a -> a -> a
<>CE -> IntSet
uE CE
n
uses (MaΠ a
_ AL
_ Temp
_ CE
n) = CE -> IntSet
uE CE
n
uses (MX a
_ FTemp
_ CFE FTemp Double CE
e) = CFE FTemp Double CE -> IntSet
forall x. CFE FTemp x CE -> IntSet
uF CFE FTemp Double CE
e
uses (Wr a
_ ArrAcc
a CE
e) = ArrAcc -> IntSet
uA ArrAcc
a IntSet -> IntSet -> IntSet
forall a. Semigroup a => a -> a -> a
<> CE -> IntSet
uE CE
e
uses (RA a
_ AL
l) = AL -> IntSet
singleton AL
l
uses (Cmov a
_ PE
e0 Temp
_ CE
e1) = PE -> IntSet
uB PE
e0IntSet -> IntSet -> IntSet
forall a. Semigroup a => a -> a -> a
<>CE -> IntSet
uE CE
e1
uses (Fcmov a
_ PE
e0 FTemp
_ CFE FTemp Double CE
e1) = PE -> IntSet
uB PE
e0IntSet -> IntSet -> IntSet
forall a. Semigroup a => a -> a -> a
<>CFE FTemp Double CE -> IntSet
forall x. CFE FTemp x CE -> IntSet
uF CFE FTemp Double CE
e1
uses (WrF a
_ ArrAcc
a CFE FTemp Double CE
e) = ArrAcc -> IntSet
uA ArrAcc
a IntSet -> IntSet -> IntSet
forall a. Semigroup a => a -> a -> a
<> CFE FTemp Double CE -> IntSet
forall x. CFE FTemp x CE -> IntSet
uF CFE FTemp Double CE
e
uses (Cset a
_ PE
e BTemp
_) = PE -> IntSet
uB PE
e
uses (MT a
_ Temp
_ CE
e) = CE -> IntSet
uE CE
e
uses (MB a
_ BTemp
_ PE
e) = PE -> IntSet
uB PE
e
uses (WrP a
_ ArrAcc
a PE
e) = ArrAcc -> IntSet
uA ArrAcc
aIntSet -> IntSet -> IntSet
forall a. Semigroup a => a -> a -> a
<>PE -> IntSet
uB PE
e
uses Rnd{} = IntSet
IS.empty
uses FRnd{} = IntSet
IS.empty
uses (PlProd a
_ Temp
_ [CE]
es) = (CE -> IntSet) -> [CE] -> IntSet
forall m a. Monoid m => (a -> m) -> [a] -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap CE -> IntSet
uE [CE]
es
uses (SZ a
_ Temp
_ Temp
_ CE
e (Just AL
l)) = AL -> IntSet -> IntSet
sinsert AL
l (CE -> IntSet
uE CE
e)
uses (SZ a
_ Temp
_ Temp
_ CE
e Maybe AL
Nothing) = CE -> IntSet
uE CE
e
uses (Pop a
_ CE
e) = CE -> IntSet
uE CE
e
uses (Sa a
_ Temp
_ CE
e) = CE -> IntSet
uE CE
e
uses (CpyD a
_ ArrAcc
d ArrAcc
s CE
n) = ArrAcc -> IntSet
uA ArrAcc
dIntSet -> IntSet -> IntSet
forall a. Semigroup a => a -> a -> a
<>ArrAcc -> IntSet
uA ArrAcc
sIntSet -> IntSet -> IntSet
forall a. Semigroup a => a -> a -> a
<>CE -> IntSet
uE CE
n
uses (CpyE a
_ ArrAcc
d ArrAcc
s CE
n Int64
_) = ArrAcc -> IntSet
uA ArrAcc
dIntSet -> IntSet -> IntSet
forall a. Semigroup a => a -> a -> a
<>ArrAcc -> IntSet
uA ArrAcc
sIntSet -> IntSet -> IntSet
forall a. Semigroup a => a -> a -> a
<>CE -> IntSet
uE CE
n
uB :: PE -> IS.IntSet
uB :: PE -> IntSet
uB (PAt ArrAcc
a) = ArrAcc -> IntSet
uA ArrAcc
a
uB BConst{} = IntSet
IS.empty
uB (IRel IRel
_ CE
e0 CE
e1) = CE -> IntSet
uE CE
e0IntSet -> IntSet -> IntSet
forall a. Semigroup a => a -> a -> a
<>CE -> IntSet
uE CE
e1
uB (FRel FRel
_ CFE FTemp Double CE
e0 CFE FTemp Double CE
e1) = CFE FTemp Double CE -> IntSet
forall x. CFE FTemp x CE -> IntSet
uF CFE FTemp Double CE
e0IntSet -> IntSet -> IntSet
forall a. Semigroup a => a -> a -> a
<>CFE FTemp Double CE -> IntSet
forall x. CFE FTemp x CE -> IntSet
uF CFE FTemp Double CE
e1
uB (Boo BBin
_ PE
e0 PE
e1) = PE -> IntSet
uB PE
e0IntSet -> IntSet -> IntSet
forall a. Semigroup a => a -> a -> a
<>PE -> IntSet
uB PE
e1
uB (IUn IUn
_ CE
e) = CE -> IntSet
uE CE
e
uB Is{} = IntSet
IS.empty
uB (BU BUn
_ PE
e) = PE -> IntSet
uB PE
e
defs :: CS a -> IS.IntSet
defs :: forall a. CS a -> IntSet
defs (Ma a
_ AL
a Temp
_ CE
_ CE
_ Int64
_) = AL -> IntSet
singleton AL
a
defs (MaΠ a
_ AL
a Temp
_ CE
_) = AL -> IntSet
singleton AL
a
defs CS a
_ = IntSet
IS.empty
next :: [CS ()] -> FreshM ([N] -> [N], [CS ControlAnn])
next :: [CS ()] -> FreshM ([N] -> [N], [CS ControlAnn])
next [CS ()]
stmts = do
nextStmts <- [CS ()] -> FreshM [CS ControlAnn]
addCF [CS ()]
stmts
case nextStmts of
[] -> ([N] -> [N], [CS ControlAnn])
-> FreshM ([N] -> [N], [CS ControlAnn])
forall a. a -> StateT (N, Map Label N, Map Label [N]) Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([N] -> [N]
forall a. a -> a
id, [])
(CS ControlAnn
stmt:[CS ControlAnn]
_) -> ([N] -> [N], [CS ControlAnn])
-> FreshM ([N] -> [N], [CS ControlAnn])
forall a. a -> StateT (N, Map Label N, Map Label [N]) Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((ControlAnn -> N
node (CS ControlAnn -> ControlAnn
forall a. CS a -> a
lann CS ControlAnn
stmt) N -> [N] -> [N]
forall a. a -> [a] -> [a]
:), [CS ControlAnn]
nextStmts)
brs :: [CS ()] -> FreshM ()
brs :: [CS ()] -> FreshM ()
brs [] = () -> FreshM ()
forall a. a -> StateT (N, Map Label N, Map Label [N]) Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
brs (G ()
_ Label
l Label
retL:[CS ()]
stmts) = do {i <- Label -> FreshM N
fm Label
retL; b3 i l; brs stmts}
brs (Def ()
_ Label
f [CS ()]
b:[CS ()]
stmts) = Label -> FreshM N
fm Label
f FreshM N -> FreshM () -> FreshM ()
forall a b.
StateT (N, Map Label N, Map Label [N]) Identity a
-> StateT (N, Map Label N, Map Label [N]) Identity b
-> StateT (N, Map Label N, Map Label [N]) Identity b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> [CS ()] -> FreshM ()
brs [CS ()]
b FreshM () -> FreshM () -> FreshM ()
forall a b.
StateT (N, Map Label N, Map Label [N]) Identity a
-> StateT (N, Map Label N, Map Label [N]) Identity b
-> StateT (N, Map Label N, Map Label [N]) Identity b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> [CS ()] -> FreshM ()
brs [CS ()]
stmts
brs (For ()
_ Temp
_ CE
_ IRel
_ CE
_ [CS ()]
ss:[CS ()]
stmts) = [CS ()] -> FreshM ()
brs [CS ()]
ss FreshM () -> FreshM () -> FreshM ()
forall a b.
StateT (N, Map Label N, Map Label [N]) Identity a
-> StateT (N, Map Label N, Map Label [N]) Identity b
-> StateT (N, Map Label N, Map Label [N]) Identity b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> [CS ()] -> FreshM ()
brs [CS ()]
stmts
brs (For1 ()
_ Temp
_ CE
_ IRel
_ CE
_ [CS ()]
ss:[CS ()]
stmts) = [CS ()] -> FreshM ()
brs [CS ()]
ss FreshM () -> FreshM () -> FreshM ()
forall a b.
StateT (N, Map Label N, Map Label [N]) Identity a
-> StateT (N, Map Label N, Map Label [N]) Identity b
-> StateT (N, Map Label N, Map Label [N]) Identity b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> [CS ()] -> FreshM ()
brs [CS ()]
stmts
brs (While ()
_ Temp
_ IRel
_ CE
_ [CS ()]
ss:[CS ()]
stmts) = [CS ()] -> FreshM ()
brs [CS ()]
ss FreshM () -> FreshM () -> FreshM ()
forall a b.
StateT (N, Map Label N, Map Label [N]) Identity a
-> StateT (N, Map Label N, Map Label [N]) Identity b
-> StateT (N, Map Label N, Map Label [N]) Identity b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> [CS ()] -> FreshM ()
brs [CS ()]
stmts
brs (WT ()
_ PE
_ [CS ()]
ss:[CS ()]
stmts) = [CS ()] -> FreshM ()
brs [CS ()]
ss FreshM () -> FreshM () -> FreshM ()
forall a b.
StateT (N, Map Label N, Map Label [N]) Identity a
-> StateT (N, Map Label N, Map Label [N]) Identity b
-> StateT (N, Map Label N, Map Label [N]) Identity b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> [CS ()] -> FreshM ()
brs [CS ()]
stmts
brs (If ()
_ PE
_ [CS ()]
ss [CS ()]
ss':[CS ()]
stmts) = [CS ()] -> FreshM ()
brs [CS ()]
ss FreshM () -> FreshM () -> FreshM ()
forall a b.
StateT (N, Map Label N, Map Label [N]) Identity a
-> StateT (N, Map Label N, Map Label [N]) Identity b
-> StateT (N, Map Label N, Map Label [N]) Identity b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> [CS ()] -> FreshM ()
brs [CS ()]
ss' FreshM () -> FreshM () -> FreshM ()
forall a b.
StateT (N, Map Label N, Map Label [N]) Identity a
-> StateT (N, Map Label N, Map Label [N]) Identity b
-> StateT (N, Map Label N, Map Label [N]) Identity b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> [CS ()] -> FreshM ()
brs [CS ()]
stmts
brs (Ifn't ()
_ PE
_ [CS ()]
ss:[CS ()]
stmts) = [CS ()] -> FreshM ()
brs [CS ()]
ss FreshM () -> FreshM () -> FreshM ()
forall a b.
StateT (N, Map Label N, Map Label [N]) Identity a
-> StateT (N, Map Label N, Map Label [N]) Identity b
-> StateT (N, Map Label N, Map Label [N]) Identity b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> [CS ()] -> FreshM ()
brs [CS ()]
stmts
brs (CS ()
_:[CS ()]
asms) = [CS ()] -> FreshM ()
brs [CS ()]
asms