summaryrefslogtreecommitdiff
path: root/compiler/vectorise/Vectorise.hs
diff options
context:
space:
mode:
authorManuel M T Chakravarty <chak@cse.unsw.edu.au>2011-08-22 23:53:04 +1000
committerManuel M T Chakravarty <chak@cse.unsw.edu.au>2011-08-24 22:44:09 +1000
commit72777694e0366f55cc37cc3db190613d1e97e717 (patch)
tree2e5a644efdf7424c245bbe16e249b8c1cfe9274c /compiler/vectorise/Vectorise.hs
parent10c882760aea96a679a98bf76a603c1eeb99ecb8 (diff)
downloadhaskell-72777694e0366f55cc37cc3db190613d1e97e717.tar.gz
Functions and types can now be post-hoc vectorised; i.e., in modules where they are not declared, but only imported
- Types already gained this functionality already in a previous commit - This commit adds the capability for functions This is a crucial step towards being able to use the standard Prelude, instead of a special vectorised one.
Diffstat (limited to 'compiler/vectorise/Vectorise.hs')
-rw-r--r--compiler/vectorise/Vectorise.hs61
1 files changed, 44 insertions, 17 deletions
diff --git a/compiler/vectorise/Vectorise.hs b/compiler/vectorise/Vectorise.hs
index 1d54b3803d..2f9035e500 100644
--- a/compiler/vectorise/Vectorise.hs
+++ b/compiler/vectorise/Vectorise.hs
@@ -33,9 +33,10 @@ import Util ( zipLazy )
import MonadUtils
import Control.Monad
+import Data.Maybe
--- | Vectorise a single module.
+-- |Vectorise a single module.
--
vectorise :: ModGuts -> CoreM ModGuts
vectorise guts
@@ -43,7 +44,7 @@ vectorise guts
; liftIO $ vectoriseIO hsc_env guts
}
--- | Vectorise a single monad, given the dynamic compiler flags and HscEnv.
+-- Vectorise a single monad, given the dynamic compiler flags and HscEnv.
--
vectoriseIO :: HscEnv -> ModGuts -> IO ModGuts
vectoriseIO hsc_env guts
@@ -58,7 +59,7 @@ vectoriseIO hsc_env guts
; return (guts' { mg_vect_info = info' })
}
--- | Vectorise a single module, in the VM monad.
+-- Vectorise a single module, in the VM monad.
--
vectModule :: ModGuts -> VM ModGuts
vectModule guts@(ModGuts { mg_types = types
@@ -73,21 +74,23 @@ vectModule guts@(ModGuts { mg_types = types
-- representaions, and the conrresponding data constructors. Moreover, we produce
-- bindings for dfuns and family instances of the classes and type families used in the
-- DPH library to represent array types.
- ; (types', new_fam_insts, tc_binds) <- vectTypeEnv types [vd | vd@(VectType _ _) <- vect_decls]
+ ; (types', new_fam_insts, tc_binds) <- vectTypeEnv types [vd
+ | vd@(VectType _ _) <- vect_decls]
; (_, fam_inst_env) <- readGEnv global_fam_inst_env
- -- Vectorise all the top level bindings.
- ; binds' <- mapM vectTopBind binds
+ -- Vectorise all the top level bindings and VECTORISE declarations on imported identifiers
+ ; binds_top <- mapM vectTopBind binds
+ ; binds_imp <- mapM vectImpBind [imp_id | Vect imp_id _ <- vect_decls, isGlobalId imp_id]
; return $ guts { mg_types = types'
- , mg_binds = Rec tc_binds : binds'
+ , mg_binds = Rec tc_binds : (binds_top ++ binds_imp)
, mg_fam_inst_env = fam_inst_env
, mg_fam_insts = fam_insts ++ new_fam_insts
}
}
--- |Try to vectorise a top-level binding. If it doesn't vectorise then return it unharmed.
+-- Try to vectorise a top-level binding. If it doesn't vectorise then return it unharmed.
--
-- For example, for the binding
--
@@ -198,7 +201,25 @@ vectTopBind b@(Rec bs)
else vectorise -- no binding has a 'NOVECTORISE' decl
}
noVectoriseErr = "NOVECTORISE must be used on all or no bindings of a recursive group"
-
+
+-- Add a vectorised binding to an imported top-level variable that has a VECTORISE [SCALAR] pragma
+-- in this module.
+--
+vectImpBind :: Id -> VM CoreBind
+vectImpBind var
+ = do { -- Vectorise the right-hand side, create an appropriate top-level binding and add it
+ -- to the vectorisation map. For the non-lifted version, we refer to the original
+ -- definition — i.e., 'Var var'.
+ ; (inline, isScalar, expr') <- vectTopRhs [] var (Var var)
+ ; var' <- vectTopBinder var inline expr'
+ ; when isScalar $
+ addGlobalScalar var
+
+ -- We add any newly created hoisted top-level bindings.
+ ; hs <- takeHoisted
+ ; return . Rec $ (var', expr') : hs
+ }
+
-- | Make the vectorised version of this top level binder, and add the mapping
-- between it and the original to the state. For some binder @foo@ the vectorised
-- version is @$v_foo@
@@ -215,13 +236,13 @@ vectTopBinder var inline expr
; vty <- vectType (idType var)
-- If there is a vectorisation declartion for this binding, make sure that its type
- -- matches
+ -- matches
; vectDecl <- lookupVectDecl var
; case vectDecl of
- Nothing -> return ()
+ Nothing -> return ()
Just (vdty, _)
| eqType vty vdty -> return ()
- | otherwise ->
+ | otherwise ->
cantVectorise ("Type mismatch in vectorisation pragma for " ++ show var) $
(text "Expected type" <+> ppr vty)
$$
@@ -263,10 +284,11 @@ vectTopRhs :: [Var] -- ^ Names of all functions in the rec block
, CoreExpr) -- (3) the vectorised right-hand side
vectTopRhs recFs var expr
= closedV
- $ do { traceVt ("vectTopRhs of " ++ show var) $ ppr expr
-
- ; globalScalar <- isGlobalScalar var
+ $ do { globalScalar <- isGlobalScalar var
; vectDecl <- lookupVectDecl var
+
+ ; traceVt ("vectTopRhs of " ++ show var ++ info globalScalar vectDecl) $ ppr expr
+
; rhs globalScalar vectDecl
}
where
@@ -278,10 +300,15 @@ vectTopRhs recFs var expr
}
rhs False Nothing -- Case (3)
= do { let fvs = freeVars expr
- ; (inline, isScalar, vexpr) <- inBind var $
- vectPolyExpr (isStrongLoopBreaker $ idOccInfo var) recFs fvs
+ ; (inline, isScalar, vexpr)
+ <- inBind var $
+ vectPolyExpr (isStrongLoopBreaker $ idOccInfo var) recFs fvs
; return (inline, isScalar, vectorised vexpr)
}
+
+ info True _ = " [VECTORISE SCALAR]"
+ info False vectDecl | isJust vectDecl = " [VECTORISE]"
+ | otherwise = " (no pragma)"
-- | Project out the vectorised version of a binding from some closure,
-- or return the original body if that doesn't work or the binding is scalar.