[project @ 2001-03-08 12:07:38 by simonpj]
[ghc-hetmet.git] / ghc / compiler / basicTypes / MkId.lhs
index 47818a3..e5a2a49 100644 (file)
@@ -13,8 +13,6 @@ have a standard form, namely:
 
 \begin{code}
 module MkId (
-       mkSpecPragmaId, mkWorkerId,
-
        mkDictFunId, mkDefaultMethodId,
        mkDictSelId,
 
@@ -41,23 +39,20 @@ import PrelNames    ( pREL_ERR, pREL_GHC )
 import PrelRules       ( primOpRule )
 import Rules           ( addRule )
 import Type            ( Type, ThetaType, mkDictTy, mkDictTys, mkTyConApp, mkTyVarTys,
-                         mkFunTys, mkFunTy, mkSigmaTy,
+                         mkFunTys, mkFunTy, mkSigmaTy, splitSigmaTy, 
                          isUnLiftedType, mkForAllTys, mkTyVarTy, tyVarsOfType,
-                         splitFunTys, splitForAllTys
+                         splitFunTys, splitForAllTys, mkPredTy
                        )
 import Module          ( Module )
 import CoreUtils       ( exprType, mkInlineMe )
 import CoreUnfold      ( mkTopUnfolding, mkCompulsoryUnfolding, mkOtherCon )
 import Literal         ( Literal(..) )
 import TyCon           ( TyCon, isNewTyCon, tyConTyVars, tyConDataCons,
-                          tyConTheta, isProductTyCon, isUnboxedTupleTyCon )
+                          tyConTheta, isProductTyCon, isDataTyCon )
 import Class           ( Class, classTyCon, classTyVars, classSelIds )
 import Var             ( Id, TyVar )
 import VarSet          ( isEmptyVarSet )
-import Name            ( mkDerivedName, mkWiredInName, mkLocalName, 
-                         mkWorkerOcc, mkCCallName,
-                         Name, NamedThing(..),
-                       )
+import Name            ( mkWiredInName, mkCCallName, Name )
 import OccName         ( mkVarOcc )
 import PrimOp          ( PrimOp(DataToTagOp, CCallOp), 
                          primOpSig, mkPrimOpIdName,
@@ -72,15 +67,15 @@ import DataCon              ( DataCon, StrictnessMark(..),
                          dataConSig, dataConStrictMarks, dataConId,
                          maybeMarkedUnboxed, splitProductType_maybe
                        )
-import Id              ( idType, mkId,
-                         mkVanillaId, mkTemplateLocals,
+import Id              ( idType, mkGlobalId, mkVanillaGlobal,
+                         mkTemplateLocals, mkTemplateLocalsNum,
                          mkTemplateLocal, idCprInfo
                        )
-import IdInfo          ( IdInfo, constantIdInfo, mkIdInfo,
+import IdInfo          ( IdInfo, vanillaIdInfo, noTyGenIdInfo, noCafOrTyGenIdInfo,
                          exactArity, setUnfoldingInfo, setCafInfo, setCprInfo,
-                         setArityInfo, setSpecInfo, setTyGenInfo,
+                         setArityInfo, setSpecInfo, 
                          mkStrictnessInfo, setStrictnessInfo,
-                         IdFlavour(..), CafInfo(..), CprInfo(..), TyGenInfo(..)
+                         GlobalIdDetails(..), CafInfo(..), CprInfo(..)
                        )
 import FieldLabel      ( mkFieldLabel, fieldLabelName, 
                          firstFieldLabelTag, allFieldLabelTags, fieldLabelType
@@ -95,7 +90,6 @@ import UnicodeUtil      ( stringToUtf8 )
 import Char             ( ord )
 \end{code}             
 
-
 %************************************************************************
 %*                                                                     *
 \subsection{Wired in Ids}
@@ -132,28 +126,6 @@ wiredInIds
 
 %************************************************************************
 %*                                                                     *
-\subsection{Easy ones}
-%*                                                                     *
-%************************************************************************
-
-\begin{code}
-mkSpecPragmaId occ uniq ty loc
-  = mkId (mkLocalName uniq occ loc) ty (mkIdInfo SpecPragmaId)
-       -- Maybe a SysLocal?  But then we'd lose the location
-
-mkDefaultMethodId dm_name rec_c ty
-  = mkId dm_name ty info
-  where
-    info = constantIdInfo `setTyGenInfo` TyGenNever
-             -- type is wired-in (see comment at TcClassDcl.tcClassSig), so
-             -- do not generalise it
-
-mkWorkerId uniq unwrkr ty
-  = mkVanillaId (mkDerivedName mkWorkerOcc (getName unwrkr) uniq) ty
-\end{code}
-
-%************************************************************************
-%*                                                                     *
 \subsection{Data constructors}
 %*                                                                     *
 %************************************************************************
@@ -163,9 +135,9 @@ 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
-  = mkId work_name (dataConRepType data_con) info
+  = mkGlobalId (DataConId data_con) work_name (dataConRepType data_con) info
   where
-    info = mkIdInfo (DataConId data_con)
+    info = noCafOrTyGenIdInfo
           `setArityInfo`       exactArity arity
           `setStrictnessInfo`  strict_info
           `setCprInfo`         cpr_info
@@ -174,20 +146,13 @@ mkDataConId work_name data_con
 
     strict_info = mkStrictnessInfo (dataConRepStrictness data_con, False)
 
+    tycon = dataConTyCon data_con
     cpr_info | isProductTyCon tycon && 
-              not (isUnboxedTupleTyCon tycon) && 
-              arity > 0                        = ReturnsCPR
-            | otherwise                        = NoCPRInfo
-            where
-               tycon = dataConTyCon data_con
-               -- Newtypes don't have a worker at all
-               -- 
-               -- If we are a product with 0 args we must be void(like)
-               -- We can't create an unboxed tuple with 0 args for this
-               -- and since Void has only one, constant value it should 
-               -- just mean returning a pointer to a pre-existing cell. 
-               -- So we won't really gain from doing anything fancy
-               -- and we treat this case as Top.
+              isDataTyCon tycon    &&
+              arity > 0                = ReturnsCPR
+            | otherwise                = NoCPRInfo
+       -- ReturnsCPR is only true for products that are real data types;
+       -- that is, not unboxed tuples or newtypes
 \end{code}
 
 The wrapper for a constructor is an ordinary top-level binding that evaluates
@@ -231,10 +196,10 @@ Notice that
 mkDataConWrapId data_con
   = wrap_id
   where
-    wrap_id = mkId (dataConName data_con) wrap_ty info
+    wrap_id = mkGlobalId (DataConWrapId data_con) (dataConName data_con) wrap_ty info
     work_id = dataConId data_con
 
-    info = mkIdInfo (DataConWrapId data_con)
+    info = noCafOrTyGenIdInfo
           `setUnfoldingInfo`   mkTopUnfolding (mkInlineMe wrap_rhs)
           `setCprInfo`         cpr_info
                -- The Cpr info can be important inside INLINE rhss, where the
@@ -242,13 +207,6 @@ mkDataConWrapId data_con
           `setArityInfo`       exactArity arity
                -- It's important to specify the arity, so that partial
                -- applications are treated as values
-          `setCafInfo`       NoCafRefs
-               -- The wrapper Id ends up in STG code as an argument,
-               -- sometimes before its definition, so we want to
-               -- signal that it has no CAFs
-           `setTyGenInfo`     TyGenNever
-                -- No point generalising its type, since it gets eagerly inlined
-                -- away anyway
 
     wrap_ty = mkForAllTys all_tyvars $
              mkFunTys all_arg_tys
@@ -389,51 +347,86 @@ mkRecordSelId tycon field_label unpack_id unpackUtf8_id
        -- we can't conjure it up out of thin air
   = sel_id
   where
-    sel_id     = mkId (fieldLabelName field_label) selector_ty info
-
+    sel_id     = mkGlobalId (RecordSelId field_label) (fieldLabelName field_label) selector_ty info
     field_ty   = fieldLabelType field_label
     data_cons  = tyConDataCons tycon
     tyvars     = tyConTyVars tycon     -- These scope over the types in 
                                        -- the FieldLabels of constructors of this type
-    tycon_theta        = tyConTheta tycon      -- The context on the data decl
-                                       --   eg data (Eq a, Ord b) => T a b = ...
-    (field_tyvars,field_tau) = splitForAllTys field_ty
-
     data_ty   = mkTyConApp tycon tyvar_tys
     tyvar_tys = mkTyVarTys tyvars
 
+    tycon_theta        = tyConTheta tycon      -- The context on the data decl
+                                       --   eg data (Eq a, Ord b) => T a b = ...
+    dict_tys  = [mkDictTy cls tys | (cls, tys) <- tycon_theta, 
+                                   needed_dict (cls, tys)]
+    needed_dict pred = or [ pred `elem` (dataConTheta dc) 
+                         | (DataAlt dc, _, _) <- the_alts]
+    n_dict_tys = length dict_tys
+
+    (field_tyvars,field_theta,field_tau) = splitSigmaTy field_ty
+    field_dict_tys                      = map mkPredTy field_theta
+    n_field_dict_tys                    = length field_dict_tys
+       -- If the field has a universally quantified type we have to 
+       -- be a bit careful.  Suppose we have
+       --      data R = R { op :: forall a. Foo a => a -> a }
+       -- Then we can't give op the type
+       --      op :: R -> forall a. Foo a => a -> a
+       -- because the typechecker doesn't understand foralls to the
+       -- right of an arrow.  The "right" type to give it is
+       --      op :: forall a. Foo a => R -> a -> a
+       -- But then we must generate the right unfolding too:
+       --      op = /\a -> \dfoo -> \ r ->
+       --           case r of
+       --              R op -> op a dfoo
+       -- 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
-    dict_tys  = [mkDictTy cls tys | (cls, tys) <- tycon_theta, needed_dict (cls, tys)]
-    needed_dict pred = or [ pred `elem` (dataConTheta dc) 
-                         | (DataAlt dc, _, _) <- the_alts]
 
     selector_ty :: Type
     selector_ty  = mkForAllTys tyvars $ mkForAllTys field_tyvars $
-                  mkFunTys dict_tys $  mkFunTy data_ty field_tau
+                  mkFunTys dict_tys  $  mkFunTys field_dict_tys $
+                  mkFunTy data_ty field_tau
       
-    info = mkIdInfo (RecordSelId field_label)
-          `setArityInfo`       exactArity (1 + length dict_tys)
+    arity = 1 + n_dict_tys + n_field_dict_tys
+    info = noTyGenIdInfo
+          `setCafInfo`         caf_info
+          `setArityInfo`       exactArity arity
           `setUnfoldingInfo`   unfolding       
-          `setCafInfo`         NoCafRefs
-           `setTyGenInfo`      TyGenNever
        -- ToDo: consider adding further IdInfo
 
     unfolding = mkTopUnfolding sel_rhs
 
-       
-    (data_id:dict_ids) = mkTemplateLocals (data_ty:dict_tys)
+       -- 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
+       -- rather than n_dict_tys, because the latter gives an infinite loop:
+       -- n_dict tys depends on the_alts, which depens on arg_ids, which depends
+       -- on arity, which depends on n_dict tys.  Sigh!  Mega sigh!
+    field_dict_base    = length tycon_theta + 1
+    dict_id_base       = field_dict_base + n_field_dict_tys
+    field_base        = dict_id_base + 1
+    dict_ids          = mkTemplateLocalsNum  1               dict_tys
+    field_dict_ids     = mkTemplateLocalsNum  field_dict_base field_dict_tys
+    data_id           = mkTemplateLocal      dict_id_base    data_ty
+
     alts      = map mk_maybe_alt data_cons
     the_alts  = catMaybes alts
-    default_alt | all isJust alts = [] -- No default needed
-               | otherwise       = [(DEFAULT, [], error_expr)]
 
-    sel_rhs = mkLams tyvars $ mkLams field_tyvars $ 
-             mkLams dict_ids $ Lam data_id $
-             sel_body
+    no_default = all isJust alts       -- No default needed
+    default_alt | no_default = []
+               | otherwise  = [(DEFAULT, [], error_expr)]
+
+       -- the default branch may have CAF refs, because it calls recSelError etc.
+    caf_info    | no_default = NoCafRefs
+               | otherwise  = MayHaveCafRefs
+
+    sel_rhs = mkLams tyvars   $ mkLams field_tyvars $ 
+             mkLams dict_ids $ mkLams field_dict_ids $
+             Lam data_id     $ sel_body
 
     sel_body | isNewTyCon tycon = Note (Coerce field_tau data_ty) (Var data_id)
             | otherwise        = Case (Var data_id) data_id (the_alts ++ default_alt)
@@ -443,13 +436,13 @@ mkRecordSelId tycon field_label unpack_id unpackUtf8_id
                Nothing         -> Nothing
                Just the_arg_id -> Just (DataAlt data_con, real_args, expr)
                  where
-                   body              = mkVarApps (Var the_arg_id) field_tyvars
+                   body              = mkVarApps (mkVarApps (Var the_arg_id) field_tyvars) field_dict_ids
                    strict_marks      = dataConStrictMarks data_con
                    (expr, real_args) = rebuildConArgs data_con arg_ids strict_marks body
-                                         (length arg_ids + 1)
+                                                      (length arg_ids + 1)
        where
-            arg_ids = mkTemplateLocals (dataConInstOrigArgTys data_con tyvar_tys)
-                                   -- The first one will shadow data_id, but who cares
+            arg_ids = mkTemplateLocalsNum field_base (dataConInstOrigArgTys data_con tyvar_tys)
+                               -- arity+1 avoids all shadowing
            maybe_the_arg_id  = assocMaybe (field_lbls `zip` arg_ids) field_label
            field_lbls        = dataConFieldLabels data_con
 
@@ -522,15 +515,13 @@ mkDictSelId name clas
   = sel_id
   where
     ty       = exprType rhs
-    sel_id    = mkId name ty info
+    sel_id    = mkGlobalId (RecordSelId field_lbl) name ty info
     field_lbl = mkFieldLabel name tycon ty tag
     tag       = assoc "MkId.mkDictSelId" (classSelIds clas `zip` allFieldLabelTags) sel_id
 
-    info      = mkIdInfo (RecordSelId field_lbl)
+    info      = noCafOrTyGenIdInfo
                `setArityInfo`      exactArity 1
                `setUnfoldingInfo`  unfolding
-               `setCafInfo`        NoCafRefs
-                `setTyGenInfo`      TyGenNever
                
        -- We no longer use 'must-inline' on record selectors.  They'll
        -- inline like crazy if they scrutinise a constructor
@@ -570,9 +561,9 @@ mkPrimOpId prim_op
     (tyvars,arg_tys,res_ty, arity, strict_info) = primOpSig prim_op
     ty   = mkForAllTys tyvars (mkFunTys arg_tys res_ty)
     name = mkPrimOpIdName prim_op
-    id   = mkId name ty info
+    id   = mkGlobalId (PrimOpId prim_op) name ty info
                
-    info = mkIdInfo (PrimOpId prim_op)
+    info = noCafOrTyGenIdInfo
           `setSpecInfo`        rules
           `setArityInfo`       exactArity arity
           `setStrictnessInfo`  strict_info
@@ -594,7 +585,7 @@ mkCCallOpId uniq ccall ty
   = ASSERT( isEmptyVarSet (tyVarsOfType ty) )
        -- A CCallOpId should have no free type variables; 
        -- when doing substitutions won't substitute over it
-    mkId name ty info
+    mkGlobalId (PrimOpId prim_op) name ty info
   where
     occ_str = showSDocIface (braces (pprCCallOp ccall <+> ppr ty))
        -- The "occurrence name" of a ccall is the full info about the
@@ -603,7 +594,7 @@ mkCCallOpId uniq ccall ty
     name    = mkCCallName uniq occ_str
     prim_op = CCallOp ccall
 
-    info = mkIdInfo (PrimOpId prim_op)
+    info = noCafOrTyGenIdInfo
           `setArityInfo`       exactArity arity
           `setStrictnessInfo`  strict_info
 
@@ -616,11 +607,14 @@ mkCCallOpId uniq ccall ty
 
 %************************************************************************
 %*                                                                     *
-\subsection{DictFuns}
+\subsection{DictFuns and default methods}
 %*                                                                     *
 %************************************************************************
 
 \begin{code}
+mkDefaultMethodId dm_name ty
+  = mkVanillaGlobal dm_name ty noTyGenIdInfo
+
 mkDictFunId :: Name            -- Name to use for the dict fun;
            -> Class 
            -> [TyVar]
@@ -629,12 +623,12 @@ mkDictFunId :: Name               -- Name to use for the dict fun;
            -> Id
 
 mkDictFunId dfun_name clas inst_tyvars inst_tys dfun_theta
-  = mkId dfun_name dfun_ty info
+  = mkVanillaGlobal dfun_name dfun_ty noTyGenIdInfo
   where
     dfun_ty = mkSigmaTy inst_tyvars dfun_theta (mkDictTy clas inst_tys)
-    info = constantIdInfo `setTyGenInfo` TyGenNever
-             -- type is wired-in (see comment at TcClassDcl.tcClassSig), so
-             -- do not generalise it
+    info     = noTyGenIdInfo
+             -- Type is wired-in (see comment at TcClassDcl.tcClassSig),
+             -- so do not generalise it
 
 {-  1 dec 99: disable the Mark Jones optimisation for the sake
     of compatibility with Hugs.
@@ -686,7 +680,7 @@ another gun with which to shoot yourself in the foot.
 unsafeCoerceId
   = pcMiscPrelId unsafeCoerceIdKey pREL_GHC SLIT("unsafeCoerce#") ty info
   where
-    info = constantIdInfo `setUnfoldingInfo` mkCompulsoryUnfolding rhs
+    info = noCafOrTyGenIdInfo `setUnfoldingInfo` mkCompulsoryUnfolding rhs
           
 
     ty  = mkForAllTys [openAlphaTyVar,openBetaTyVar]
@@ -704,8 +698,7 @@ evaluate its argument and call the dataToTag# primitive.
 getTagId
   = pcMiscPrelId getTagIdKey pREL_GHC SLIT("getTag#") ty info
   where
-    info = constantIdInfo
-          `setUnfoldingInfo`   mkCompulsoryUnfolding rhs
+    info = noCafOrTyGenIdInfo `setUnfoldingInfo` mkCompulsoryUnfolding rhs
        -- We don't provide a defn for this; you must inline it
 
     ty = mkForAllTys [alphaTyVar] (mkFunTy alphaTy intPrimTy)
@@ -723,7 +716,7 @@ nasty as-is, change it back to a literal (@Literal@).
 realWorldPrimId        -- :: State# RealWorld
   = pcMiscPrelId realWorldPrimIdKey pREL_GHC SLIT("realWorld#")
                 realWorldStatePrimTy
-                (noCafIdInfo `setUnfoldingInfo` mkOtherCon [])
+                (noCafOrTyGenIdInfo `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
@@ -776,8 +769,7 @@ aBSENT_ERROR_ID
 
 pAR_ERROR_ID
   = pcMiscPrelId parErrorIdKey pREL_ERR SLIT("parError")
-    (mkSigmaTy [openAlphaTyVar] [] openAlphaTy) noCafIdInfo
-
+    (mkSigmaTy [openAlphaTyVar] [] openAlphaTy) noCafOrTyGenIdInfo
 \end{code}
 
 
@@ -792,7 +784,7 @@ pcMiscPrelId :: Unique{-IdKey-} -> Module -> FAST_STRING -> Type -> IdInfo -> Id
 pcMiscPrelId key mod str ty info
   = let
        name = mkWiredInName mod (mkVarOcc str) key
-       imp  = mkId name ty info -- the usual case...
+       imp  = mkVanillaGlobal name ty info -- the usual case...
     in
     imp
     -- We lie and say the thing is imported; otherwise, we get into
@@ -804,16 +796,13 @@ pcMiscPrelId key mod str ty info
 pc_bottoming_Id key mod name ty
  = pcMiscPrelId key mod name ty bottoming_info
  where
-    bottoming_info = noCafIdInfo 
+    bottoming_info = noCafOrTyGenIdInfo 
                     `setStrictnessInfo` mkStrictnessInfo ([wwStrict], True)
                     
        -- these "bottom" out, no matter what their arguments
 
 generic_ERROR_ID u n = pc_bottoming_Id u pREL_ERR n errorTy
 
--- Very useful...
-noCafIdInfo = constantIdInfo `setCafInfo` NoCafRefs
-
 (openAlphaTyVar:openBetaTyVar:_) = openAlphaTyVars
 openAlphaTy  = mkTyVarTy openAlphaTyVar
 openBetaTy   = mkTyVarTy openBetaTyVar