{-# LANGUAGE BangPatterns #-}
module GHC.Utils.FV (
FV, InterestingVarFun,
fvVarList, fvVarSet, fvDVarSet,
unitFV,
emptyFV,
mkFVs,
unionFV,
unionsFV,
delFV,
delFVs,
filterFV,
mapUnionFV,
) where
import GHC.Prelude
import GHC.Types.Var
import GHC.Types.Var.Set
type InterestingVarFun = Var -> Bool
type FV = InterestingVarFun
-> VarSet
-> VarAcc
-> VarAcc
type VarAcc = ([Var], VarSet)
fvVarAcc :: FV -> ([Var], VarSet)
fvVarAcc :: FV -> ([Var], VarSet)
fvVarAcc FV
fv = FV
fv (Bool -> Var -> Bool
forall a b. a -> b -> a
const Bool
True) VarSet
emptyVarSet ([], VarSet
emptyVarSet)
fvVarList :: FV -> [Var]
fvVarList :: FV -> [Var]
fvVarList = ([Var], VarSet) -> [Var]
forall a b. (a, b) -> a
fst (([Var], VarSet) -> [Var])
-> (FV -> ([Var], VarSet)) -> FV -> [Var]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FV -> ([Var], VarSet)
fvVarAcc
fvDVarSet :: FV -> DVarSet
fvDVarSet :: FV -> DVarSet
fvDVarSet = [Var] -> DVarSet
mkDVarSet ([Var] -> DVarSet) -> (FV -> [Var]) -> FV -> DVarSet
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FV -> [Var]
fvVarList
fvVarSet :: FV -> VarSet
fvVarSet :: FV -> VarSet
fvVarSet = ([Var], VarSet) -> VarSet
forall a b. (a, b) -> b
snd (([Var], VarSet) -> VarSet)
-> (FV -> ([Var], VarSet)) -> FV -> VarSet
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FV -> ([Var], VarSet)
fvVarAcc
unitFV :: Id -> FV
unitFV :: Var -> FV
unitFV Var
var Var -> Bool
fv_cand VarSet
in_scope acc :: ([Var], VarSet)
acc@([Var]
have, VarSet
haveSet)
| Var
var Var -> VarSet -> Bool
`elemVarSet` VarSet
in_scope = ([Var], VarSet)
acc
| Var
var Var -> VarSet -> Bool
`elemVarSet` VarSet
haveSet = ([Var], VarSet)
acc
| Var -> Bool
fv_cand Var
var = (Var
varVar -> [Var] -> [Var]
forall a. a -> [a] -> [a]
:[Var]
have, VarSet -> Var -> VarSet
extendVarSet VarSet
haveSet Var
var)
| Bool
otherwise = ([Var], VarSet)
acc
{-# INLINE unitFV #-}
emptyFV :: FV
emptyFV :: FV
emptyFV Var -> Bool
_ VarSet
_ ([Var], VarSet)
acc = ([Var], VarSet)
acc
{-# INLINE emptyFV #-}
unionFV :: FV -> FV -> FV
unionFV :: FV -> FV -> FV
unionFV FV
fv1 FV
fv2 Var -> Bool
fv_cand VarSet
in_scope ([Var], VarSet)
acc =
FV
fv1 Var -> Bool
fv_cand VarSet
in_scope (([Var], VarSet) -> ([Var], VarSet))
-> ([Var], VarSet) -> ([Var], VarSet)
forall a b. (a -> b) -> a -> b
$! FV
fv2 Var -> Bool
fv_cand VarSet
in_scope (([Var], VarSet) -> ([Var], VarSet))
-> ([Var], VarSet) -> ([Var], VarSet)
forall a b. (a -> b) -> a -> b
$! ([Var], VarSet)
acc
{-# INLINE unionFV #-}
delFV :: Var -> FV -> FV
delFV :: Var -> FV -> FV
delFV Var
var FV
fv Var -> Bool
fv_cand !VarSet
in_scope ([Var], VarSet)
acc =
FV
fv Var -> Bool
fv_cand (VarSet -> Var -> VarSet
extendVarSet VarSet
in_scope Var
var) ([Var], VarSet)
acc
{-# INLINE delFV #-}
delFVs :: VarSet -> FV -> FV
delFVs :: VarSet -> FV -> FV
delFVs VarSet
vars FV
fv Var -> Bool
fv_cand !VarSet
in_scope ([Var], VarSet)
acc =
FV
fv Var -> Bool
fv_cand (VarSet
in_scope VarSet -> VarSet -> VarSet
`unionVarSet` VarSet
vars) ([Var], VarSet)
acc
{-# INLINE delFVs #-}
filterFV :: InterestingVarFun -> FV -> FV
filterFV :: (Var -> Bool) -> FV -> FV
filterFV Var -> Bool
fv_cand2 FV
fv Var -> Bool
fv_cand1 VarSet
in_scope ([Var], VarSet)
acc =
FV
fv (\Var
v -> Var -> Bool
fv_cand1 Var
v Bool -> Bool -> Bool
&& Var -> Bool
fv_cand2 Var
v) VarSet
in_scope ([Var], VarSet)
acc
{-# INLINE filterFV #-}
mapUnionFV :: (a -> FV) -> [a] -> FV
mapUnionFV :: forall a. (a -> FV) -> [a] -> FV
mapUnionFV a -> FV
_f [] Var -> Bool
_fv_cand VarSet
_in_scope ([Var], VarSet)
acc = ([Var], VarSet)
acc
mapUnionFV a -> FV
f (a
a:[a]
as) Var -> Bool
fv_cand VarSet
in_scope ([Var], VarSet)
acc =
(a -> FV) -> [a] -> FV
forall a. (a -> FV) -> [a] -> FV
mapUnionFV a -> FV
f [a]
as Var -> Bool
fv_cand VarSet
in_scope (([Var], VarSet) -> ([Var], VarSet))
-> ([Var], VarSet) -> ([Var], VarSet)
forall a b. (a -> b) -> a -> b
$! a -> FV
f a
a Var -> Bool
fv_cand VarSet
in_scope (([Var], VarSet) -> ([Var], VarSet))
-> ([Var], VarSet) -> ([Var], VarSet)
forall a b. (a -> b) -> a -> b
$! ([Var], VarSet)
acc
{-# INLINABLE mapUnionFV #-}
unionsFV :: [FV] -> FV
unionsFV :: [FV] -> FV
unionsFV [FV]
fvs Var -> Bool
fv_cand VarSet
in_scope ([Var], VarSet)
acc = (FV -> FV) -> [FV] -> FV
forall a. (a -> FV) -> [a] -> FV
mapUnionFV FV -> FV
forall a. a -> a
id [FV]
fvs Var -> Bool
fv_cand VarSet
in_scope ([Var], VarSet)
acc
{-# INLINE unionsFV #-}
mkFVs :: [Var] -> FV
mkFVs :: [Var] -> FV
mkFVs [Var]
vars Var -> Bool
fv_cand VarSet
in_scope ([Var], VarSet)
acc =
(Var -> FV) -> [Var] -> FV
forall a. (a -> FV) -> [a] -> FV
mapUnionFV Var -> FV
unitFV [Var]
vars Var -> Bool
fv_cand VarSet
in_scope ([Var], VarSet)
acc
{-# INLINE mkFVs #-}