-- ** @RULE@ declarations
RuleDecl(..), LRuleDecl, RuleBndr(..),
collectRuleBndrSigTys,
+ -- ** @VECTORISE@ declarations
+ VectDecl(..), LVectDecl,
-- ** @default@ declarations
DefaultDecl(..), LDefaultDecl,
-- ** Top-level template haskell splice
) where
-- friends:
-import {-# SOURCE #-} HsExpr( HsExpr, pprExpr )
+import {-# SOURCE #-} HsExpr( LHsExpr, HsExpr, pprExpr )
-- Because Expr imports Decls via HsBracket
import HsBinds
| WarningD (WarnDecl id)
| AnnD (AnnDecl id)
| RuleD (RuleDecl id)
+ | VectD (VectDecl id)
| SpliceD (SpliceDecl id)
| DocD (DocDecl)
| QuasiQuoteD (HsQuasiQuote id)
data HsGroup id
= HsGroup {
hs_valds :: HsValBinds id,
- hs_tyclds :: [LTyClDecl id],
+
+ hs_tyclds :: [[LTyClDecl id]],
+ -- A list of mutually-recursive groups
+ -- Parser generates a singleton list;
+ -- renamer does dependency analysis
+
hs_instds :: [LInstDecl id],
hs_derivds :: [LDerivDecl id],
-- Snaffled out of both top-level fixity signatures,
-- and those in class declarations
- hs_defds :: [LDefaultDecl id],
- hs_fords :: [LForeignDecl id],
- hs_warnds :: [LWarnDecl id],
- hs_annds :: [LAnnDecl id],
- hs_ruleds :: [LRuleDecl id],
+ hs_defds :: [LDefaultDecl id],
+ hs_fords :: [LForeignDecl id],
+ hs_warnds :: [LWarnDecl id],
+ hs_annds :: [LAnnDecl id],
+ hs_ruleds :: [LRuleDecl id],
+ hs_vects :: [LVectDecl id],
- hs_docs :: [LDocDecl]
+ hs_docs :: [LDocDecl]
} deriving (Data, Typeable)
emptyGroup, emptyRdrGroup, emptyRnGroup :: HsGroup a
emptyGroup = HsGroup { hs_tyclds = [], hs_instds = [], hs_derivds = [],
hs_fixds = [], hs_defds = [], hs_annds = [],
- hs_fords = [], hs_warnds = [], hs_ruleds = [],
+ hs_fords = [], hs_warnds = [], hs_ruleds = [], hs_vects = [],
hs_valds = error "emptyGroup hs_valds: Can't happen",
hs_docs = [] }
appendGroups :: HsGroup a -> HsGroup a -> HsGroup a
appendGroups
HsGroup {
- hs_valds = val_groups1,
- hs_tyclds = tyclds1,
- hs_instds = instds1,
+ hs_valds = val_groups1,
+ hs_tyclds = tyclds1,
+ hs_instds = instds1,
hs_derivds = derivds1,
- hs_fixds = fixds1,
- hs_defds = defds1,
- hs_annds = annds1,
- hs_fords = fords1,
- hs_warnds = warnds1,
- hs_ruleds = rulds1,
+ hs_fixds = fixds1,
+ hs_defds = defds1,
+ hs_annds = annds1,
+ hs_fords = fords1,
+ hs_warnds = warnds1,
+ hs_ruleds = rulds1,
+ hs_vects = vects1,
hs_docs = docs1 }
HsGroup {
- hs_valds = val_groups2,
- hs_tyclds = tyclds2,
- hs_instds = instds2,
+ hs_valds = val_groups2,
+ hs_tyclds = tyclds2,
+ hs_instds = instds2,
hs_derivds = derivds2,
- hs_fixds = fixds2,
- hs_defds = defds2,
- hs_annds = annds2,
- hs_fords = fords2,
- hs_warnds = warnds2,
- hs_ruleds = rulds2,
- hs_docs = docs2 }
+ hs_fixds = fixds2,
+ hs_defds = defds2,
+ hs_annds = annds2,
+ hs_fords = fords2,
+ hs_warnds = warnds2,
+ hs_ruleds = rulds2,
+ hs_vects = vects2,
+ hs_docs = docs2 }
=
HsGroup {
- hs_valds = val_groups1 `plusHsValBinds` val_groups2,
- hs_tyclds = tyclds1 ++ tyclds2,
- hs_instds = instds1 ++ instds2,
+ hs_valds = val_groups1 `plusHsValBinds` val_groups2,
+ hs_tyclds = tyclds1 ++ tyclds2,
+ hs_instds = instds1 ++ instds2,
hs_derivds = derivds1 ++ derivds2,
- hs_fixds = fixds1 ++ fixds2,
- hs_annds = annds1 ++ annds2,
- hs_defds = defds1 ++ defds2,
- hs_fords = fords1 ++ fords2,
- hs_warnds = warnds1 ++ warnds2,
- hs_ruleds = rulds1 ++ rulds2,
- hs_docs = docs1 ++ docs2 }
+ hs_fixds = fixds1 ++ fixds2,
+ hs_annds = annds1 ++ annds2,
+ hs_defds = defds1 ++ defds2,
+ hs_fords = fords1 ++ fords2,
+ hs_warnds = warnds1 ++ warnds2,
+ hs_ruleds = rulds1 ++ rulds2,
+ hs_vects = vects1 ++ vects2,
+ hs_docs = docs1 ++ docs2 }
\end{code}
\begin{code}
ppr (ForD fd) = ppr fd
ppr (SigD sd) = ppr sd
ppr (RuleD rd) = ppr rd
+ ppr (VectD vect) = ppr vect
ppr (WarningD wd) = ppr wd
ppr (AnnD ad) = ppr ad
ppr (SpliceD dd) = ppr dd
hs_annds = ann_decls,
hs_fords = foreign_decls,
hs_defds = default_decls,
- hs_ruleds = rule_decls })
+ hs_ruleds = rule_decls,
+ hs_vects = vect_decls })
= vcat_mb empty
[ppr_ds fix_decls, ppr_ds default_decls,
ppr_ds deprec_decls, ppr_ds ann_decls,
ppr_ds rule_decls,
+ ppr_ds vect_decls,
if isEmptyValBinds val_decls
then Nothing
else Just (ppr val_decls),
- ppr_ds tycl_decls, ppr_ds inst_decls,
+ ppr_ds (concat tycl_decls),
+ ppr_ds inst_decls,
ppr_ds deriv_decls,
ppr_ds foreign_decls]
where
+ ppr_ds :: Outputable a => [a] -> Maybe SDoc
ppr_ds [] = Nothing
ppr_ds ds = Just (vcat (map ppr ds))
top_matter = ptext (sLit "class")
<+> pp_decl_head (unLoc context) lclas tyvars Nothing
<+> pprFundeps (map unLoc fds)
+ ppr_semi :: Outputable a => a -> SDoc
ppr_semi decl = ppr decl <> semi
pp_decl_head :: OutputableBndr name
-- * `Safety' is irrelevant for `CLabel' and `CWrapper'
--
CImport CCallConv -- ccall or stdcall
- Safety -- safe or unsafe
+ Safety -- interruptible, safe or unsafe
FastString -- name of C header
CImportSpec -- details of the C entity
deriving (Data, Typeable)
ppr (RuleBndrSig name ty) = ppr name <> dcolon <> ppr ty
\end{code}
+
+%************************************************************************
+%* *
+\subsection{Vectorisation declarations}
+%* *
+%************************************************************************
+
+A vectorisation pragma
+
+ {-# VECTORISE f = closure1 g (scalar_map g) #-} OR
+ {-# VECTORISE SCALAR f #-}
+
+Note [Typechecked vectorisation pragmas]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+In case of the first variant of vectorisation pragmas (with an explicit expression),
+we need to infer the type of that expression during type checking and then keep that type
+around until vectorisation, so that it can be checked against the *vectorised* type of 'f'.
+(We cannot determine vectorised types during type checking due to internal information of
+the vectoriser being needed.)
+
+To this end, we annotate the 'Id' of 'f' (the variable mentioned in the PRAGMA) with the
+inferred type of the expression. This is slightly dodgy, as this is really the type of
+'$v_f' (the name of the vectorised function).
+
+\begin{code}
+type LVectDecl name = Located (VectDecl name)
+
+data VectDecl name
+ = HsVect
+ (Located name)
+ (Maybe (LHsExpr name)) -- 'Nothing' => SCALAR declaration
+ deriving (Data, Typeable)
+
+instance OutputableBndr name => Outputable (VectDecl name) where
+ ppr (HsVect v rhs)
+ = sep [text "{-# VECTORISE" <+> ppr v,
+ nest 4 (case rhs of
+ Nothing -> text "SCALAR #-}"
+ Just rhs -> pprExpr (unLoc rhs) <+> text "#-}") ]
+\end{code}
+
%************************************************************************
%* *
\subsection[DocDecl]{Document comments}