module Vectorise.Monad.Global (
readGEnv,
setGEnv,
updGEnv,
defGlobalVar,
lookupVectDecl, noVectDecl,
globalScalarVars, isGlobalScalarVar, globalScalarTyCons,
lookupTyCon,
defTyConName, defTyCon, globalVectTyCons,
lookupDataCon,
defDataCon,
lookupTyConPA,
defTyConPAs,
lookupTyConPR
) where
import Vectorise.Monad.Base
import Vectorise.Env
import CoreSyn
import Type
import TyCon
import DataCon
import NameEnv
import NameSet
import Name
import VarEnv
import VarSet
import Var as Var
import FastString
import Outputable
readGEnv :: (GlobalEnv -> a) -> VM a
readGEnv f = VM $ \_ genv lenv -> return (Yes genv lenv (f genv))
setGEnv :: GlobalEnv -> VM ()
setGEnv genv = VM $ \_ _ lenv -> return (Yes genv lenv ())
updGEnv :: (GlobalEnv -> GlobalEnv) -> VM ()
updGEnv f = VM $ \_ genv lenv -> return (Yes (f genv) lenv ())
defGlobalVar :: Var -> Var -> VM ()
defGlobalVar v v'
= do { traceVt "add global var mapping:" (ppr v <+> text "-->" <+> ppr v')
; currentDef <- readGEnv $ \env -> lookupVarEnv (global_vars env) v
; case currentDef of
Just old_v' -> cantVectorise "Variable is already vectorised:" $
ppr v <+> moduleOf v old_v'
Nothing -> return ()
; updGEnv $ \env -> env { global_vars = extendVarEnv (global_vars env) v v' }
}
where
moduleOf var var' | var == var'
= ptext (sLit "vectorises to itself")
| Just mod <- nameModule_maybe (Var.varName var')
= ptext (sLit "in module") <+> ppr mod
| otherwise
= ptext (sLit "in the current module")
lookupVectDecl :: Var -> VM (Maybe (Type, CoreExpr))
lookupVectDecl var = readGEnv $ \env -> lookupVarEnv (global_vect_decls env) var
noVectDecl :: Var -> VM Bool
noVectDecl var = readGEnv $ \env -> elemVarSet var (global_novect_vars env)
globalScalarVars :: VM VarSet
globalScalarVars = readGEnv global_scalar_vars
isGlobalScalarVar :: Var -> VM Bool
isGlobalScalarVar var = readGEnv $ \env -> var `elemVarSet` global_scalar_vars env
globalScalarTyCons :: VM NameSet
globalScalarTyCons = readGEnv global_scalar_tycons
lookupTyCon :: TyCon -> VM (Maybe TyCon)
lookupTyCon tc
| isUnLiftedTyCon tc || isTupleTyCon tc
= return (Just tc)
| otherwise
= readGEnv $ \env -> lookupNameEnv (global_tycons env) (tyConName tc)
defTyConName :: TyCon -> Name -> TyCon -> VM ()
defTyConName tc nameOfTc' tc'
= do { traceVt "add global tycon mapping:" (ppr tc <+> text "-->" <+> ppr nameOfTc')
; currentDef <- readGEnv $ \env -> lookupNameEnv (global_tycons env) (tyConName tc)
; case currentDef of
Just old_tc' -> cantVectorise "Type constructor or class is already vectorised:" $
ppr tc <+> moduleOf tc old_tc'
Nothing -> return ()
; updGEnv $ \env ->
env { global_tycons = extendNameEnv (global_tycons env) (tyConName tc) tc' }
}
where
moduleOf tc tc' | tc == tc'
= ptext (sLit "vectorises to itself")
| Just mod <- nameModule_maybe (tyConName tc')
= ptext (sLit "in module") <+> ppr mod
| otherwise
= ptext (sLit "in the current module")
defTyCon :: TyCon -> TyCon -> VM ()
defTyCon tc tc' = defTyConName tc (tyConName tc') tc'
globalVectTyCons :: VM (NameEnv TyCon)
globalVectTyCons = readGEnv global_tycons
lookupDataCon :: DataCon -> VM (Maybe DataCon)
lookupDataCon dc
| isTupleTyCon (dataConTyCon dc)
= return (Just dc)
| otherwise
= readGEnv $ \env -> lookupNameEnv (global_datacons env) (dataConName dc)
defDataCon :: DataCon -> DataCon -> VM ()
defDataCon dc dc' = updGEnv $ \env ->
env { global_datacons = extendNameEnv (global_datacons env) (dataConName dc) dc' }
lookupTyConPA :: TyCon -> VM (Maybe Var)
lookupTyConPA tc
= readGEnv $ \env -> lookupNameEnv (global_pa_funs env) (tyConName tc)
defTyConPAs :: [(TyCon, Var)] -> VM ()
defTyConPAs ps = updGEnv $ \env ->
env { global_pa_funs = extendNameEnvList (global_pa_funs env)
[(tyConName tc, pa) | (tc, pa) <- ps] }
lookupTyConPR :: TyCon -> VM (Maybe Var)
lookupTyConPR tc = readGEnv $ \env -> lookupNameEnv (global_pr_funs env) (tyConName tc)