summaryrefslogtreecommitdiff
path: root/compiler
diff options
context:
space:
mode:
authorDavid Waern <david.waern@gmail.com>2011-11-26 00:02:29 +0100
committerDavid Waern <david.waern@gmail.com>2011-11-26 00:02:29 +0100
commitfdf98d6255deba9582dd475e6953b1bb49fba660 (patch)
tree839d39e5cdb3ec89868ed74705464b0674cd69b3 /compiler
parentee2dad13f8a3cd484f25aa949895535d6eb0f15e (diff)
parent381becf01a71654464a8c73ba8f4671337ebae9a (diff)
downloadhaskell-fdf98d6255deba9582dd475e6953b1bb49fba660.tar.gz
Merge branch 'master' of http://darcs.haskell.org/ghc
Diffstat (limited to 'compiler')
-rw-r--r--compiler/coreSyn/CoreFVs.lhs2
-rw-r--r--compiler/coreSyn/CoreSubst.lhs2
-rw-r--r--compiler/coreSyn/CoreSyn.lhs2
-rw-r--r--compiler/coreSyn/PprCore.lhs3
-rw-r--r--compiler/deSugar/Desugar.lhs13
-rw-r--r--compiler/deSugar/DsBinds.lhs60
-rw-r--r--compiler/ghc.mk6
-rw-r--r--compiler/ghci/ByteCodeItbls.lhs13
-rw-r--r--compiler/hsSyn/HsDecls.lhs26
-rw-r--r--compiler/iface/FlagChecker.hs4
-rw-r--r--compiler/iface/MkIface.lhs18
-rw-r--r--compiler/iface/TcIface.lhs101
-rw-r--r--compiler/main/DriverPipeline.hs19
-rw-r--r--compiler/main/DynFlags.hs44
-rw-r--r--compiler/main/HscTypes.lhs3
-rw-r--r--compiler/main/StaticFlags.hs4
-rw-r--r--compiler/main/SysTools.lhs14
-rw-r--r--compiler/nativeGen/PPC/CodeGen.hs1
-rw-r--r--compiler/parser/Lexer.x14
-rw-r--r--compiler/parser/Parser.y.pp18
-rw-r--r--compiler/parser/RdrHsSyn.lhs3
-rw-r--r--compiler/rename/RnSource.lhs6
-rw-r--r--compiler/typecheck/TcBinds.lhs12
-rw-r--r--compiler/typecheck/TcCanonical.lhs29
-rw-r--r--compiler/typecheck/TcForeign.lhs22
-rw-r--r--compiler/typecheck/TcGenGenerics.lhs5
-rw-r--r--compiler/typecheck/TcHsSyn.lhs10
-rw-r--r--compiler/typecheck/TcHsType.lhs121
-rw-r--r--compiler/typecheck/TcMType.lhs24
-rw-r--r--compiler/types/Kind.lhs12
-rw-r--r--compiler/types/Type.lhs8
-rw-r--r--compiler/utils/Platform.hs2
-rw-r--r--compiler/vectorise/Vectorise.hs14
-rw-r--r--compiler/vectorise/Vectorise/Builtins/Initialise.hs3
-rw-r--r--compiler/vectorise/Vectorise/Env.hs20
-rw-r--r--compiler/vectorise/Vectorise/Exp.hs6
-rw-r--r--compiler/vectorise/Vectorise/Generic/Description.hs64
-rw-r--r--compiler/vectorise/Vectorise/Generic/PAMethods.hs50
-rw-r--r--compiler/vectorise/Vectorise/Monad.hs20
-rw-r--r--compiler/vectorise/Vectorise/Monad/Global.hs6
-rw-r--r--compiler/vectorise/Vectorise/Type/Env.hs155
-rw-r--r--compiler/vectorise/Vectorise/Type/PRepr.hs369
-rw-r--r--compiler/vectorise/Vectorise/Utils/Base.hs272
-rw-r--r--compiler/vectorise/Vectorise/Utils/PADict.hs5
44 files changed, 728 insertions, 877 deletions
diff --git a/compiler/coreSyn/CoreFVs.lhs b/compiler/coreSyn/CoreFVs.lhs
index 2402a47e70..cbb3bd877f 100644
--- a/compiler/coreSyn/CoreFVs.lhs
+++ b/compiler/coreSyn/CoreFVs.lhs
@@ -333,7 +333,7 @@ vectsFreeVars = foldr (unionVarSet . vectFreeVars) emptyVarSet
vectFreeVars (NoVect _) = noFVs
vectFreeVars (VectType _ _ _) = noFVs
vectFreeVars (VectClass _) = noFVs
- vectFreeVars (VectInst _ _) = noFVs
+ vectFreeVars (VectInst _) = noFVs
-- this function is only concerned with values, not types
\end{code}
diff --git a/compiler/coreSyn/CoreSubst.lhs b/compiler/coreSyn/CoreSubst.lhs
index 741c48eac9..09f00c70b2 100644
--- a/compiler/coreSyn/CoreSubst.lhs
+++ b/compiler/coreSyn/CoreSubst.lhs
@@ -754,7 +754,7 @@ substVect subst (Vect v (Just rhs)) = Vect v (Just (simpleOptExprWith subst r
substVect _subst vd@(NoVect _) = vd
substVect _subst vd@(VectType _ _ _) = vd
substVect _subst vd@(VectClass _) = vd
-substVect _subst vd@(VectInst _ _) = vd
+substVect _subst vd@(VectInst _) = vd
------------------
substVarSet :: Subst -> VarSet -> VarSet
diff --git a/compiler/coreSyn/CoreSyn.lhs b/compiler/coreSyn/CoreSyn.lhs
index 3258d3da3a..78c733d830 100644
--- a/compiler/coreSyn/CoreSyn.lhs
+++ b/compiler/coreSyn/CoreSyn.lhs
@@ -538,7 +538,7 @@ data CoreVect = Vect Id (Maybe CoreExpr)
| NoVect Id
| VectType Bool TyCon (Maybe TyCon)
| VectClass TyCon -- class tycon
- | VectInst Bool Id -- (1) whether SCALAR & (2) instance dfun
+ | VectInst Id -- instance dfun (always SCALAR)
\end{code}
diff --git a/compiler/coreSyn/PprCore.lhs b/compiler/coreSyn/PprCore.lhs
index c575b68857..9def8e8ca7 100644
--- a/compiler/coreSyn/PprCore.lhs
+++ b/compiler/coreSyn/PprCore.lhs
@@ -510,6 +510,5 @@ instance Outputable CoreVect where
ppr (VectType True var (Just tc)) = ptext (sLit "VECTORISE SCALAR type") <+> ppr var <+>
char '=' <+> ppr tc
ppr (VectClass tc) = ptext (sLit "VECTORISE class") <+> ppr tc
- ppr (VectInst False var) = ptext (sLit "VECTORISE instance") <+> ppr var
- ppr (VectInst True var) = ptext (sLit "VECTORISE SCALAR instance") <+> ppr var
+ ppr (VectInst var) = ptext (sLit "VECTORISE SCALAR instance") <+> ppr var
\end{code}
diff --git a/compiler/deSugar/Desugar.lhs b/compiler/deSugar/Desugar.lhs
index e88b57e835..d0713bcf99 100644
--- a/compiler/deSugar/Desugar.lhs
+++ b/compiler/deSugar/Desugar.lhs
@@ -23,6 +23,7 @@ import TcRnTypes
import MkIface
import Id
import Name
+import Type
import InstEnv
import Class
import Avail
@@ -415,15 +416,19 @@ dsVect (L loc (HsVect (L _ v) rhs))
dsVect (L _loc (HsNoVect (L _ v)))
= return $ NoVect v
dsVect (L _loc (HsVectTypeOut isScalar tycon rhs_tycon))
- = return $ VectType isScalar tycon rhs_tycon
+ = return $ VectType isScalar tycon' rhs_tycon
+ where
+ tycon' | Just ty <- coreView $ mkTyConTy tycon
+ , (tycon', []) <- splitTyConApp ty = tycon'
+ | otherwise = tycon
dsVect vd@(L _ (HsVectTypeIn _ _ _))
= pprPanic "Desugar.dsVect: unexpected 'HsVectTypeIn'" (ppr vd)
dsVect (L _loc (HsVectClassOut cls))
= return $ VectClass (classTyCon cls)
dsVect vc@(L _ (HsVectClassIn _))
= pprPanic "Desugar.dsVect: unexpected 'HsVectClassIn'" (ppr vc)
-dsVect (L _loc (HsVectInstOut isScalar inst))
- = return $ VectInst isScalar (instanceDFunId inst)
-dsVect vi@(L _ (HsVectInstIn _ _))
+dsVect (L _loc (HsVectInstOut inst))
+ = return $ VectInst (instanceDFunId inst)
+dsVect vi@(L _ (HsVectInstIn _))
= pprPanic "Desugar.dsVect: unexpected 'HsVectInstIn'" (ppr vi)
\end{code}
diff --git a/compiler/deSugar/DsBinds.lhs b/compiler/deSugar/DsBinds.lhs
index 46c93781f2..b6a5e3e507 100644
--- a/compiler/deSugar/DsBinds.lhs
+++ b/compiler/deSugar/DsBinds.lhs
@@ -512,17 +512,31 @@ dsSpec mb_poly_rhs (L loc (SpecPrag poly_id spec_co spec_inl))
; let spec_id = mkLocalId spec_name spec_ty
`setInlinePragma` inl_prag
`setIdUnfolding` spec_unf
+ id_inl = idInlinePragma poly_id
+
+ -- See Note [Activation pragmas for SPECIALISE]
inl_prag | not (isDefaultInlinePragma spec_inl) = spec_inl
| not is_local_id -- See Note [Specialising imported functions]
-- in OccurAnal
, isStrongLoopBreaker (idOccInfo poly_id) = neverInlinePragma
- | otherwise = idInlinePragma poly_id
+ | otherwise = id_inl
-- Get the INLINE pragma from SPECIALISE declaration, or,
-- failing that, from the original Id
+ spec_prag_act = inlinePragmaActivation spec_inl
+
+ -- See Note [Activation pragmas for SPECIALISE]
+ -- no_act_spec is True if the user didn't write an explicit
+ -- phase specification in the SPECIALISE pragma
+ no_act_spec = case inlinePragmaSpec spec_inl of
+ NoInline -> isNeverActive spec_prag_act
+ _ -> isAlwaysActive spec_prag_act
+ rule_act | no_act_spec = inlinePragmaActivation id_inl -- Inherit
+ | otherwise = spec_prag_act -- Specified by user
+
rule = mkRule False {- Not auto -} is_local_id
(mkFastString ("SPEC " ++ showSDoc (ppr poly_name)))
- AlwaysActive poly_name
+ rule_act poly_name
final_bndrs args
(mkVarApps (Var spec_id) bndrs)
@@ -557,6 +571,48 @@ specUnfolding _ _ _
= return (noUnfolding, nilOL)
\end{code}
+
+Note [Activation pragmas for SPECIALISE]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+From a user SPECIALISE pragma for f, we generate
+ a) A top-level binding spec_fn = rhs
+ b) A RULE f dOrd = spec_fn
+
+We need two pragma-like things:
+
+* spec_fn's inline pragma: inherited from f's inline pragma (ignoring
+ activation on SPEC), unless overriden by SPEC INLINE
+
+* Activation of RULE: from SPECIALISE pragma (if activation given)
+ otherwise from f's inline pragma
+
+This is not obvious (see Trac #5237)!
+
+Examples Rule activation Inline prag on spec'd fn
+---------------------------------------------------------------------
+SPEC [n] f :: ty [n] Always, or NOINLINE [n]
+ copy f's prag
+
+NOINLINE f
+SPEC [n] f :: ty [n] NOINLINE
+ copy f's prag
+
+NOINLINE [k] f
+SPEC [n] f :: ty [n] NOINLINE [k]
+ copy f's prag
+
+INLINE [k] f
+SPEC [n] f :: ty [n] INLINE [k]
+ copy f's prag
+
+SPEC INLINE [n] f :: ty [n] INLINE [n]
+ (ignore INLINE prag on f,
+ same activation for rule and spec'd fn)
+
+NOINLINE [k] f
+SPEC f :: ty [n] INLINE [k]
+
+
%************************************************************************
%* *
\subsection{Adding inline pragmas}
diff --git a/compiler/ghc.mk b/compiler/ghc.mk
index 9893a5e142..95cd45bd4e 100644
--- a/compiler/ghc.mk
+++ b/compiler/ghc.mk
@@ -129,12 +129,6 @@ endif
@echo 'cGHC_SYSMAN_DIR = "$(GHC_SYSMAN_DIR)"' >> $@
@echo 'cDEFAULT_TMPDIR :: String' >> $@
@echo 'cDEFAULT_TMPDIR = "$(DEFAULT_TMPDIR)"' >> $@
- @echo 'cRelocatableBuild :: Bool' >> $@
-ifeq "$(RelocatableBuild)" "YES"
- @echo 'cRelocatableBuild = True' >> $@
-else
- @echo 'cRelocatableBuild = False' >> $@
-endif
@echo 'cLibFFI :: Bool' >> $@
ifeq "$(UseLibFFIForAdjustors)" "YES"
@echo 'cLibFFI = True' >> $@
diff --git a/compiler/ghci/ByteCodeItbls.lhs b/compiler/ghci/ByteCodeItbls.lhs
index 76d01dfc08..2dd1d11ea6 100644
--- a/compiler/ghci/ByteCodeItbls.lhs
+++ b/compiler/ghci/ByteCodeItbls.lhs
@@ -237,18 +237,21 @@ mkJumpToAddr a
= undefined
#endif
-
-byte0, byte1, byte2, byte3, byte4, byte5, byte6, byte7
- :: (Integral w, Bits w) => w -> Word8
+#if defined(i386_TARGET_ARCH) || defined(x86_64_TARGET_ARCH)
+byte0, byte1, byte2, byte3 :: (Integral w, Bits w) => w -> Word8
byte0 w = fromIntegral w
byte1 w = fromIntegral (w `shiftR` 8)
byte2 w = fromIntegral (w `shiftR` 16)
byte3 w = fromIntegral (w `shiftR` 24)
+#endif
+
+#if defined(x86_64_TARGET_ARCH)
+byte4, byte5, byte6, byte7 :: (Integral w, Bits w) => w -> Word8
byte4 w = fromIntegral (w `shiftR` 32)
byte5 w = fromIntegral (w `shiftR` 40)
byte6 w = fromIntegral (w `shiftR` 48)
byte7 w = fromIntegral (w `shiftR` 56)
-
+#endif
#ifndef __HADDOCK__
-- entry point for direct returns for created constr itbls
@@ -372,7 +375,7 @@ instance Storable StgInfoTable where
return
StgInfoTable {
#ifndef GHCI_TABLES_NEXT_TO_CODE
- entry = entry,
+ entry = entry',
#endif
ptrs = ptrs',
nptrs = nptrs',
diff --git a/compiler/hsSyn/HsDecls.lhs b/compiler/hsSyn/HsDecls.lhs
index ea34e7991c..d4463632af 100644
--- a/compiler/hsSyn/HsDecls.lhs
+++ b/compiler/hsSyn/HsDecls.lhs
@@ -1093,11 +1093,9 @@ data VectDecl name
(Located name)
| HsVectClassOut -- post type-checking
Class
- | HsVectInstIn -- pre type-checking
- Bool -- 'TRUE' => SCALAR declaration
+ | HsVectInstIn -- pre type-checking (always SCALAR)
(LHsType name)
- | HsVectInstOut -- post type-checking
- Bool -- 'TRUE' => SCALAR declaration
+ | HsVectInstOut -- post type-checking (always SCALAR)
Instance
deriving (Data, Typeable)
@@ -1108,15 +1106,13 @@ lvectDeclName (L _ (HsVectTypeIn _ (L _ name) _)) = getName name
lvectDeclName (L _ (HsVectTypeOut _ tycon _)) = getName tycon
lvectDeclName (L _ (HsVectClassIn (L _ name))) = getName name
lvectDeclName (L _ (HsVectClassOut cls)) = getName cls
-lvectDeclName (L _ (HsVectInstIn _ _)) = panic "HsDecls.lvectDeclName: HsVectInstIn"
-lvectDeclName (L _ (HsVectInstOut _ _)) = panic "HsDecls.lvectDeclName: HsVectInstOut"
--- lvectDeclName (L _ (HsVectInstIn _ (L _ name))) = getName name
--- lvectDeclName (L _ (HsVectInstOut _ inst)) = getName inst
+lvectDeclName (L _ (HsVectInstIn _)) = panic "HsDecls.lvectDeclName: HsVectInstIn"
+lvectDeclName (L _ (HsVectInstOut _)) = panic "HsDecls.lvectDeclName: HsVectInstOut"
lvectInstDecl :: LVectDecl name -> Bool
-lvectInstDecl (L _ (HsVectInstIn _ _)) = True
-lvectInstDecl (L _ (HsVectInstOut _ _)) = True
-lvectInstDecl _ = False
+lvectInstDecl (L _ (HsVectInstIn _)) = True
+lvectInstDecl (L _ (HsVectInstOut _)) = True
+lvectInstDecl _ = False
instance OutputableBndr name => Outputable (VectDecl name) where
ppr (HsVect v Nothing)
@@ -1147,13 +1143,9 @@ instance OutputableBndr name => Outputable (VectDecl name) where
= sep [text "{-# VECTORISE class" <+> ppr c <+> text "#-}" ]
ppr (HsVectClassOut c)
= sep [text "{-# VECTORISE class" <+> ppr c <+> text "#-}" ]
- ppr (HsVectInstIn False ty)
- = sep [text "{-# VECTORISE instance" <+> ppr ty <+> text "#-}" ]
- ppr (HsVectInstIn True ty)
+ ppr (HsVectInstIn ty)
= sep [text "{-# VECTORISE SCALAR instance" <+> ppr ty <+> text "#-}" ]
- ppr (HsVectInstOut False i)
- = sep [text "{-# VECTORISE instance" <+> ppr i <+> text "#-}" ]
- ppr (HsVectInstOut True i)
+ ppr (HsVectInstOut i)
= sep [text "{-# VECTORISE SCALAR instance" <+> ppr i <+> text "#-}" ]
\end{code}
diff --git a/compiler/iface/FlagChecker.hs b/compiler/iface/FlagChecker.hs
index f670437ffe..0ea1f3b0fc 100644
--- a/compiler/iface/FlagChecker.hs
+++ b/compiler/iface/FlagChecker.hs
@@ -14,7 +14,7 @@ import Name
import Fingerprint
-- import Outputable
-import Data.List (sort)
+import qualified Data.IntSet as IntSet
import System.FilePath (normalise)
-- | Produce a fingerprint of a @DynFlags@ value. We only base
@@ -31,7 +31,7 @@ fingerprintDynFlags DynFlags{..} nameio =
-- *all* the extension flags and the language
lang = (fmap fromEnum language,
- sort $ map fromEnum $ extensionFlags)
+ IntSet.toList $ extensionFlags)
-- -I, -D and -U flags affect CPP
cpp = (map normalise includePaths, sOpt_P settings)
diff --git a/compiler/iface/MkIface.lhs b/compiler/iface/MkIface.lhs
index 3196614510..3edf1d64e5 100644
--- a/compiler/iface/MkIface.lhs
+++ b/compiler/iface/MkIface.lhs
@@ -102,6 +102,7 @@ import ListSetOps
import Binary
import Fingerprint
import Bag
+import Exception
import Control.Monad
import Data.List
@@ -1324,10 +1325,19 @@ checkModUsage this_pkg UsageHomeModule{
else up_to_date (ptext (sLit " Great! The bits I use are up to date"))
-checkModUsage _this_pkg UsageFile{ usg_file_path = file, usg_mtime = old_mtime } = do
- new_mtime <- liftIO $ getModificationTime file
- return $ old_mtime /= new_mtime
-
+checkModUsage _this_pkg UsageFile{ usg_file_path = file,
+ usg_mtime = old_mtime } =
+ liftIO $
+ handleIO handle $ do
+ new_mtime <- getModificationTime file
+ return $ old_mtime /= new_mtime
+ where
+ handle =
+#ifdef DEBUG
+ \e -> pprTrace "UsageFile" (text (show e)) $ return True
+#else
+ \_ -> return True -- if we can't find the file, just recompile, don't fail
+#endif
------------------------
checkModuleFingerprint :: Fingerprint -> Fingerprint -> IfG RecompileRequired
diff --git a/compiler/iface/TcIface.lhs b/compiler/iface/TcIface.lhs
index d17b90d7f3..8a279ca3a1 100644
--- a/compiler/iface/TcIface.lhs
+++ b/compiler/iface/TcIface.lhs
@@ -728,10 +728,11 @@ tcIfaceVectInfo mod typeEnv (IfaceVectInfo
, ifaceVectInfoScalarTyCons = scalarTyCons
})
= do { let scalarTyConsSet = mkNameSet scalarTyCons
- ; vVars <- mapM vectVarMapping vars
- ; tyConRes1 <- mapM vectTyConMapping tycons
- ; tyConRes2 <- mapM (vectTyConReuseMapping scalarTyConsSet) tyconsReuse
- ; vScalarVars <- mapM vectVar scalarVars
+ ; vVars <- mapM vectVarMapping vars
+ ; let varsSet = mkVarSet (map fst vVars)
+ ; tyConRes1 <- mapM (vectTyConVectMapping varsSet) tycons
+ ; tyConRes2 <- mapM (vectTyConReuseMapping varsSet) tyconsReuse
+ ; vScalarVars <- mapM vectVar scalarVars
; let (vTyCons, vDataCons) = unzip (tyConRes1 ++ tyConRes2)
; return $ VectInfo
{ vectInfoVar = mkVarEnv vVars
@@ -757,69 +758,51 @@ tcIfaceVectInfo mod typeEnv (IfaceVectInfo
= forkM (ptext (sLit "vect scalar var") <+> ppr name) $
tcIfaceExtId name
- vectTyConMapping name
+ vectTyConVectMapping vars name
= do { vName <- lookupOrig mod (mkLocalisedOccName mod mkVectTyConOcc name)
+ ; vectTyConMapping vars name vName
+ }
+
+ vectTyConReuseMapping vars name
+ = vectTyConMapping vars name name
+
+ vectTyConMapping vars name vName
+ = do { tycon <- lookupLocalOrExternal name
+ ; vTycon <- lookupLocalOrExternal vName
+
+ -- map the data constructors of the original type constructor to those of the
+ -- vectorised type constructor /unless/ the type constructor was vectorised
+ -- abstractly; if it was vectorised abstractly, the workers of its data constructors
+ -- do not appear in the set of vectorised variables
+ ; let isAbstract | isClassTyCon tycon = False
+ | datacon:_ <- tyConDataCons tycon
+ = not $ dataConWrapId datacon `elemVarSet` vars
+ | otherwise = True
+ vDataCons | isAbstract = []
+ | otherwise = [ (dataConName datacon, (datacon, vDatacon))
+ | (datacon, vDatacon) <- zip (tyConDataCons tycon)
+ (tyConDataCons vTycon)
+ ]
- -- we need a fully defined version of the type constructor to be able to extract
- -- its data constructors etc.
- ; tycon <- do { let mb_tycon = lookupTypeEnv typeEnv name
- ; case mb_tycon of
- -- tycon is local
- Just (ATyCon tycon) -> return tycon
- -- name is not a tycon => internal inconsistency
- Just _ -> notATyConErr
- -- tycon is external
- Nothing -> tcIfaceTyCon (IfaceTc name)
- }
- ; vTycon <- forkM (text ("vect vTycon") <+> ppr vName) $
- tcIfaceTyCon (IfaceTc vName)
-
- -- we need to handle class type constructors differently due to the manner in which
- -- the name for the dictionary data constructor is computed
- ; vDataCons <- if isClassTyCon tycon
- then vectClassDataConMapping vName (tyConSingleDataCon_maybe tycon)
- else mapM vectDataConMapping (tyConDataCons tycon)
; return ( (name, (tycon, vTycon)) -- (T, T_v)
, vDataCons -- list of (Ci, Ci_v)
)
}
where
- notATyConErr = pprPanic "TcIface.tcIfaceVectInfo: not a tycon" (ppr name)
-
- vectTyConReuseMapping scalarNames name
- = do { tycon <- forkM (text ("vect reuse tycon") <+> ppr name) $
- tcIfaceTyCon (IfaceTc name) -- somewhat naughty for wired in tycons, but ok
- ; if name `elemNameSet` scalarNames
- then do
- { return ( (name, (tycon, tycon)) -- scalar type constructors expose no data..
- , [] -- ..constructors see..
- ) -- .."Note [Pragmas to vectorise tycons]"..
- -- ..in 'Vectorise.Type.Env'
- } else do
- { let { vDataCons = [ (dataConName dc, (dc, dc))
- | dc <- tyConDataCons tycon]
- }
- ; return ( (name, (tycon, tycon)) -- (T, T)
- , vDataCons -- list of (Ci, Ci)
- )
- }}
-
- vectClassDataConMapping _vTyconName Nothing = panic "tcIfaceVectInfo: vectClassDataConMapping"
- vectClassDataConMapping vTyconName (Just datacon)
- = do { let name = dataConName datacon
- ; vName <- lookupOrig mod (mkClassDataConOcc . nameOccName $ vTyconName)
- ; vDataCon <- forkM (text ("vect class datacon") <+> ppr name) $
- tcIfaceDataCon vName
- ; return [(name, (datacon, vDataCon))]
- }
+ -- we need a fully defined version of the type constructor to be able to extract
+ -- its data constructors etc.
+ lookupLocalOrExternal name
+ = do { let mb_tycon = lookupTypeEnv typeEnv name
+ ; case mb_tycon of
+ -- tycon is local
+ Just (ATyCon tycon) -> return tycon
+ -- name is not a tycon => internal inconsistency
+ Just _ -> notATyConErr
+ -- tycon is external
+ Nothing -> tcIfaceTyCon (IfaceTc name)
+ }
- vectDataConMapping datacon
- = do { let name = dataConName datacon
- ; vName <- lookupOrig mod (mkLocalisedOccName mod mkVectDataConOcc name)
- ; vDataCon <- forkM (text ("vect datacon") <+> ppr name) $
- tcIfaceDataCon vName
- ; return (name, (datacon, vDataCon))
- }
+ notATyConErr = pprPanic "TcIface.tcIfaceVectInfo: not a tycon" (ppr name)
\end{code}
%************************************************************************
diff --git a/compiler/main/DriverPipeline.hs b/compiler/main/DriverPipeline.hs
index 9851ce1d75..2230f3fa40 100644
--- a/compiler/main/DriverPipeline.hs
+++ b/compiler/main/DriverPipeline.hs
@@ -745,9 +745,7 @@ runPhase (Unlit sf) input_fn dflags
[ -- The -h option passes the file name for unlit to
-- put in a #line directive
SysTools.Option "-h"
- -- cpp interprets \b etc as escape sequences,
- -- so we use / for filenames in pragmas
- , SysTools.Option $ reslash Forwards $ normalise input_fn
+ , SysTools.Option $ escape $ normalise input_fn
, SysTools.FileOption "" input_fn
, SysTools.FileOption "" output_fn
]
@@ -755,6 +753,19 @@ runPhase (Unlit sf) input_fn dflags
io $ SysTools.runUnlit dflags flags
return (Cpp sf, output_fn)
+ where
+ -- escape the characters \, ", and ', but don't try to escape
+ -- Unicode or anything else (so we don't use Util.charToC
+ -- here). If we get this wrong, then in
+ -- Coverage.addTicksToBinds where we check that the filename in
+ -- a SrcLoc is the same as the source filenaame, the two will
+ -- look bogusly different. See test:
+ -- libraries/hpc/tests/function/subdir/tough2.lhs
+ escape ('\\':cs) = '\\':'\\': escape cs
+ escape ('\"':cs) = '\\':'\"': escape cs
+ escape ('\'':cs) = '\\':'\'': escape cs
+ escape (c:cs) = c : escape cs
+ escape [] = []
-------------------------------------------------------------------------------
-- Cpp phase : (a) gets OPTIONS out of file
@@ -1703,7 +1714,7 @@ linkBinary dflags o_files dep_packages = do
let
thread_opts | WayThreaded `elem` ways = [
-#if !defined(mingw32_TARGET_OS) && !defined(freebsd_TARGET_OS) && !defined(openbsd_TARGET_OS) && !defined(haiku_TARGET_OS)
+#if !defined(mingw32_TARGET_OS) && !defined(freebsd_TARGET_OS) && !defined(openbsd_TARGET_OS) && !defined(netbsd_TARGET_OS) && !defined(haiku_TARGET_OS)
"-lpthread"
#endif
#if defined(osf3_TARGET_OS)
diff --git a/compiler/main/DynFlags.hs b/compiler/main/DynFlags.hs
index 4eb6dc9bcb..fce75b0bff 100644
--- a/compiler/main/DynFlags.hs
+++ b/compiler/main/DynFlags.hs
@@ -129,6 +129,9 @@ import qualified Data.Set as Set
import System.FilePath
import System.IO ( stderr, hPutChar )
+import Data.IntSet (IntSet)
+import qualified Data.IntSet as IntSet
+
-- -----------------------------------------------------------------------------
-- DynFlags
@@ -304,7 +307,7 @@ data DynFlag
| Opt_DistrustAllPackages
| Opt_PackageTrust
- deriving (Eq, Show)
+ deriving (Eq, Show, Enum)
data WarningFlag =
Opt_WarnDuplicateExports
@@ -341,7 +344,7 @@ data WarningFlag =
| Opt_WarnAlternativeLayoutRuleTransitional
| Opt_WarnUnsafe
| Opt_WarnSafe
- deriving (Eq, Show)
+ deriving (Eq, Show, Enum)
data Language = Haskell98 | Haskell2010
deriving Enum
@@ -552,8 +555,8 @@ data DynFlags = DynFlags {
generatedDumps :: IORef (Set FilePath),
-- hsc dynamic flags
- flags :: [DynFlag],
- warningFlags :: [WarningFlag],
+ flags :: IntSet,
+ warningFlags :: IntSet,
-- Don't change this without updating extensionFlags:
language :: Maybe Language,
-- | Safe Haskell mode
@@ -569,7 +572,7 @@ data DynFlags = DynFlags {
extensions :: [OnOff ExtensionFlag],
-- extensionFlags should always be equal to
-- flattenExtensionFlags language extensions
- extensionFlags :: [ExtensionFlag],
+ extensionFlags :: IntSet,
-- | Message output action: use "ErrUtils" instead of this if you can
log_action :: LogAction,
@@ -894,8 +897,8 @@ defaultDynFlags mySettings =
dirsToClean = panic "defaultDynFlags: No dirsToClean",
generatedDumps = panic "defaultDynFlags: No generatedDumps",
haddockOptions = Nothing,
- flags = defaultFlags,
- warningFlags = standardWarnings,
+ flags = IntSet.fromList (map fromEnum defaultFlags),
+ warningFlags = IntSet.fromList (map fromEnum standardWarnings),
language = Nothing,
safeHaskell = Sf_SafeInfered,
thOnLoc = noSrcSpan,
@@ -938,12 +941,11 @@ data OnOff a = On a
-- OnOffs accumulate in reverse order, so we use foldr in order to
-- process them in the right order
-flattenExtensionFlags :: Maybe Language -> [OnOff ExtensionFlag]
- -> [ExtensionFlag]
+flattenExtensionFlags :: Maybe Language -> [OnOff ExtensionFlag] -> IntSet
flattenExtensionFlags ml = foldr f defaultExtensionFlags
- where f (On f) flags = f : delete f flags
- f (Off f) flags = delete f flags
- defaultExtensionFlags = languageExtensions ml
+ where f (On f) flags = IntSet.insert (fromEnum f) flags
+ f (Off f) flags = IntSet.delete (fromEnum f) flags
+ defaultExtensionFlags = IntSet.fromList (map fromEnum (languageExtensions ml))
languageExtensions :: Maybe Language -> [ExtensionFlag]
@@ -985,31 +987,31 @@ languageExtensions (Just Haskell2010)
-- | Test whether a 'DynFlag' is set
dopt :: DynFlag -> DynFlags -> Bool
-dopt f dflags = f `elem` (flags dflags)
+dopt f dflags = fromEnum f `IntSet.member` flags dflags
-- | Set a 'DynFlag'
dopt_set :: DynFlags -> DynFlag -> DynFlags
-dopt_set dfs f = dfs{ flags = f : flags dfs }
+dopt_set dfs f = dfs{ flags = IntSet.insert (fromEnum f) (flags dfs) }
-- | Unset a 'DynFlag'
dopt_unset :: DynFlags -> DynFlag -> DynFlags
-dopt_unset dfs f = dfs{ flags = filter (/= f) (flags dfs) }
+dopt_unset dfs f = dfs{ flags = IntSet.delete (fromEnum f) (flags dfs) }
-- | Test whether a 'WarningFlag' is set
wopt :: WarningFlag -> DynFlags -> Bool
-wopt f dflags = f `elem` (warningFlags dflags)
+wopt f dflags = fromEnum f `IntSet.member` warningFlags dflags
-- | Set a 'WarningFlag'
wopt_set :: DynFlags -> WarningFlag -> DynFlags
-wopt_set dfs f = dfs{ warningFlags = f : warningFlags dfs }
+wopt_set dfs f = dfs{ warningFlags = IntSet.insert (fromEnum f) (warningFlags dfs) }
-- | Unset a 'WarningFlag'
wopt_unset :: DynFlags -> WarningFlag -> DynFlags
-wopt_unset dfs f = dfs{ warningFlags = filter (/= f) (warningFlags dfs) }
+wopt_unset dfs f = dfs{ warningFlags = IntSet.delete (fromEnum f) (warningFlags dfs) }
-- | Test whether a 'ExtensionFlag' is set
xopt :: ExtensionFlag -> DynFlags -> Bool
-xopt f dflags = f `elem` extensionFlags dflags
+xopt f dflags = fromEnum f `IntSet.member` extensionFlags dflags
-- | Set a 'ExtensionFlag'
xopt_set :: DynFlags -> ExtensionFlag -> DynFlags
@@ -1589,9 +1591,9 @@ dynamic_flags = [
, Flag "Werror" (NoArg (setDynFlag Opt_WarnIsError))
, Flag "Wwarn" (NoArg (unSetDynFlag Opt_WarnIsError))
, Flag "Wall" (NoArg (mapM_ setWarningFlag minusWallOpts))
- , Flag "Wnot" (NoArg (do upd (\dfs -> dfs {warningFlags = []})
+ , Flag "Wnot" (NoArg (do upd (\dfs -> dfs {warningFlags = IntSet.empty})
deprecate "Use -w instead"))
- , Flag "w" (NoArg (upd (\dfs -> dfs {warningFlags = []})))
+ , Flag "w" (NoArg (upd (\dfs -> dfs {warningFlags = IntSet.empty})))
------ Plugin flags ------------------------------------------------
, Flag "fplugin-opt" (hasArg addPluginModuleNameOption)
diff --git a/compiler/main/HscTypes.lhs b/compiler/main/HscTypes.lhs
index 2424ddc989..6b389fd1b2 100644
--- a/compiler/main/HscTypes.lhs
+++ b/compiler/main/HscTypes.lhs
@@ -1948,6 +1948,9 @@ data VectInfo
--
-- NB: The field 'ifaceVectInfoVar' explicitly contains the workers of data constructors as well as
-- class selectors — i.e., their mappings are /not/ implicitly generated from the data types.
+-- Moreover, whether the worker of a data constructor is in 'ifaceVectInfoVar' determines
+-- whether that data constructor was vectorised (or is part of an abstractly vectorised type
+-- constructor).
--
data IfaceVectInfo
= IfaceVectInfo
diff --git a/compiler/main/StaticFlags.hs b/compiler/main/StaticFlags.hs
index dd00d3d6b3..e89d9b32a4 100644
--- a/compiler/main/StaticFlags.hs
+++ b/compiler/main/StaticFlags.hs
@@ -491,7 +491,7 @@ way_details =
-- the problems are our fault or theirs, but it seems that using the
-- alternative 1:1 threading library libthr works around it:
"-optl-lthr"
-#elif defined(openbsd_TARGET_OS)
+#elif defined(openbsd_TARGET_OS) || defined(netbsd_TARGET_OS)
"-optc-pthread"
, "-optl-pthread"
#elif defined(solaris2_TARGET_OS)
@@ -509,7 +509,7 @@ way_details =
-- with -fPIC. Labels not in the current package are assumed to be in a DLL
-- different from the current one.
, "-fPIC"
-#elif defined(openbsd_TARGET_OS)
+#elif defined(openbsd_TARGET_OS) || defined(netbsd_TARGET_OS)
-- Without this, linking the shared libHSffi fails because
-- it uses pthread mutexes.
, "-optl-pthread"
diff --git a/compiler/main/SysTools.lhs b/compiler/main/SysTools.lhs
index 00311597d8..4a51b313e2 100644
--- a/compiler/main/SysTools.lhs
+++ b/compiler/main/SysTools.lhs
@@ -582,10 +582,22 @@ copyWithHeader dflags purpose maybe_header from to = do
hout <- openBinaryFile to WriteMode
hin <- openBinaryFile from ReadMode
ls <- hGetContents hin -- inefficient, but it'll do for now. ToDo: speed up
- maybe (return ()) (hPutStr hout) maybe_header
+ maybe (return ()) (header hout) maybe_header
hPutStr hout ls
hClose hout
hClose hin
+ where
+#if __GLASGOW_HASKELL__ >= 702
+ -- write the header string in UTF-8. The header is something like
+ -- {-# LINE "foo.hs" #-}
+ -- and we want to make sure a Unicode filename isn't mangled.
+ header h str = do
+ hSetEncoding h utf8
+ hPutStr h str
+ hSetBinaryMode h True
+#else
+ header h str = hPutStr h str
+#endif
-- | read the contents of the named section in an ELF object as a
-- String.
diff --git a/compiler/nativeGen/PPC/CodeGen.hs b/compiler/nativeGen/PPC/CodeGen.hs
index 607e05d66b..8c80ec40c1 100644
--- a/compiler/nativeGen/PPC/CodeGen.hs
+++ b/compiler/nativeGen/PPC/CodeGen.hs
@@ -853,6 +853,7 @@ genCCall target dest_regs argsAndHints
OSMinGW32 -> panic "PPC.CodeGen.genCCall: not defined for this os"
OSFreeBSD -> panic "PPC.CodeGen.genCCall: not defined for this os"
OSOpenBSD -> panic "PPC.CodeGen.genCCall: not defined for this os"
+ OSNetBSD -> panic "PPC.CodeGen.genCCall: not defined for this os"
OSUnknown -> panic "PPC.CodeGen.genCCall: not defined for this os"
data GenCCallPlatform = GCPLinux | GCPDarwin
diff --git a/compiler/parser/Lexer.x b/compiler/parser/Lexer.x
index 9f2083cf92..ea01070c94 100644
--- a/compiler/parser/Lexer.x
+++ b/compiler/parser/Lexer.x
@@ -1126,7 +1126,19 @@ setLine code span buf len = do
setFile :: Int -> Action
setFile code span buf len = do
- let file = lexemeToFastString (stepOn buf) (len-2)
+ let file = mkFastString (go (lexemeToString (stepOn buf) (len-2)))
+ where go ('\\':c:cs) = c : go cs
+ go (c:cs) = c : go cs
+ go [] = []
+ -- decode escapes in the filename. e.g. on Windows
+ -- when our filenames have backslashes in, gcc seems to
+ -- escape the backslashes. One symptom of not doing this
+ -- is that filenames in error messages look a bit strange:
+ -- C:\\foo\bar.hs
+ -- only the first backslash is doubled, because we apply
+ -- System.FilePath.normalise before printing out
+ -- filenames and it does not remove duplicate
+ -- backslashes after the drive letter (should it?).
setAlrLastLoc $ alrInitialLoc file
setSrcLoc (mkRealSrcLoc file (srcSpanEndLine span) (srcSpanEndCol span))
addSrcFile file
diff --git a/compiler/parser/Parser.y.pp b/compiler/parser/Parser.y.pp
index 0701b9f7c9..de15f1cf2f 100644
--- a/compiler/parser/Parser.y.pp
+++ b/compiler/parser/Parser.y.pp
@@ -589,11 +589,12 @@ topdecl :: { OrdList (LHsDecl RdrName) }
| '{-# VECTORISE' 'type' gtycon '=' gtycon '#-}'
{ unitOL $ LL $
VectD (HsVectTypeIn False $3 (Just $5)) }
+ | '{-# VECTORISE_SCALAR' 'type' gtycon '=' gtycon '#-}'
+ { unitOL $ LL $
+ VectD (HsVectTypeIn True $3 (Just $5)) }
| '{-# VECTORISE' 'class' gtycon '#-}' { unitOL $ LL $ VectD (HsVectClassIn $3) }
- | '{-# VECTORISE' 'instance' type '#-}'
- { unitOL $ LL $ VectD (HsVectInstIn False $3) }
| '{-# VECTORISE_SCALAR' 'instance' type '#-}'
- { unitOL $ LL $ VectD (HsVectInstIn True $3) }
+ { unitOL $ LL $ VectD (HsVectInstIn $3) }
| annotation { unitOL $1 }
| decl { unLoc $1 }
@@ -1320,14 +1321,15 @@ sigdecl :: { Located (OrdList (LHsDecl RdrName)) }
{ LL $ toOL [ LL $ SigD (TypeSig ($1 : unLoc $3) $5) ] }
| infix prec ops { LL $ toOL [ LL $ SigD (FixSig (FixitySig n (Fixity $2 (unLoc $1))))
| n <- unLoc $3 ] }
- | '{-# INLINE' activation qvar '#-}'
+ | '{-# INLINE' activation qvar '#-}'
{ LL $ unitOL (LL $ SigD (InlineSig $3 (mkInlinePragma (getINLINE $1) $2))) }
- | '{-# SPECIALISE' qvar '::' sigtypes1 '#-}'
- { LL $ toOL [ LL $ SigD (SpecSig $2 t defaultInlinePragma)
- | t <- $4] }
+ | '{-# SPECIALISE' activation qvar '::' sigtypes1 '#-}'
+ { let inl_prag = mkInlinePragma (EmptyInlineSpec, FunLike) $2
+ in LL $ toOL [ LL $ SigD (SpecSig $3 t inl_prag)
+ | t <- $5] }
| '{-# SPECIALISE_INLINE' activation qvar '::' sigtypes1 '#-}'
{ LL $ toOL [ LL $ SigD (SpecSig $3 t (mkInlinePragma (getSPEC_INLINE $1) $2))
- | t <- $5] }
+ | t <- $5] }
| '{-# SPECIALISE' 'instance' inst_type '#-}'
{ LL $ unitOL (LL $ SigD (SpecInstSig $3)) }
diff --git a/compiler/parser/RdrHsSyn.lhs b/compiler/parser/RdrHsSyn.lhs
index 8ab71f3885..3b1a289fd2 100644
--- a/compiler/parser/RdrHsSyn.lhs
+++ b/compiler/parser/RdrHsSyn.lhs
@@ -885,7 +885,8 @@ mk_rec_fields fs False = HsRecFields { rec_flds = fs, rec_dotdot = Nothing }
mk_rec_fields fs True = HsRecFields { rec_flds = fs, rec_dotdot = Just (length fs) }
mkInlinePragma :: (InlineSpec, RuleMatchInfo) -> Maybe Activation -> InlinePragma
--- The Maybe is because the user can omit the activation spec (and usually does)
+-- The (Maybe Activation) is because the user can omit
+-- the activation spec (and usually does)
mkInlinePragma (inl, match_info) mb_act
= InlinePragma { inl_inline = inl
, inl_sat = Nothing
diff --git a/compiler/rename/RnSource.lhs b/compiler/rename/RnSource.lhs
index 7d8d1d5a89..d79dcb868e 100644
--- a/compiler/rename/RnSource.lhs
+++ b/compiler/rename/RnSource.lhs
@@ -672,11 +672,11 @@ rnHsVectDecl (HsVectClassIn cls)
}
rnHsVectDecl (HsVectClassOut _)
= panic "RnSource.rnHsVectDecl: Unexpected 'HsVectClassOut'"
-rnHsVectDecl (HsVectInstIn isScalar instTy)
+rnHsVectDecl (HsVectInstIn instTy)
= do { instTy' <- rnLHsInstType (text "In a VECTORISE pragma") instTy
- ; return (HsVectInstIn isScalar instTy', emptyFVs)
+ ; return (HsVectInstIn instTy', emptyFVs)
}
-rnHsVectDecl (HsVectInstOut _ _)
+rnHsVectDecl (HsVectInstOut _)
= panic "RnSource.rnHsVectDecl: Unexpected 'HsVectInstOut'"
\end{code}
diff --git a/compiler/typecheck/TcBinds.lhs b/compiler/typecheck/TcBinds.lhs
index f12bad426d..072f77c2f2 100644
--- a/compiler/typecheck/TcBinds.lhs
+++ b/compiler/typecheck/TcBinds.lhs
@@ -694,7 +694,11 @@ tcVect (HsNoVect name)
tcVect (HsVectTypeIn isScalar lname rhs_name)
= addErrCtxt (vectCtxt lname) $
do { tycon <- tcLookupLocatedTyCon lname
- ; checkTc (not isScalar || tyConArity tycon == 0) scalarTyConMustBeNullary
+ ; checkTc ( not isScalar -- either we have a non-SCALAR declaration
+ || isJust rhs_name -- or we explicitly provide a vectorised type
+ || tyConArity tycon == 0 -- otherwise the type constructor must be nullary
+ )
+ scalarTyConMustBeNullary
; rhs_tycon <- fmapMaybeM (tcLookupTyCon . unLoc) rhs_name
; return $ HsVectTypeOut isScalar tycon rhs_tycon
@@ -708,13 +712,13 @@ tcVect (HsVectClassIn lname)
}
tcVect (HsVectClassOut _)
= panic "TcBinds.tcVect: Unexpected 'HsVectClassOut'"
-tcVect (HsVectInstIn isScalar linstTy)
+tcVect (HsVectInstIn linstTy)
= addErrCtxt (vectCtxt linstTy) $
do { (cls, tys) <- tcHsVectInst linstTy
; inst <- tcLookupInstance cls tys
- ; return $ HsVectInstOut isScalar inst
+ ; return $ HsVectInstOut inst
}
-tcVect (HsVectInstOut _ _)
+tcVect (HsVectInstOut _)
= panic "TcBinds.tcVect: Unexpected 'HsVectInstOut'"
vectCtxt :: Outputable thing => thing -> SDoc
diff --git a/compiler/typecheck/TcCanonical.lhs b/compiler/typecheck/TcCanonical.lhs
index d5e1f75b8d..09a5403508 100644
--- a/compiler/typecheck/TcCanonical.lhs
+++ b/compiler/typecheck/TcCanonical.lhs
@@ -579,48 +579,49 @@ flatten d fl (TyConApp tc tys)
-- in which case the remaining arguments should
-- be dealt with by AppTys
fam_ty = mkTyConApp tc xi_args
- ; (ret_co, rhs_var, ct) <-
+ ; (ret_co, rhs_xi, ct) <-
do { is_cached <- getCachedFlatEq tc xi_args fl Any
; case is_cached of
- Just (rhs_var,ret_eq) ->
+ Just (rhs_xi,ret_eq) ->
do { traceTcS "is_cached!" $ ppr ret_eq
- ; return (ret_eq, rhs_var, []) }
+ ; return (ret_eq, rhs_xi, []) }
Nothing
| isGivenOrSolved fl ->
- do { rhs_var <- newFlattenSkolemTy fam_ty
- ; eqv <- newGivenEqVar fl fam_ty rhs_var (mkReflCo fam_ty)
+ do { rhs_xi_var <- newFlattenSkolemTy fam_ty
+ ; eqv <- newGivenEqVar fl fam_ty rhs_xi_var (mkReflCo fam_ty)
; let ct = CFunEqCan { cc_id = eqv
, cc_flavor = fl -- Given
, cc_fun = tc
, cc_tyargs = xi_args
- , cc_rhs = rhs_var
+ , cc_rhs = rhs_xi_var
, cc_depth = d }
-- Update the flat cache: just an optimisation!
- ; updateFlatCache eqv fl tc xi_args rhs_var WhileFlattening
+ ; updateFlatCache eqv fl tc xi_args rhs_xi_var WhileFlattening
- ; return (mkEqVarLCo eqv, rhs_var, [ct]) }
+ ; return (mkEqVarLCo eqv, rhs_xi_var, [ct]) }
| otherwise ->
-- Derived or Wanted: make a new /unification/ flatten variable
- do { rhs_var <- newFlexiTcSTy (typeKind fam_ty)
+ do { rhs_xi_var <- newFlexiTcSTy (typeKind fam_ty)
; let wanted_flavor = mkWantedFlavor fl
- ; evc <- newEqVar wanted_flavor fam_ty rhs_var
+ ; evc <- newEqVar wanted_flavor fam_ty rhs_xi_var
; let eqv = evc_the_evvar evc -- Not going to be cached
ct = CFunEqCan { cc_id = eqv
, cc_flavor = wanted_flavor
-- Always Wanted, not Derived
, cc_fun = tc
, cc_tyargs = xi_args
- , cc_rhs = rhs_var
+ , cc_rhs = rhs_xi_var
, cc_depth = d }
-- Update the flat cache: just an optimisation!
- ; updateFlatCache eqv fl tc xi_args rhs_var WhileFlattening
- ; return (mkEqVarLCo eqv, rhs_var, [ct]) } }
+ ; updateFlatCache eqv fl tc xi_args rhs_xi_var WhileFlattening
+ ; return (mkEqVarLCo eqv, rhs_xi_var, [ct]) } }
-- Emit the flat constraints
; updWorkListTcS $ appendWorkListEqs ct
; let (cos_args, cos_rest) = splitAt (tyConArity tc) cos
- ; return ( foldl AppTy rhs_var xi_rest
+ ; return ( mkAppTys rhs_xi xi_rest -- NB mkAppTys: rhs_xi might not be a type variable
+ -- cf Trac #5655
, foldl AppCo (mkSymCo ret_co `mkTransCo` mkTyConAppCo tc cos_args)
cos_rest) }
diff --git a/compiler/typecheck/TcForeign.lhs b/compiler/typecheck/TcForeign.lhs
index 886b84d22e..5a4bf776fa 100644
--- a/compiler/typecheck/TcForeign.lhs
+++ b/compiler/typecheck/TcForeign.lhs
@@ -121,17 +121,29 @@ normaliseFfiType' env ty0 = go [] ty0
panic "normaliseFfiType': Got more GREs than expected"
_ ->
return False
- if newtypeOK
- then do let nt_co = mkAxInstCo (newTyConCo tc) tys
- add_co nt_co rec_nts' nt_rhs
- else children_only
+ when (not newtypeOK) $
+ -- later: stop_here
+ addWarnTc (ptext (sLit "newtype") <+> quotes (ppr tc) <+>
+ ptext (sLit "is used in an FFI declaration,") $$
+ ptext (sLit "but its constructor is not in scope.") $$
+ ptext (sLit "This will become an error in GHC 7.6.1."))
+
+ let nt_co = mkAxInstCo (newTyConCo tc) tys
+ add_co nt_co rec_nts' nt_rhs
+
| isFamilyTyCon tc -- Expand open tycons
, (co, ty) <- normaliseTcApp env tc tys
, not (isReflCo co)
= add_co co rec_nts ty
+
| otherwise
- = children_only
+ = return (mkReflCo ty, ty)
+ -- If we have reached an ordinary (non-newtype) type constructor,
+ -- we are done. Note that we don't need to normalise the arguments,
+ -- because whether an FFI type is legal or not depends only on
+ -- the top-level type constructor (e.g. "Ptr a" is valid for all a).
where
+
children_only = do xs <- mapM (go rec_nts) tys
let (cos, tys') = unzip xs
return (mkTyConAppCo tc cos, mkTyConApp tc tys')
diff --git a/compiler/typecheck/TcGenGenerics.lhs b/compiler/typecheck/TcGenGenerics.lhs
index d034a39b95..126575d45e 100644
--- a/compiler/typecheck/TcGenGenerics.lhs
+++ b/compiler/typecheck/TcGenGenerics.lhs
@@ -239,8 +239,8 @@ mkBindsRep tycon =
`unionBags`
unitBag (L loc (mkFunBind (L loc to_RDR) to_matches))
where
- from_matches = [mkSimpleHsAlt pat rhs | (pat,rhs) <- from_alts]
- to_matches = [mkSimpleHsAlt pat rhs | (pat,rhs) <- to_alts ]
+ from_matches = [mkSimpleHsAlt pat rhs | (pat,rhs) <- from_alts]
+ to_matches = [mkSimpleHsAlt pat rhs | (pat,rhs) <- to_alts ]
loc = srcLocSpan (getSrcLoc tycon)
datacons = tyConDataCons tycon
@@ -267,7 +267,6 @@ tc_mkRepTyCon tycon metaDts mod =
; rep0Ty <- tc_mkRepTy tycon metaDts
-- `rep_name` is a name we generate for the synonym
--- ; rep_name <- newImplicitBinder (tyConName tycon) mkGenR
; rep_name <- newGlobalBinder mod (mkGenR (nameOccName (tyConName tycon)))
(nameSrcSpan (tyConName tycon))
; let -- `tyvars` = [a,b]
diff --git a/compiler/typecheck/TcHsSyn.lhs b/compiler/typecheck/TcHsSyn.lhs
index ce6b48c7fa..4f8cdb2a77 100644
--- a/compiler/typecheck/TcHsSyn.lhs
+++ b/compiler/typecheck/TcHsSyn.lhs
@@ -1063,9 +1063,9 @@ zonkVect _ (HsVectTypeIn _ _ _) = panic "TcHsSyn.zonkVect: HsVectTypeIn"
zonkVect _env (HsVectClassOut c)
= return $ HsVectClassOut c
zonkVect _ (HsVectClassIn _) = panic "TcHsSyn.zonkVect: HsVectClassIn"
-zonkVect _env (HsVectInstOut s i)
- = return $ HsVectInstOut s i
-zonkVect _ (HsVectInstIn _ _) = panic "TcHsSyn.zonkVect: HsVectInstIn"
+zonkVect _env (HsVectInstOut i)
+ = return $ HsVectInstOut i
+zonkVect _ (HsVectInstIn _) = panic "TcHsSyn.zonkVect: HsVectInstIn"
\end{code}
%************************************************************************
@@ -1206,9 +1206,7 @@ zonkTvCollecting :: TcRef TyVarSet -> UnboundTyVarZonker
-- Works on both types and kinds
zonkTvCollecting unbound_tv_set tv
= do { poly_kinds <- xoptM Opt_PolyKinds
- ; if isKiVar tv && not poly_kinds then
- do { defaultKindVarToStar tv
- ; return liftedTypeKind }
+ ; if isKiVar tv && not poly_kinds then defaultKindVarToStar tv
else do
{ tv' <- zonkQuantifiedTyVar tv
; tv_set <- readMutVar unbound_tv_set
diff --git a/compiler/typecheck/TcHsType.lhs b/compiler/typecheck/TcHsType.lhs
index 425ad69390..b86321e82e 100644
--- a/compiler/typecheck/TcHsType.lhs
+++ b/compiler/typecheck/TcHsType.lhs
@@ -67,7 +67,7 @@ import NameSet
import TysWiredIn
import BasicTypes
import SrcLoc
-import DynFlags ( ExtensionFlag( Opt_ConstraintKinds, Opt_PolyKinds ) )
+import DynFlags ( ExtensionFlag( Opt_PolyKinds ) )
import Util
import UniqSupply
import Outputable
@@ -375,31 +375,60 @@ kc_hs_type (HsKindSig ty sig_k) exp_kind = do
return (HsKindSig ty' sig_k)
-- See Note [Distinguishing tuple kinds] in HsTypes
-kc_hs_type (HsTupleTy HsBoxedOrConstraintTuple tys) exp_kind@(EK exp_k _ctxt)
- = do { fact_tup_ok <- xoptM Opt_ConstraintKinds
- ; let (k, tupleType) = if fact_tup_ok && isConstraintKind exp_k
- then (constraintKind, HsConstraintTuple)
- -- If it's not a constraint, then it has to be *
- -- Unboxed tuples are a separate case
- else (liftedTypeKind, HsBoxedTuple)
- ; kc_hs_tuple_type tys tupleType k exp_kind }
-
-kc_hs_type (HsTupleTy HsBoxedTuple tys) exp_kind
- = kc_hs_tuple_type tys HsBoxedTuple liftedTypeKind exp_kind
-
-kc_hs_type (HsTupleTy HsConstraintTuple tys) exp_kind
- = kc_hs_tuple_type tys HsConstraintTuple constraintKind exp_kind
-
--- JPM merge with kc_hs_tuple_type ?
-kc_hs_type ty@(HsTupleTy HsUnboxedTuple tys) exp_kind
- = do { tys' <- kcArgs (ptext (sLit "an unboxed tuple")) tys argTypeKind
- ; checkExpectedKindS ty ubxTupleKind exp_kind
- ; return (HsTupleTy HsUnboxedTuple tys') }
+kc_hs_type ty@(HsTupleTy HsBoxedOrConstraintTuple tys) exp_kind@(EK exp_k _ctxt)
+ | isConstraintOrLiftedKind exp_k -- (NB: not zonking, to avoid left-right bias)
+ = do { tys' <- kcArgs (ptext (sLit "a tuple")) tys exp_k
+ ; return $ if isConstraintKind exp_k
+ then HsTupleTy HsConstraintTuple tys'
+ else HsTupleTy HsBoxedTuple tys' }
+ | otherwise
+ -- It is not clear from the context if it's * or Constraint,
+ -- so we infer the kind from the arguments
+ = do { k <- newMetaKindVar
+ ; tys' <- kcArgs (ptext (sLit "a tuple")) tys k
+ ; k' <- zonkTcKind k
+ ; if isConstraintKind k'
+ then do { checkExpectedKind ty k' exp_kind
+ ; return (HsTupleTy HsConstraintTuple tys') }
+ -- If it's not clear from the arguments that it's Constraint, then
+ -- it must be *. Check the arguments again to give good error messages
+ -- in eg. `(Maybe, Maybe)`
+ else do { tys'' <- kcArgs (ptext (sLit "a tuple")) tys liftedTypeKind
+ ; checkExpectedKind ty liftedTypeKind exp_kind
+ ; return (HsTupleTy HsBoxedTuple tys'') } }
+{-
+Note that we will still fail to infer the correct kind in this case:
+
+ type T a = ((a,a), D a)
+ type family D :: Constraint -> Constraint
+
+While kind checking T, we do not yet know the kind of D, so we will default the
+kind of T to * -> *. It works if we annotate `a` with kind `Constraint`.
+-}
+
+kc_hs_type ty@(HsTupleTy tup_sort tys) exp_kind
+ = do { tys' <- kcArgs cxt_doc tys arg_kind
+ ; checkExpectedKind ty out_kind exp_kind
+ ; return (HsTupleTy tup_sort tys') }
+ where
+ arg_kind = case tup_sort of
+ HsBoxedTuple -> liftedTypeKind
+ HsUnboxedTuple -> argTypeKind
+ HsConstraintTuple -> constraintKind
+ _ -> panic "kc_hs_type arg_kind"
+ out_kind = case tup_sort of
+ HsUnboxedTuple -> ubxTupleKind
+ _ -> arg_kind
+ cxt_doc = case tup_sort of
+ HsBoxedTuple -> ptext (sLit "a tuple")
+ HsUnboxedTuple -> ptext (sLit "an unboxed tuple")
+ HsConstraintTuple -> ptext (sLit "a constraint tuple")
+ _ -> panic "kc_hs_type tup_sort"
kc_hs_type ty@(HsFunTy ty1 ty2) exp_kind@(EK _ ctxt) = do
ty1' <- kc_lhs_type ty1 (EK argTypeKind ctxt)
ty2' <- kc_lhs_type ty2 (EK openTypeKind ctxt)
- checkExpectedKindS ty liftedTypeKind exp_kind
+ checkExpectedKind ty liftedTypeKind exp_kind
return (HsFunTy ty1' ty2')
kc_hs_type ty@(HsOpTy ty1 (_, l_op@(L loc op)) ty2) exp_kind = do
@@ -421,7 +450,7 @@ kc_hs_type ipTy@(HsIParamTy n ty) exp_kind = do
ty' <- kc_lhs_type ty
(EK liftedTypeKind
(ptext (sLit "The type argument of the implicit parameter had")))
- checkExpectedKindS ipTy constraintKind exp_kind
+ checkExpectedKind ipTy constraintKind exp_kind
return (HsIParamTy n ty')
kc_hs_type ty@(HsEqTy ty1 ty2) exp_kind = do
@@ -429,7 +458,7 @@ kc_hs_type ty@(HsEqTy ty1 ty2) exp_kind = do
(ty2', kind2) <- kc_lhs_type_fresh ty2
checkExpectedKind ty2 kind2
(EK kind1 (ptext (sLit "The left argument of the equality predicate had")))
- checkExpectedKindS ty constraintKind exp_kind
+ checkExpectedKind ty constraintKind exp_kind
return (HsEqTy ty1' ty2')
kc_hs_type (HsCoreTy ty) exp_kind = do
@@ -467,7 +496,7 @@ kc_hs_type ty@(HsRecTy _) _exp_kind
#ifdef GHCI /* Only if bootstrapped */
kc_hs_type (HsSpliceTy sp fvs _) exp_kind = do
(ty, k) <- kcSpliceType sp fvs
- checkExpectedKindS ty k exp_kind
+ checkExpectedKind ty k exp_kind
return ty
#else
kc_hs_type ty@(HsSpliceTy {}) _exp_kind =
@@ -485,27 +514,19 @@ kc_hs_type (HsDocTy ty _) exp_kind
kc_hs_type ty@(HsExplicitListTy _k tys) exp_kind
= do { ty_k_s <- mapM kc_lhs_type_fresh tys
; kind <- unifyKinds (ptext (sLit "In a promoted list")) ty_k_s
- ; checkExpectedKindS ty (mkListTy kind) exp_kind
+ ; checkExpectedKind ty (mkListTy kind) exp_kind
; return (HsExplicitListTy kind (map fst ty_k_s)) }
kc_hs_type ty@(HsExplicitTupleTy _ tys) exp_kind = do
ty_k_s <- mapM kc_lhs_type_fresh tys
let tupleKi = mkTyConApp (tupleTyCon BoxedTuple (length tys)) (map snd ty_k_s)
- checkExpectedKindS ty tupleKi exp_kind
+ checkExpectedKind ty tupleKi exp_kind
return (HsExplicitTupleTy (map snd ty_k_s) (map fst ty_k_s))
kc_hs_type (HsWrapTy {}) _exp_kind =
panic "kc_hs_type HsWrapTy" -- We kind checked something twice
---------------------------
-kc_hs_tuple_type :: [LHsType Name] -> HsTupleSort -> Kind -> ExpKind
- -> TcM (HsType Name)
-kc_hs_tuple_type tys tuple_type kind exp_kind
- = do { tys' <- kcArgs (ptext (sLit "a tuple")) tys kind
- ; let hsTupleTy = HsTupleTy tuple_type tys'
- ; checkExpectedKindS hsTupleTy kind exp_kind
- ; return hsTupleTy }
-
kcApps :: Outputable a
=> a
-> TcKind -- Function kind
@@ -523,7 +544,7 @@ kcCheckApps :: Outputable a => a -> TcKind -> [LHsType Name]
kcCheckApps the_fun fun_kind args ty exp_kind
= do { (args_w_kinds, res_kind) <- splitFunKind (ppr the_fun) 1 fun_kind args
; args_w_kinds' <- kc_lhs_types args_w_kinds
- ; checkExpectedKindS ty res_kind exp_kind
+ ; checkExpectedKind ty res_kind exp_kind
; return args_w_kinds' }
@@ -1208,14 +1229,18 @@ checkExpectedKind ty act_kind ek@(EK exp_kind ek_ctxt) = do
env0 <- tcInitTidyEnv
let (exp_as, _) = splitKindFunTys exp_kind
(act_as, _) = splitKindFunTys act_kind
- n_exp_as = length exp_as
- n_act_as = length act_as
+ n_exp_as = length exp_as
+ n_act_as = length act_as
+ n_diff_as = n_act_as - n_exp_as
(env1, tidy_exp_kind) = tidyOpenKind env0 exp_kind
(env2, tidy_act_kind) = tidyOpenKind env1 act_kind
err | n_exp_as < n_act_as -- E.g. [Maybe]
- = quotes (ppr ty) <+> ptext (sLit "is not applied to enough type arguments")
+ = ptext (sLit "Expecting") <+>
+ speakN n_diff_as <+> ptext (sLit "more argument") <>
+ (if n_diff_as > 1 then char 's' else empty) <+>
+ ptext (sLit "to") <+> quotes (ppr ty)
-- Now n_exp_as >= n_act_as. In the next two cases,
-- n_exp_as == 0, and hence so is n_act_as
@@ -1223,7 +1248,7 @@ checkExpectedKind ty act_kind ek@(EK exp_kind ek_ctxt) = do
= text "Predicate" <+> quotes (ppr ty) <+> text "used as a type"
| isConstraintKind tidy_exp_kind
- = text "Type of kind " <+> ppr tidy_act_kind <+> text "used as a constraint"
+ = text "Type of kind" <+> ppr tidy_act_kind <+> text "used as a constraint"
| isLiftedTypeKind exp_kind && isUnliftedTypeKind act_kind
= ptext (sLit "Expecting a lifted type, but") <+> quotes (ppr ty)
@@ -1234,26 +1259,14 @@ checkExpectedKind ty act_kind ek@(EK exp_kind ek_ctxt) = do
<+> ptext (sLit "is lifted")
| otherwise -- E.g. Monad [Int]
- = ptext (sLit "Kind mis-match")
+ = ptext (sLit "Kind mis-match") $$ more_info
more_info = sep [ ek_ctxt <+> ptext (sLit "kind")
<+> quotes (pprKind tidy_exp_kind) <> comma,
ptext (sLit "but") <+> quotes (ppr ty) <+>
ptext (sLit "has kind") <+> quotes (pprKind tidy_act_kind)]
- failWithTcM (env2, err $$ more_info)
-
--- We infer the kind of the type, and then complain if it's not right.
--- But we don't want to complain about
--- (ty) or !(ty) or forall a. ty
--- when the real difficulty is with the 'ty' part.
-checkExpectedKindS :: HsType Name -> TcKind -> ExpKind -> TcM ()
-checkExpectedKindS ty = checkExpectedKind (strip ty)
- where
- strip (HsParTy (L _ ty)) = strip ty
- strip (HsBangTy _ (L _ ty)) = strip ty
- strip (HsForAllTy _ _ _ (L _ ty)) = strip ty
- strip ty = ty
+ failWithTcM (env2, err)
\end{code}
%************************************************************************
diff --git a/compiler/typecheck/TcMType.lhs b/compiler/typecheck/TcMType.lhs
index 19bf384275..409dd722e7 100644
--- a/compiler/typecheck/TcMType.lhs
+++ b/compiler/typecheck/TcMType.lhs
@@ -576,11 +576,12 @@ zonkTcPredType = zonkTcType
are used at the end of type checking
\begin{code}
-defaultKindVarToStar :: TcTyVar -> TcM ()
+defaultKindVarToStar :: TcTyVar -> TcM Kind
-- We have a meta-kind: unify it with '*'
defaultKindVarToStar kv
- = ASSERT ( isKiVar kv && isMetaTyVar kv )
- writeMetaTyVar kv liftedTypeKind
+ = do { ASSERT ( isKiVar kv && isMetaTyVar kv )
+ writeMetaTyVar kv liftedTypeKind
+ ; return liftedTypeKind }
zonkQuantifiedTyVars :: TcTyVarSet -> TcM [TcTyVar]
-- Precondition: a kind variable occurs before a type
@@ -907,11 +908,12 @@ expectedKindInCtxt _ = Just argTypeKind
checkValidType :: UserTypeCtxt -> Type -> TcM ()
-- Checks that the type is valid for the given context
checkValidType ctxt ty = do
- traceTc "checkValidType" (ppr ty)
- unboxed <- xoptM Opt_UnboxedTuples
- rank2 <- xoptM Opt_Rank2Types
- rankn <- xoptM Opt_RankNTypes
- polycomp <- xoptM Opt_PolymorphicComponents
+ traceTc "checkValidType" (ppr ty <+> text "::" <+> ppr (typeKind ty))
+ unboxed <- xoptM Opt_UnboxedTuples
+ rank2 <- xoptM Opt_Rank2Types
+ rankn <- xoptM Opt_RankNTypes
+ polycomp <- xoptM Opt_PolymorphicComponents
+ constraintKinds <- xoptM Opt_ConstraintKinds
let
gen_rank n | rankn = ArbitraryRank
| rank2 = Rank 2
@@ -960,10 +962,12 @@ checkValidType ctxt ty = do
-- Check that the thing has kind Type, and is lifted if necessary
-- Do this second, because we can't usefully take the kind of an
-- ill-formed type such as (a~Int)
- traceTc "checkValidType kind_ok ctxt" (ppr kind_ok $$ pprUserTypeCtxt ctxt)
checkTc kind_ok (kindErr actual_kind)
- traceTc "checkValidType done" (ppr ty)
+ -- Check that the thing does not have kind Constraint,
+ -- if -XConstraintKinds isn't enabled
+ unless constraintKinds
+ $ checkTc (not (isConstraintKind actual_kind)) (predTupleErr ty)
checkValidMonoType :: Type -> TcM ()
checkValidMonoType ty = check_mono_type MustBeMonoType ty
diff --git a/compiler/types/Kind.lhs b/compiler/types/Kind.lhs
index b19e2b3c06..fa467a7f27 100644
--- a/compiler/types/Kind.lhs
+++ b/compiler/types/Kind.lhs
@@ -35,7 +35,8 @@ module Kind (
-- ** Predicates on Kinds
isLiftedTypeKind, isUnliftedTypeKind, isOpenTypeKind,
- isUbxTupleKind, isArgTypeKind, isConstraintKind, isKind,
+ isUbxTupleKind, isArgTypeKind, isConstraintKind,
+ isConstraintOrLiftedKind, isKind,
isSuperKind, noHashInKind,
isLiftedTypeKindCon, isConstraintKindCon,
isAnyKind, isAnyKindCon,
@@ -138,7 +139,7 @@ synTyConResKind tycon = kindAppResult (tyConKind tycon) (map mkTyVarTy (tyConTyV
-- | See "Type#kind_subtyping" for details of the distinction between these 'Kind's
isUbxTupleKind, isOpenTypeKind, isArgTypeKind, isUnliftedTypeKind,
- isConstraintKind, isAnyKind :: Kind -> Bool
+ isConstraintKind, isAnyKind, isConstraintOrLiftedKind :: Kind -> Bool
isOpenTypeKindCon, isUbxTupleKindCon, isArgTypeKindCon,
isUnliftedTypeKindCon, isSubArgTypeKindCon, tcIsSubArgTypeKindCon,
@@ -175,6 +176,9 @@ isConstraintKindCon tc = tyConUnique tc == constraintKindTyConKey
isConstraintKind (TyConApp tc _) = isConstraintKindCon tc
isConstraintKind _ = False
+isConstraintOrLiftedKind (TyConApp tc _)
+ = isConstraintKindCon tc || isLiftedTypeKindCon tc
+isConstraintOrLiftedKind _ = False
-- Subkinding
-- The tc variants are used during type-checking, where we don't want the
@@ -288,8 +292,8 @@ defaultKind :: Kind -> Kind
-- and the calling conventions differ.
-- This defaulting is done in TcMType.zonkTcTyVarBndr.
defaultKind k
- | isSubOpenTypeKind k = liftedTypeKind
- | otherwise = k
+ | tcIsSubOpenTypeKind k = liftedTypeKind
+ | otherwise = k
splitKiTyVars :: [TyVar] -> ([KindVar], [TyVar])
-- Precondition: kind variables should precede type variables
diff --git a/compiler/types/Type.lhs b/compiler/types/Type.lhs
index e09d94e630..579ae754a6 100644
--- a/compiler/types/Type.lhs
+++ b/compiler/types/Type.lhs
@@ -824,14 +824,18 @@ Make PredTypes
mkEqPred :: (Type, Type) -> PredType
mkEqPred (ty1, ty2)
-- IA0_TODO: The caller should give the kind.
- = TyConApp eqTyCon [k, ty1, ty2]
+ = WARN ( not (k `eqKind` defaultKind k), ppr (k, ty1, ty2) )
+ TyConApp eqTyCon [k, ty1, ty2]
where k = defaultKind (typeKind ty1)
+-- where k = typeKind ty1
mkPrimEqType :: (Type, Type) -> Type
mkPrimEqType (ty1, ty2)
-- IA0_TODO: The caller should give the kind.
- = TyConApp eqPrimTyCon [k, ty1, ty2]
+ = WARN ( not (k `eqKind` defaultKind k), ppr (k, ty1, ty2) )
+ TyConApp eqPrimTyCon [k, ty1, ty2]
where k = defaultKind (typeKind ty1)
+-- where k = typeKind ty1
\end{code}
--------------------- Implicit parameters ---------------------------------
diff --git a/compiler/utils/Platform.hs b/compiler/utils/Platform.hs
index e99d70600f..027c510546 100644
--- a/compiler/utils/Platform.hs
+++ b/compiler/utils/Platform.hs
@@ -55,6 +55,7 @@ data OS
| OSMinGW32
| OSFreeBSD
| OSOpenBSD
+ | OSNetBSD
deriving (Read, Show, Eq)
-- | ARM Instruction Set Architecture and Extensions
@@ -90,6 +91,7 @@ osElfTarget :: OS -> Bool
osElfTarget OSLinux = True
osElfTarget OSFreeBSD = True
osElfTarget OSOpenBSD = True
+osElfTarget OSNetBSD = True
osElfTarget OSSolaris2 = True
osElfTarget OSDarwin = False
osElfTarget OSMinGW32 = False
diff --git a/compiler/vectorise/Vectorise.hs b/compiler/vectorise/Vectorise.hs
index dc467f5187..cd87868081 100644
--- a/compiler/vectorise/Vectorise.hs
+++ b/compiler/vectorise/Vectorise.hs
@@ -87,8 +87,8 @@ vectModule guts@(ModGuts { mg_tcs = tycons
-- Vectorise all the top level bindings and VECTORISE declarations on imported identifiers
-- NB: Need to vectorise the imported bindings first (local bindings may depend on them).
- ; let impBinds = [imp_id | Vect imp_id _ <- vect_decls, isGlobalId imp_id] ++
- [imp_id | VectInst True imp_id <- vect_decls, isGlobalId imp_id]
+ ; let impBinds = [imp_id | Vect imp_id _ <- vect_decls, isGlobalId imp_id] ++
+ [imp_id | VectInst imp_id <- vect_decls, isGlobalId imp_id]
; binds_imp <- mapM vectImpBind impBinds
; binds_top <- mapM vectTopBind binds
@@ -150,7 +150,7 @@ vectTopBind b@(NonRec var expr)
; (inline, isScalar, expr') <- vectTopRhs [] var expr
; var' <- vectTopBinder var inline expr'
; when isScalar $
- addGlobalScalar var
+ addGlobalScalarVar var
-- We replace the original top-level binding by a value projected from the vectorised
-- closure and add any newly created hoisted top-level bindings.
@@ -182,7 +182,7 @@ vectTopBind b@(Rec bs)
; if and areScalars
then -- (1) Entire recursive group is scalar
-- => add all variables to the global set of scalars
- do { mapM_ addGlobalScalar vars
+ do { mapM_ addGlobalScalarVar vars
; return (vars', inlines, exprs', hs)
}
else -- (2) At least one binding is not scalar
@@ -226,7 +226,7 @@ vectImpBind var
; (inline, isScalar, expr') <- vectTopRhs [] var (Var var)
; var' <- vectTopBinder var inline expr'
; when isScalar $
- addGlobalScalar var
+ addGlobalScalarVar var
-- We add any newly created hoisted top-level bindings.
; hs <- takeHoisted
@@ -340,7 +340,7 @@ vectTopRhs :: [Var] -- ^ Names of all functions in the rec block
, CoreExpr) -- (3) the vectorised right-hand side
vectTopRhs recFs var expr
= closedV
- $ do { globalScalar <- isGlobalScalar var
+ $ do { globalScalar <- isGlobalScalarVar var
; vectDecl <- lookupVectDecl var
; let isDFun = isDFunId var
@@ -385,7 +385,7 @@ tryConvert :: Var -- ^ Name of the original binding (eg @foo@)
-> CoreExpr -- ^ The original body of the binding.
-> VM CoreExpr
tryConvert var vect_var rhs
- = do { globalScalar <- isGlobalScalar var
+ = do { globalScalar <- isGlobalScalarVar var
; if globalScalar
then
return rhs
diff --git a/compiler/vectorise/Vectorise/Builtins/Initialise.hs b/compiler/vectorise/Vectorise/Builtins/Initialise.hs
index 56ae67f40b..e2fddefacd 100644
--- a/compiler/vectorise/Vectorise/Builtins/Initialise.hs
+++ b/compiler/vectorise/Vectorise/Builtins/Initialise.hs
@@ -199,7 +199,8 @@ initBuiltinVars (Builtins { })
-- |Get a list of names to `TyCon`s in the mock prelude.
--
initBuiltinTyCons :: Builtins -> DsM [(Name, TyCon)]
--- FIXME: must be replaced by VECTORISE pragmas!!!
+-- FIXME: * must be replaced by VECTORISE pragmas!!!
+-- * then we can remove 'parrayTyCon' from the Builtins as well
initBuiltinTyCons bi
= do
return $ (tyConName funTyCon, closureTyCon bi)
diff --git a/compiler/vectorise/Vectorise/Env.hs b/compiler/vectorise/Vectorise/Env.hs
index 64ab075cef..ffaf388b31 100644
--- a/compiler/vectorise/Vectorise/Env.hs
+++ b/compiler/vectorise/Vectorise/Env.hs
@@ -129,6 +129,10 @@ data GlobalEnv
-- |Create an initial global environment.
--
+-- We add scalar variables and type constructors identified by vectorisation pragmas already here
+-- to the global table, so that we can query scalarness during vectorisation, and especially, when
+-- vectorising the scalar entities' definitions themselves.
+--
initGlobalEnv :: VectInfo -> [CoreVect] -> (InstEnv, InstEnv) -> FamInstEnvs -> GlobalEnv
initGlobalEnv info vectDecls instEnvs famInstEnvs
= GlobalEnv
@@ -151,10 +155,16 @@ initGlobalEnv info vectDecls instEnvs famInstEnvs
-- FIXME: we currently only allow RHSes consisting of a
-- single variable to be able to obtain the type without
-- inference — see also 'TcBinds.tcVect'
- scalar_vars = [var | Vect var Nothing <- vectDecls] ++
- [var | VectInst True var <- vectDecls]
- novects = [var | NoVect var <- vectDecls]
- scalar_tycons = [tyConName tycon | VectType True tycon _ <- vectDecls]
+ scalar_vars = [var | Vect var Nothing <- vectDecls] ++
+ [var | VectInst var <- vectDecls]
+ novects = [var | NoVect var <- vectDecls]
+ scalar_tycons = [tyConName tycon | VectType True tycon Nothing <- vectDecls] ++
+ [tyConName tycon | VectType _ tycon (Just tycon') <- vectDecls
+ , tycon == tycon']
+ -- - for 'VectType True tycon Nothing', we checked that the type does not
+ -- contain arrays (or type variables that could be instatiated to arrays)
+ -- - for 'VectType _ tycon (Just tycon')', where the two tycons are the same,
+ -- we also know that there can be no embedded arrays
-- Operators on Global Environments -------------------------------------------
@@ -207,7 +217,7 @@ modVectInfo env mg_ids mg_tyCons vectDecls info
}
where
vectIds = [id | Vect id _ <- vectDecls] ++
- [id | VectInst _ id <- vectDecls]
+ [id | VectInst id <- vectDecls]
vectTypeTyCons = [tycon | VectType _ tycon _ <- vectDecls] ++
[tycon | VectClass tycon <- vectDecls]
vectDataCons = concatMap tyConDataCons vectTypeTyCons
diff --git a/compiler/vectorise/Vectorise/Exp.hs b/compiler/vectorise/Vectorise/Exp.hs
index 8afe149496..d695fcbf80 100644
--- a/compiler/vectorise/Vectorise/Exp.hs
+++ b/compiler/vectorise/Vectorise/Exp.hs
@@ -625,9 +625,8 @@ vectAlgCase _tycon _ty_args scrut bndr ty [(DataAlt dc, bndrs, body)]
. vectBndrsIn bndrs
$ vectExpr body
let (vect_bndrs, lift_bndrs) = unzip vbndrs
- (vscrut, lscrut, pdata_tc, _arg_tys) <- mkVScrut (vVar vbndr)
+ (vscrut, lscrut, pdata_dc) <- pdataUnwrapScrut (vVar vbndr)
vect_dc <- maybeV dataConErr (lookupDataCon dc)
- let [pdata_dc] = tyConDataCons pdata_tc
let vcase = mk_wild_case vscrut vty vect_dc vect_bndrs vect_body
lcase = mk_wild_case lscrut lty pdata_dc lift_bndrs lift_body
@@ -657,8 +656,7 @@ vectAlgCase tycon _ty_args scrut bndr ty alts
let (vect_dcs, vect_bndrss, lift_bndrss, vbodies) = unzip4 valts
vexpr <- vectExpr scrut
- (vect_scrut, lift_scrut, pdata_tc, _arg_tys) <- mkVScrut (vVar vbndr)
- let [pdata_dc] = tyConDataCons pdata_tc
+ (vect_scrut, lift_scrut, pdata_dc) <- pdataUnwrapScrut (vVar vbndr)
let (vect_bodies, lift_bodies) = unzip vbodies
diff --git a/compiler/vectorise/Vectorise/Generic/Description.hs b/compiler/vectorise/Vectorise/Generic/Description.hs
index d0d4469023..eed01b0818 100644
--- a/compiler/vectorise/Vectorise/Generic/Description.hs
+++ b/compiler/vectorise/Vectorise/Generic/Description.hs
@@ -1,16 +1,20 @@
-
--- | Compute a description of the generic representation that we use for
--- a user defined data type.
+-- |Compute a description of the generic representation that we use for a user defined data type.
--
--- During vectorisation, we generate a PRepr and PA instance for each user defined
--- data type. The PA dictionary contains methods to convert the user type to and
--- from our generic representation. This module computes a description of what
--- that generic representation is.
+-- During vectorisation, we generate a PRepr and PA instance for each user defined
+-- data type. The PA dictionary contains methods to convert the user type to and
+-- from our generic representation. This module computes a description of what
+-- that generic representation is.
--
-module Vectorise.Generic.Description (
- CompRepr (..), ProdRepr (..), ConRepr (..), SumRepr (..),
- tyConRepr, sumReprType, conReprType, prodReprType, compReprType, compOrigType
-) where
+module Vectorise.Generic.Description
+ ( CompRepr(..)
+ , ProdRepr(..)
+ , ConRepr(..)
+ , SumRepr(..)
+ , tyConRepr
+ , sumReprType
+ , compOrigType
+ )
+where
import Vectorise.Utils
import Vectorise.Monad
@@ -108,8 +112,8 @@ data CompRepr
-------------------------------------------------------------------------------
--- | Determine the generic representation of a data type, given its tycon.
--- The `TyCon` contains a description of the whole data type.
+-- |Determine the generic representation of a data type, given its tycon.
+--
tyConRepr :: TyCon -> VM SumRepr
tyConRepr tc
= sum_repr (tyConDataCons tc)
@@ -129,9 +133,8 @@ tyConRepr tc
sum_tc <- builtin (sumTyCon arity)
-- Get the 'PData' and 'PDatas' tycons for the sum.
- let sumapp = mkTyConApp sum_tc tys
- psum_tc <- liftM fst $ pdataReprTyCon sumapp
- psums_tc <- liftM fst $ pdatasReprTyCon sumapp
+ psum_tc <- pdataReprTyConExact sum_tc
+ psums_tc <- pdatasReprTyConExact sum_tc
sel_ty <- builtin (selTy arity)
sels_ty <- builtin (selsTy arity)
@@ -165,9 +168,8 @@ tyConRepr tc
tup_tc <- builtin (prodTyCon arity)
-- Get the 'PData' and 'PDatas' tycons for the product.
- let prodapp = mkTyConApp tup_tc tys'
- ptup_tc <- liftM fst $ pdataReprTyCon prodapp
- ptups_tc <- liftM fst $ pdatasReprTyCon prodapp
+ ptup_tc <- pdataReprTyConExact tup_tc
+ ptups_tc <- pdatasReprTyConExact tup_tc
return $ Prod
{ repr_tup_tc = tup_tc
@@ -181,37 +183,35 @@ tyConRepr tc
comp_repr ty = liftM (Keep ty) (prDictOfReprType ty)
`orElseV` return (Wrap ty)
-
--- | Yield the type of this sum representation.
+-- |Yield the type of this sum representation.
+--
sumReprType :: SumRepr -> VM Type
sumReprType EmptySum = voidType
sumReprType (UnarySum r) = conReprType r
sumReprType (Sum { repr_sum_tc = sum_tc, repr_con_tys = tys })
= return $ mkTyConApp sum_tc tys
-
--- | Yield the type of this constructor representation.
+-- Yield the type of this constructor representation.
+--
conReprType :: ConRepr -> VM Type
conReprType (ConRepr _ r) = prodReprType r
-
--- | Yield the type of of this product representation.
+-- Yield the type of of this product representation.
+--
prodReprType :: ProdRepr -> VM Type
prodReprType EmptyProd = voidType
prodReprType (UnaryProd r) = compReprType r
prodReprType (Prod { repr_tup_tc = tup_tc, repr_comp_tys = tys })
= return $ mkTyConApp tup_tc tys
-
--- | Yield the type of this data constructor field \/ component representation.
+-- Yield the type of this data constructor field \/ component representation.
+--
compReprType :: CompRepr -> VM Type
compReprType (Keep ty _) = return ty
-compReprType (Wrap ty)
- = do wrap_tc <- builtin wrapTyCon
- return $ mkTyConApp wrap_tc [ty]
-
+compReprType (Wrap ty) = mkWrapType ty
--- Yield the original component type of a data constructor component representation.
+-- |Yield the original component type of a data constructor component representation.
+--
compOrigType :: CompRepr -> Type
compOrigType (Keep ty _) = ty
compOrigType (Wrap ty) = ty
diff --git a/compiler/vectorise/Vectorise/Generic/PAMethods.hs b/compiler/vectorise/Vectorise/Generic/PAMethods.hs
index c02dedad54..85e33367d7 100644
--- a/compiler/vectorise/Vectorise/Generic/PAMethods.hs
+++ b/compiler/vectorise/Vectorise/Generic/PAMethods.hs
@@ -164,13 +164,13 @@ buildToPRepr vect_tc repr_tc _ _ repr
-- CoreExp to convert a data constructor component to the generic representation.
to_comp :: CoreExpr -> CompRepr -> VM CoreExpr
to_comp expr (Keep _ _) = return expr
- to_comp expr (Wrap ty)
- = do wrap_tc <- builtin wrapTyCon
- return $ wrapNewTypeBody wrap_tc [ty] expr
+ to_comp expr (Wrap ty) = wrapNewTypeBodyOfWrap expr ty
-- buildFromPRepr -------------------------------------------------------------
--- | Build the 'fromPRepr' method of the PA class.
+
+-- |Build the 'fromPRepr' method of the PA class.
+--
buildFromPRepr :: PAInstanceBuilder
buildFromPRepr vect_tc repr_tc _ _ repr
= do
@@ -217,14 +217,13 @@ buildFromPRepr vect_tc repr_tc _ _ repr
[(DataAlt tup_con, vars, con `mkApps` es)]
from_comp expr (Keep _ _) = return expr
- from_comp expr (Wrap ty)
- = do
- wrap <- builtin wrapTyCon
- return $ unwrapNewTypeBody wrap [ty] expr
+ from_comp expr (Wrap ty) = unwrapNewTypeBodyOfWrap expr ty
-- buildToArrRepr -------------------------------------------------------------
--- | Build the 'toArrRepr' method of the PA class.
+
+-- |Build the 'toArrRepr' method of the PA class.
+--
buildToArrPRepr :: PAInstanceBuilder
buildToArrPRepr vect_tc prepr_tc pdata_tc _ r
= do arg_ty <- mkPDataType el_ty
@@ -283,17 +282,14 @@ buildToArrPRepr vect_tc prepr_tc pdata_tc _ r
to_con (ConRepr _ r) = to_prod r
- -- FIXME: this is bound to be wrong!
to_comp expr (Keep _ _) = return expr
- to_comp expr (Wrap ty)
- = do
- wrap_tc <- builtin wrapTyCon
- pwrap_tc <- pdataReprTyConExact (mkTyConApp wrap_tc [ty])
- return $ wrapNewTypeBody pwrap_tc [ty] expr
+ to_comp expr (Wrap ty) = wrapNewTypeBodyOfPDataWrap expr ty
-- buildFromArrPRepr ----------------------------------------------------------
--- | Build the 'fromArrPRepr' method for the PA class.
+
+-- |Build the 'fromArrPRepr' method for the PA class.
+--
buildFromArrPRepr :: PAInstanceBuilder
buildFromArrPRepr vect_tc prepr_tc pdata_tc _ r
= do arg_ty <- mkPDataType =<< mkPReprType el_ty
@@ -355,11 +351,9 @@ buildFromArrPRepr vect_tc prepr_tc pdata_tc _ r
from_con res_ty res expr (ConRepr _ r) = from_prod res_ty res expr r
from_comp _ res expr (Keep _ _) = return (res, [expr])
- from_comp _ res expr (Wrap ty)
- = do wrap_tc <- builtin wrapTyCon
- pwrap_tc <- pdataReprTyConExact (mkTyConApp wrap_tc [ty])
- return (res, [unwrapNewTypeBody pwrap_tc [ty]
- $ unwrapFamInstScrut pwrap_tc [ty] expr])
+ from_comp _ res expr (Wrap ty) = do { expr' <- unwrapNewTypeBodyOfPDataWrap expr ty
+ ; return (res, [expr'])
+ }
fold f res_ty res exprs rs
= foldrM f' (res, []) (zip exprs rs)
@@ -457,12 +451,8 @@ buildToArrPReprs vect_tc prepr_tc _ pdatas_tc r
to_con xSums (ConRepr _ r)
= to_prod xSums r
- -- FIXME: this is bound to be wrong!
to_comp expr (Keep _ _) = return expr
- to_comp expr (Wrap ty)
- = do wrap_tc <- builtin wrapTyCon
- (pwrap_tc, _) <- pdatasReprTyCon (mkTyConApp wrap_tc [ty])
- return $ wrapNewTypeBody pwrap_tc [ty] expr
+ to_comp expr (Wrap ty) = wrapNewTypeBodyOfPDatasWrap expr ty
-- buildFromArrPReprs ---------------------------------------------------------
@@ -545,11 +535,9 @@ buildFromArrPReprs vect_tc prepr_tc _ pdatas_tc r
= from_prod res_ty res expr r
from_comp _ res expr (Keep _ _) = return (res, [expr])
- from_comp _ res expr (Wrap ty)
- = do wrap_tc <- builtin wrapTyCon
- (pwraps_tc, _) <- pdatasReprTyCon (mkTyConApp wrap_tc [ty])
- return (res, [unwrapNewTypeBody pwraps_tc [ty]
- $ unwrapFamInstScrut pwraps_tc [ty] expr])
+ from_comp _ res expr (Wrap ty) = do { expr' <- unwrapNewTypeBodyOfPDatasWrap expr ty
+ ; return (res, [expr'])
+ }
fold f res_ty res exprs rs
= foldrM f' (res, []) (zip exprs rs)
diff --git a/compiler/vectorise/Vectorise/Monad.hs b/compiler/vectorise/Vectorise/Monad.hs
index b9a1fdf046..0706e25f4f 100644
--- a/compiler/vectorise/Vectorise/Monad.hs
+++ b/compiler/vectorise/Vectorise/Monad.hs
@@ -14,7 +14,8 @@ module Vectorise.Monad (
-- * Variables
lookupVar,
lookupVar_maybe,
- addGlobalScalar,
+ addGlobalScalarVar,
+ addGlobalScalarTyCon,
) where
import Vectorise.Monad.Base
@@ -32,6 +33,8 @@ import DynFlags
import MonadUtils (liftIO)
import InstEnv
import Class
+import TyCon
+import NameSet
import VarSet
import VarEnv
import Var
@@ -174,8 +177,17 @@ dumpVar var
-- |Mark the given variable as scalar — i.e., executing the associated code does not involve any
-- parallel array computations.
--
-addGlobalScalar :: Var -> VM ()
-addGlobalScalar var
- = do { traceVt "addGlobalScalar" (ppr var)
+addGlobalScalarVar :: Var -> VM ()
+addGlobalScalarVar var
+ = do { traceVt "addGlobalScalarVar" (ppr var)
; updGEnv $ \env -> env{global_scalar_vars = extendVarSet (global_scalar_vars env) var}
}
+
+-- |Mark the given type constructor as scalar — i.e., its values cannot embed parallel arrays.
+--
+addGlobalScalarTyCon :: TyCon -> VM ()
+addGlobalScalarTyCon tycon
+ = do { traceVt "addGlobalScalarTyCon" (ppr tycon)
+ ; updGEnv $ \env ->
+ env{global_scalar_tycons = addOneToNameSet (global_scalar_tycons env) (tyConName tycon)}
+ }
diff --git a/compiler/vectorise/Vectorise/Monad/Global.hs b/compiler/vectorise/Vectorise/Monad/Global.hs
index bc68a5012f..f393f01e92 100644
--- a/compiler/vectorise/Vectorise/Monad/Global.hs
+++ b/compiler/vectorise/Vectorise/Monad/Global.hs
@@ -12,7 +12,7 @@ module Vectorise.Monad.Global (
lookupVectDecl, noVectDecl,
-- * Scalars
- globalScalarVars, isGlobalScalar, globalScalarTyCons,
+ globalScalarVars, isGlobalScalarVar, globalScalarTyCons,
-- * TyCons
lookupTyCon,
@@ -96,8 +96,8 @@ globalScalarVars = readGEnv global_scalar_vars
-- |Check whether a given variable is in the set of global scalar variables.
--
-isGlobalScalar :: Var -> VM Bool
-isGlobalScalar var = readGEnv $ \env -> var `elemVarSet` global_scalar_vars env
+isGlobalScalarVar :: Var -> VM Bool
+isGlobalScalarVar var = readGEnv $ \env -> var `elemVarSet` global_scalar_vars env
-- |Get the set of global scalar type constructors including both those scalar type constructors
-- declared in an imported module and those declared in the current module.
diff --git a/compiler/vectorise/Vectorise/Type/Env.hs b/compiler/vectorise/Vectorise/Type/Env.hs
index 1b806c3138..5d2213ac26 100644
--- a/compiler/vectorise/Vectorise/Type/Env.hs
+++ b/compiler/vectorise/Vectorise/Type/Env.hs
@@ -32,14 +32,18 @@ import Id
import MkId
import NameEnv
import NameSet
+import OccName
import Util
import Outputable
import FastString
import MonadUtils
+
import Control.Monad
+import Data.Maybe
import Data.List
+
-- Note [Pragmas to vectorise tycons]
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--
@@ -60,7 +64,20 @@ import Data.List
-- Type constructors declared with {-# VECTORISE SCALAR type T #-} are treated in this manner.
-- (The vectoriser never treats a type constructor automatically in this manner.)
--
--- (2) Data type constructor 'T' that together with its constructors 'Cn' may be used in vectorised
+-- (2) Data type constructor 'T' that may be used in vectorised code, where 'T' is represented by an
+-- explicitly given 'Tv', but the representation of 'T' is opaque in vectorised code.
+--
+-- An example is the treatment of '[::]'. '[::]'s can be used in vectorised code and is
+-- vectorised to 'PArray'. However, the representation of '[::]' is not exposed in vectorised
+-- code. Instead, computations involving the representation need to be confined to scalar code.
+--
+-- 'PData' and 'PRepr' instances need to be explicitly supplied for 'T' (they are not generated
+-- by the vectoriser).
+--
+-- Type constructors declared with {-# VECTORISE SCALAR type T = T' #-} are treated in this
+-- manner. (The vectoriser never treats a type constructor automatically in this manner.)
+--
+-- (3) Data type constructor 'T' that together with its constructors 'Cn' may be used in vectorised
-- code, where 'T' and the 'Cn' are automatically vectorised in the same manner as data types
-- declared in a vectorised module. This includes the case where the vectoriser determines that
-- the original representation of 'T' may be used in vectorised code (as it does not embed any
@@ -74,13 +91,13 @@ import Data.List
--
-- Type constructors declared with {-# VECTORISE type T #-} are treated in this manner.
--
--- (3) Data type constructor 'T' that together with its constructors 'Cn' may be used in vectorised
+-- (4) Data type constructor 'T' that together with its constructors 'Cn' may be used in vectorised
-- code, where 'T' is represented by an explicitly given 'Tv' whose constructors 'Cvn' represent
-- the original constructors in vectorised code. As a special case, we can have 'Tv = T'
--
-- An example is the treatment of 'Bool', which is represented by itself in vectorised code
-- (as it cannot embed any parallel arrays). However, we do not want any automatic generation
--- of class and family instances, which is why Case (2) does not apply.
+-- of class and family instances, which is why Case (3) does not apply.
--
-- 'PData' and 'PRepr' instances need to be explicitly supplied for 'T' (they are not generated
-- by the vectoriser).
@@ -139,64 +156,65 @@ vectTypeEnv tycons vectTypeDecls vectClassDecls
allScalarTyConNames
; let -- {-# VECTORISE SCALAR type T -#} (imported and local tycons)
- localScalarTyCons = [tycon | VectType True tycon Nothing <- vectTypeDecls]
+ localAbstractTyCons = [tycon | VectType True tycon Nothing <- vectTypeDecls]
-- {-# VECTORISE type T -#} (ONLY the imported tycons)
impVectTyCons = ( [tycon | VectType False tycon Nothing <- vectTypeDecls]
++ [tycon | VectClass tycon <- vectClassDecls])
\\ tycons
- -- {-# VECTORISE type T = ty -#} (imported and local tycons)
- vectTyConsWithRHS = [ (tycon, rhs)
- | VectType False tycon (Just rhs) <- vectTypeDecls]
+ -- {-# VECTORISE [SCALAR] type T = T' -#} (imported and local tycons)
+ vectTyConsWithRHS = [ (tycon, rhs, isAbstract)
+ | VectType isAbstract tycon (Just rhs) <- vectTypeDecls]
-- filter VECTORISE SCALAR tycons and VECTORISE tycons with explicit rhses
vectSpecialTyConNames = mkNameSet . map tyConName $
- localScalarTyCons ++ map fst vectTyConsWithRHS
- notLocalScalarTyCon tc = not $ (tyConName tc) `elemNameSet` vectSpecialTyConNames
+ localAbstractTyCons ++ map fst3 vectTyConsWithRHS
+ notVectSpecialTyCon tc = not $ (tyConName tc) `elemNameSet` vectSpecialTyConNames
-- Split the list of 'TyCons' into the ones (1) that we must vectorise and those (2)
-- that we could, but don't need to vectorise. Type constructors that are not data
-- type constructors or use non-Haskell98 features are being dropped. They may not
-- appear in vectorised code. (We also drop the local type constructors appearing in a
-- VECTORISE SCALAR pragma or a VECTORISE pragma with an explicit right-hand side, as
- -- these are being handled separately.)
+ -- these are being handled separately. NB: Some type constructors may be marked SCALAR
+ -- /and/ have an explicit right-hand side.)
+ --
-- Furthermore, 'drop_tcs' are those type constructors that we cannot vectorise.
- ; let maybeVectoriseTyCons = filter notLocalScalarTyCon tycons ++ impVectTyCons
+ ; let maybeVectoriseTyCons = filter notVectSpecialTyCon tycons ++ impVectTyCons
(conv_tcs, keep_tcs, drop_tcs) = classifyTyCons vectTyConFlavour maybeVectoriseTyCons
- ; traceVt " VECT SCALAR : " $ ppr localScalarTyCons
+ ; traceVt " VECT SCALAR : " $ ppr localAbstractTyCons
; traceVt " VECT [class] : " $ ppr impVectTyCons
- ; traceVt " VECT with rhs : " $ ppr (map fst vectTyConsWithRHS)
+ ; traceVt " VECT with rhs : " $ ppr (map fst3 vectTyConsWithRHS)
; traceVt " -- after classification (local and VECT [class] tycons) --" empty
; traceVt " reuse : " $ ppr keep_tcs
; traceVt " convert : " $ ppr conv_tcs
-- warn the user about unvectorised type constructors
- ; let explanation = ptext (sLit "(They use unsupported language extensions") $$
- ptext (sLit "or depend on type constructors that are not vectorised)")
- ; unless (null drop_tcs) $
+ ; let explanation = ptext (sLit "(They use unsupported language extensions") $$
+ ptext (sLit "or depend on type constructors that are not vectorised)")
+ drop_tcs_nosyn = filter (not . isSynTyCon) drop_tcs
+ ; unless (null drop_tcs_nosyn) $
emitVt "Warning: cannot vectorise these type constructors:" $
- pprQuotedList drop_tcs $$ explanation
-
- ; let defTyConDataCons origTyCon vectTyCon
- = do { defTyCon origTyCon vectTyCon
- ; MASSERT(length (tyConDataCons origTyCon) == length (tyConDataCons vectTyCon))
- ; zipWithM_ defDataCon (tyConDataCons origTyCon) (tyConDataCons vectTyCon)
- }
-
- -- For the type constructors that we don't need to vectorise, we use the original
- -- representation in both unvectorised and vectorised code.
- ; zipWithM_ defTyConDataCons keep_tcs keep_tcs
-
- -- We do the same for type constructors declared VECTORISE SCALAR, while ignoring their
- -- representation (data constructors) — see "Note [Pragmas to vectorise tycons]".
- ; zipWithM_ defTyCon localScalarTyCons localScalarTyCons
-
- -- For type constructors declared VECTORISE with an explicit vectorised type, we use the
- -- explicitly given type in vectorised code and map data constructors one for one — see
- -- "Note [Pragmas to vectorise tycons]".
- ; mapM_ (uncurry defTyConDataCons) vectTyConsWithRHS
+ pprQuotedList drop_tcs_nosyn $$ explanation
+
+ ; mapM_ addGlobalScalarTyCon keep_tcs
+
+ ; let mapping =
+ -- Type constructors that we don't need to vectorise, use the same
+ -- representation in both unvectorised and vectorised code; they are not
+ -- abstract.
+ [(tycon, tycon, False) | tycon <- keep_tcs]
+ -- We do the same for type constructors declared VECTORISE SCALAR /without/
+ -- an explicit right-hand side, but ignore their representation (data
+ -- constructors) as they are abstract.
+ ++ [(tycon, tycon, True) | tycon <- localAbstractTyCons]
+ -- Type constructors declared VECTORISE /with/ an explicit vectorised type,
+ -- we map from the original to the given type; whether they are abstract depends
+ -- on whether the vectorisation declaration was SCALAR.
+ ++ vectTyConsWithRHS
+ ; syn_tcs <- catMaybes <$> mapM defTyConDataCons mapping
-- Vectorise all the data type declarations that we can and must vectorise (enter the
-- type and data constructors into the vectorisation map on-the-fly.)
@@ -226,22 +244,20 @@ vectTypeEnv tycons vectTypeDecls vectClassDecls
; (_, binds) <- fixV $ \ ~(dfuns, _) ->
do { defTyConPAs (zipLazy vect_tcs dfuns)
- -- query the 'PData' instance type constructors for type constructors that have a
- -- VECTORISE pragma with an explicit right-hand side (this is Item (3) of
- -- "Note [Pragmas to vectorise tycons]" above)
- ; pdata_withRHS_tcs <- mapM pdataReprTyConExact
- [ mkTyConApp tycon tys
- | (tycon, _) <- vectTyConsWithRHS
- , let tys = mkTyVarTys (tyConTyVars tycon)
- ]
+ -- Query the 'PData' instance type constructors for type constructors that have a
+ -- VECTORISE pragma with an explicit right-hand side (this is Item (4) of
+ -- "Note [Pragmas to vectorise tycons]" above).
+ ; let (withRHS_non_abstract, vwithRHS_non_abstract)
+ = unzip [(tycon, vtycon) | (tycon, vtycon, False) <- vectTyConsWithRHS]
+ ; pdata_withRHS_tcs <- mapM pdataReprTyConExact withRHS_non_abstract
- -- build workers for all vectorised data constructors (except scalar ones)
+ -- Build workers for all vectorised data constructors (except abstract ones)
; sequence_ $
- zipWith3 vectDataConWorkers (orig_tcs ++ map fst vectTyConsWithRHS)
- (vect_tcs ++ map snd vectTyConsWithRHS)
+ zipWith3 vectDataConWorkers (orig_tcs ++ withRHS_non_abstract)
+ (vect_tcs ++ vwithRHS_non_abstract)
(pdata_tcs ++ pdata_withRHS_tcs)
- -- build a 'PA' dictionary for all type constructors (except scalar ones and those
+ -- Build a 'PA' dictionary for all type constructors (except abstract ones & those
-- defined with an explicit right-hand side where the dictionary is user-supplied)
; dfuns <- sequence $
zipWith4 buildTyConPADict
@@ -256,8 +272,49 @@ vectTypeEnv tycons vectTypeDecls vectClassDecls
-- Return the vectorised variants of type constructors as well as the generated instance
-- type constructors, family instances, and dfun bindings.
- ; return (new_tcs ++ inst_tcs, fam_insts, binds)
+ ; return (new_tcs ++ inst_tcs ++ syn_tcs, fam_insts, binds)
}
+ where
+ fst3 (a, _, _) = a
+
+ -- Add a mapping from the original to vectorised type constructor to the vectorisation map.
+ -- Unless the type constructor is abstract, also mappings from the orignal's data constructors
+ -- to the vectorised type's data constructors.
+ --
+ -- We have three cases: (1) original and vectorised type constructor are the same, (2) the
+ -- name of the vectorised type constructor is canonical (as prescribed by 'mkVectTyConOcc'), or
+ -- (3) the name is not canonical. In the third case, we additionally introduce a type synonym
+ -- with the canonical name that is set equal to the non-canonical name (so that we find the
+ -- right type constructor when reading vectorisation information from interface files).
+ --
+ defTyConDataCons (origTyCon, vectTyCon, isAbstract)
+ = do { canonName <- mkLocalisedName mkVectTyConOcc origName
+ ; if origName == vectName -- Case (1)
+ || vectName == canonName -- Case (2)
+ then do
+ { defTyCon origTyCon vectTyCon -- T --> vT
+ ; defDataCons -- Ci --> vCi
+ ; return Nothing
+ }
+ else do -- Case (3)
+ { let synTyCon = mkSyn canonName (mkTyConTy vectTyCon) -- type S = vT
+ ; defTyCon origTyCon synTyCon -- T --> S
+ ; defDataCons -- Ci --> vCi
+ ; return $ Just synTyCon
+ }
+ }
+ where
+ origName = tyConName origTyCon
+ vectName = tyConName vectTyCon
+
+ mkSyn canonName ty = mkSynTyCon canonName (typeKind ty) [] (SynonymTyCon ty) NoParentTyCon
+
+ defDataCons
+ | isAbstract = return ()
+ | otherwise
+ = do { MASSERT(length (tyConDataCons origTyCon) == length (tyConDataCons vectTyCon))
+ ; zipWithM_ defDataCon (tyConDataCons origTyCon) (tyConDataCons vectTyCon)
+ }
-- Helpers --------------------------------------------------------------------
diff --git a/compiler/vectorise/Vectorise/Type/PRepr.hs b/compiler/vectorise/Vectorise/Type/PRepr.hs
deleted file mode 100644
index 6e427ccec4..0000000000
--- a/compiler/vectorise/Vectorise/Type/PRepr.hs
+++ /dev/null
@@ -1,369 +0,0 @@
-
-{-# OPTIONS -fno-warn-tabs #-}
--- The above warning supression flag is a temporary kludge.
--- While working on this module you are encouraged to remove it and
--- detab the module (please do the detabbing in a separate patch). See
--- http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#TabsvsSpaces
--- for details
-
-module Vectorise.Type.PRepr
- ( buildPReprTyCon
- , buildPAScAndMethods
- ) where
-
-import Vectorise.Utils
-import Vectorise.Monad
-import Vectorise.Builtins
-import Vectorise.Type.Repr
-import CoreSyn
-import CoreUtils
-import MkCore ( mkWildCase )
-import TyCon
-import Type
-import BuildTyCl
-import OccName
-import Coercion
-import MkId
-
-import FastString
-import MonadUtils
-import Control.Monad
-
-
-mk_fam_inst :: TyCon -> TyCon -> (TyCon, [Type])
-mk_fam_inst fam_tc arg_tc
- = (fam_tc, [mkTyConApp arg_tc . mkTyVarTys $ tyConTyVars arg_tc])
-
-
-buildPReprTyCon :: TyCon -> TyCon -> SumRepr -> VM TyCon
-buildPReprTyCon orig_tc vect_tc repr
- = do
- name <- mkLocalisedName mkPReprTyConOcc (tyConName orig_tc)
- -- rhs_ty <- buildPReprType vect_tc
- rhs_ty <- sumReprType repr
- prepr_tc <- builtin preprTyCon
- liftDs $ buildSynTyCon name
- tyvars
- (SynonymTyCon rhs_ty)
- (typeKind rhs_ty)
- NoParentTyCon
- (Just $ mk_fam_inst prepr_tc vect_tc)
- where
- tyvars = tyConTyVars vect_tc
-
-
------------------------------------------------------
-buildPAScAndMethods :: [(String, TyCon -> TyCon -> TyCon -> SumRepr -> VM CoreExpr)]
--- buildPAScandmethods says how to build the PR superclass and methods of PA
--- class class PR (PRepr a) => PA a where
--- toPRepr :: a -> PRepr a
--- fromPRepr :: PRepr a -> a
--- toArrPRepr :: PData a -> PData (PRepr a)
--- fromArrPRepr :: PData (PRepr a) -> PData a
-
-buildPAScAndMethods = [("PR", buildPRDict),
- ("toPRepr", buildToPRepr),
- ("fromPRepr", buildFromPRepr),
- ("toArrPRepr", buildToArrPRepr),
- ("fromArrPRepr", buildFromArrPRepr)]
-
-buildPRDict :: TyCon -> TyCon -> TyCon -> SumRepr -> VM CoreExpr
-buildPRDict vect_tc prepr_tc _ _
- = prDictOfPReprInstTyCon inst_ty prepr_tc arg_tys
- where
- arg_tys = mkTyVarTys (tyConTyVars vect_tc)
- inst_ty = mkTyConApp vect_tc arg_tys
-
-buildToPRepr :: TyCon -> TyCon -> TyCon -> SumRepr -> VM CoreExpr
-buildToPRepr vect_tc repr_tc _ repr
- = do
- let arg_ty = mkTyConApp vect_tc ty_args
- res_ty <- mkPReprType arg_ty
- arg <- newLocalVar (fsLit "x") arg_ty
- result <- to_sum (Var arg) arg_ty res_ty repr
- return $ Lam arg result
- where
- ty_args = mkTyVarTys (tyConTyVars vect_tc)
-
- wrap_repr_inst = wrapFamInstBody repr_tc ty_args
-
- to_sum _ _ _ EmptySum
- = do
- void <- builtin voidVar
- return $ wrap_repr_inst $ Var void
-
- to_sum arg arg_ty res_ty (UnarySum r)
- = do
- (pat, vars, body) <- con_alt r
- return $ mkWildCase arg arg_ty res_ty
- [(pat, vars, wrap_repr_inst body)]
-
- to_sum arg arg_ty res_ty (Sum { repr_sum_tc = sum_tc
- , repr_con_tys = tys
- , repr_cons = cons })
- = do
- alts <- mapM con_alt cons
- let alts' = [(pat, vars, wrap_repr_inst
- $ mkConApp sum_con (map Type tys ++ [body]))
- | ((pat, vars, body), sum_con)
- <- zip alts (tyConDataCons sum_tc)]
- return $ mkWildCase arg arg_ty res_ty alts'
-
- con_alt (ConRepr con r)
- = do
- (vars, body) <- to_prod r
- return (DataAlt con, vars, body)
-
- to_prod EmptyProd
- = do
- void <- builtin voidVar
- return ([], Var void)
-
- to_prod (UnaryProd comp)
- = do
- var <- newLocalVar (fsLit "x") (compOrigType comp)
- body <- to_comp (Var var) comp
- return ([var], body)
-
- to_prod(Prod { repr_tup_tc = tup_tc
- , repr_comp_tys = tys
- , repr_comps = comps })
- = do
- vars <- newLocalVars (fsLit "x") (map compOrigType comps)
- exprs <- zipWithM to_comp (map Var vars) comps
- return (vars, mkConApp tup_con (map Type tys ++ exprs))
- where
- [tup_con] = tyConDataCons tup_tc
-
- to_comp expr (Keep _ _) = return expr
- to_comp expr (Wrap ty) = do
- wrap_tc <- builtin wrapTyCon
- return $ wrapNewTypeBody wrap_tc [ty] expr
-
-
-buildFromPRepr :: TyCon -> TyCon -> TyCon -> SumRepr -> VM CoreExpr
-buildFromPRepr vect_tc repr_tc _ repr
- = do
- arg_ty <- mkPReprType res_ty
- arg <- newLocalVar (fsLit "x") arg_ty
-
- result <- from_sum (unwrapFamInstScrut repr_tc ty_args (Var arg))
- repr
- return $ Lam arg result
- where
- ty_args = mkTyVarTys (tyConTyVars vect_tc)
- res_ty = mkTyConApp vect_tc ty_args
-
- from_sum _ EmptySum
- = do
- dummy <- builtin fromVoidVar
- return $ Var dummy `App` Type res_ty
-
- from_sum expr (UnarySum r) = from_con expr r
- from_sum expr (Sum { repr_sum_tc = sum_tc
- , repr_con_tys = tys
- , repr_cons = cons })
- = do
- vars <- newLocalVars (fsLit "x") tys
- es <- zipWithM from_con (map Var vars) cons
- return $ mkWildCase expr (exprType expr) res_ty
- [(DataAlt con, [var], e)
- | (con, var, e) <- zip3 (tyConDataCons sum_tc) vars es]
-
- from_con expr (ConRepr con r)
- = from_prod expr (mkConApp con $ map Type ty_args) r
-
- from_prod _ con EmptyProd = return con
- from_prod expr con (UnaryProd r)
- = do
- e <- from_comp expr r
- return $ con `App` e
-
- from_prod expr con (Prod { repr_tup_tc = tup_tc
- , repr_comp_tys = tys
- , repr_comps = comps
- })
- = do
- vars <- newLocalVars (fsLit "y") tys
- es <- zipWithM from_comp (map Var vars) comps
- return $ mkWildCase expr (exprType expr) res_ty
- [(DataAlt tup_con, vars, con `mkApps` es)]
- where
- [tup_con] = tyConDataCons tup_tc
-
- from_comp expr (Keep _ _) = return expr
- from_comp expr (Wrap ty)
- = do
- wrap <- builtin wrapTyCon
- return $ unwrapNewTypeBody wrap [ty] expr
-
-
-buildToArrPRepr :: TyCon -> TyCon -> TyCon -> SumRepr -> VM CoreExpr
-buildToArrPRepr vect_tc prepr_tc pdata_tc r
- = do
- arg_ty <- mkPDataType el_ty
- res_ty <- mkPDataType =<< mkPReprType el_ty
- arg <- newLocalVar (fsLit "xs") arg_ty
-
- pdata_co <- mkBuiltinCo pdataTyCon
- let Just repr_co = tyConFamilyCoercion_maybe prepr_tc
- co = mkAppCo pdata_co
- . mkSymCo
- $ mkAxInstCo repr_co ty_args
-
- scrut = unwrapFamInstScrut pdata_tc ty_args (Var arg)
-
- (vars, result) <- to_sum r
-
- return . Lam arg
- $ mkWildCase scrut (mkTyConApp pdata_tc ty_args) res_ty
- [(DataAlt pdata_dc, vars, mkCast result co)]
- where
- ty_args = mkTyVarTys $ tyConTyVars vect_tc
- el_ty = mkTyConApp vect_tc ty_args
-
- [pdata_dc] = tyConDataCons pdata_tc
-
-
- to_sum EmptySum = do
- pvoid <- builtin pvoidVar
- return ([], Var pvoid)
- to_sum (UnarySum r) = to_con r
- to_sum (Sum { repr_psum_tc = psum_tc
- , repr_sel_ty = sel_ty
- , repr_con_tys = tys
- , repr_cons = cons
- })
- = do
- (vars, exprs) <- mapAndUnzipM to_con cons
- sel <- newLocalVar (fsLit "sel") sel_ty
- return (sel : concat vars, mk_result (Var sel) exprs)
- where
- [psum_con] = tyConDataCons psum_tc
- mk_result sel exprs = wrapFamInstBody psum_tc tys
- $ mkConApp psum_con
- $ map Type tys ++ (sel : exprs)
-
- to_con (ConRepr _ r) = to_prod r
-
- to_prod EmptyProd = do
- pvoid <- builtin pvoidVar
- return ([], Var pvoid)
- to_prod (UnaryProd r)
- = do
- pty <- mkPDataType (compOrigType r)
- var <- newLocalVar (fsLit "x") pty
- expr <- to_comp (Var var) r
- return ([var], expr)
-
- to_prod (Prod { repr_ptup_tc = ptup_tc
- , repr_comp_tys = tys
- , repr_comps = comps })
- = do
- ptys <- mapM (mkPDataType . compOrigType) comps
- vars <- newLocalVars (fsLit "x") ptys
- es <- zipWithM to_comp (map Var vars) comps
- return (vars, mk_result es)
- where
- [ptup_con] = tyConDataCons ptup_tc
- mk_result exprs = wrapFamInstBody ptup_tc tys
- $ mkConApp ptup_con
- $ map Type tys ++ exprs
-
- to_comp expr (Keep _ _) = return expr
-
- -- FIXME: this is bound to be wrong!
- to_comp expr (Wrap ty)
- = do
- wrap_tc <- builtin wrapTyCon
- pwrap_tc <- pdataReprTyConExact (mkTyConApp wrap_tc [ty])
- return $ wrapNewTypeBody pwrap_tc [ty] expr
-
-
-buildFromArrPRepr :: TyCon -> TyCon -> TyCon -> SumRepr -> VM CoreExpr
-buildFromArrPRepr vect_tc prepr_tc pdata_tc r
- = do
- arg_ty <- mkPDataType =<< mkPReprType el_ty
- res_ty <- mkPDataType el_ty
- arg <- newLocalVar (fsLit "xs") arg_ty
-
- pdata_co <- mkBuiltinCo pdataTyCon
- let Just repr_co = tyConFamilyCoercion_maybe prepr_tc
- co = mkAppCo pdata_co
- $ mkAxInstCo repr_co var_tys
-
- scrut = mkCast (Var arg) co
-
- mk_result args = wrapFamInstBody pdata_tc var_tys
- $ mkConApp pdata_con
- $ map Type var_tys ++ args
-
- (expr, _) <- fixV $ \ ~(_, args) ->
- from_sum res_ty (mk_result args) scrut r
-
- return $ Lam arg expr
-
- -- (args, mk) <- from_sum res_ty scrut r
-
- -- let result = wrapFamInstBody pdata_tc var_tys
- -- . mkConApp pdata_dc
- -- $ map Type var_tys ++ args
-
- -- return $ Lam arg (mk result)
- where
- var_tys = mkTyVarTys $ tyConTyVars vect_tc
- el_ty = mkTyConApp vect_tc var_tys
-
- [pdata_con] = tyConDataCons pdata_tc
-
- from_sum _ res _ EmptySum = return (res, [])
- from_sum res_ty res expr (UnarySum r) = from_con res_ty res expr r
- from_sum res_ty res expr (Sum { repr_psum_tc = psum_tc
- , repr_sel_ty = sel_ty
- , repr_con_tys = tys
- , repr_cons = cons })
- = do
- sel <- newLocalVar (fsLit "sel") sel_ty
- ptys <- mapM mkPDataType tys
- vars <- newLocalVars (fsLit "xs") ptys
- (res', args) <- fold from_con res_ty res (map Var vars) cons
- let scrut = unwrapFamInstScrut psum_tc tys expr
- body = mkWildCase scrut (exprType scrut) res_ty
- [(DataAlt psum_con, sel : vars, res')]
- return (body, Var sel : args)
- where
- [psum_con] = tyConDataCons psum_tc
-
-
- from_con res_ty res expr (ConRepr _ r) = from_prod res_ty res expr r
-
- from_prod _ res _ EmptyProd = return (res, [])
- from_prod res_ty res expr (UnaryProd r)
- = from_comp res_ty res expr r
- from_prod res_ty res expr (Prod { repr_ptup_tc = ptup_tc
- , repr_comp_tys = tys
- , repr_comps = comps })
- = do
- ptys <- mapM mkPDataType tys
- vars <- newLocalVars (fsLit "ys") ptys
- (res', args) <- fold from_comp res_ty res (map Var vars) comps
- let scrut = unwrapFamInstScrut ptup_tc tys expr
- body = mkWildCase scrut (exprType scrut) res_ty
- [(DataAlt ptup_con, vars, res')]
- return (body, args)
- where
- [ptup_con] = tyConDataCons ptup_tc
-
- from_comp _ res expr (Keep _ _) = return (res, [expr])
- from_comp _ res expr (Wrap ty)
- = do
- wrap_tc <- builtin wrapTyCon
- pwrap_tc <- pdataReprTyConExact (mkTyConApp wrap_tc [ty])
- return (res, [unwrapNewTypeBody pwrap_tc [ty]
- $ unwrapFamInstScrut pwrap_tc [ty] expr])
-
- fold f res_ty res exprs rs = foldrM f' (res, []) (zip exprs rs)
- where
- f' (expr, r) (res, args) = do
- (res', args') <- f res_ty res expr r
- return (res', args' ++ args)
diff --git a/compiler/vectorise/Vectorise/Utils/Base.hs b/compiler/vectorise/Vectorise/Utils/Base.hs
index a08174d513..0c111f49c7 100644
--- a/compiler/vectorise/Vectorise/Utils/Base.hs
+++ b/compiler/vectorise/Vectorise/Utils/Base.hs
@@ -1,23 +1,26 @@
-module Vectorise.Utils.Base (
- voidType,
- newLocalVVar,
-
- mkDataConTagLit,
- mkDataConTag, dataConTagZ,
- mkBuiltinTyConApp,
- mkBuiltinTyConApps,
- mkWrapType,
- mkClosureTypes,
- mkPReprType,
- mkPArrayType, splitPrimTyCon,
- mkPArray,
- mkPDataType, mkPDatasType,
- mkBuiltinCo,
- mkVScrut,
-
- pdataReprTyCon, pdataReprTyConExact, pdatasReprTyCon,
- pdataReprDataCon, pdatasReprDataCon,
- prDFunOfTyCon
+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
) where
import Vectorise.Monad
@@ -28,24 +31,20 @@ import CoreSyn
import CoreUtils
import Coercion
import Type
-import TypeRep
import TyCon
import DataCon
import MkId
-import Literal
-import Outputable
import FastString
-import ListSetOps
-
-import Control.Monad (liftM)
-- Simple Types ---------------------------------------------------------------
+
voidType :: VM Type
voidType = mkBuiltinTyConApp voidTyCon []
-- Name Generation ------------------------------------------------------------
+
newLocalVVar :: FastString -> Type -> VM VVar
newLocalVVar fs vty
= do
@@ -56,70 +55,64 @@ newLocalVVar fs vty
-- Constructors ---------------------------------------------------------------
-mkDataConTagLit :: DataCon -> Literal
-mkDataConTagLit = mkMachInt . toInteger . dataConTagZ
-
mkDataConTag :: DataCon -> CoreExpr
mkDataConTag = mkIntLitInt . dataConTagZ
-
dataConTagZ :: DataCon -> Int
dataConTagZ con = dataConTag con - fIRST_TAG
-- Type Construction ----------------------------------------------------------
--- | Make an application of a builtin type constructor to some arguments.
-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]
-
-
--- | Make an application of the 'Wrap' type constructor.
+-- |Make an application of the 'Wrap' type constructor.
+--
mkWrapType :: Type -> VM Type
-mkWrapType ty = mkBuiltinTyConApp wrapTyCon [ty]
-
+mkWrapType ty = mkBuiltinTyConApp wrapTyCon [ty]
--- | Make an application of the closure type constructor.
+-- |Make an application of the closure type constructor.
+--
mkClosureTypes :: [Type] -> Type -> VM Type
mkClosureTypes = mkBuiltinTyConApps closureTyCon
-
--- | Make an application of the 'PRepr' type constructor.
+-- |Make an application of the 'PRepr' type constructor.
+--
mkPReprType :: Type -> VM Type
mkPReprType ty = mkBuiltinTyConApp preprTyCon [ty]
-
--- | Wrap a type into 'PArray', treating unboxed types specially.
-mkPArrayType :: Type -> VM Type
-mkPArrayType ty
- | Just tycon <- splitPrimTyCon ty
- = do { arr <- builtin (parray_PrimTyCon tycon)
- ; return $ mkTyConApp arr []
- }
-mkPArrayType ty = mkBuiltinTyConApp parrayTyCon [ty]
-
-
-- | Make an appliction of the 'PData' tycon to some argument.
+--
mkPDataType :: Type -> VM Type
-mkPDataType ty = mkBuiltinTyConApp pdataTyCon [ty]
-
+mkPDataType ty = mkBuiltinTyConApp pdataTyCon [ty]
-- | Make an application of the 'PDatas' tycon to some argument.
+--
mkPDatasType :: Type -> VM Type
mkPDatasType ty = mkBuiltinTyConApp pdatasTyCon [ty]
+-- Make an application of a builtin type constructor to some arguments.
+--
+mkBuiltinTyConApp :: (Builtins -> TyCon) -> [Type] -> VM Type
+mkBuiltinTyConApp get_tc tys
+ = do { tc <- builtin get_tc
+ ; return $ mkTyConApp tc tys
+ }
+
+-- Make a cascading application of a builtin type constructor.
+--
+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]
+
+
+-- Type decomposition ---------------------------------------------------------
-- |Checks if a type constructor is defined in 'GHC.Prim' (e.g., 'Int#'); if so, returns it.
+--
splitPrimTyCon :: Type -> Maybe TyCon
splitPrimTyCon ty
| Just (tycon, []) <- splitTyConApp_maybe ty
@@ -128,38 +121,73 @@ splitPrimTyCon ty
| otherwise = Nothing
+-- Coercion Construction -----------------------------------------------------
--- CoreExpr Construction ------------------------------------------------------
--- | Make an application of the 'PArray' data constructor.
-mkPArray
- :: Type -- ^ Element type
- -> CoreExpr -- ^ 'Int' for the array length.
- -> CoreExpr -- ^ 'PData' for the array data.
- -> VM CoreExpr
+-- |Make a coersion to some builtin type.
+--
+mkBuiltinCo :: (Builtins -> TyCon) -> VM Coercion
+mkBuiltinCo get_tc
+ = do { tc <- builtin get_tc
+ ; return $ mkTyConAppCo tc []
+ }
-mkPArray ty len dat
- = do tc <- builtin parrayTyCon
- let [dc] = tyConDataCons tc
- return $ mkConApp dc [Type ty, len, dat]
+-- Wrapping and unwrapping the 'Wrap' newtype ---------------------------------
--- Coercion Construction -----------------------------------------------------
--- | Make a coersion to some builtin type.
-mkBuiltinCo :: (Builtins -> TyCon) -> VM Coercion
-mkBuiltinCo get_tc
- = do tc <- builtin get_tc
- return $ mkTyConAppCo tc []
+-- |Apply the constructor wrapper of the 'Wrap' /newtype/.
+--
+wrapNewTypeBodyOfWrap :: CoreExpr -> Type -> VM CoreExpr
+wrapNewTypeBodyOfWrap e ty
+ = do { wrap_tc <- builtin wrapTyCon
+ ; return $ wrapNewTypeBody wrap_tc [ty] e
+ }
+
+-- |Strip the constructor wrapper of the 'Wrap' /newtype/.
+--
+unwrapNewTypeBodyOfWrap :: CoreExpr -> Type -> VM CoreExpr
+unwrapNewTypeBodyOfWrap e ty
+ = do { wrap_tc <- builtin wrapTyCon
+ ; return $ unwrapNewTypeBody wrap_tc [ty] e
+ }
+-- |Apply the constructor wrapper of the 'PData' /newtype/ instance of 'Wrap'.
+--
+wrapNewTypeBodyOfPDataWrap :: CoreExpr -> Type -> VM CoreExpr
+wrapNewTypeBodyOfPDataWrap e ty
+ = do { wrap_tc <- builtin wrapTyCon
+ ; pwrap_tc <- pdataReprTyConExact wrap_tc
+ ; return $ wrapNewTypeBody pwrap_tc [ty] e
+ }
--------------------------------------------------------------------------------
+-- |Strip the constructor wrapper of the 'PData' /newtype/ instance of 'Wrap'.
+--
+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)
+ }
-mkVScrut :: VExpr -> VM (CoreExpr, CoreExpr, TyCon, [Type])
-mkVScrut (ve, le)
- = do
- (tc, arg_tys) <- pdataReprTyCon ty
- return (ve, unwrapFamInstScrut tc arg_tys le, tc, arg_tys)
- where
- ty = exprType ve
+-- |Apply the constructor wrapper of the 'PDatas' /newtype/ instance of 'Wrap'.
+--
+wrapNewTypeBodyOfPDatasWrap :: CoreExpr -> Type -> VM CoreExpr
+wrapNewTypeBodyOfPDatasWrap e ty
+ = do { wrap_tc <- builtin wrapTyCon
+ ; pwrap_tc <- pdatasReprTyConExact wrap_tc
+ ; return $ wrapNewTypeBody pwrap_tc [ty] e
+ }
+
+-- |Strip the constructor wrapper of the 'PDatas' /newtype/ instance of 'Wrap'.
+--
+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)
+ }
+
+
+-- 'PData' representation types ----------------------------------------------
-- |Get the representation tycon of the 'PData' data family for a given type.
--
@@ -175,43 +203,41 @@ mkVScrut (ve, le)
pdataReprTyCon :: Type -> VM (TyCon, [Type])
pdataReprTyCon ty = builtin pdataTyCon >>= (`lookupFamInst` [ty])
--- |Get the representation tycon of the 'PData' data family for a given type which must match the
--- type index in the looked up 'PData' instance exactly.
---
-pdataReprTyConExact :: Type -> VM TyCon
-pdataReprTyConExact ty
- = do { (tycon, tys) <- pdataReprTyCon ty
- ; if uniqueTyVars tys
- then
- return tycon
- else
- cantVectorise "No exact 'PData' family instance for" (ppr ty)
- }
- where
- uniqueTyVars tys = all isTyVarTy tys && hasNoDups (map extractTyVar tys)
- where
- extractTyVar (TyVarTy tv) = tv
- extractTyVar _ = panic "Vectorise.Utils.Base: extractTyVar"
-
-pdataReprDataCon :: Type -> VM (DataCon, [Type])
-pdataReprDataCon ty
- = do { (tc, arg_tys) <- pdataReprTyCon ty
- ; let [dc] = tyConDataCons tc
- ; return (dc, arg_tys)
+-- |Get the representation tycon of the 'PData' data family for a given type constructor.
+--
+-- For example, for a binary type constructor 'T', we determine the representation type constructor
+-- for 'PData (T a b)'.
+--
+pdataReprTyConExact :: TyCon -> VM TyCon
+pdataReprTyConExact tycon
+ = do { -- look up the representation tycon; if there is a match at all, it will be be exact
+ ; -- (i.e.,' _tys' will be distinct type variables)
+ ; (ptycon, _tys) <- pdataReprTyCon (tycon `mkTyConApp` mkTyVarTys (tyConTyVars tycon))
+ ; return ptycon
}
-pdatasReprTyCon :: Type -> VM (TyCon, [Type])
-pdatasReprTyCon ty = builtin pdatasTyCon >>= (`lookupFamInst` [ty])
+-- |Get the representation tycon of the 'PDatas' data family for a given type constructor.
+--
+-- For example, for a binary type constructor 'T', we determine the representation type constructor
+-- for 'PDatas (T a b)'.
+--
+pdatasReprTyConExact :: TyCon -> VM TyCon
+pdatasReprTyConExact tycon
+ = do { -- look up the representation tycon; if there is a match at all, it will be be exact
+ ; -- (i.e.,' _tys' will be distinct type variables)
+ ; (ptycon, _tys) <- pdatasReprTyCon (tycon `mkTyConApp` mkTyVarTys (tyConTyVars tycon))
+ ; return ptycon
+ }
+ where
+ pdatasReprTyCon ty = builtin pdatasTyCon >>= (`lookupFamInst` [ty])
-pdatasReprDataCon :: Type -> VM (DataCon, [Type])
-pdatasReprDataCon ty
- = do { (tc, arg_tys) <- pdatasReprTyCon ty
+-- |Unwrap a 'PData' representation scrutinee.
+--
+pdataUnwrapScrut :: VExpr -> VM (CoreExpr, CoreExpr, DataCon)
+pdataUnwrapScrut (ve, le)
+ = do { (tc, arg_tys) <- pdataReprTyCon ty
; let [dc] = tyConDataCons tc
- ; return (dc, arg_tys)
+ ; return (ve, unwrapFamInstScrut tc arg_tys le, dc)
}
-
-prDFunOfTyCon :: TyCon -> VM CoreExpr
-prDFunOfTyCon tycon
- = liftM Var
- . maybeCantVectoriseM "No PR dictionary for tycon" (ppr tycon)
- $ lookupTyConPR tycon
+ where
+ ty = exprType ve
diff --git a/compiler/vectorise/Vectorise/Utils/PADict.hs b/compiler/vectorise/Vectorise/Utils/PADict.hs
index 5a38ecd557..164ebae229 100644
--- a/compiler/vectorise/Vectorise/Utils/PADict.hs
+++ b/compiler/vectorise/Vectorise/Utils/PADict.hs
@@ -75,11 +75,12 @@ paDictOfType ty
-- the representation type if the tycon is polymorphic
paDictOfTyApp (TyConApp tc []) ty_args
= do
- dfun <- maybeCantVectoriseM "No PA dictionary for type constructor"
- (ppr tc <+> text "in" <+> ppr ty)
+ dfun <- maybeCantVectoriseM noPADictErr (ppr tc <+> text "in" <+> ppr ty)
$ lookupTyConPA tc
dicts <- mapM paDictOfType ty_args
return $ Var dfun `mkTyApps` ty_args `mkApps` dicts
+ where
+ noPADictErr = "No PA dictionary for type constructor (did you import 'Data.Array.Parallel'?)"
paDictOfTyApp _ _ = failure