module Tip.Calls
( module VarSet
, Constructors(..)
, exprCalls
, calls
, transCalls
, transFrom
) where
import CoreSyn
import Id
import VarSet
import CoreFVs
import DataCon
import TyCon
import Tip.GHCUtils
import Tip.Unfoldings
import Tip.FreeTyCons
import qualified Data.Set as S
data Constructors = With | Without deriving Eq
exprCalls :: Constructors -> CoreExpr -> VarSet
exprCalls cons = exprSomeFreeVars $ \ v ->
(isLocalId v || isGlobalId v || (cons == With && isDataConId v && not (isNewtypeConId v)))
&& (cons == With || not (isDataConId v))
calls :: Constructors -> Id -> VarSet
calls c v = cons `unionVarSet` case maybeUnfolding v of
Just e -> exprCalls c e
_ -> emptyVarSet
where
cons | c == With = mkVarSet (concatMap (map dataConWorkId . tyConDataCons)
(filter (not . isClassTyCon) (S.toList (varTyCons v))))
| otherwise = emptyVarSet
transCalls :: Constructors -> Id -> VarSet
transCalls c = transFrom c . unitVarSet
transFrom :: Constructors -> VarSet -> VarSet
transFrom c = go emptyVarSet
where
go visited queue
| isEmptyVarSet to_visit = visited
| otherwise = go (visited `unionVarSet` to_visit)
(foldVarSet (\ i vs -> calls c i `unionVarSet` vs)
emptyVarSet
to_visit)
where to_visit = queue `minusVarSet` visited