X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Fcompiler%2FbasicTypes%2FMkId.lhs;h=cbbe8ec489c5d8d7ed8a2e9e4516709b53aa4788;hb=f714e6b642fd614a9971717045ae47c3d871275e;hp=0d5bcec0148a1ed2b3d246288ff7dbbb0eac0d3d;hpb=83a812bf720eb9d6662f32d2c25a283614d82c45;p=ghc-hetmet.git diff --git a/ghc/compiler/basicTypes/MkId.lhs b/ghc/compiler/basicTypes/MkId.lhs index 0d5bcec..cbbe8ec 100644 --- a/ghc/compiler/basicTypes/MkId.lhs +++ b/ghc/compiler/basicTypes/MkId.lhs @@ -14,18 +14,23 @@ have a standard form, namely: \begin{code} module MkId ( mkDictFunId, mkDefaultMethodId, - mkDictSelId, + mkDictSelId, - mkDataConId, mkDataConWrapId, - mkRecordSelId, rebuildConArgs, + mkDataConIds, + mkRecordSelId, mkPrimOpId, mkFCallId, + mkReboxingAlt, mkNewTypeBody, + -- And some particular Ids; see below for why they are wired in - wiredInIds, - unsafeCoerceId, realWorldPrimId, - 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, seqId, + lazyId, lazyIdUnfolding, lazyIdKey, + + 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, eRROR_ID ) where #include "HsVersions.h" @@ -33,63 +38,64 @@ module MkId ( import BasicTypes ( Arity, StrictnessMark(..), isMarkedUnboxed, isMarkedStrict ) import TysPrim ( openAlphaTyVars, alphaTyVar, alphaTy, - intPrimTy, realWorldStatePrimTy, addrPrimTy + realWorldStatePrimTy, addrPrimTy ) import TysWiredIn ( charTy, mkListTy ) -import PrelRules ( primOpRule ) +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, mkInlineMe ) +import CoreUtils ( exprType ) import CoreUnfold ( mkTopUnfolding, mkCompulsoryUnfolding, mkOtherCon ) -import Literal ( Literal(..) ) +import Literal ( Literal(..), nullAddrLit ) import TyCon ( TyCon, isNewTyCon, tyConTyVars, tyConDataCons, tyConTheta, isProductTyCon, isDataTyCon, isRecursiveTyCon ) import Class ( Class, classTyCon, classTyVars, classSelIds ) -import Var ( Id, TyVar ) +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 ) +import OccName ( mkOccFS, varName ) +import PrimOp ( PrimOp, primOpSig, primOpOcc, primOpTag ) import ForeignCall ( ForeignCall ) -import DataCon ( DataCon, - dataConFieldLabels, dataConRepArity, dataConTyCon, - dataConArgTys, dataConRepType, dataConRepStrictness, - dataConInstOrigArgTys, - dataConName, dataConTheta, - dataConSig, dataConStrictMarks, dataConId, +import DataCon ( DataCon, DataConIds(..), + dataConFieldLabels, dataConRepArity, + dataConArgTys, dataConRepType, + 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, noCafNoTyGenIdInfo, - exactArity, setUnfoldingInfo, setCprInfo, - setArityInfo, setSpecInfo, setCgInfo, - mkNewStrictnessInfo, setNewStrictnessInfo, - GlobalIdDetails(..), CafInfo(..), CprInfo(..), - CgInfo(..), setCgArity +import IdInfo ( IdInfo, noCafIdInfo, setUnfoldingInfo, + setArityInfo, setSpecInfo, setCafInfo, + setAllStrictnessInfo, vanillaIdInfo, + GlobalIdDetails(..), CafInfo(..) ) -import NewDemand ( mkStrictSig, strictSigResInfo, DmdResult(..), - mkTopDmdType, topDmd, evalDmd ) -import FieldLabel ( mkFieldLabel, fieldLabelName, - firstFieldLabelTag, allFieldLabelTags, fieldLabelType +import NewDemand ( mkStrictSig, DmdResult(..), + mkTopDmdType, topDmd, evalDmd, lazyDmd, retCPR, + Demand(..), Demands(..) ) +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 ) +import Util ( dropList, isSingleton ) import Outputable +import FastString import ListSetOps ( assoc, assocMaybe ) import UnicodeUtil ( stringToUtf8 ) -import Char ( ord ) +import List ( nubBy ) \end{code} %************************************************************************ @@ -106,24 +112,33 @@ wiredInIds -- -- [The interface file format now carry such information, but there's -- no way yet of expressing at the definition site for these - -- 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 three can't be defined in Haskell - , realWorldPrimId - , unsafeCoerceId - , getTagId + -- error-reporting functions that they have an 'open' + -- result type. -- sof 1/99] + + eRROR_ID, -- This one isn't used anywhere else in the compiler + -- But we still need it in wiredInIds so that when GHC + -- compiles a program that mentions 'error' we don't + -- import its type from the interface file; we just get + -- the Id defined here. Which has an 'open-tyvar' type. + + rUNTIME_ERROR_ID, + iRREFUT_PAT_ERROR_ID, + nON_EXHAUSTIVE_GUARDS_ERROR_ID, + nO_METHOD_BINDING_ERROR_ID, + pAT_ERROR_ID, + rEC_CON_ERROR_ID, + + lazyId + ] ++ 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, + seqId ] \end{code} @@ -133,43 +148,6 @@ wiredInIds %* * %************************************************************************ -\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 - = id - where - id = mkGlobalId (DataConId data_con) work_name (dataConRepType data_con) info - info = noCafNoTyGenIdInfo - `setCgArity` arity - `setArityInfo` arity - `setNewStrictnessInfo` Just strict_sig - - arity = dataConRepArity data_con - strict_sig = mkStrictSig id arity (mkTopDmdType (dataConRepStrictness data_con) cpr_info) - - 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. @@ -207,87 +185,118 @@ 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 - = wrap_id - where - wrap_id = mkGlobalId (DataConWrapId data_con) (dataConName data_con) wrap_ty info - work_id = dataConId data_con - - info = noCafNoTyGenIdInfo - `setUnfoldingInfo` mkTopUnfolding (mkInlineMe wrap_rhs) - `setCgArity` arity - -- The NoCaf-ness is set by noCafNoTyGenIdInfo - `setArityInfo` arity - -- It's important to specify the arity, so that partial - -- applications are treated as values - `setNewStrictnessInfo` Just wrap_sig - - wrap_ty = mkForAllTys all_tyvars $ - mkFunTys all_arg_tys - result_ty - - res_info = strictSigResInfo (idNewStrictness work_id) - wrap_sig = mkStrictSig wrap_id arity (mkTopDmdType (replicate arity topDmd) res_info) - -- The Cpr info can be important inside INLINE rhss, where the - -- wrapper constructor isn't inlined - -- But we are sloppy about the argument demands, because we expect - -- to inline the constructor very vigorously. - - wrap_rhs | isNewTyCon tycon - = ASSERT( null ex_tyvars && null ex_dict_args && length orig_arg_tys == 1 ) - -- No existentials on a newtype, but it can have a context - -- e.g. newtype Eq a => T a = MkT (...) - mkLams tyvars $ mkLams dict_args $ Lam id_arg1 $ - mkNewTypeBody tycon result_ty id_arg1 - - | null dict_args && not (any isMarkedStrict strict_marks) - = 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), and thence into (map (\x xs. $w: x xs) ys) - -- in core-to-stg. 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 - = mkLams all_tyvars $ mkLams dict_args $ - 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)) +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 - (tyvars, theta, ex_tyvars, ex_theta, orig_arg_tys, tycon) = dataConSig data_con - all_tyvars = tyvars ++ ex_tyvars + | any isMarkedStrict all_strict_marks -- Algebraic, needs wrapper + = AlgDC (Just alg_wrap_id) wrk_id + + | otherwise -- Algebraic, no wrapper + = AlgDC Nothing wrk_id + where + (tyvars, _, ex_tyvars, ex_theta, orig_arg_tys, tycon) = dataConSig data_con + all_tyvars = tyvars ++ ex_tyvars - dict_tys = mkPredTys theta ex_dict_tys = mkPredTys ex_theta - all_arg_tys = dict_tys ++ ex_dict_tys ++ orig_arg_tys + all_arg_tys = ex_dict_tys ++ orig_arg_tys result_ty = mkTyConApp tycon (mkTyVarTys tyvars) - mkLocals i tys = (zipWith mkTemplateLocal [i..i+n-1] tys, i+n) - where - n = length tys + 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. - (dict_args, i1) = mkLocals 1 dict_tys - (ex_dict_args,i2) = mkLocals i1 ex_dict_tys - (id_args,i3) = mkLocals i2 orig_arg_tys - arity = i3-1 - (id_arg1:_) = id_args -- Used for newtype only + 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 - strict_marks = dataConStrictMarks data_con + ----------- 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 + -- wrapper constructor isn't inlined. + -- And the argument strictness can be important too; we + -- may not inline a contructor when it is partially applied. + -- For example: + -- data W = C !Int !Int !Int + -- ...(let w = C x in ...(w p q)...)... + -- we want to see that w is strict in its two arguments + + 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 [] + + 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 + alg_arity = i3-1 mk_case :: (Id, StrictnessMark) -- Arg, strictness @@ -310,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} @@ -350,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 unpack_id unpackUtf8_id +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 @@ -373,13 +394,22 @@ mkRecordSelId tycon field_label unpack_id unpackUtf8_id data_ty = mkTyConApp tycon tyvar_tys tyvar_tys = mkTyVarTys tyvars - tycon_theta = tyConTheta tycon -- The context on the data decl + -- Very tiresomely, the selectors are (unnecessarily!) overloaded over + -- just the dictionaries in the types of the constructors that contain + -- the relevant field. [The Report says that pattern matching on a + -- constructor gives the same constraints as applying it.] Urgh. + -- + -- However, not all data cons have all constraints (because of + -- TcTyDecls.thinContext). So we need to find all the data cons + -- involved in the pattern match and take the union of their constraints. + -- + -- NB: this code relies on the fact that DataCons are quantified over + -- the identical type variables as their parent TyCon + tycon_theta = tyConTheta tycon -- The context on the data decl -- eg data (Eq a, Ord b) => T a b = ... - dict_tys = [mkPredTy pred | pred <- tycon_theta, - needed_dict pred] - needed_dict pred = or [ tcEqPred pred p - | (DataAlt dc, _, _) <- the_alts, p <- dataConTheta dc] - n_dict_tys = length dict_tys + needed_preds = [pred | (DataAlt dc, _, _) <- the_alts, pred <- dataConTheta dc] + dict_tys = map mkPredTy (nubBy tcEqPred needed_preds) + n_dict_tys = length dict_tys (field_tyvars,field_theta,field_tau) = tcSplitSigmaTy field_ty field_dict_tys = map mkPredTy field_theta @@ -399,25 +429,22 @@ mkRecordSelId tycon field_label unpack_id unpackUtf8_id -- Note that this is exactly the type we'd infer from a user defn -- op (R op) = op - -- Very tiresomely, the selectors are (unnecessarily!) overloaded over - -- just the dictionaries in the types of the constructors that contain - -- the relevant field. Urgh. - -- NB: this code relies on the fact that DataCons are quantified over - -- the identical type variables as their parent TyCon - selector_ty :: Type selector_ty = mkForAllTys tyvars $ mkForAllTys field_tyvars $ mkFunTys dict_tys $ mkFunTys field_dict_tys $ mkFunTy data_ty field_tau arity = 1 + n_dict_tys + n_field_dict_tys - info = noCafNoTyGenIdInfo - `setCgInfo` (CgInfo arity caf_info) - `setArityInfo` arity - `setUnfoldingInfo` unfolding - -- ToDo: consider adding further IdInfo - unfolding = mkTopUnfolding sel_rhs + (strict_sig, rhs_w_str) = dmdAnalTopRhs sel_rhs + -- Use the demand analyser to work out strictness. + -- With all this unpackery it's not easy! + + info = noCafIdInfo + `setCafInfo` caf_info + `setArityInfo` arity + `setUnfoldingInfo` mkTopUnfolding rhs_w_str + `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 @@ -438,7 +465,7 @@ mkRecordSelId tycon field_label unpack_id unpackUtf8_id default_alt | no_default = [] | otherwise = [(DEFAULT, [], error_expr)] - -- the default branch may have CAF refs, because it calls recSelError etc. + -- The default branch may have CAF refs, because it calls recSelError etc. caf_info | no_default = NoCafRefs | otherwise = MayHaveCafRefs @@ -446,81 +473,96 @@ mkRecordSelId tycon field_label unpack_id unpackUtf8_id mkLams dict_ids $ mkLams field_dict_ids $ Lam data_id $ sel_body - sel_body | isNewTyCon tycon = mkNewTypeBody tycon field_tau 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 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 } + -- + -- foo :: forall a. T -> a -> a + -- foo = /\a. \t:T. case t of { MkT f -> f a } + mk_maybe_alt data_con - = case maybe_the_arg_id of + = case maybe_the_arg_id of Nothing -> Nothing - Just the_arg_id -> Just (DataAlt data_con, real_args, mkLets binds body) - where - body = mkVarApps (mkVarApps (Var the_arg_id) field_tyvars) field_dict_ids - strict_marks = dataConStrictMarks data_con - (binds, real_args) = rebuildConArgs arg_ids strict_marks - (map mkBuiltinUnique [unpack_base..]) + Just the_arg_id -> Just (mkReboxingAlt uniqs data_con arg_ids body) + where + body = mk_result (Var the_arg_id) where - arg_ids = mkTemplateLocalsNum field_base (dataConInstOrigArgTys data_con tyvar_tys) + 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..] -- arity+1 avoids all shadowing maybe_the_arg_id = assocMaybe (field_lbls `zip` arg_ids) field_label field_lbls = dataConFieldLabels data_con - error_expr = mkApps (Var rEC_SEL_ERROR_ID) [Type field_tau, err_string] - err_string - | all safeChar full_msg - = App (Var unpack_id) (Lit (MachStr (_PK_ full_msg))) - | otherwise - = App (Var unpackUtf8_id) (Lit (MachStr (_PK_ (stringToUtf8 (map ord full_msg))))) - where - safeChar c = c >= '\1' && c <= '\xFF' - -- TODO: Putting this Unicode stuff here is ugly. Find a better - -- generic place to make string literals. This logic is repeated - -- in DsUtils. + error_expr = mkRuntimeErrorApp rEC_SEL_ERROR_ID field_tau full_msg full_msg = showSDoc (sep [text "No match in record selector", ppr sel_id]) --- This rather ugly function converts the unpacked data con --- arguments back into their packed form. - -rebuildConArgs - :: [Id] -- Source-level args - -> [StrictnessMark] -- Strictness annotations (per-arg) - -> [Unique] -- Uniques for the new Ids - -> ([CoreBind], [Id]) -- A binding for each source-level arg, plus - -- a list of the representation-level arguments --- e.g. data T = MkT Int !Int +-- (mkReboxingAlt us con xs rhs) basically constructs the case +-- alternative (con, xs, rhs) +-- but it does the reboxing necessary to construct the *source* +-- arguments, xs, from the representation arguments ys. +-- For example: +-- data T = MkT !(Int,Int) Bool -- --- rebuild [x::Int, y::Int] [Not, Unbox] --- = ([ y = I# t ], [x,t]) +-- mkReboxingAlt MkT [x,b] r +-- = (DataAlt MkT, [y::Int,z::Int,b], let x = (y,z) in r) +-- +-- mkDataAlt should really be in DataCon, but it can't because +-- it manipulates CoreSyn. -rebuildConArgs [] stricts us = ([], []) +mkReboxingAlt + :: [Unique] -- Uniques for the new Ids + -> DataCon + -> [Var] -- Source-level args + -> CoreExpr -- RHS + -> CoreAlt --- Type variable case -rebuildConArgs (arg:args) stricts us - | isTyVar arg - = let (binds, args') = rebuildConArgs args stricts us - in (binds, arg:args') +mkReboxingAlt us con args rhs + | not (any isMarkedUnboxed stricts) + = (DataAlt con, args, rhs) --- Term variable case -rebuildConArgs (arg:args) (str:stricts) us - | isMarkedUnboxed str + | otherwise = let - arg_ty = idType arg - - (_, tycon_args, pack_con, con_arg_tys) - = splitProductType "rebuildConArgs" arg_ty - - unpacked_args = zipWith (mkSysLocal SLIT("rb")) us con_arg_tys - (binds, args') = rebuildConArgs args stricts (drop (length con_arg_tys) us) - con_app = mkConApp pack_con (map Type tycon_args ++ map Var unpacked_args) + (binds, args') = go args stricts us in - (NonRec arg con_app : binds, unpacked_args ++ args') + (DataAlt con, args', mkLets binds rhs) - | otherwise - = let (binds, args') = rebuildConArgs args stricts us - in (binds, arg:args') + where + stricts = dataConExStricts con ++ dataConStrictMarks con + + go [] stricts us = ([], []) + + -- Type variable case + go (arg:args) stricts us + | isTyVar arg + = let (binds, args') = go args stricts us + in (binds, arg:args') + + -- Term variable case + go (arg:args) (str:stricts) us + | isMarkedUnboxed str + = let + (_, tycon_args, pack_con, con_arg_tys) + = splitProductType "mkReboxingAlt" (idType arg) + + unpacked_args = zipWith (mkSysLocal FSLIT("rb")) us con_arg_tys + (binds, args') = go args stricts (dropList con_arg_tys us) + con_app = mkConApp pack_con (map Type tycon_args ++ map Var unpacked_args) + in + (NonRec arg con_app : binds, unpacked_args ++ args') + + | otherwise + = let (binds, args') = go args stricts us + in (binds, arg:args') \end{code} @@ -533,12 +575,25 @@ rebuildConArgs (arg:args) (str:stricts) us 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 @@ -547,18 +602,24 @@ 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 + `setArityInfo` 1 + `setUnfoldingInfo` mkTopUnfolding rhs + `setAllStrictnessInfo` Just strict_sig - info = noCafNoTyGenIdInfo - `setCgArity` 1 - `setArityInfo` 1 - `setUnfoldingInfo` unfolding - -- We no longer use 'must-inline' on record selectors. They'll -- inline like crazy if they scrutinise a constructor - unfolding = mkTopUnfolding rhs + -- The strictness signature is of the form U(AAAVAAAA) -> T + -- where the V depends on which item we are selecting + -- 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 = evalDmd + | otherwise = Eval (Prod [ if the_arg_id == id then evalDmd else Abs + | id <- arg_ids ]) tyvars = classTyVars clas @@ -572,16 +633,18 @@ mkDictSelId name clas (dict_id:arg_ids) = mkTemplateLocals (mkPredTy pred : arg_tys) rhs | isNewTyCon tycon = mkLams tyvars $ Lam dict_id $ - mkNewTypeBody tycon (head arg_tys) dict_id + mkNewTypeBody tycon (head arg_tys) (Var dict_id) | otherwise = mkLams tyvars $ Lam dict_id $ Case (Var dict_id) dict_id [(DataAlt data_con, arg_ids, Var the_arg_id)] -mkNewTypeBody tycon result_ty result_id +mkNewTypeBody tycon result_ty result_expr + -- Adds a coerce where necessary + -- Used for both wrapping and unwrapping | isRecursiveTyCon tycon -- Recursive case; use a coerce - = Note (Coerce result_ty (idType result_id)) (Var result_id) + = Note (Coerce result_ty (exprType result_expr)) result_expr | otherwise -- Normal case - = Var result_id + = result_expr \end{code} @@ -596,20 +659,19 @@ mkPrimOpId :: PrimOp -> Id 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 + name = mkWiredInName gHC_PRIM (primOpOcc prim_op) + (mkPrimOpIdUnique (primOpTag prim_op)) + Nothing (AnId id) id = mkGlobalId (PrimOpId prim_op) name ty info - info = noCafNoTyGenIdInfo + info = noCafIdInfo `setSpecInfo` rules - `setCgArity` arity `setArityInfo` arity - `setNewStrictnessInfo` Just (mkNewStrictnessInfo id arity strict_info NoCPRInfo) - -- Until we modify the primop generation code + `setAllStrictnessInfo` Just strict_sig - rules = maybe emptyCoreRules (addRule emptyCoreRules id) - (primOpRule prim_op) + rules = foldl (addRule id) emptyCoreRules (primOpRules prim_op) -- For each ccall we manufacture a separate CCallOpId, giving it @@ -626,24 +688,22 @@ mkFCallId uniq fcall ty = ASSERT( isEmptyVarSet (tyVarsOfType ty) ) -- A CCallOpId should have no free type variables; -- when doing substitutions won't substitute over it - id + mkGlobalId (FCallId fcall) name ty info where - id = mkGlobalId (FCallId fcall) name ty info - occ_str = showSDocIface (braces (ppr fcall <+> ppr ty)) + occ_str = showSDoc (braces (ppr fcall <+> ppr ty)) -- The "occurrence name" of a ccall is the full info about the -- ccall; it is encoded, but may have embedded spaces etc! name = mkFCallName uniq occ_str - info = noCafNoTyGenIdInfo - `setCgArity` arity + info = noCafIdInfo `setArityInfo` arity - `setNewStrictnessInfo` Just strict_sig + `setAllStrictnessInfo` Just strict_sig (_, tau) = tcSplitForAllTys ty (arg_tys, _) = tcSplitFunTys tau arity = length arg_tys - strict_sig = mkStrictSig id arity (mkTopDmdType (replicate arity evalDmd) TopRes) + strict_sig = mkStrictSig (mkTopDmdType (replicate arity evalDmd) TopRes) \end{code} @@ -653,19 +713,44 @@ mkFCallId uniq fcall ty %* * %************************************************************************ +Important notes about dict funs and default methods +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Dict funs and default methods are *not* ImplicitIds. Their definition +involves user-written code, so we can't figure out their strictness etc +based on fixed info, as we can for constructors and record selectors (say). + +We build them as GlobalIds, but when in the module where they are +bound, we turn the Id at the *binding site* into an exported LocalId. +This ensures that they are taken to account by free-variable finding +and dependency analysis (e.g. CoreFVs.exprFreeVars). The simplifier +will propagate the LocalId to all occurrence sites. + +Why shouldn't they be bound as GlobalIds? Because, in particular, if +they are globals, the specialiser floats dict uses above their defns, +which prevents good simplifications happening. Also the strictness +analyser treats a occurrence of a GlobalId as imported and assumes it +contains strictness in its IdInfo, which isn't true if the thing is +bound in the same module as the occurrence. + +It's OK for dfuns to be LocalIds, because we form the instance-env to +pass on to the next module (md_insts) in CoreTidy, afer tidying +and globalising the top-level Ids. + +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 noCafNoTyGenIdInfo +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 noCafNoTyGenIdInfo +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) @@ -705,7 +790,12 @@ mkDictFunId dfun_name clas inst_tyvars inst_tys dfun_theta %* * %************************************************************************ -These two can't be defined in Haskell. +These Ids can't be defined in Haskell. They could be defined in +unfoldings in the wired-in GHC.Prim interface file, but we'd have to +ensure that they were definitely, definitely inlined, because there is +no curried identifier for them. That's what mkCompulsoryUnfolding +does. If we had a way to get a compulsory unfolding from an interface +file, we could do that, but we don't right now. unsafeCoerce# isn't so much a PrimOp as a phantom identifier, that just gets expanded into a type coercion wherever it occurs. Hence we @@ -716,10 +806,34 @@ 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) + +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 pREL_GHC SLIT("unsafeCoerce#") ty info + = pcMiscPrelId unsafeCoerceName ty info where - info = noCafNoTyGenIdInfo `setUnfoldingInfo` mkCompulsoryUnfolding rhs + info = noCafIdInfo `setUnfoldingInfo` mkCompulsoryUnfolding rhs ty = mkForAllTys [openAlphaTyVar,openBetaTyVar] @@ -727,39 +841,66 @@ unsafeCoerceId [x] = mkTemplateLocals [openAlphaTy] rhs = mkLams [openAlphaTyVar,openBetaTyVar,x] $ Note (Coerce openBetaTy openAlphaTy) (Var x) -\end{code} - -@getTag#@ is another function which can't be defined in Haskell. It needs to -evaluate its argument and call the dataToTag# primitive. +-- nullAddr# :: Addr# +-- The reason is is here is because we don't provide +-- a way to write this literal in Haskell. +nullAddrId + = pcMiscPrelId nullAddrName addrPrimTy info + where + info = noCafIdInfo `setUnfoldingInfo` + mkCompulsoryUnfolding (Lit nullAddrLit) -\begin{code} -getTagId - = pcMiscPrelId getTagIdKey pREL_GHC SLIT("getTag#") ty info +seqId + = pcMiscPrelId seqName ty info where - info = noCafNoTyGenIdInfo `setUnfoldingInfo` mkCompulsoryUnfolding rhs - -- We don't provide a defn for this; you must inline it + info = noCafIdInfo `setUnfoldingInfo` mkCompulsoryUnfolding rhs + - 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]) ] + 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 +-- No unfolding: it gets "inlined" by the worker/wrapper pass +-- Also, no strictness: by being a built-in Id, it overrides all +-- the info in PrelBase.hi. This is important, because the strictness +-- analyser will spot it as strict! +lazyId + = pcMiscPrelId lazyIdName ty info + where + info = noCafIdInfo + ty = mkForAllTys [alphaTyVar] (mkFunTy alphaTy alphaTy) -dataToTagId = mkPrimOpId DataToTagOp +lazyIdUnfolding :: CoreExpr -- Used to expand LazyOp after strictness anal +lazyIdUnfolding = mkLams [openAlphaTyVar,x] (Var x) + where + [x] = mkTemplateLocals [openAlphaTy] \end{code} @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#") - realWorldStatePrimTy - (noCafNoTyGenIdInfo `setUnfoldingInfo` mkOtherCon []) + = pcMiscPrelId realWorldName realWorldStatePrimTy + (noCafIdInfo `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} @@ -785,33 +926,39 @@ not know to be a bottoming Id. It is used in the @_par_@ and @_seq_@ templates, but we don't ever expect to generate code for it. \begin{code} -eRROR_ID - = pc_bottoming_Id errorIdKey pREL_ERR SLIT("error") errorTy -eRROR_CSTRING_ID - = pc_bottoming_Id errorCStringIdKey pREL_ERR SLIT("errorCString") - (mkSigmaTy [openAlphaTyVar] [] (mkFunTy addrPrimTy openAlphaTy)) -pAT_ERROR_ID - = generic_ERROR_ID patErrorIdKey SLIT("patError") -rEC_SEL_ERROR_ID - = generic_ERROR_ID recSelErrIdKey SLIT("recSelError") -rEC_CON_ERROR_ID - = generic_ERROR_ID recConErrorIdKey SLIT("recConError") -rEC_UPD_ERROR_ID - = generic_ERROR_ID recUpdErrorIdKey SLIT("recUpdError") -iRREFUT_PAT_ERROR_ID - = generic_ERROR_ID irrefutPatErrorIdKey SLIT("irrefutPatError") -nON_EXHAUSTIVE_GUARDS_ERROR_ID - = generic_ERROR_ID nonExhaustiveGuardsErrorIdKey SLIT("nonExhaustiveGuardsError") -nO_METHOD_BINDING_ERROR_ID - = generic_ERROR_ID noMethodBindingErrorIdKey SLIT("noMethodBindingError") - -aBSENT_ERROR_ID - = pc_bottoming_Id absentErrorIdKey pREL_ERR SLIT("absentErr") - (mkSigmaTy [openAlphaTyVar] [] openAlphaTy) - -pAR_ERROR_ID - = pcMiscPrelId parErrorIdKey pREL_ERR SLIT("parError") - (mkSigmaTy [openAlphaTyVar] [] openAlphaTy) noCafNoTyGenIdInfo +mkRuntimeErrorApp + :: Id -- Should be of type (forall a. Addr# -> a) + -- where Addr# points to a UTF8 encoded string + -> Type -- The type to instantiate 'a' + -> String -- The string to print + -> CoreExpr + +mkRuntimeErrorApp err_id res_ty err_msg + = mkApps (Var err_id) [Type res_ty, err_string] + where + err_string = Lit (MachStr (mkFastString (stringToUtf8 err_msg))) + +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 name = pc_bottoming_Id name runtimeErrorTy +runtimeErrorTy = mkSigmaTy [openAlphaTyVar] [] (mkFunTy addrPrimTy openAlphaTy) +\end{code} + +\begin{code} +eRROR_ID = pc_bottoming_Id errorName errorTy + +errorTy :: Type +errorTy = mkSigmaTy [openAlphaTyVar] [] (mkFunTys [mkListTy charTy] openAlphaTy) + -- Notice the openAlphaTyVar. It says that "error" can be applied + -- to unboxed as well as boxed types. This is OK because it never + -- returns, so the return type is irrelevant. \end{code} @@ -822,39 +969,33 @@ pAR_ERROR_ID %************************************************************************ \begin{code} -pcMiscPrelId :: Unique{-IdKey-} -> Module -> FAST_STRING -> 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 - = id +pc_bottoming_Id name ty + = pcMiscPrelId name ty bottoming_info where - id = pcMiscPrelId key mod name ty bottoming_info - arity = 1 - strict_sig = mkStrictSig id arity (mkTopDmdType [evalDmd] BotRes) - bottoming_info = noCafNoTyGenIdInfo `setNewStrictnessInfo` Just strict_sig - -- these "bottom" out, no matter what their arguments - -generic_ERROR_ID u n = pc_bottoming_Id u pREL_ERR n errorTy + 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 + -- In due course we may arrange that these error-y things are + -- regarded by the GC as permanently live, in which case we + -- can give them NoCaf info. As it is, any function that calls + -- any pc_bottoming_Id will itself have CafRefs, which bloats + -- SRTs. + + strict_sig = mkStrictSig (mkTopDmdType [evalDmd] BotRes) + -- These "bottom" out, no matter what their arguments (openAlphaTyVar:openBetaTyVar:_) = openAlphaTyVars openAlphaTy = mkTyVarTy openAlphaTyVar openBetaTy = mkTyVarTy openBetaTyVar - -errorTy :: Type -errorTy = mkSigmaTy [openAlphaTyVar] [] (mkFunTys [mkListTy charTy] - openAlphaTy) - -- Notice the openAlphaTyVar. It says that "error" can be applied - -- to unboxed as well as boxed types. This is OK because it never - -- returns, so the return type is irrelevant. \end{code}