X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Fcompiler%2FbasicTypes%2FMkId.lhs;h=dcd057d205fef5525e69bee51ef2d91f17a2f0d4;hb=bb88e732b7383c10496c0f60c3bdea2c22362cc6;hp=954ada9a461ed9aec111942dc01134c2da6f7160;hpb=33ce2a14d1220bd3b9f00e8d461b8f9ef31ee411;p=ghc-hetmet.git diff --git a/ghc/compiler/basicTypes/MkId.lhs b/ghc/compiler/basicTypes/MkId.lhs index 954ada9..dcd057d 100644 --- a/ghc/compiler/basicTypes/MkId.lhs +++ b/ghc/compiler/basicTypes/MkId.lhs @@ -16,7 +16,7 @@ module MkId ( mkDictFunId, mkDefaultMethodId, mkDictSelId, - mkDataConId, mkDataConWrapId, + mkDataConIds, mkRecordSelId, mkPrimOpId, mkFCallId, @@ -30,26 +30,26 @@ module MkId ( mkRuntimeErrorApp, rEC_CON_ERROR_ID, iRREFUT_PAT_ERROR_ID, rUNTIME_ERROR_ID, nON_EXHAUSTIVE_GUARDS_ERROR_ID, nO_METHOD_BINDING_ERROR_ID, - pAT_ERROR_ID + pAT_ERROR_ID, eRROR_ID ) where #include "HsVersions.h" import BasicTypes ( Arity, StrictnessMark(..), isMarkedUnboxed, isMarkedStrict ) -import TysPrim ( openAlphaTyVars, alphaTyVar, alphaTy, betaTyVar, betaTy, - intPrimTy, realWorldStatePrimTy, addrPrimTy +import TysPrim ( openAlphaTyVars, alphaTyVar, alphaTy, + realWorldStatePrimTy, addrPrimTy ) import TysWiredIn ( charTy, mkListTy ) import PrelRules ( primOpRules ) import Rules ( addRule ) +import Type ( TyThing(..) ) import TcType ( Type, ThetaType, mkDictTy, mkPredTys, mkTyConApp, mkTyVarTys, mkClassPred, tcEqPred, mkFunTys, mkFunTy, mkSigmaTy, tcSplitSigmaTy, isUnLiftedType, mkForAllTys, mkTyVarTy, tyVarsOfType, tcSplitFunTys, tcSplitForAllTys, mkPredTy ) -import Module ( Module ) import CoreUtils ( exprType ) import CoreUnfold ( mkTopUnfolding, mkCompulsoryUnfolding, mkOtherCon ) import Literal ( Literal(..), nullAddrLit ) @@ -58,37 +58,35 @@ import TyCon ( TyCon, isNewTyCon, tyConTyVars, tyConDataCons, import Class ( Class, classTyCon, classTyVars, classSelIds ) import Var ( Id, TyVar, Var ) import VarSet ( isEmptyVarSet ) -import Name ( mkWiredInName, mkFCallName, Name ) -import OccName ( mkVarOcc ) -import PrimOp ( PrimOp(DataToTagOp), primOpSig, mkPrimOpIdName ) +import Name ( mkFCallName, mkWiredInName, Name, BuiltInSyntax(..) ) +import OccName ( mkOccFS, varName ) +import PrimOp ( PrimOp, primOpSig, primOpOcc, primOpTag ) import ForeignCall ( ForeignCall ) -import DataCon ( DataCon, - dataConFieldLabels, dataConRepArity, dataConTyCon, +import DataCon ( DataCon, DataConIds(..), + dataConFieldLabels, dataConRepArity, dataConArgTys, dataConRepType, - dataConOrigArgTys, - dataConName, dataConTheta, - dataConSig, dataConStrictMarks, dataConWorkId, + dataConOrigArgTys, dataConTheta, + dataConSig, dataConStrictMarks, dataConExStricts, splitProductType ) -import Id ( idType, mkGlobalId, mkVanillaGlobal, mkSysLocal, - mkTemplateLocals, mkTemplateLocalsNum, - mkTemplateLocal, idNewStrictness, idName +import Id ( idType, mkGlobalId, mkVanillaGlobal, mkSysLocal, + mkTemplateLocals, mkTemplateLocalsNum, mkExportedLocalId, + mkTemplateLocal, idName ) -import IdInfo ( IdInfo, noCafIdInfo, hasCafIdInfo, - setUnfoldingInfo, +import IdInfo ( IdInfo, noCafIdInfo, setUnfoldingInfo, setArityInfo, setSpecInfo, setCafInfo, - setAllStrictnessInfo, + setAllStrictnessInfo, vanillaIdInfo, GlobalIdDetails(..), CafInfo(..) ) -import NewDemand ( mkStrictSig, strictSigResInfo, DmdResult(..), +import NewDemand ( mkStrictSig, DmdResult(..), mkTopDmdType, topDmd, evalDmd, lazyDmd, retCPR, Demand(..), Demands(..) ) -import FieldLabel ( mkFieldLabel, fieldLabelName, - firstFieldLabelTag, allFieldLabelTags, fieldLabelType +import FieldLabel ( fieldLabelName, firstFieldLabelTag, + allFieldLabelTags, fieldLabelType ) import DmdAnal ( dmdAnalTopRhs ) import CoreSyn -import Unique ( mkBuiltinUnique ) +import Unique ( mkBuiltinUnique, mkPrimOpIdUnique ) import Maybes import PrelNames import Maybe ( isJust ) @@ -98,7 +96,6 @@ import FastString import ListSetOps ( assoc, assocMaybe ) import UnicodeUtil ( stringToUtf8 ) import List ( nubBy ) -import Char ( ord ) \end{code} %************************************************************************ @@ -141,7 +138,6 @@ ghcPrimIds realWorldPrimId, unsafeCoerceId, nullAddrId, - getTagId, seqId ] \end{code} @@ -152,57 +148,6 @@ ghcPrimIds %* * %************************************************************************ -\begin{code} -mkDataConId :: Name -> DataCon -> Id - -- Makes the *worker* for the data constructor; that is, the function - -- that takes the reprsentation arguments and builds the constructor. -mkDataConId work_name data_con - = mkGlobalId (DataConId data_con) work_name (dataConRepType data_con) info - where - info = noCafIdInfo - `setArityInfo` arity - `setAllStrictnessInfo` Just strict_sig - - arity = dataConRepArity data_con - - strict_sig = mkStrictSig (mkTopDmdType (replicate arity topDmd) cpr_info) - -- Notice that we do *not* say the worker is strict - -- even if the data constructor is declared strict - -- e.g. data T = MkT !(Int,Int) - -- Why? Because the *wrapper* is strict (and its unfolding has case - -- expresssions that do the evals) but the *worker* itself is not. - -- If we pretend it is strict then when we see - -- case x of y -> $wMkT y - -- the simplifier thinks that y is "sure to be evaluated" (because - -- $wMkT is strict) and drops the case. No, $wMkT is not strict. - -- - -- When the simplifer sees a pattern - -- case e of MkT x -> ... - -- it uses the dataConRepStrictness of MkT to mark x as evaluated; - -- but that's fine... dataConRepStrictness comes from the data con - -- not from the worker Id. - - tycon = dataConTyCon data_con - cpr_info | isProductTyCon tycon && - isDataTyCon tycon && - arity > 0 && - arity <= mAX_CPR_SIZE = retCPR - | otherwise = TopRes - -- RetCPR is only true for products that are real data types; - -- that is, not unboxed tuples or [non-recursive] newtypes - -mAX_CPR_SIZE :: Arity -mAX_CPR_SIZE = 10 --- We do not treat very big tuples as CPR-ish: --- a) for a start we get into trouble because there aren't --- "enough" unboxed tuple types (a tiresome restriction, --- but hard to fix), --- b) more importantly, big unboxed tuples get returned mainly --- on the stack, and are often then allocated in the heap --- by the caller. So doing CPR for them may in fact make --- things worse. -\end{code} - The wrapper for a constructor is an ordinary top-level binding that evaluates any strict args, unboxes any args that are going to be flattened, and calls the worker. @@ -240,23 +185,94 @@ Notice that Making an explicit case expression allows the simplifier to eliminate it in the (common) case where the constructor arg is already evaluated. + \begin{code} -mkDataConWrapId data_con - = mkGlobalId (DataConWrapId data_con) (dataConName data_con) wrap_ty info +mkDataConIds :: Name -> Name -> DataCon -> DataConIds + -- Makes the *worker* for the data constructor; that is, the function + -- that takes the reprsentation arguments and builds the constructor. +mkDataConIds wrap_name wkr_name data_con + | isNewTyCon tycon + = NewDC nt_wrap_id + + | any isMarkedStrict all_strict_marks -- Algebraic, needs wrapper + = AlgDC (Just alg_wrap_id) wrk_id + + | otherwise -- Algebraic, no wrapper + = AlgDC Nothing wrk_id where - work_id = dataConWorkId data_con + (tyvars, _, ex_tyvars, ex_theta, orig_arg_tys, tycon) = dataConSig data_con + all_tyvars = tyvars ++ ex_tyvars - info = noCafIdInfo - `setUnfoldingInfo` wrap_unf - -- The NoCaf-ness is set by noCafIdInfo - `setArityInfo` arity - -- It's important to specify the arity, so that partial - -- applications are treated as values - `setAllStrictnessInfo` Just wrap_sig - - wrap_sig = mkStrictSig (mkTopDmdType arg_dmds res_info) - res_info = strictSigResInfo (idNewStrictness work_id) - arg_dmds = map mk_dmd strict_marks + ex_dict_tys = mkPredTys ex_theta + all_arg_tys = ex_dict_tys ++ orig_arg_tys + result_ty = mkTyConApp tycon (mkTyVarTys tyvars) + + wrap_ty = mkForAllTys all_tyvars (mkFunTys all_arg_tys result_ty) + -- We used to include the stupid theta in the wrapper's args + -- but now we don't. Instead the type checker just injects these + -- extra constraints where necessary. + + ----------- Worker (algebraic data types only) -------------- + wrk_id = mkGlobalId (DataConWorkId data_con) wkr_name + (dataConRepType data_con) wkr_info + + wkr_arity = dataConRepArity data_con + wkr_info = noCafIdInfo + `setArityInfo` wkr_arity + `setAllStrictnessInfo` Just wkr_sig + + wkr_sig = mkStrictSig (mkTopDmdType (replicate wkr_arity topDmd) cpr_info) + -- Notice that we do *not* say the worker is strict + -- even if the data constructor is declared strict + -- e.g. data T = MkT !(Int,Int) + -- Why? Because the *wrapper* is strict (and its unfolding has case + -- expresssions that do the evals) but the *worker* itself is not. + -- If we pretend it is strict then when we see + -- case x of y -> $wMkT y + -- the simplifier thinks that y is "sure to be evaluated" (because + -- $wMkT is strict) and drops the case. No, $wMkT is not strict. + -- + -- When the simplifer sees a pattern + -- case e of MkT x -> ... + -- it uses the dataConRepStrictness of MkT to mark x as evaluated; + -- but that's fine... dataConRepStrictness comes from the data con + -- not from the worker Id. + + cpr_info | isProductTyCon tycon && + isDataTyCon tycon && + wkr_arity > 0 && + wkr_arity <= mAX_CPR_SIZE = retCPR + | otherwise = TopRes + -- RetCPR is only true for products that are real data types; + -- that is, not unboxed tuples or [non-recursive] newtypes + + ----------- Wrappers for newtypes -------------- + nt_wrap_id = mkGlobalId (DataConWrapId data_con) wrap_name wrap_ty nt_wrap_info + nt_wrap_info = noCafIdInfo -- The NoCaf-ness is set by noCafIdInfo + `setArityInfo` 1 -- Arity 1 + `setUnfoldingInfo` newtype_unf + newtype_unf = ASSERT( null ex_tyvars && null ex_theta && + isSingleton orig_arg_tys ) + -- No existentials on a newtype, but it can have a context + -- e.g. newtype Eq a => T a = MkT (...) + mkTopUnfolding $ Note InlineMe $ + mkLams tyvars $ Lam id_arg1 $ + mkNewTypeBody tycon result_ty (Var id_arg1) + + id_arg1 = mkTemplateLocal 1 (head orig_arg_tys) + + ----------- Wrappers for algebraic data types -------------- + alg_wrap_id = mkGlobalId (DataConWrapId data_con) wrap_name wrap_ty alg_wrap_info + alg_wrap_info = noCafIdInfo -- The NoCaf-ness is set by noCafIdInfo + `setArityInfo` alg_arity + -- It's important to specify the arity, so that partial + -- applications are treated as values + `setUnfoldingInfo` alg_unf + `setAllStrictnessInfo` Just wrap_sig + + all_strict_marks = dataConExStricts data_con ++ dataConStrictMarks data_con + wrap_sig = mkStrictSig (mkTopDmdType arg_dmds cpr_info) + arg_dmds = map mk_dmd all_strict_marks mk_dmd str | isMarkedStrict str = evalDmd | otherwise = lazyDmd -- The Cpr info can be important inside INLINE rhss, where the @@ -268,65 +284,19 @@ mkDataConWrapId data_con -- ...(let w = C x in ...(w p q)...)... -- we want to see that w is strict in its two arguments - wrap_unf | isNewTyCon tycon - = ASSERT( null ex_tyvars && null ex_dict_args && isSingleton orig_arg_tys ) - -- No existentials on a newtype, but it can have a context - -- e.g. newtype Eq a => T a = MkT (...) - mkTopUnfolding $ Note InlineMe $ - mkLams tyvars $ Lam id_arg1 $ - mkNewTypeBody tycon result_ty (Var id_arg1) - - | not (any isMarkedStrict strict_marks) - = mkCompulsoryUnfolding (Var work_id) - -- The common case. Not only is this efficient, - -- but it also ensures that the wrapper is replaced - -- by the worker even when there are no args. - -- f (:) x - -- becomes - -- f $w: x - -- This is really important in rule matching, - -- (We could match on the wrappers, - -- but that makes it less likely that rules will match - -- when we bring bits of unfoldings together.) - -- - -- NB: because of this special case, (map (:) ys) turns into - -- (map $w: ys). The top-level defn for (:) is never used. - -- This is somewhat of a bore, but I'm currently leaving it - -- as is, so that there still is a top level curried (:) for - -- the interpreter to call. - - | otherwise - = mkTopUnfolding $ Note InlineMe $ - mkLams all_tyvars $ - mkLams ex_dict_args $ mkLams id_args $ - foldr mk_case con_app - (zip (ex_dict_args++id_args) strict_marks) i3 [] - - con_app i rep_ids = mkApps (Var work_id) - (map varToCoreExpr (all_tyvars ++ reverse rep_ids)) - - (tyvars, _, ex_tyvars, ex_theta, orig_arg_tys, tycon) = dataConSig data_con - all_tyvars = tyvars ++ ex_tyvars + alg_unf = mkTopUnfolding $ Note InlineMe $ + mkLams all_tyvars $ + mkLams ex_dict_args $ mkLams id_args $ + foldr mk_case con_app + (zip (ex_dict_args ++ id_args) all_strict_marks) + i3 [] - ex_dict_tys = mkPredTys ex_theta - all_arg_tys = ex_dict_tys ++ orig_arg_tys - result_ty = mkTyConApp tycon (mkTyVarTys tyvars) - - wrap_ty = mkForAllTys all_tyvars (mkFunTys all_arg_tys result_ty) - -- We used to include the stupid theta in the wrapper's args - -- but now we don't. Instead the type checker just injects these - -- extra constraints where necessary. - - mkLocals i tys = (zipWith mkTemplateLocal [i..i+n-1] tys, i+n) - where - n = length tys + con_app i rep_ids = mkApps (Var wrk_id) + (map varToCoreExpr (all_tyvars ++ reverse rep_ids)) (ex_dict_args,i2) = mkLocals 1 ex_dict_tys (id_args,i3) = mkLocals i2 orig_arg_tys - arity = i3-1 - (id_arg1:_) = id_args -- Used for newtype only - - strict_marks = dataConStrictMarks data_con + alg_arity = i3-1 mk_case :: (Id, StrictnessMark) -- Arg, strictness @@ -349,6 +319,21 @@ mkDataConWrapId data_con body i' (reverse con_args ++ rep_args))] where (con_args, i') = mkLocals i tys + +mAX_CPR_SIZE :: Arity +mAX_CPR_SIZE = 10 +-- We do not treat very big tuples as CPR-ish: +-- a) for a start we get into trouble because there aren't +-- "enough" unboxed tuple types (a tiresome restriction, +-- but hard to fix), +-- b) more importantly, big unboxed tuples get returned mainly +-- on the stack, and are often then allocated in the heap +-- by the caller. So doing CPR for them may in fact make +-- things worse. + +mkLocals i tys = (zipWith mkTemplateLocal [i..i+n-1] tys, i+n) + where + n = length tys \end{code} @@ -389,19 +374,16 @@ Then we want (not f :: R -> forall a. a->a, which gives the type inference mechanism problems at call sites) -Similarly for newtypes +Similarly for (recursive) newtypes newtype N = MkN { unN :: forall a. a->a } - unN :: forall a. N -> a -> a - unN = /\a -> \n:N -> coerce (a->a) n + unN :: forall b. N -> b -> b + unN = /\b -> \n:N -> (coerce (forall a. a->a) n) \begin{code} mkRecordSelId tycon field_label -- Assumes that all fields with the same field label have the same type - -- - -- Annoyingly, we have to pass in the unpackCString# Id, because - -- we can't conjure it up out of thin air = sel_id where sel_id = mkGlobalId (RecordSelId field_label) (fieldLabelName field_label) selector_ty info @@ -491,10 +473,10 @@ mkRecordSelId tycon field_label mkLams dict_ids $ mkLams field_dict_ids $ Lam data_id $ sel_body - sel_body | isNewTyCon tycon = mkNewTypeBody tycon field_tau (mk_result data_id) + sel_body | isNewTyCon tycon = mk_result (mkNewTypeBody tycon field_ty (Var data_id)) | otherwise = Case (Var data_id) data_id (default_alt ++ the_alts) - mk_result result_id = mkVarApps (mkVarApps (Var result_id) field_tyvars) field_dict_ids + mk_result poly_result = mkVarApps (mkVarApps poly_result field_tyvars) field_dict_ids -- We pull the field lambdas to the top, so we need to -- apply them in the body. For example: -- data T = MkT { foo :: forall a. a->a } @@ -507,10 +489,11 @@ mkRecordSelId tycon field_label Nothing -> Nothing Just the_arg_id -> Just (mkReboxingAlt uniqs data_con arg_ids body) where - body = mk_result the_arg_id + body = mk_result (Var the_arg_id) where arg_ids = mkTemplateLocalsNum field_base (dataConOrigArgTys data_con) -- No need to instantiate; same tyvars in datacon as tycon + -- Records can't be existential, so no existential tyvars or dicts unpack_base = field_base + length arg_ids uniqs = map mkBuiltinUnique [unpack_base..] @@ -554,7 +537,7 @@ mkReboxingAlt us con args rhs (DataAlt con, args', mkLets binds rhs) where - stricts = dataConStrictMarks con + stricts = dataConExStricts con ++ dataConStrictMarks con go [] stricts us = ([], []) @@ -592,12 +575,25 @@ mkReboxingAlt us con args rhs Selecting a field for a dictionary. If there is just one field, then there's nothing to do. -ToDo: unify with mkRecordSelId. +Dictionary selectors may get nested forall-types. Thus: + + class Foo a where + op :: forall b. Ord b => a -> b -> b + +Then the top-level type for op is + + op :: forall a. Foo a => + forall b. Ord b => + a -> b -> b + +This is unlike ordinary record selectors, which have all the for-alls +at the outside. When dealing with classes it's very convenient to +recover the original type signature from the class op selector. \begin{code} mkDictSelId :: Name -> Class -> Id mkDictSelId name clas - = mkGlobalId (RecordSelId field_lbl) name sel_ty info + = mkGlobalId (ClassOpId clas) name sel_ty info where sel_ty = mkForAllTys tyvars (mkFunTy (idType dict_id) (idType the_arg_id)) -- We can't just say (exprType rhs), because that would give a type @@ -606,10 +602,9 @@ mkDictSelId name clas -- But it's type must expose the representation of the dictionary -- to gat (say) C a -> (a -> a) - field_lbl = mkFieldLabel name tycon sel_ty tag - tag = assoc "MkId.mkDictSelId" (map idName (classSelIds clas) `zip` allFieldLabelTags) name + tag = assoc "MkId.mkDictSelId" (map idName (classSelIds clas) `zip` allFieldLabelTags) name - info = noCafIdInfo + info = noCafIdInfo `setArityInfo` 1 `setUnfoldingInfo` mkTopUnfolding rhs `setAllStrictnessInfo` Just strict_sig @@ -666,7 +661,9 @@ mkPrimOpId prim_op where (tyvars,arg_tys,res_ty, arity, strict_sig) = primOpSig prim_op ty = mkForAllTys tyvars (mkFunTys arg_tys res_ty) - name = mkPrimOpIdName prim_op + name = mkWiredInName gHC_PRIM (primOpOcc prim_op) + (mkPrimOpIdUnique (primOpTag prim_op)) + Nothing (AnId id) UserSyntax id = mkGlobalId (PrimOpId prim_op) name ty info info = noCafIdInfo @@ -743,17 +740,17 @@ BUT make sure they are *exported* LocalIds (setIdLocalExported) so that they aren't discarded by the occurrence analyser. \begin{code} -mkDefaultMethodId dm_name ty = mkVanillaGlobal dm_name ty noCafIdInfo +mkDefaultMethodId dm_name ty = mkExportedLocalId dm_name ty mkDictFunId :: Name -- Name to use for the dict fun; - -> Class -> [TyVar] - -> [Type] -> ThetaType + -> Class + -> [Type] -> Id -mkDictFunId dfun_name clas inst_tyvars inst_tys dfun_theta - = mkVanillaGlobal dfun_name dfun_ty noCafIdInfo +mkDictFunId dfun_name inst_tyvars dfun_theta clas inst_tys + = mkExportedLocalId dfun_name dfun_ty where dfun_ty = mkSigmaTy inst_tyvars dfun_theta (mkDictTy clas inst_tys) @@ -809,9 +806,32 @@ they can unify with both unlifted and lifted types. Hence we provide another gun with which to shoot yourself in the foot. \begin{code} +mkWiredInIdName mod fs uniq id + = mkWiredInName mod (mkOccFS varName fs) uniq Nothing (AnId id) UserSyntax + +unsafeCoerceName = mkWiredInIdName gHC_PRIM FSLIT("unsafeCoerce#") unsafeCoerceIdKey unsafeCoerceId +nullAddrName = mkWiredInIdName gHC_PRIM FSLIT("nullAddr#") nullAddrIdKey nullAddrId +seqName = mkWiredInIdName gHC_PRIM FSLIT("seq") seqIdKey seqId +realWorldName = mkWiredInIdName gHC_PRIM FSLIT("realWorld#") realWorldPrimIdKey realWorldPrimId +lazyIdName = mkWiredInIdName pREL_BASE FSLIT("lazy") lazyIdKey lazyId + +errorName = mkWiredInIdName pREL_ERR FSLIT("error") errorIdKey eRROR_ID +recSelErrorName = mkWiredInIdName pREL_ERR FSLIT("recSelError") recSelErrorIdKey rEC_SEL_ERROR_ID +runtimeErrorName = mkWiredInIdName pREL_ERR FSLIT("runtimeError") runtimeErrorIdKey rUNTIME_ERROR_ID +irrefutPatErrorName = mkWiredInIdName pREL_ERR FSLIT("irrefutPatError") irrefutPatErrorIdKey iRREFUT_PAT_ERROR_ID +recConErrorName = mkWiredInIdName pREL_ERR FSLIT("recConError") recConErrorIdKey rEC_CON_ERROR_ID +patErrorName = mkWiredInIdName pREL_ERR FSLIT("patError") patErrorIdKey pAT_ERROR_ID +noMethodBindingErrorName = mkWiredInIdName pREL_ERR FSLIT("noMethodBindingError") + noMethodBindingErrorIdKey nO_METHOD_BINDING_ERROR_ID +nonExhaustiveGuardsErrorName + = mkWiredInIdName pREL_ERR FSLIT("nonExhaustiveGuardsError") + nonExhaustiveGuardsErrorIdKey nON_EXHAUSTIVE_GUARDS_ERROR_ID +\end{code} + +\begin{code} -- unsafeCoerce# :: forall a b. a -> b unsafeCoerceId - = pcMiscPrelId unsafeCoerceIdKey gHC_PRIM FSLIT("unsafeCoerce#") ty info + = pcMiscPrelId unsafeCoerceName ty info where info = noCafIdInfo `setUnfoldingInfo` mkCompulsoryUnfolding rhs @@ -826,21 +846,21 @@ unsafeCoerceId -- The reason is is here is because we don't provide -- a way to write this literal in Haskell. nullAddrId - = pcMiscPrelId nullAddrIdKey gHC_PRIM FSLIT("nullAddr#") addrPrimTy info + = pcMiscPrelId nullAddrName addrPrimTy info where info = noCafIdInfo `setUnfoldingInfo` mkCompulsoryUnfolding (Lit nullAddrLit) seqId - = pcMiscPrelId seqIdKey gHC_PRIM FSLIT("seq") ty info + = pcMiscPrelId seqName ty info where info = noCafIdInfo `setUnfoldingInfo` mkCompulsoryUnfolding rhs - ty = mkForAllTys [alphaTyVar,betaTyVar] - (mkFunTy alphaTy (mkFunTy betaTy betaTy)) - [x,y] = mkTemplateLocals [alphaTy, betaTy] - rhs = mkLams [alphaTyVar,betaTyVar,x,y] (Case (Var x) x [(DEFAULT, [], Var y)]) + ty = mkForAllTys [alphaTyVar,openBetaTyVar] + (mkFunTy alphaTy (mkFunTy openBetaTy openBetaTy)) + [x,y] = mkTemplateLocals [alphaTy, openBetaTy] + rhs = mkLams [alphaTyVar,openBetaTyVar,x,y] (Case (Var x) x [(DEFAULT, [], Var y)]) -- lazy :: forall a?. a? -> a? (i.e. works for unboxed types too) -- Used to lazify pseq: pseq a b = a `seq` lazy b @@ -849,7 +869,7 @@ seqId -- the info in PrelBase.hi. This is important, because the strictness -- analyser will spot it as strict! lazyId - = pcMiscPrelId lazyIdKey pREL_BASE FSLIT("lazy") ty info + = pcMiscPrelId lazyIdName ty info where info = noCafIdInfo ty = mkForAllTys [alphaTyVar] (mkFunTy alphaTy alphaTy) @@ -860,24 +880,6 @@ lazyIdUnfolding = mkLams [openAlphaTyVar,x] (Var x) [x] = mkTemplateLocals [openAlphaTy] \end{code} -@getTag#@ is another function which can't be defined in Haskell. It needs to -evaluate its argument and call the dataToTag# primitive. - -\begin{code} -getTagId - = pcMiscPrelId getTagIdKey gHC_PRIM FSLIT("getTag#") ty info - where - info = noCafIdInfo `setUnfoldingInfo` mkCompulsoryUnfolding rhs - -- We don't provide a defn for this; you must inline it - - ty = mkForAllTys [alphaTyVar] (mkFunTy alphaTy intPrimTy) - [x,y] = mkTemplateLocals [alphaTy,alphaTy] - rhs = mkLams [alphaTyVar,x] $ - Case (Var x) y [ (DEFAULT, [], mkApps (Var dataToTagId) [Type alphaTy, Var y]) ] - -dataToTagId = mkPrimOpId DataToTagOp -\end{code} - @realWorld#@ used to be a magic literal, \tr{void#}. If things get nasty as-is, change it back to a literal (@Literal@). @@ -890,8 +892,7 @@ This comes up in strictness analysis \begin{code} realWorldPrimId -- :: State# RealWorld - = pcMiscPrelId realWorldPrimIdKey gHC_PRIM FSLIT("realWorld#") - realWorldStatePrimTy + = pcMiscPrelId realWorldName realWorldStatePrimTy (noCafIdInfo `setUnfoldingInfo` mkOtherCon []) -- The mkOtherCon makes it look that realWorld# is evaluated -- which in turn makes Simplify.interestingArg return True, @@ -937,22 +938,21 @@ mkRuntimeErrorApp err_id res_ty err_msg where err_string = Lit (MachStr (mkFastString (stringToUtf8 err_msg))) -rEC_SEL_ERROR_ID = mkRuntimeErrorId recSelErrIdKey FSLIT("recSelError") -rUNTIME_ERROR_ID = mkRuntimeErrorId runtimeErrorIdKey FSLIT("runtimeError") - -iRREFUT_PAT_ERROR_ID = mkRuntimeErrorId irrefutPatErrorIdKey FSLIT("irrefutPatError") -rEC_CON_ERROR_ID = mkRuntimeErrorId recConErrorIdKey FSLIT("recConError") -nON_EXHAUSTIVE_GUARDS_ERROR_ID = mkRuntimeErrorId nonExhaustiveGuardsErrorIdKey FSLIT("nonExhaustiveGuardsError") -pAT_ERROR_ID = mkRuntimeErrorId patErrorIdKey FSLIT("patError") -nO_METHOD_BINDING_ERROR_ID = mkRuntimeErrorId noMethodBindingErrorIdKey FSLIT("noMethodBindingError") +rEC_SEL_ERROR_ID = mkRuntimeErrorId recSelErrorName +rUNTIME_ERROR_ID = mkRuntimeErrorId runtimeErrorName +iRREFUT_PAT_ERROR_ID = mkRuntimeErrorId irrefutPatErrorName +rEC_CON_ERROR_ID = mkRuntimeErrorId recConErrorName +pAT_ERROR_ID = mkRuntimeErrorId patErrorName +nO_METHOD_BINDING_ERROR_ID = mkRuntimeErrorId noMethodBindingErrorName +nON_EXHAUSTIVE_GUARDS_ERROR_ID = mkRuntimeErrorId nonExhaustiveGuardsErrorName -- The runtime error Ids take a UTF8-encoded string as argument -mkRuntimeErrorId key name = pc_bottoming_Id key pREL_ERR name runtimeErrorTy -runtimeErrorTy = mkSigmaTy [openAlphaTyVar] [] (mkFunTy addrPrimTy openAlphaTy) +mkRuntimeErrorId name = pc_bottoming_Id name runtimeErrorTy +runtimeErrorTy = mkSigmaTy [openAlphaTyVar] [] (mkFunTy addrPrimTy openAlphaTy) \end{code} \begin{code} -eRROR_ID = pc_bottoming_Id errorIdKey pREL_ERR FSLIT("error") errorTy +eRROR_ID = pc_bottoming_Id errorName errorTy errorTy :: Type errorTy = mkSigmaTy [openAlphaTyVar] [] (mkFunTys [mkListTy charTy] openAlphaTy) @@ -969,23 +969,19 @@ errorTy = mkSigmaTy [openAlphaTyVar] [] (mkFunTys [mkListTy charTy] openAlphaTy %************************************************************************ \begin{code} -pcMiscPrelId :: Unique{-IdKey-} -> Module -> FastString -> Type -> IdInfo -> Id -pcMiscPrelId key mod str ty info - = let - name = mkWiredInName mod (mkVarOcc str) key - imp = mkVanillaGlobal name ty info -- the usual case... - in - imp +pcMiscPrelId :: Name -> Type -> IdInfo -> Id +pcMiscPrelId name ty info + = mkVanillaGlobal name ty info -- We lie and say the thing is imported; otherwise, we get into -- a mess with dependency analysis; e.g., core2stg may heave in -- random calls to GHCbase.unpackPS__. If GHCbase is the module -- being compiled, then it's just a matter of luck if the definition -- will be in "the right place" to be in scope. -pc_bottoming_Id key mod name ty - = pcMiscPrelId key mod name ty bottoming_info +pc_bottoming_Id name ty + = pcMiscPrelId name ty bottoming_info where - bottoming_info = hasCafIdInfo `setAllStrictnessInfo` Just strict_sig + bottoming_info = vanillaIdInfo `setAllStrictnessInfo` Just strict_sig -- Do *not* mark them as NoCafRefs, because they can indeed have -- CAF refs. For example, pAT_ERROR_ID calls GHC.Err.untangle, -- which has some CAFs