Modify generation of PR dictionaries for new scheme
[ghc-hetmet.git] / compiler / vectorise / VectUtils.hs
index b3c110e..a1f554d 100644 (file)
@@ -1,12 +1,18 @@
 module VectUtils (
   collectAnnTypeBinders, collectAnnTypeArgs, isAnnTypeArg,
   collectAnnValBinders,
+  mkDataConTag,
   splitClosureTy,
-  mkPADictType, mkPArrayType,
-  paDictArgType, paDictOfType,
-  paMethod, lengthPA, replicatePA, emptyPA, liftPA,
+
+  TyConRepr(..), mkTyConRepr,
+  mkToArrPRepr, mkFromArrPRepr,
+  mkPADictType, mkPArrayType, mkPReprType,
+
+  parrayCoerce, parrayReprTyCon, parrayReprDataCon, mkVScrut,
+  prDFunOfTyCon, prCoerce,
+  paDictArgType, paDictOfType, paDFunType,
+  paMethod, mkPR, lengthPA, replicatePA, emptyPA, liftPA,
   polyAbstract, polyApply, polyVApply,
-  lookupPArrayFamInst,
   hoistBinding, hoistExpr, hoistPolyVExpr, takeHoisted,
   buildClosure, buildClosures,
   mkClosureApp
@@ -20,21 +26,25 @@ import VectMonad
 import DsUtils
 import CoreSyn
 import CoreUtils
+import Coercion
 import Type
 import TypeRep
 import TyCon
-import DataCon            ( dataConWrapId )
+import DataCon
 import Var
 import Id                 ( mkWildId )
 import MkId               ( unwrapFamInstScrut )
+import Name               ( Name )
 import PrelNames
 import TysWiredIn
 import BasicTypes         ( Boxity(..) )
 
 import Outputable
 import FastString
+import Maybes             ( orElse )
 
-import Control.Monad         ( liftM, zipWithM_ )
+import Data.List             ( zipWith4 )
+import Control.Monad         ( liftM, liftM2, zipWithM_ )
 
 collectAnnTypeArgs :: AnnExpr b ann -> (AnnExpr b ann, [Type])
 collectAnnTypeArgs expr = go expr []
@@ -58,53 +68,200 @@ isAnnTypeArg :: AnnExpr b ann -> Bool
 isAnnTypeArg (_, AnnType t) = True
 isAnnTypeArg _              = False
 
-isClosureTyCon :: TyCon -> Bool
-isClosureTyCon tc = tyConName tc == closureTyConName
+mkDataConTag :: DataCon -> CoreExpr
+mkDataConTag dc = mkConApp intDataCon [mkIntLitInt $ dataConTag dc]
 
-splitClosureTy :: Type -> (Type, Type)
-splitClosureTy ty
-  | Just (tc, [arg_ty, res_ty]) <- splitTyConApp_maybe ty
-  , isClosureTyCon tc
-  = (arg_ty, res_ty)
+splitUnTy :: String -> Name -> Type -> Type
+splitUnTy s name ty
+  | Just (tc, [ty']) <- splitTyConApp_maybe ty
+  , tyConName tc == name
+  = ty'
+
+  | otherwise = pprPanic s (ppr ty)
+
+splitBinTy :: String -> Name -> Type -> (Type, Type)
+splitBinTy s name ty
+  | Just (tc, [ty1, ty2]) <- splitTyConApp_maybe ty
+  , tyConName tc == name
+  = (ty1, ty2)
+
+  | otherwise = pprPanic s (ppr ty)
 
-  | otherwise = pprPanic "splitClosureTy" (ppr ty)
+splitFixedTyConApp :: TyCon -> Type -> [Type]
+splitFixedTyConApp tc ty
+  | Just (tc', tys) <- splitTyConApp_maybe ty
+  , tc == tc'
+  = tys
 
-isPArrayTyCon :: TyCon -> Bool
-isPArrayTyCon tc = tyConName tc == parrayTyConName
+  | otherwise = pprPanic "splitFixedTyConApp" (ppr tc <+> ppr ty)
+
+splitClosureTy :: Type -> (Type, Type)
+splitClosureTy = splitBinTy "splitClosureTy" closureTyConName
 
 splitPArrayTy :: Type -> Type
-splitPArrayTy ty
-  | Just (tc, [arg_ty]) <- splitTyConApp_maybe ty
-  , isPArrayTyCon tc
-  = arg_ty
+splitPArrayTy = splitUnTy "splitPArrayTy" parrayTyConName
 
-  | otherwise = pprPanic "splitPArrayTy" (ppr ty)
+mkBuiltinTyConApp :: (Builtins -> TyCon) -> [Type] -> VM Type
+mkBuiltinTyConApp get_tc tys
+  = do
+      tc <- builtin get_tc
+      return $ mkTyConApp tc tys
 
-mkClosureType :: Type -> Type -> VM Type
-mkClosureType arg_ty res_ty
+mkBuiltinTyConApps :: (Builtins -> TyCon) -> [Type] -> Type -> VM Type
+mkBuiltinTyConApps get_tc tys ty
   = do
-      tc <- builtin closureTyCon
-      return $ mkTyConApp tc [arg_ty, res_ty]
+      tc <- builtin get_tc
+      return $ foldr (mk tc) ty tys
+  where
+    mk tc ty1 ty2 = mkTyConApp tc [ty1,ty2]
 
-mkClosureTypes :: [Type] -> Type -> VM Type
-mkClosureTypes arg_tys res_ty
+mkBuiltinTyConApps1 :: (Builtins -> TyCon) -> Type -> [Type] -> VM Type
+mkBuiltinTyConApps1 get_tc dft [] = return dft
+mkBuiltinTyConApps1 get_tc dft tys
+  = do
+      tc <- builtin get_tc
+      case tys of
+        [] -> pprPanic "mkBuiltinTyConApps1" (ppr tc)
+        _  -> return $ foldr1 (mk tc) tys
+  where
+    mk tc ty1 ty2 = mkTyConApp tc [ty1,ty2]
+
+data TyConRepr = TyConRepr {
+                   repr_tyvars         :: [TyVar]
+                 , repr_tys            :: [[Type]]
+
+                 , repr_prod_tycons    :: [Maybe TyCon]
+                 , repr_prod_data_cons :: [Maybe DataCon]
+                 , repr_prod_tys       :: [Type]
+                 , repr_sum_tycon      :: Maybe TyCon
+                 , repr_sum_data_cons  :: [DataCon]
+                 , repr_type           :: Type
+                 }
+
+mkTyConRepr :: TyCon -> VM TyConRepr
+mkTyConRepr vect_tc
   = do
-      tc <- builtin closureTyCon
-      return $ foldr (mk tc) res_ty arg_tys
+      prod_tycons <- mapM (mk_tycon prodTyCon) rep_tys
+      let prod_tys = zipWith mk_tc_app_maybe prod_tycons rep_tys
+      sum_tycon   <- mk_tycon sumTyCon prod_tys
+
+      return $ TyConRepr {
+                 repr_tyvars         = tyvars
+               , repr_tys            = rep_tys
+
+               , repr_prod_tycons    = prod_tycons
+               , repr_prod_data_cons = map (fmap mk_single_datacon) prod_tycons
+               , repr_prod_tys       = prod_tys
+               , repr_sum_tycon      = sum_tycon
+               , repr_sum_data_cons  = fmap tyConDataCons sum_tycon `orElse` []
+               , repr_type           = mk_tc_app_maybe sum_tycon prod_tys
+               }
   where
-    mk tc arg_ty res_ty = mkTyConApp tc [arg_ty, res_ty]
+    tyvars = tyConTyVars vect_tc
+    data_cons = tyConDataCons vect_tc
+    rep_tys   = map dataConRepArgTys data_cons
 
-mkPADictType :: Type -> VM Type
-mkPADictType ty
+    mk_tycon get_tc tys
+      | n > 1     = builtin (Just . get_tc n)
+      | otherwise = return Nothing
+      where n = length tys
+
+    mk_single_datacon tc | [dc] <- tyConDataCons tc = dc
+
+    mk_tc_app_maybe Nothing   []   = unitTy
+    mk_tc_app_maybe Nothing   [ty] = ty
+    mk_tc_app_maybe (Just tc) tys  = mkTyConApp tc tys
+
+mkToArrPRepr :: CoreExpr -> CoreExpr -> [[CoreExpr]] -> VM CoreExpr
+mkToArrPRepr len sel ess
   = do
-      tc <- builtin paDictTyCon
-      return $ TyConApp tc [ty]
+      let mk_sum [(expr, ty)] = return (expr, ty)
+          mk_sum es
+            = do
+                sum_tc <- builtin . sumTyCon $ length es
+                (sum_rtc, _) <- parrayReprTyCon (mkTyConApp sum_tc tys)
+                let [sum_rdc] = tyConDataCons sum_rtc
+
+                return (mkConApp sum_rdc (map Type tys ++ (len : sel : exprs)),
+                        mkTyConApp sum_tc tys)
+            where
+              (exprs, tys) = unzip es
+
+          mk_prod [expr] = return (expr, splitPArrayTy (exprType expr))
+          mk_prod exprs
+            = do
+                prod_tc <- builtin . prodTyCon $ length exprs
+                (prod_rtc, _) <- parrayReprTyCon (mkTyConApp prod_tc tys)
+                let [prod_rdc] = tyConDataCons prod_rtc
+
+                return (mkConApp prod_rdc (map Type tys ++ (len : exprs)),
+                        mkTyConApp prod_tc tys)
+            where
+              tys = map (splitPArrayTy . exprType) exprs
+
+      liftM fst (mk_sum =<< mapM mk_prod ess)
+
+mkFromArrPRepr :: CoreExpr -> Type -> Var -> Var -> [[Var]] -> CoreExpr
+               -> VM CoreExpr
+mkFromArrPRepr scrut res_ty len sel vars res
+  = return (Var unitDataConId)
+
+mkClosureType :: Type -> Type -> VM Type
+mkClosureType arg_ty res_ty = mkBuiltinTyConApp closureTyCon [arg_ty, res_ty]
+
+mkClosureTypes :: [Type] -> Type -> VM Type
+mkClosureTypes = mkBuiltinTyConApps closureTyCon
+
+mkPReprType :: Type -> VM Type
+mkPReprType ty = mkBuiltinTyConApp preprTyCon [ty]
+
+mkPADictType :: Type -> VM Type
+mkPADictType ty = mkBuiltinTyConApp paTyCon [ty]
 
 mkPArrayType :: Type -> VM Type
-mkPArrayType ty
+mkPArrayType ty = mkBuiltinTyConApp parrayTyCon [ty]
+
+parrayCoerce :: TyCon -> [Type] -> CoreExpr -> VM CoreExpr
+parrayCoerce repr_tc args expr
+  | Just arg_co <- tyConFamilyCoercion_maybe repr_tc
+  = do
+      parray <- builtin parrayTyCon
+
+      let co = mkAppCoercion (mkTyConApp parray [])
+                             (mkSymCoercion (mkTyConApp arg_co args))
+
+      return $ mkCoerce co expr
+
+parrayReprTyCon :: Type -> VM (TyCon, [Type])
+parrayReprTyCon ty = builtin parrayTyCon >>= (`lookupFamInst` [ty])
+
+parrayReprDataCon :: Type -> VM (DataCon, [Type])
+parrayReprDataCon ty
+  = do
+      (tc, arg_tys) <- parrayReprTyCon ty
+      let [dc] = tyConDataCons tc
+      return (dc, arg_tys)
+
+mkVScrut :: VExpr -> VM (VExpr, TyCon, [Type])
+mkVScrut (ve, le)
   = do
-      tc <- builtin parrayTyCon
-      return $ TyConApp tc [ty]
+      (tc, arg_tys) <- parrayReprTyCon (exprType ve)
+      return ((ve, unwrapFamInstScrut tc arg_tys le), tc, arg_tys)
+
+prDFunOfTyCon :: TyCon -> VM CoreExpr
+prDFunOfTyCon tycon
+  = liftM Var (traceMaybeV "prDictOfTyCon" (ppr tycon) (lookupTyConPR tycon))
+
+prCoerce :: TyCon -> [Type] -> CoreExpr -> VM CoreExpr
+prCoerce repr_tc args expr
+  | Just arg_co <- tyConFamilyCoercion_maybe repr_tc
+  = do
+      pr_tc <- builtin prTyCon
+
+      let co = mkAppCoercion (mkTyConApp pr_tc [])
+                             (mkSymCoercion (mkTyConApp arg_co args))
+
+      return $ mkCoerce co expr
 
 paDictArgType :: TyVar -> VM (Maybe Type)
 paDictArgType tv = go (TyVarTy tv) (tyVarKind tv)
@@ -140,11 +297,21 @@ paDictOfTyApp (TyVarTy tv) ty_args
       paDFunApply dfun ty_args
 paDictOfTyApp (TyConApp tc _) ty_args
   = do
-      pa_class <- builtin paClass
-      (dfun, ty_args') <- lookupInst pa_class [TyConApp tc ty_args]
-      paDFunApply (Var dfun) ty_args'
+      dfun <- traceMaybeV "paDictOfTyApp" (ppr tc) (lookupTyConPA tc)
+      paDFunApply (Var dfun) ty_args
 paDictOfTyApp ty ty_args = pprPanic "paDictOfTyApp" (ppr ty)
 
+paDFunType :: TyCon -> VM Type
+paDFunType tc
+  = do
+      margs <- mapM paDictArgType tvs
+      res   <- mkPADictType (mkTyConApp tc arg_tys)
+      return . mkForAllTys tvs
+             $ mkFunTys [arg | Just arg <- margs] res
+  where
+    tvs = tyConTyVars tc
+    arg_tys = mkTyVarTys tvs
+
 paDFunApply :: CoreExpr -> [Type] -> VM CoreExpr
 paDFunApply dfun tys
   = do
@@ -158,6 +325,9 @@ paMethod method ty
       dict <- paDictOfType ty
       return $ mkApps (Var fn) [Type ty, dict]
 
+mkPR :: Type -> VM CoreExpr
+mkPR = paMethod mkPRVar
+
 lengthPA :: CoreExpr -> VM CoreExpr
 lengthPA x = liftM (`App` x) (paMethod lengthPAVar ty)
   where
@@ -212,9 +382,6 @@ polyVApply expr tys
       dicts <- mapM paDictOfType tys
       return $ mapVect (\e -> e `mkTyApps` tys `mkApps` dicts) expr
 
-lookupPArrayFamInst :: Type -> VM (TyCon, [Type])
-lookupPArrayFamInst ty = builtin parrayTyCon >>= (`lookupFamInst` [ty])
-
 hoistBinding :: Var -> CoreExpr -> VM ()
 hoistBinding v e = updGEnv $ \env ->
   env { global_bindings = (v,e) : global_bindings env }
@@ -269,6 +436,8 @@ mkClosureApp (vclo, lclo) (varg, larg)
     (arg_ty, res_ty) = splitClosureTy (exprType vclo)
 
 buildClosures :: [TyVar] -> [VVar] -> [Type] -> Type -> VM VExpr -> VM VExpr
+buildClosures tvs vars [] res_ty mk_body
+  = mk_body
 buildClosures tvs vars [arg_ty] res_ty mk_body
   = buildClosure tvs vars arg_ty res_ty mk_body
 buildClosures tvs vars (arg_ty : arg_tys) res_ty mk_body
@@ -340,7 +509,7 @@ mkLiftEnv lc [ty] [v]
 -- NOTE: this transparently deals with empty environments
 mkLiftEnv lc tys vs
   = do
-      (env_tc, env_tyargs) <- lookupPArrayFamInst vty
+      (env_tc, env_tyargs) <- parrayReprTyCon vty
       let [env_con] = tyConDataCons env_tc
           
           env = Var (dataConWrapId env_con)