2 module Vectorise.Utils.PADict (
9 import Vectorise.Builtins
10 import Vectorise.Utils.Base
24 paDictArgType :: TyVar -> VM (Maybe Type)
25 paDictArgType tv = go (TyVarTy tv) (tyVarKind tv)
27 go ty k | Just k' <- kindView k = go ty k'
30 tv <- newTyVar (fsLit "a") k1
31 mty1 <- go (TyVarTy tv) k1
34 mty2 <- go (AppTy ty (TyVarTy tv)) k2
35 return $ fmap (ForAllTy tv . FunTy ty1) mty2
40 = liftM Just (mkBuiltinTyConApp paTyCon [ty])
42 go _ _ = return Nothing
45 -- | Get the PA dictionary for some type
46 paDictOfType :: Type -> VM CoreExpr
48 = paDictOfTyApp ty_fn ty_args
50 (ty_fn, ty_args) = splitAppTys ty
52 paDictOfTyApp :: Type -> [Type] -> VM CoreExpr
53 paDictOfTyApp ty_fn ty_args
54 | Just ty_fn' <- coreView ty_fn
55 = paDictOfTyApp ty_fn' ty_args
57 -- for type variables, look up the dfun and apply to the PA dictionaries
58 -- of the type arguments
59 paDictOfTyApp (TyVarTy tv) ty_args
60 = do dfun <- maybeV (lookupTyVarPA tv)
61 dicts <- mapM paDictOfType ty_args
62 return $ dfun `mkTyApps` ty_args `mkApps` dicts
64 -- for tycons, we also need to apply the dfun to the PR dictionary of
65 -- the representation type
66 paDictOfTyApp (TyConApp tc []) ty_args
68 dfun <- maybeV $ lookupTyConPA tc
69 pr <- prDictOfPRepr tc ty_args
70 dicts <- mapM paDictOfType ty_args
71 return $ Var dfun `mkTyApps` ty_args `mkApps` (pr:dicts)
73 paDictOfTyApp _ _ = failure
75 failure = cantVectorise "Can't construct PA dictionary for type" (ppr ty)
77 paMethod :: (Builtins -> Var) -> String -> Type -> VM CoreExpr
79 | Just tycon <- splitPrimTyCon ty
81 . maybeCantVectoriseM "No PA method" (text name <+> text "for" <+> ppr tycon)
82 $ lookupPrimMethod tycon name
87 dict <- paDictOfType ty
88 return $ mkApps (Var fn) [Type ty, dict]
90 -- | Get the PR (PRepr t) dictionary, where t is the tycon applied to the type
92 prDictOfPRepr :: TyCon -> [Type] -> VM CoreExpr
93 prDictOfPRepr tycon tys
95 (prepr_tc, prepr_args) <- preprSynTyCon (mkTyConApp tycon tys)
96 case coreView (mkTyConApp prepr_tc prepr_args) of
98 dict <- prDictOfReprType rhs
99 pr_co <- mkBuiltinCo prTyCon
100 let Just arg_co = tyConFamilyCoercion_maybe prepr_tc
101 let co = mkAppCoercion pr_co
103 $ mkTyConApp arg_co prepr_args
104 return $ mkCoerce co dict
105 Nothing -> cantVectorise "Invalid PRepr type instance"
106 $ ppr $ mkTyConApp prepr_tc prepr_args
108 -- | Get the PR dictionary for a type. The argument must be a representation
110 prDictOfReprType :: Type -> VM CoreExpr
112 | Just (tycon, tyargs) <- splitTyConApp_maybe ty
114 -- a representation tycon must have a PR instance
115 dfun <- maybeV $ lookupTyConPR tycon
116 prDFunApply dfun tyargs
120 -- it is a tyvar or an application of a tyvar
121 -- determine the PR dictionary from its PA dictionary
123 -- NOTE: This assumes that PRepr t ~ t is for all representation types
126 -- FIXME: This doesn't work for kinds other than * at the moment. We'd
127 -- have to simply abstract the term over the missing type arguments.
128 pa <- paDictOfType ty
129 prsel <- builtin paPRSel
130 return $ Var prsel `mkApps` [Type ty, pa]
132 -- | Apply a tycon's PR dfun to dictionary arguments (PR or PA) corresponding
133 -- to the argument types.
134 prDFunApply :: Var -> [Type] -> VM CoreExpr
136 | Just [] <- ctxs -- PR (a :-> b) doesn't have a context
137 = return $ Var dfun `mkTyApps` tys
139 | Just tycons <- ctxs
140 , length tycons == length tys
142 pa <- builtin paTyCon
143 pr <- builtin prTyCon
144 args <- zipWithM (dictionary pa pr) tys tycons
145 return $ Var dfun `mkTyApps` tys `mkApps` args
147 | otherwise = invalid
149 -- the dfun's contexts - if its type is (PA a, PR b) => PR (C a b) then
150 -- ctxs is Just [PA, PR]
151 ctxs = fmap (map fst)
153 $ map splitTyConApp_maybe
160 dictionary pa pr ty tycon
161 | tycon == pa = paDictOfType ty
162 | tycon == pr = prDictOfReprType ty
163 | otherwise = invalid
165 invalid = cantVectorise "Invalid PR dfun type" (ppr (varType dfun) <+> ppr tys)