mkPrimOpId, mkFCallId,
-- And some particular Ids; see below for why they are wired in
- wiredInIds,
- unsafeCoerceId, realWorldPrimId, nullAddrId,
- eRROR_ID, eRROR_CSTRING_ID, rEC_SEL_ERROR_ID, pAT_ERROR_ID, rEC_CON_ERROR_ID,
- rEC_UPD_ERROR_ID, iRREFUT_PAT_ERROR_ID, nON_EXHAUSTIVE_GUARDS_ERROR_ID,
- nO_METHOD_BINDING_ERROR_ID, aBSENT_ERROR_ID, pAR_ERROR_ID
+ wiredInIds, ghcPrimIds,
+ unsafeCoerceId, realWorldPrimId, voidArgId, nullAddrId,
+ eRROR_ID, eRROR_CSTRING_ID, rEC_SEL_ERROR_ID, pAT_ERROR_ID,
+ rEC_CON_ERROR_ID, rEC_UPD_ERROR_ID, iRREFUT_PAT_ERROR_ID,
+ nON_EXHAUSTIVE_GUARDS_ERROR_ID, nO_METHOD_BINDING_ERROR_ID,
+ aBSENT_ERROR_ID, pAR_ERROR_ID
) where
#include "HsVersions.h"
tcSplitFunTys, tcSplitForAllTys, mkPredTy
)
import Module ( Module )
-import CoreUtils ( mkInlineMe, exprType )
+import CoreUtils ( exprType )
import CoreUnfold ( mkTopUnfolding, mkCompulsoryUnfolding, mkOtherCon )
import Literal ( Literal(..), nullAddrLit )
import TyCon ( TyCon, isNewTyCon, tyConTyVars, tyConDataCons,
)
import IdInfo ( IdInfo, noCafNoTyGenIdInfo,
setUnfoldingInfo,
- setArityInfo, setSpecInfo, setCgInfo, setCafInfo,
- mkNewStrictnessInfo, setNewStrictnessInfo,
- GlobalIdDetails(..), CafInfo(..), CprInfo(..),
- CgInfo
+ setArityInfo, setSpecInfo, setCafInfo,
+ setAllStrictnessInfo,
+ GlobalIdDetails(..), CafInfo(..)
)
import NewDemand ( mkStrictSig, strictSigResInfo, DmdResult(..),
- mkTopDmdType, topDmd, evalDmd, Demand(..), Keepity(..) )
+ mkTopDmdType, topDmd, evalDmd, lazyDmd,
+ Demand(..), Demands(..) )
import FieldLabel ( mkFieldLabel, fieldLabelName,
firstFieldLabelTag, allFieldLabelTags, fieldLabelType
)
-- error-reporting functions that they have an 'open'
-- result type. -- sof 1/99]
- aBSENT_ERROR_ID
- , eRROR_ID
- , eRROR_CSTRING_ID
- , iRREFUT_PAT_ERROR_ID
- , nON_EXHAUSTIVE_GUARDS_ERROR_ID
- , nO_METHOD_BINDING_ERROR_ID
- , pAR_ERROR_ID
- , pAT_ERROR_ID
- , rEC_CON_ERROR_ID
- , rEC_UPD_ERROR_ID
-
- -- These can't be defined in Haskell, but they have
+ aBSENT_ERROR_ID,
+ eRROR_ID,
+ eRROR_CSTRING_ID,
+ iRREFUT_PAT_ERROR_ID,
+ nON_EXHAUSTIVE_GUARDS_ERROR_ID,
+ nO_METHOD_BINDING_ERROR_ID,
+ pAR_ERROR_ID,
+ pAT_ERROR_ID,
+ rEC_CON_ERROR_ID,
+ rEC_UPD_ERROR_ID
+ ] ++ ghcPrimIds
+
+-- These Ids are exported from GHC.Prim
+ghcPrimIds
+ = [ -- These can't be defined in Haskell, but they have
-- perfectly reasonable unfoldings in Core
- , realWorldPrimId
- , unsafeCoerceId
- , nullAddrId
- , getTagId
- , seqId
+ realWorldPrimId,
+ unsafeCoerceId,
+ nullAddrId,
+ getTagId,
+ seqId
]
\end{code}
where
info = noCafNoTyGenIdInfo
`setArityInfo` arity
- `setNewStrictnessInfo` Just strict_sig
+ `setAllStrictnessInfo` Just strict_sig
arity = dataConRepArity data_con
`setArityInfo` arity
-- It's important to specify the arity, so that partial
-- applications are treated as values
- `setNewStrictnessInfo` Just wrap_sig
+ `setAllStrictnessInfo` Just wrap_sig
wrap_ty = mkForAllTys all_tyvars (mkFunTys all_arg_tys result_ty)
wrap_sig = mkStrictSig (mkTopDmdType arg_dmds res_info)
res_info = strictSigResInfo (idNewStrictness work_id)
arg_dmds = [Abs | d <- dict_args] ++ map mk_dmd strict_marks
- mk_dmd str | isMarkedStrict str = Eval
- | otherwise = Lazy
+ mk_dmd str | isMarkedStrict str = evalDmd
+ | otherwise = lazyDmd
-- The Cpr info can be important inside INLINE rhss, where the
-- wrapper constructor isn't inlined.
-- And the argument strictness can be important too; we
`setCafInfo` caf_info
`setArityInfo` arity
`setUnfoldingInfo` mkTopUnfolding rhs_w_str
- `setNewStrictnessInfo` Just strict_sig
+ `setAllStrictnessInfo` Just strict_sig
-- Allocate Ids. We do it a funny way round because field_dict_tys is
-- almost always empty. Also note that we use length_tycon_theta
(_, tycon_args, pack_con, con_arg_tys)
= splitProductType "rebuildConArgs" arg_ty
- unpacked_args = zipWith (mkSysLocal SLIT("rb")) us con_arg_tys
+ unpacked_args = zipWith (mkSysLocal FSLIT("rb")) us con_arg_tys
(binds, args') = rebuildConArgs args stricts (dropList con_arg_tys us)
con_app = mkConApp pack_con (map Type tycon_args ++ map Var unpacked_args)
in
info = noCafNoTyGenIdInfo
`setArityInfo` 1
`setUnfoldingInfo` mkTopUnfolding rhs
- `setNewStrictnessInfo` Just strict_sig
+ `setAllStrictnessInfo` Just strict_sig
-- We no longer use 'must-inline' on record selectors. They'll
-- inline like crazy if they scrutinise a constructor
-- It's worth giving one, so that absence info etc is generated
-- even if the selector isn't inlined
strict_sig = mkStrictSig (mkTopDmdType [arg_dmd] TopRes)
- arg_dmd | isNewTyCon tycon = Eval
- | otherwise = Seq Drop [ if the_arg_id == id then Eval else Abs
- | id <- arg_ids ]
+ arg_dmd | isNewTyCon tycon = evalDmd
+ | otherwise = Eval (Prod [ if the_arg_id == id then evalDmd else Abs
+ | id <- arg_ids ])
tyvars = classTyVars clas
mkPrimOpId prim_op
= id
where
- (tyvars,arg_tys,res_ty, arity, strict_info) = primOpSig prim_op
+ (tyvars,arg_tys,res_ty, arity, strict_sig) = primOpSig prim_op
ty = mkForAllTys tyvars (mkFunTys arg_tys res_ty)
name = mkPrimOpIdName prim_op
id = mkGlobalId (PrimOpId prim_op) name ty info
info = noCafNoTyGenIdInfo
`setSpecInfo` rules
`setArityInfo` arity
- `setNewStrictnessInfo` Just (mkNewStrictnessInfo id arity strict_info NoCPRInfo)
- -- Until we modify the primop generation code
+ `setAllStrictnessInfo` Just strict_sig
rules = foldl (addRule id) emptyCoreRules (primOpRules prim_op)
info = noCafNoTyGenIdInfo
`setArityInfo` arity
- `setNewStrictnessInfo` Just strict_sig
+ `setAllStrictnessInfo` Just strict_sig
(_, tau) = tcSplitForAllTys ty
(arg_tys, _) = tcSplitFunTys tau
\begin{code}
-- unsafeCoerce# :: forall a b. a -> b
unsafeCoerceId
- = pcMiscPrelId unsafeCoerceIdKey pREL_GHC SLIT("unsafeCoerce#") ty info
+ = pcMiscPrelId unsafeCoerceIdKey gHC_PRIM FSLIT("unsafeCoerce#") ty info
where
info = noCafNoTyGenIdInfo `setUnfoldingInfo` mkCompulsoryUnfolding rhs
-- The reason is is here is because we don't provide
-- a way to write this literal in Haskell.
nullAddrId
- = pcMiscPrelId nullAddrIdKey pREL_GHC SLIT("nullAddr#") addrPrimTy info
+ = pcMiscPrelId nullAddrIdKey gHC_PRIM FSLIT("nullAddr#") addrPrimTy info
where
info = noCafNoTyGenIdInfo `setUnfoldingInfo`
mkCompulsoryUnfolding (Lit nullAddrLit)
seqId
- = pcMiscPrelId seqIdKey pREL_GHC SLIT("seq") ty info
+ = pcMiscPrelId seqIdKey gHC_PRIM FSLIT("seq") ty info
where
info = noCafNoTyGenIdInfo `setUnfoldingInfo` mkCompulsoryUnfolding rhs
\begin{code}
getTagId
- = pcMiscPrelId getTagIdKey pREL_GHC SLIT("getTag#") ty info
+ = pcMiscPrelId getTagIdKey gHC_PRIM FSLIT("getTag#") ty info
where
info = noCafNoTyGenIdInfo `setUnfoldingInfo` mkCompulsoryUnfolding rhs
-- We don't provide a defn for this; you must inline it
@realWorld#@ used to be a magic literal, \tr{void#}. If things get
nasty as-is, change it back to a literal (@Literal@).
+voidArgId is a Local Id used simply as an argument in functions
+where we just want an arg to avoid having a thunk of unlifted type.
+E.g.
+ x = \ void :: State# RealWorld -> (# p, q #)
+
+This comes up in strictness analysis
+
\begin{code}
realWorldPrimId -- :: State# RealWorld
- = pcMiscPrelId realWorldPrimIdKey pREL_GHC SLIT("realWorld#")
+ = pcMiscPrelId realWorldPrimIdKey gHC_PRIM FSLIT("realWorld#")
realWorldStatePrimTy
(noCafNoTyGenIdInfo `setUnfoldingInfo` mkOtherCon [])
-- The mkOtherCon makes it look that realWorld# is evaluated
-- which in turn makes Simplify.interestingArg return True,
-- which in turn makes INLINE things applied to realWorld# likely
-- to be inlined
+
+voidArgId -- :: State# RealWorld
+ = mkSysLocal FSLIT("void") voidArgIdKey realWorldStatePrimTy
\end{code}
\begin{code}
eRROR_ID
- = pc_bottoming_Id errorIdKey pREL_ERR SLIT("error") errorTy
+ = pc_bottoming_Id errorIdKey pREL_ERR FSLIT("error") errorTy
eRROR_CSTRING_ID
- = pc_bottoming_Id errorCStringIdKey pREL_ERR SLIT("errorCString")
+ = pc_bottoming_Id errorCStringIdKey pREL_ERR FSLIT("errorCString")
(mkSigmaTy [openAlphaTyVar] [] (mkFunTy addrPrimTy openAlphaTy))
pAT_ERROR_ID
- = generic_ERROR_ID patErrorIdKey SLIT("patError")
+ = generic_ERROR_ID patErrorIdKey FSLIT("patError")
rEC_SEL_ERROR_ID
- = generic_ERROR_ID recSelErrIdKey SLIT("recSelError")
+ = generic_ERROR_ID recSelErrIdKey FSLIT("recSelError")
rEC_CON_ERROR_ID
- = generic_ERROR_ID recConErrorIdKey SLIT("recConError")
+ = generic_ERROR_ID recConErrorIdKey FSLIT("recConError")
rEC_UPD_ERROR_ID
- = generic_ERROR_ID recUpdErrorIdKey SLIT("recUpdError")
+ = generic_ERROR_ID recUpdErrorIdKey FSLIT("recUpdError")
iRREFUT_PAT_ERROR_ID
- = generic_ERROR_ID irrefutPatErrorIdKey SLIT("irrefutPatError")
+ = generic_ERROR_ID irrefutPatErrorIdKey FSLIT("irrefutPatError")
nON_EXHAUSTIVE_GUARDS_ERROR_ID
- = generic_ERROR_ID nonExhaustiveGuardsErrorIdKey SLIT("nonExhaustiveGuardsError")
+ = generic_ERROR_ID nonExhaustiveGuardsErrorIdKey FSLIT("nonExhaustiveGuardsError")
nO_METHOD_BINDING_ERROR_ID
- = generic_ERROR_ID noMethodBindingErrorIdKey SLIT("noMethodBindingError")
+ = generic_ERROR_ID noMethodBindingErrorIdKey FSLIT("noMethodBindingError")
aBSENT_ERROR_ID
- = pc_bottoming_Id absentErrorIdKey pREL_ERR SLIT("absentErr")
+ = pc_bottoming_Id absentErrorIdKey pREL_ERR FSLIT("absentErr")
(mkSigmaTy [openAlphaTyVar] [] openAlphaTy)
pAR_ERROR_ID
- = pcMiscPrelId parErrorIdKey pREL_ERR SLIT("parError")
+ = pcMiscPrelId parErrorIdKey pREL_ERR FSLIT("parError")
(mkSigmaTy [openAlphaTyVar] [] openAlphaTy) noCafNoTyGenIdInfo
\end{code}
= pcMiscPrelId key mod name ty bottoming_info
where
strict_sig = mkStrictSig (mkTopDmdType [evalDmd] BotRes)
- bottoming_info = noCafNoTyGenIdInfo `setNewStrictnessInfo` Just strict_sig
+ bottoming_info = noCafNoTyGenIdInfo `setAllStrictnessInfo` Just strict_sig
-- these "bottom" out, no matter what their arguments
generic_ERROR_ID u n = pc_bottoming_Id u pREL_ERR n errorTy