{-# LANGUAGE CPP #-}
module Vectorise.Utils.Base
( voidType
, newLocalVVar
, mkDataConTag, dataConTagZ
, mkWrapType
, mkClosureTypes
, mkPReprType
, mkPDataType, mkPDatasType
, splitPrimTyCon
, mkBuiltinCo
, wrapNewTypeBodyOfWrap
, unwrapNewTypeBodyOfWrap
, wrapNewTypeBodyOfPDataWrap
, unwrapNewTypeBodyOfPDataWrap
, wrapNewTypeBodyOfPDatasWrap
, unwrapNewTypeBodyOfPDatasWrap
, pdataReprTyCon
, pdataReprTyConExact
, pdatasReprTyConExact
, pdataUnwrapScrut
, preprFamInst
) where
import Vectorise.Monad
import Vectorise.Vect
import Vectorise.Builtins
import CoreSyn
import CoreUtils
import FamInstEnv
import Coercion
import Type
import TyCon
import DataCon
import MkId
import DynFlags
import FastString
#include "HsVersions.h"
voidType :: VM Type
voidType = mkBuiltinTyConApp voidTyCon []
newLocalVVar :: FastString -> Type -> VM VVar
newLocalVVar fs vty
= do
lty <- mkPDataType vty
vv <- newLocalVar fs vty
lv <- newLocalVar fs lty
return (vv,lv)
mkDataConTag :: DynFlags -> DataCon -> CoreExpr
mkDataConTag dflags = mkIntLitInt dflags . dataConTagZ
dataConTagZ :: DataCon -> Int
dataConTagZ con = dataConTag con - fIRST_TAG
mkWrapType :: Type -> VM Type
mkWrapType ty = mkBuiltinTyConApp wrapTyCon [ty]
mkClosureTypes :: [Type] -> Type -> VM Type
mkClosureTypes = mkBuiltinTyConApps closureTyCon
mkPReprType :: Type -> VM Type
mkPReprType ty = mkBuiltinTyConApp preprTyCon [ty]
mkPDataType :: Type -> VM Type
mkPDataType ty = mkBuiltinTyConApp pdataTyCon [ty]
mkPDatasType :: Type -> VM Type
mkPDatasType ty = mkBuiltinTyConApp pdatasTyCon [ty]
mkBuiltinTyConApp :: (Builtins -> TyCon) -> [Type] -> VM Type
mkBuiltinTyConApp get_tc tys
= do { tc <- builtin get_tc
; return $ mkTyConApp tc tys
}
mkBuiltinTyConApps :: (Builtins -> TyCon) -> [Type] -> Type -> VM Type
mkBuiltinTyConApps get_tc tys ty
= do { tc <- builtin get_tc
; return $ foldr (mk tc) ty tys
}
where
mk tc ty1 ty2 = mkTyConApp tc [ty1,ty2]
splitPrimTyCon :: Type -> Maybe TyCon
splitPrimTyCon ty
| Just (tycon, []) <- splitTyConApp_maybe ty
, isPrimTyCon tycon
= Just tycon
| otherwise = Nothing
mkBuiltinCo :: (Builtins -> TyCon) -> VM Coercion
mkBuiltinCo get_tc
= do { tc <- builtin get_tc
; return $ mkTyConAppCo Representational tc []
}
wrapNewTypeBodyOfWrap :: CoreExpr -> Type -> VM CoreExpr
wrapNewTypeBodyOfWrap e ty
= do { wrap_tc <- builtin wrapTyCon
; return $ wrapNewTypeBody wrap_tc [ty] e
}
unwrapNewTypeBodyOfWrap :: CoreExpr -> Type -> VM CoreExpr
unwrapNewTypeBodyOfWrap e ty
= do { wrap_tc <- builtin wrapTyCon
; return $ unwrapNewTypeBody wrap_tc [ty] e
}
wrapNewTypeBodyOfPDataWrap :: CoreExpr -> Type -> VM CoreExpr
wrapNewTypeBodyOfPDataWrap e ty
= do { wrap_tc <- builtin wrapTyCon
; pwrap_tc <- pdataReprTyConExact wrap_tc
; return $ wrapNewTypeBody pwrap_tc [ty] e
}
unwrapNewTypeBodyOfPDataWrap :: CoreExpr -> Type -> VM CoreExpr
unwrapNewTypeBodyOfPDataWrap e ty
= do { wrap_tc <- builtin wrapTyCon
; pwrap_tc <- pdataReprTyConExact wrap_tc
; return $ unwrapNewTypeBody pwrap_tc [ty] (unwrapFamInstScrut pwrap_tc [ty] e)
}
wrapNewTypeBodyOfPDatasWrap :: CoreExpr -> Type -> VM CoreExpr
wrapNewTypeBodyOfPDatasWrap e ty
= do { wrap_tc <- builtin wrapTyCon
; pwrap_tc <- pdatasReprTyConExact wrap_tc
; return $ wrapNewTypeBody pwrap_tc [ty] e
}
unwrapNewTypeBodyOfPDatasWrap :: CoreExpr -> Type -> VM CoreExpr
unwrapNewTypeBodyOfPDatasWrap e ty
= do { wrap_tc <- builtin wrapTyCon
; pwrap_tc <- pdatasReprTyConExact wrap_tc
; return $ unwrapNewTypeBody pwrap_tc [ty] (unwrapFamInstScrut pwrap_tc [ty] e)
}
pdataReprTyCon :: Type -> VM (TyCon, [Type])
pdataReprTyCon ty
= do
{ FamInstMatch { fim_instance = famInst
, fim_tys = tys } <- builtin pdataTyCon >>= (`lookupFamInst` [ty])
; return (dataFamInstRepTyCon famInst, tys)
}
pdataReprTyConExact :: TyCon -> VM TyCon
pdataReprTyConExact tycon
= do {
;
; (ptycon, _tys) <- pdataReprTyCon (tycon `mkTyConApp` mkTyVarTys (tyConTyVars tycon))
; return ptycon
}
pdatasReprTyConExact :: TyCon -> VM TyCon
pdatasReprTyConExact tycon
= do {
; (FamInstMatch { fim_instance = ptycon }) <- pdatasReprTyCon (tycon `mkTyConApp` mkTyVarTys (tyConTyVars tycon))
; return $ dataFamInstRepTyCon ptycon
}
where
pdatasReprTyCon ty = builtin pdatasTyCon >>= (`lookupFamInst` [ty])
pdataUnwrapScrut :: VExpr -> VM (CoreExpr, CoreExpr, DataCon)
pdataUnwrapScrut (ve, le)
= do { (tc, arg_tys) <- pdataReprTyCon ty
; let [dc] = tyConDataCons tc
; return (ve, unwrapFamInstScrut tc arg_tys le, dc)
}
where
ty = exprType ve
preprFamInst :: Type -> VM FamInstMatch
preprFamInst ty = builtin preprTyCon >>= (`lookupFamInst` [ty])