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

sus :: a
sus = [Char] -> a
forall a. HasCallStack => [Char] -> a
error [Char]
"Array only freed at the beginning of one branch of the conditional."

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]
fss 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]
fss 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]
fss Liveness
l
    gg [s :: CS Liveness
s@(Ifn't Liveness
l PE
_ b :: [CS Liveness]
b@(CS Liveness
b0:[CS Liveness]
_))]              = Liveness -> CS Liveness -> [CS Liveness] -> [CS Liveness]
forall {p}. Liveness -> CS Liveness -> p -> p
gEs Liveness
l CS Liveness
b0 [CS Liveness
s { branch = gg b }]
    gg [s :: CS Liveness
s@(Ifn't Liveness
l PE
_ [])]                    = CS Liveness
sCS Liveness -> [CS Liveness] -> [CS Liveness]
forall a. a -> [a] -> [a]
:Liveness -> [CS Liveness]
forall {a}. Liveness -> [CS a]
fss Liveness
l
    gg [s :: CS Liveness
s@(If Liveness
l PE
_ [] [])]                    = CS Liveness
sCS Liveness -> [CS Liveness] -> [CS Liveness]
forall a. a -> [a] -> [a]
:Liveness -> [CS Liveness]
forall {a}. Liveness -> [CS a]
fss Liveness
l
    gg [s :: CS Liveness
s@(If Liveness
l PE
_ b0 :: [CS Liveness]
b0@(CS Liveness
b00:[CS Liveness]
_) [])]            = Liveness -> CS Liveness -> [CS Liveness] -> [CS Liveness]
forall {p}. Liveness -> CS Liveness -> p -> p
gEs Liveness
l CS Liveness
b00 [CS Liveness
s { iBranch = gg b0 }]
    gg [s :: CS Liveness
s@(If Liveness
l PE
_ [] b1 :: [CS Liveness]
b1@(CS Liveness
b10:[CS Liveness]
_))]            = Liveness -> CS Liveness -> [CS Liveness] -> [CS Liveness]
forall {p}. Liveness -> CS Liveness -> p -> p
gEs Liveness
l CS Liveness
b10 [CS Liveness
s { eBranch = gg b1 }]
    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
_ b0 :: [CS Liveness]
b0@(CS Liveness
b00:[CS Liveness]
_) b1 :: [CS Liveness]
b1@(CS Liveness
b10:[CS Liveness]
_)):[CS Liveness]
ss) = CS Liveness
s { iBranch = fs l b00++gg b0, eBranch = fs l b10++gg b1 }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
_ b0 :: [CS Liveness]
b0@(CS Liveness
b00:[CS Liveness]
_) [CS Liveness]
_):ss :: [CS Liveness]
ss@(CS Liveness
s0:[CS Liveness]
_))   = Liveness -> CS Liveness -> [CS Liveness] -> [CS Liveness]
forall {p}. Liveness -> CS Liveness -> p -> p
gEs Liveness
l CS Liveness
b00 ([CS Liveness] -> [CS Liveness]) -> [CS Liveness] -> [CS Liveness]
forall a b. (a -> b) -> a -> b
$ CS Liveness
s { iBranch = gg b0 }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]
_ b1 :: [CS Liveness]
b1@(CS Liveness
b10:[CS Liveness]
_)):ss :: [CS Liveness]
ss@(CS Liveness
s0:[CS Liveness]
_))   = Liveness -> CS Liveness -> [CS Liveness] -> [CS Liveness]
forall {p}. Liveness -> CS Liveness -> p -> p
gEs Liveness
l CS Liveness
b10 ([CS Liveness] -> [CS Liveness]) -> [CS Liveness] -> [CS Liveness]
forall a b. (a -> b) -> a -> b
$ CS Liveness
s { 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@(If Liveness
l PE
_ [CS Liveness]
_ [CS Liveness]
_):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 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
_ b :: [CS Liveness]
b@(CS Liveness
b0:[CS Liveness]
_)):ss :: [CS Liveness]
ss@(CS Liveness
s0:[CS Liveness]
_))    = Liveness -> CS Liveness -> [CS Liveness] -> [CS Liveness]
forall {p}. Liveness -> CS Liveness -> p -> p
gEs Liveness
l CS Liveness
b0 ([CS Liveness] -> [CS Liveness]) -> [CS Liveness] -> [CS Liveness]
forall a b. (a -> b) -> a -> b
$ 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@(Ifn't Liveness
l PE
_ [CS Liveness]
_):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 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]
fss (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 []                                    = []

    es :: Liveness -> CS Liveness -> Bool
es Liveness
l CS Liveness
s = [Temp] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null([Temp] -> Bool) -> [Temp] -> Bool
forall a b. (a -> b) -> a -> b
$Liveness -> CS Liveness -> [Temp]
ts Liveness
l CS Liveness
s
    gEs :: Liveness -> CS Liveness -> p -> p
gEs Liveness
l CS Liveness
s p
x = if Liveness -> CS Liveness -> Bool
es Liveness
l CS Liveness
s then p
x else p
forall {a}. a
sus

    fss :: Liveness -> [CS a]
fss Liveness
l = [ Temp -> CS a
forall a. Temp -> CS a
Free Temp
t | Temp
t <- Liveness -> [Temp]
tss Liveness
l ]
    tss :: Liveness -> [Temp]
tss 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)))