Use (UArr Int) instead of PArray_Int# in vectorisation
[ghc-hetmet.git] / compiler / vectorise / VectType.hs
index bef08f7..86dcaf2 100644 (file)
@@ -1,5 +1,14 @@
+{-# OPTIONS -w #-}
+-- The above warning supression flag is a temporary kludge.
+-- While working on this module you are encouraged to remove it and fix
+-- any warnings in the module. See
+--     http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#Warnings
+-- for details
+
 module VectType ( vectTyCon, vectType, vectTypeEnv,
-                   PAInstance, buildPADict )
+                  mkRepr, arrShapeTys, arrShapeVars, arrSelector,
+                  PAInstance, buildPADict,
+                  fromVect )
 where
 
 #include "HsVersions.h"
@@ -26,7 +35,7 @@ import Var               ( Var )
 import Id                ( mkWildId )
 import Name              ( Name, getOccName )
 import NameEnv
-import TysWiredIn        ( unitTy, unitTyCon, intTy, intDataCon, unitDataConId )
+import TysWiredIn
 import TysPrim           ( intPrimTy )
 
 import Unique
@@ -62,7 +71,7 @@ vectType (TyVarTy tv) = return $ TyVarTy tv
 vectType (AppTy ty1 ty2) = liftM2 AppTy (vectType ty1) (vectType ty2)
 vectType (TyConApp tc tys) = liftM2 TyConApp (vectTyCon tc) (mapM vectType tys)
 vectType (FunTy ty1 ty2)   = liftM2 TyConApp (builtin closureTyCon)
-                                             (mapM vectType [ty1,ty2])
+                                             (mapM vectAndBoxType [ty1,ty2])
 vectType ty@(ForAllTy _ _)
   = do
       mdicts   <- mapM paDictArgType tyvars
@@ -73,6 +82,23 @@ vectType ty@(ForAllTy _ _)
 
 vectType ty = pprPanic "vectType:" (ppr ty)
 
+vectAndBoxType :: Type -> VM Type
+vectAndBoxType ty = vectType ty >>= boxType
+
+-- ----------------------------------------------------------------------------
+-- Boxing
+
+boxType :: Type -> VM Type
+boxType ty
+  | Just (tycon, []) <- splitTyConApp_maybe ty
+  , isUnLiftedTyCon tycon
+  = do
+      r <- lookupBoxedTyCon tycon
+      case r of
+        Just tycon' -> return $ mkTyConApp tycon' []
+        Nothing     -> return ty
+boxType ty = return ty
+
 -- ----------------------------------------------------------------------------
 -- Type definitions
 
@@ -232,6 +258,13 @@ data Repr = ProdRepr {
             , void_bottom       :: CoreExpr
             }
 
+          | EnumRepr {
+              enum_tycon        :: TyCon
+            , enum_data_con     :: DataCon
+            , enum_arr_tycon    :: TyCon
+            , enum_arr_data_con :: DataCon
+            }
+
 voidRepr :: VM Repr
 voidRepr
   = do
@@ -242,6 +275,21 @@ voidRepr
                , void_bottom = Var var
                }
 
+enumRepr :: VM Repr
+enumRepr
+  = do
+      tycon <- builtin enumerationTyCon
+      let [data_con] = tyConDataCons tycon
+      (arr_tycon, _) <- parrayReprTyCon (mkTyConApp tycon [])
+      let [arr_data_con] = tyConDataCons arr_tycon
+
+      return $ EnumRepr {
+                 enum_tycon       = tycon
+               , enum_data_con     = data_con
+               , enum_arr_tycon    = arr_tycon
+               , enum_arr_data_con = arr_data_con
+               }
+
 unboxedProductRepr :: [Type] -> VM Repr
 unboxedProductRepr []   = voidRepr
 unboxedProductRepr [ty] = return $ IdRepr ty
@@ -253,7 +301,8 @@ boxedProductRepr tys
       tycon <- builtin (prodTyCon arity)
       let [data_con] = tyConDataCons tycon
 
-      (arr_tycon, _) <- parrayReprTyCon $ mkTyConApp tycon tys
+      tys' <- mapM boxType tys
+      (arr_tycon, _) <- parrayReprTyCon $ mkTyConApp tycon tys'
       let [arr_data_con] = tyConDataCons arr_tycon
 
       return $ ProdRepr {
@@ -303,31 +352,44 @@ reprType (SumRepr { sum_tycon = tycon, sum_components = reprs })
   = mkTyConApp tycon (map reprType reprs)
 reprType (IdRepr ty) = ty
 reprType (VoidRepr { void_tycon = tycon }) = mkTyConApp tycon []
+reprType (EnumRepr { enum_tycon = tycon }) = mkTyConApp tycon []
 
 arrReprType :: Repr -> VM Type
 arrReprType = mkPArrayType . reprType
 
 arrShapeTys :: Repr -> VM [Type]
-arrShapeTys (SumRepr  {})
-  = do
-      int_arr <- builtin parrayIntPrimTyCon
-      return [intPrimTy, mkTyConApp int_arr [], mkTyConApp int_arr []]
+arrShapeTys (SumRepr  {}) = sumShapeTys
 arrShapeTys (ProdRepr {}) = return [intPrimTy]
 arrShapeTys (IdRepr _)    = return []
 arrShapeTys (VoidRepr {}) = return [intPrimTy]
+arrShapeTys (EnumRepr {}) = sumShapeTys
+
+sumShapeTys :: VM [Type]
+sumShapeTys = do
+                int_arr <- builtin intPrimArrayTy
+                return [intPrimTy, int_arr, int_arr]
+
 
 arrShapeVars :: Repr -> VM [Var]
 arrShapeVars repr = mapM (newLocalVar FSLIT("sh")) =<< arrShapeTys repr
 
 replicateShape :: Repr -> CoreExpr -> CoreExpr -> VM [CoreExpr]
-replicateShape (ProdRepr {}) len _ = return [len]
-replicateShape (SumRepr {})  len tag
+replicateShape (ProdRepr {}) len _   = return [len]
+replicateShape (SumRepr {})  len tag = replicateSumShape len tag
+replicateShape (IdRepr _) _ _        = return []
+replicateShape (VoidRepr {}) len _   = return [len]
+replicateShape (EnumRepr {}) len tag = replicateSumShape len tag
+
+replicateSumShape :: CoreExpr -> CoreExpr -> VM [CoreExpr]
+replicateSumShape len tag
   = do
       rep <- builtin replicatePAIntPrimVar
       up  <- builtin upToPAIntPrimVar
       return [len, Var rep `mkApps` [len, tag], Var up `App` len]
-replicateShape (IdRepr _) _ _ = return []
-replicateShape (VoidRepr {}) len _ = return [len]
+
+arrSelector :: Repr -> [CoreExpr] -> VM (CoreExpr, CoreExpr, CoreExpr)
+arrSelector (SumRepr {})  [len, sel, is] = return (len, sel, is)
+arrSelector (EnumRepr {}) [len, sel, is] = return (len, sel, is)
 
 emptyArrRepr :: Repr -> VM [CoreExpr]
 emptyArrRepr (SumRepr { sum_components = prods })
@@ -340,6 +402,8 @@ emptyArrRepr (IdRepr ty)
   = liftM singleton $ emptyPA ty
 emptyArrRepr (VoidRepr { void_tycon = tycon })
   = liftM singleton $ emptyPA (mkTyConApp tycon [])
+emptyArrRepr (EnumRepr { enum_tycon = tycon })
+  = return []
 
 arrReprTys :: Repr -> VM [Type]
 arrReprTys (SumRepr { sum_components = reprs })
@@ -352,6 +416,8 @@ arrReprTys (IdRepr ty)
   = liftM singleton $ mkPArrayType ty
 arrReprTys (VoidRepr { void_tycon = tycon })
   = liftM singleton $ mkPArrayType (mkTyConApp tycon [])
+arrReprTys (EnumRepr {})
+  = return []
 
 arrReprTys' :: Repr -> VM [[Type]]
 arrReprTys' (SumRepr { sum_components = reprs })
@@ -364,7 +430,9 @@ arrReprVars repr
 
 mkRepr :: TyCon -> VM Repr
 mkRepr vect_tc
-  = sumRepr =<< mapM unboxedProductRepr rep_tys
+  | [tys] <- rep_tys = boxedProductRepr tys
+  -- | all null rep_tys = enumRepr
+  | otherwise        = sumRepr =<< mapM unboxedProductRepr rep_tys
   where
     rep_tys = map dataConRepArgTys $ tyConDataCons vect_tc
 
@@ -392,7 +460,7 @@ buildToPRepr repr vect_tc prepr_tc _
                      , sum_tycon      = tycon })
             expr
       = do
-          (vars, bodies) <- mapAndUnzipM prod_alt prods
+          (vars, bodies) <- mapAndUnzipM to_unboxed prods
           return . Case expr (mkWildId (exprType expr)) res_ty
                  $ zipWith4 mk_alt cons vars (tyConDataCons tycon) bodies
       where
@@ -401,24 +469,30 @@ buildToPRepr repr vect_tc prepr_tc _
 
         ty_args = map (Type . reprType) prods
 
+    to_repr (EnumRepr { enum_data_con = data_con }) expr
+      = return . Case expr (mkWildId (exprType expr)) res_ty
+               $ map mk_alt cons
+      where
+        mk_alt con = (DataAlt con, [], mkConApp data_con [mkDataConTag con])
+
     to_repr prod expr
       = do
-          (vars, body) <- prod_alt prod
+          (vars, body) <- to_unboxed prod
           return $ Case expr (mkWildId (exprType expr)) res_ty
                    [(DataAlt con, vars, body)]
 
-    prod_alt (ProdRepr { prod_components = tys
-                       , prod_data_con   = data_con })
+    to_unboxed (ProdRepr { prod_components = tys
+                         , prod_data_con   = data_con })
       = do
           vars <- mapM (newLocalVar FSLIT("r")) tys
           return (vars, mkConApp data_con (map Type tys ++ map Var vars))
 
-    prod_alt (IdRepr ty)
+    to_unboxed (IdRepr ty)
       = do
           var <- newLocalVar FSLIT("y") ty
           return ([var], Var var)
 
-    prod_alt (VoidRepr { void_bottom = bottom })
+    to_unboxed (VoidRepr { void_bottom = bottom })
       = return ([], bottom)
 
 
@@ -443,17 +517,34 @@ buildFromPRepr repr vect_tc prepr_tc _
               expr
       = do
           vars   <- mapM (newLocalVar FSLIT("x")) (map reprType prods)
-          bodies <- sequence . zipWith3 from_prod prods cons
+          bodies <- sequence . zipWith3 from_unboxed prods cons
                              $ map Var vars
           return . Case expr (mkWildId (reprType repr)) res_ty
                  $ zipWith3 sum_alt (tyConDataCons tycon) vars bodies
       where
         sum_alt data_con var body = (DataAlt data_con, [var], body)
 
-    from_repr repr expr = from_prod repr con expr
+    from_repr repr@(EnumRepr { enum_data_con = data_con }) expr
+      = do
+          var <- newLocalVar FSLIT("n") intPrimTy
+
+          let res = Case (Var var) (mkWildId intPrimTy) res_ty
+                  $ (DEFAULT, [], error_expr)
+                  : zipWith mk_alt (tyConDataCons vect_tc) cons
 
-    from_prod prod@(ProdRepr { prod_components = tys
-                             , prod_data_con   = data_con })
+          return $ Case expr (mkWildId (reprType repr)) res_ty
+                   [(DataAlt data_con, [var], res)]
+      where
+        mk_alt data_con con = (LitAlt (mkDataConTagLit data_con), [], con)
+
+        error_expr = mkRuntimeErrorApp rUNTIME_ERROR_ID res_ty
+                   . showSDoc
+                   $ sep [text "Invalid NDP representation of", ppr vect_tc]
+
+    from_repr repr expr = from_unboxed repr con expr
+
+    from_unboxed prod@(ProdRepr { prod_components = tys
+                                , prod_data_con   = data_con })
               con
               expr
       = do
@@ -461,10 +552,10 @@ buildFromPRepr repr vect_tc prepr_tc _
           return $ Case expr (mkWildId (reprType prod)) res_ty
                    [(DataAlt data_con, vars, con `mkVarApps` vars)]
 
-    from_prod (IdRepr _) con expr
+    from_unboxed (IdRepr _) con expr
        = return $ con `App` expr
 
-    from_prod (VoidRepr {}) con expr
+    from_unboxed (VoidRepr {}) con expr
        = return con
 
 buildToArrPRepr :: Repr -> TyCon -> TyCon -> TyCon -> VM CoreExpr
@@ -522,12 +613,20 @@ buildToArrPRepr repr vect_tc prepr_tc arr_tc
                 . mkConApp data_con
                 $ map Type tys ++ map Var (len_var : repr_vars)
 
+    to_repr shape_vars
+            _
+            (EnumRepr { enum_arr_tycon    = tycon
+                      , enum_arr_data_con = data_con })
+      = return . wrapFamInstBody tycon []
+               . mkConApp data_con
+                $ map Var shape_vars
+
     to_prod repr_vars@(r : _)
-            (ProdRepr { prod_components   = tys
+            (ProdRepr { prod_components   = tys@(ty : _)
                       , prod_arr_tycon    = tycon
                       , prod_arr_data_con = data_con })
       = do
-          len <- lengthPA (Var r)
+          len <- lengthPA ty (Var r)
           return . wrapFamInstBody tycon tys
                  . mkConApp data_con
                  $ map Type tys ++ len : map Var repr_vars
@@ -613,6 +712,19 @@ buildFromArrPRepr repr vect_tc prepr_tc arr_tc
           return $ Case scrut (mkWildId scrut_ty) res_ty
                    [(DataAlt data_con, shape_vars ++ repr_vars, body)]
 
+    from_prod (EnumRepr { enum_arr_tycon = tycon
+                        , enum_arr_data_con = data_con })
+              expr
+              shape_vars
+              _
+              res_ty
+              body
+      = let scrut    = unwrapFamInstScrut tycon [] expr
+            scrut_ty = mkTyConApp tycon []
+        in
+        return $ Case scrut (mkWildId scrut_ty) res_ty
+                 [(DataAlt data_con, shape_vars, body)]
+
     from_prod (IdRepr ty)
               expr
               shape_vars
@@ -650,6 +762,9 @@ buildPRDictRepr (SumRepr {
       dfun <- prDFunOfTyCon tycon
       return $ dfun `mkTyApps` map reprType prods `mkApps` prs
 
+buildPRDictRepr (EnumRepr { enum_tycon = tycon })
+  = prDFunOfTyCon tycon
+
 buildPRDict :: Repr -> TyCon -> TyCon -> TyCon -> VM CoreExpr
 buildPRDict repr vect_tc prepr_tc _
   = do
@@ -893,3 +1008,41 @@ tyConsOfType other             = pprPanic "ClosureConv.tyConsOfType" $ ppr other
 tyConsOfTypes :: [Type] -> UniqSet TyCon
 tyConsOfTypes = unionManyUniqSets . map tyConsOfType
 
+
+-- ----------------------------------------------------------------------------
+-- Conversions
+
+fromVect :: Type -> CoreExpr -> VM CoreExpr
+fromVect ty expr | Just ty' <- coreView ty = fromVect ty' expr
+fromVect (FunTy arg_ty res_ty) expr
+  = do
+      arg     <- newLocalVar FSLIT("x") arg_ty
+      varg    <- toVect arg_ty (Var arg)
+      varg_ty <- vectType arg_ty
+      vres_ty <- vectType res_ty
+      apply   <- builtin applyClosureVar
+      body    <- fromVect res_ty
+               $ Var apply `mkTyApps` [varg_ty, vres_ty] `mkApps` [expr, varg]
+      return $ Lam arg body
+fromVect ty expr
+  = identityConv ty >> return expr
+
+toVect :: Type -> CoreExpr -> VM CoreExpr
+toVect ty expr = identityConv ty >> return expr
+
+identityConv :: Type -> VM ()
+identityConv ty | Just ty' <- coreView ty = identityConv ty'
+identityConv (TyConApp tycon tys)
+  = do
+      mapM_ identityConv tys
+      identityConvTyCon tycon
+identityConv ty = noV
+
+identityConvTyCon :: TyCon -> VM ()
+identityConvTyCon tc
+  | isBoxedTupleTyCon tc = return ()
+  | isUnLiftedTyCon tc   = return ()
+  | otherwise            = do
+                             tc' <- maybeV (lookupTyCon tc)
+                             if tc == tc' then return () else noV
+