module C.Alloc ( live, frees ) where

import           C
import           C.CF
import           CF
import qualified Data.IntMap as IM
import qualified Data.IntSet as IS
import           Data.Maybe  (mapMaybe)
import           LR

frees :: IM.IntMap Temp -> [CS ()] -> [CS Liveness]
frees :: IntMap Temp -> [CS ()] -> [CS Liveness]
frees IntMap Temp
a = IntMap Temp -> [CS Liveness] -> [CS Liveness]
iF IntMap Temp
a([CS Liveness] -> [CS Liveness])
-> ([CS ()] -> [CS Liveness]) -> [CS ()] -> [CS Liveness]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.[CS ()] -> [CS Liveness]
live

live :: [CS ()] -> [CS Liveness]
live :: [CS ()] -> [CS Liveness]
live = (CS NLiveness -> CS Liveness) -> [CS NLiveness] -> [CS Liveness]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((NLiveness -> Liveness) -> CS NLiveness -> CS Liveness
forall a b. (a -> b) -> CS a -> CS b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap NLiveness -> Liveness
liveness) ([CS NLiveness] -> [CS Liveness])
-> ([CS ()] -> [CS NLiveness]) -> [CS ()] -> [CS Liveness]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (\([Int]
is,[CS ControlAnn]
isns,LivenessMap
lm) -> [Int] -> LivenessMap -> [CS ControlAnn] -> [CS NLiveness]
forall (p :: * -> *).
Copointed p =>
[Int] -> LivenessMap -> [p ControlAnn] -> [p NLiveness]
reconstruct [Int]
is LivenessMap
lm [CS ControlAnn]
isns) (([Int], [CS ControlAnn], LivenessMap) -> [CS NLiveness])
-> ([CS ()] -> ([Int], [CS ControlAnn], LivenessMap))
-> [CS ()]
-> [CS NLiveness]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [CS ()] -> ([Int], [CS ControlAnn], LivenessMap)
cfC

iF :: IM.IntMap Temp -> [CS Liveness] -> [CS Liveness]
iF :: IntMap Temp -> [CS Liveness] -> [CS Liveness]
iF IntMap Temp
a = [CS Liveness] -> [CS Liveness]
gg where
    gg :: [CS Liveness] -> [CS Liveness]
gg (RA{}:[CS Liveness]
cs)                         = [CS Liveness] -> [CS Liveness]
gg [CS Liveness]
cs
    gg [s :: CS Liveness
s@(For Liveness
l Temp
_ CE
_ IRel
_ CE
_ [CS Liveness]
cs)]            = CS Liveness
s { body = gg cs }CS Liveness -> [CS Liveness] -> [CS Liveness]
forall a. a -> [a] -> [a]
:Liveness -> [CS Liveness]
forall {a}. Liveness -> [CS a]
fs0 Liveness
l
    gg [s :: CS Liveness
s@(While Liveness
l Temp
_ IRel
_ CE
_ [CS Liveness]
cs)]            = CS Liveness
s { body = gg cs }CS Liveness -> [CS Liveness] -> [CS Liveness]
forall a. a -> [a] -> [a]
:Liveness -> [CS Liveness]
forall {a}. Liveness -> [CS a]
fs0 Liveness
l
    gg [s :: CS Liveness
s@(For1 Liveness
l Temp
_ CE
_ IRel
_ CE
_ [CS Liveness]
cs)]           = CS Liveness
s { body = gg cs }CS Liveness -> [CS Liveness] -> [CS Liveness]
forall a. a -> [a] -> [a]
:Liveness -> [CS Liveness]
forall {a}. Liveness -> [CS a]
fs0 Liveness
l
    gg [s :: CS Liveness
s@(If Liveness
l PE
_ [CS Liveness]
b0 [CS Liveness]
b1)]                = CS Liveness
s { iBranch = gg b0, eBranch = gg b1 }CS Liveness -> [CS Liveness] -> [CS Liveness]
forall a. a -> [a] -> [a]
:Liveness -> [CS Liveness]
forall {a}. Liveness -> [CS a]
fs0 Liveness
l
    gg [s :: CS Liveness
s@(Ifn't Liveness
l PE
_ [CS Liveness]
b)]                 = CS Liveness
s { branch = gg b }CS Liveness -> [CS Liveness] -> [CS Liveness]
forall a. a -> [a] -> [a]
:Liveness -> [CS Liveness]
forall {a}. Liveness -> [CS a]
fs0 Liveness
l
    gg [s :: CS Liveness
s@(Def Liveness
_ Label
_ [CS Liveness]
cs)]                  = [CS Liveness
s { body = gg cs }]
    gg (s :: CS Liveness
s@(For Liveness
l Temp
_ CE
_ IRel
_ CE
_ [CS Liveness]
cs):ss :: [CS Liveness]
ss@(CS Liveness
s0:[CS Liveness]
_))  = CS Liveness
s { body = gg cs }CS Liveness -> [CS Liveness] -> [CS Liveness]
forall a. a -> [a] -> [a]
:Liveness -> CS Liveness -> [CS Liveness]
forall {a}. Liveness -> CS Liveness -> [CS a]
fs Liveness
l CS Liveness
s0[CS Liveness] -> [CS Liveness] -> [CS Liveness]
forall a. [a] -> [a] -> [a]
++[CS Liveness] -> [CS Liveness]
gg [CS Liveness]
ss
    gg (s :: CS Liveness
s@(While Liveness
l Temp
_ IRel
_ CE
_ [CS Liveness]
cs):ss :: [CS Liveness]
ss@(CS Liveness
s0:[CS Liveness]
_))  = CS Liveness
s { body = gg cs }CS Liveness -> [CS Liveness] -> [CS Liveness]
forall a. a -> [a] -> [a]
:Liveness -> CS Liveness -> [CS Liveness]
forall {a}. Liveness -> CS Liveness -> [CS a]
fs Liveness
l CS Liveness
s0[CS Liveness] -> [CS Liveness] -> [CS Liveness]
forall a. [a] -> [a] -> [a]
++[CS Liveness] -> [CS Liveness]
gg [CS Liveness]
ss
    gg (s :: CS Liveness
s@(For1 Liveness
l Temp
_ CE
_ IRel
_ CE
_ [CS Liveness]
cs):ss :: [CS Liveness]
ss@(CS Liveness
s0:[CS Liveness]
_)) = CS Liveness
s { body = gg cs }CS Liveness -> [CS Liveness] -> [CS Liveness]
forall a. a -> [a] -> [a]
:Liveness -> CS Liveness -> [CS Liveness]
forall {a}. Liveness -> CS Liveness -> [CS a]
fs Liveness
l CS Liveness
s0[CS Liveness] -> [CS Liveness] -> [CS Liveness]
forall a. [a] -> [a] -> [a]
++[CS Liveness] -> [CS Liveness]
gg [CS Liveness]
ss
    gg (s :: CS Liveness
s@(If Liveness
l PE
_ [CS Liveness]
b0 [CS Liveness]
b1):ss :: [CS Liveness]
ss@(CS Liveness
s0:[CS Liveness]
_))      = CS Liveness
s { iBranch = gg b0, eBranch = gg b1 }CS Liveness -> [CS Liveness] -> [CS Liveness]
forall a. a -> [a] -> [a]
:Liveness -> CS Liveness -> [CS Liveness]
forall {a}. Liveness -> CS Liveness -> [CS a]
fs Liveness
l CS Liveness
s0[CS Liveness] -> [CS Liveness] -> [CS Liveness]
forall a. [a] -> [a] -> [a]
++[CS Liveness] -> [CS Liveness]
gg [CS Liveness]
ss
    gg (s :: CS Liveness
s@(Ifn't Liveness
l PE
_ [CS Liveness]
b):ss :: [CS Liveness]
ss@(CS Liveness
s0:[CS Liveness]
_))       = CS Liveness
s { branch = gg b }CS Liveness -> [CS Liveness] -> [CS Liveness]
forall a. a -> [a] -> [a]
:Liveness -> CS Liveness -> [CS Liveness]
forall {a}. Liveness -> CS Liveness -> [CS a]
fs Liveness
l CS Liveness
s0[CS Liveness] -> [CS Liveness] -> [CS Liveness]
forall a. [a] -> [a] -> [a]
++[CS Liveness] -> [CS Liveness]
gg [CS Liveness]
ss
    gg (s :: CS Liveness
s@(Def Liveness
l Label
_ [CS Liveness]
cs):ss :: [CS Liveness]
ss@(CS Liveness
s0:[CS Liveness]
_))        = CS Liveness
s { body = gg cs }CS Liveness -> [CS Liveness] -> [CS Liveness]
forall a. a -> [a] -> [a]
:Liveness -> CS Liveness -> [CS Liveness]
forall {a}. Liveness -> CS Liveness -> [CS a]
fs Liveness
l CS Liveness
s0[CS Liveness] -> [CS Liveness] -> [CS Liveness]
forall a. [a] -> [a] -> [a]
++[CS Liveness] -> [CS Liveness]
gg [CS Liveness]
ss
    gg [CS Liveness
s]                               = CS Liveness
sCS Liveness -> [CS Liveness] -> [CS Liveness]
forall a. a -> [a] -> [a]
:Liveness -> [CS Liveness]
forall {a}. Liveness -> [CS a]
fs0 (CS Liveness -> Liveness
forall a. CS a -> a
lann CS Liveness
s)
    gg (CS Liveness
s:ss :: [CS Liveness]
ss@(CS Liveness
s0:[CS Liveness]
_))                     = CS Liveness
sCS Liveness -> [CS Liveness] -> [CS Liveness]
forall a. a -> [a] -> [a]
:Liveness -> CS Liveness -> [CS Liveness]
forall {a}. Liveness -> CS Liveness -> [CS a]
fs (CS Liveness -> Liveness
forall a. CS a -> a
lann CS Liveness
s) CS Liveness
s0[CS Liveness] -> [CS Liveness] -> [CS Liveness]
forall a. [a] -> [a] -> [a]
++[CS Liveness] -> [CS Liveness]
gg [CS Liveness]
ss
    gg []                                = []

    fs0 :: Liveness -> [CS a]
fs0 Liveness
l = [ Temp -> CS a
forall a. Temp -> CS a
Free Temp
t | Temp
t <- Liveness -> [Temp]
ts0 Liveness
l ]
    ts0 :: Liveness -> [Temp]
ts0 Liveness
l = (Int -> Maybe Temp) -> [Int] -> [Temp]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe (Int -> IntMap Temp -> Maybe Temp
forall a. Int -> IntMap a -> Maybe a
`IM.lookup` IntMap Temp
a) (IntSet -> [Int]
IS.toList (Liveness -> IntSet
ins Liveness
l IntSet -> IntSet -> IntSet
`IS.difference` Liveness -> IntSet
out Liveness
l))
    fs :: Liveness -> CS Liveness -> [CS a]
fs Liveness
l0 CS Liveness
s1 = [ Temp -> CS a
forall a. Temp -> CS a
Free Temp
t | Temp
t <- Liveness -> CS Liveness -> [Temp]
ts Liveness
l0 CS Liveness
s1 ]
    ts :: Liveness -> CS Liveness -> [Temp]
ts Liveness
l0 CS Liveness
s1 = (Int -> Maybe Temp) -> [Int] -> [Temp]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe (Int -> IntMap Temp -> Maybe Temp
forall a. Int -> IntMap a -> Maybe a
`IM.lookup` IntMap Temp
a) (IntSet -> [Int]
IS.toList (Liveness -> IntSet
ins Liveness
l0 IntSet -> IntSet -> IntSet
`IS.difference` Liveness -> IntSet
ins (CS Liveness -> Liveness
forall a. CS a -> a
lann CS Liveness
s1)))