[project @ 2002-12-05 23:49:43 by mthomas]
[ghc-hetmet.git] / ghc / compiler / basicTypes / MkId.lhs
index adcd06b..c8b00b7 100644 (file)
@@ -25,6 +25,7 @@ module MkId (
        -- And some particular Ids; see below for why they are wired in
        wiredInIds, ghcPrimIds,
        unsafeCoerceId, realWorldPrimId, voidArgId, nullAddrId, seqId,
+       lazyId, lazyIdUnfolding, lazyIdKey,
 
        mkRuntimeErrorApp,
        rEC_CON_ERROR_ID, iRREFUT_PAT_ERROR_ID, rUNTIME_ERROR_ID,
@@ -48,7 +49,6 @@ import TcType         ( Type, ThetaType, mkDictTy, mkPredTys, mkTyConApp,
                          isUnLiftedType, mkForAllTys, mkTyVarTy, tyVarsOfType,
                          tcSplitFunTys, tcSplitForAllTys, mkPredTy
                        )
-import Module          ( Module )
 import CoreUtils       ( exprType )
 import CoreUnfold      ( mkTopUnfolding, mkCompulsoryUnfolding, mkOtherCon )
 import Literal         ( Literal(..), nullAddrLit )
@@ -57,8 +57,7 @@ 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 Name            ( mkFCallName, Name )
 import PrimOp          ( PrimOp(DataToTagOp), primOpSig, mkPrimOpIdName )
 import ForeignCall     ( ForeignCall )
 import DataCon         ( DataCon, 
@@ -73,14 +72,14 @@ import Id           ( idType, mkGlobalId, mkVanillaGlobal, mkSysLocal,
                          mkTemplateLocals, mkTemplateLocalsNum,
                          mkTemplateLocal, idNewStrictness, idName
                        )
-import IdInfo          ( IdInfo, noCafNoTyGenIdInfo,
+import IdInfo          ( IdInfo, noCafIdInfo, hasCafIdInfo,
                          setUnfoldingInfo, 
                          setArityInfo, setSpecInfo, setCafInfo,
                          setAllStrictnessInfo,
                          GlobalIdDetails(..), CafInfo(..)
                        )
 import NewDemand       ( mkStrictSig, strictSigResInfo, DmdResult(..),
-                         mkTopDmdType, topDmd, evalDmd, lazyDmd, 
+                         mkTopDmdType, topDmd, evalDmd, lazyDmd, retCPR,
                          Demand(..), Demands(..) )
 import FieldLabel      ( mkFieldLabel, fieldLabelName, 
                          firstFieldLabelTag, allFieldLabelTags, fieldLabelType
@@ -93,10 +92,10 @@ import PrelNames
 import Maybe            ( isJust )
 import Util             ( dropList, isSingleton )
 import Outputable
+import FastString
 import ListSetOps      ( assoc, assocMaybe )
 import UnicodeUtil      ( stringToUtf8 )
 import List            ( nubBy )
-import Char             ( ord )
 \end{code}             
 
 %************************************************************************
@@ -116,12 +115,20 @@ wiredInIds
        -- 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
+    rEC_CON_ERROR_ID,
+
+    lazyId
     ] ++ ghcPrimIds
 
 -- These Ids are exported from GHC.Prim
@@ -149,7 +156,7 @@ mkDataConId :: Name -> DataCon -> Id
 mkDataConId work_name data_con
   = mkGlobalId (DataConId data_con) work_name (dataConRepType data_con) info
   where
-    info = noCafNoTyGenIdInfo
+    info = noCafIdInfo
           `setArityInfo`               arity
           `setAllStrictnessInfo`       Just strict_sig
 
@@ -176,7 +183,7 @@ mkDataConId work_name data_con
     cpr_info | isProductTyCon tycon && 
               isDataTyCon tycon    &&
               arity > 0            &&
-              arity <= mAX_CPR_SIZE    = RetCPR
+              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
@@ -236,9 +243,9 @@ mkDataConWrapId data_con
   where
     work_id = dataConWorkId data_con
 
-    info = noCafNoTyGenIdInfo
+    info = noCafIdInfo
           `setUnfoldingInfo`   wrap_unf
-               -- The NoCaf-ness is set by noCafNoTyGenIdInfo
+               -- The NoCaf-ness is set by noCafIdInfo
           `setArityInfo`       arity
                -- It's important to specify the arity, so that partial
                -- applications are treated as values
@@ -379,12 +386,12 @@ 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
@@ -448,7 +455,7 @@ mkRecordSelId tycon field_label
        -- Use the demand analyser to work out strictness.
        -- With all this unpackery it's not easy!
 
-    info = noCafNoTyGenIdInfo
+    info = noCafIdInfo
           `setCafInfo`           caf_info
           `setArityInfo`         arity
           `setUnfoldingInfo`     mkTopUnfolding rhs_w_str
@@ -473,7 +480,7 @@ mkRecordSelId tycon field_label
     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
 
@@ -481,10 +488,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 }
@@ -497,7 +504,7 @@ 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
@@ -582,7 +589,22 @@ 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.
+
+ToDo: unify with mkRecordSelId?
 
 \begin{code}
 mkDictSelId :: Name -> Class -> Id
@@ -599,7 +621,7 @@ mkDictSelId name clas
     field_lbl = mkFieldLabel name tycon sel_ty tag
     tag       = assoc "MkId.mkDictSelId" (map idName (classSelIds clas) `zip` allFieldLabelTags) name
 
-    info      = noCafNoTyGenIdInfo
+    info      = noCafIdInfo
                `setArityInfo`          1
                `setUnfoldingInfo`      mkTopUnfolding rhs
                `setAllStrictnessInfo`  Just strict_sig
@@ -659,7 +681,7 @@ mkPrimOpId prim_op
     name = mkPrimOpIdName prim_op
     id   = mkGlobalId (PrimOpId prim_op) name ty info
                
-    info = noCafNoTyGenIdInfo
+    info = noCafIdInfo
           `setSpecInfo`        rules
           `setArityInfo`       arity
           `setAllStrictnessInfo` Just strict_sig
@@ -689,7 +711,7 @@ mkFCallId uniq fcall ty
 
     name = mkFCallName uniq occ_str
 
-    info = noCafNoTyGenIdInfo
+    info = noCafIdInfo
           `setArityInfo`               arity
           `setAllStrictnessInfo`       Just strict_sig
 
@@ -733,17 +755,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 noCafNoTyGenIdInfo
+mkDefaultMethodId dm_name ty = mkVanillaGlobal dm_name ty noCafIdInfo
 
 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
+  = mkVanillaGlobal dfun_name dfun_ty noCafIdInfo
   where
     dfun_ty = mkSigmaTy inst_tyvars dfun_theta (mkDictTy clas inst_tys)
 
@@ -801,9 +823,9 @@ another gun with which to shoot yourself in the foot.
 \begin{code}
 -- unsafeCoerce# :: forall a b. a -> b
 unsafeCoerceId
-  = pcMiscPrelId unsafeCoerceIdKey gHC_PRIM FSLIT("unsafeCoerce#") ty info
+  = pcMiscPrelId unsafeCoerceName ty info
   where
-    info = noCafNoTyGenIdInfo `setUnfoldingInfo` mkCompulsoryUnfolding rhs
+    info = noCafIdInfo `setUnfoldingInfo` mkCompulsoryUnfolding rhs
           
 
     ty  = mkForAllTys [openAlphaTyVar,openBetaTyVar]
@@ -816,21 +838,38 @@ 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 = noCafNoTyGenIdInfo `setUnfoldingInfo` 
+    info = noCafIdInfo `setUnfoldingInfo` 
           mkCompulsoryUnfolding (Lit nullAddrLit)
 
 seqId
-  = pcMiscPrelId seqIdKey gHC_PRIM FSLIT("seq") ty info
+  = pcMiscPrelId seqName ty info
   where
-    info = noCafNoTyGenIdInfo `setUnfoldingInfo` mkCompulsoryUnfolding rhs
+    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)])
+
+-- 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)
+
+lazyIdUnfolding :: CoreExpr    -- Used to expand LazyOp after strictness anal
+lazyIdUnfolding = mkLams [openAlphaTyVar,x] (Var x)
+               where
+                 [x] = mkTemplateLocals [openAlphaTy]
 \end{code}
 
 @getTag#@ is another function which can't be defined in Haskell.  It needs to
@@ -838,9 +877,9 @@ evaluate its argument and call the dataToTag# primitive.
 
 \begin{code}
 getTagId
-  = pcMiscPrelId getTagIdKey gHC_PRIM FSLIT("getTag#") ty info
+  = pcMiscPrelId getTagName ty info
   where
-    info = noCafNoTyGenIdInfo `setUnfoldingInfo` mkCompulsoryUnfolding rhs
+    info = noCafIdInfo `setUnfoldingInfo` mkCompulsoryUnfolding rhs
        -- We don't provide a defn for this; you must inline it
 
     ty = mkForAllTys [alphaTyVar] (mkFunTy alphaTy intPrimTy)
@@ -863,9 +902,8 @@ This comes up in strictness analysis
 
 \begin{code}
 realWorldPrimId        -- :: State# RealWorld
-  = pcMiscPrelId realWorldPrimIdKey gHC_PRIM FSLIT("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
@@ -908,20 +946,29 @@ mkRuntimeErrorApp
 mkRuntimeErrorApp err_id res_ty err_msg 
   = mkApps (Var err_id) [Type res_ty, err_string]
   where
-    err_string = Lit (MachStr (_PK_ (stringToUtf8 err_msg)))
+    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
+nON_EXHAUSTIVE_GUARDS_ERROR_ID = mkRuntimeErrorId nonExhaustiveGuardsErrorName
+pAT_ERROR_ID                   = mkRuntimeErrorId patErrorName
+nO_METHOD_BINDING_ERROR_ID      = mkRuntimeErrorId noMethodBindingErrorName
 
 -- 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 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}
 
 
@@ -932,37 +979,33 @@ runtimeErrorTy              = mkSigmaTy [openAlphaTyVar] [] (mkFunTy addrPrimTy openAlpha
 %************************************************************************
 
 \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
- = pcMiscPrelId key mod name ty bottoming_info
+pc_bottoming_Id name ty
+ = pcMiscPrelId name ty bottoming_info
  where
-    strict_sig    = mkStrictSig (mkTopDmdType [evalDmd] BotRes)
-    bottoming_info = noCafNoTyGenIdInfo `setAllStrictnessInfo` Just strict_sig
-       -- these "bottom" out, no matter what their arguments
+    bottoming_info = hasCafIdInfo `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.
 
-generic_ERROR_ID u n = pc_bottoming_Id u pREL_ERR n errorTy
+    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}