[project @ 2001-05-16 12:49:59 by simonmar]
[ghc-hetmet.git] / ghc / compiler / basicTypes / MkId.lhs
index 1f29b86..dae32df 100644 (file)
@@ -13,8 +13,6 @@ have a standard form, namely:
 
 \begin{code}
 module MkId (
-       mkSpecPragmaId, mkWorkerId,
-
        mkDictFunId, mkDefaultMethodId,
        mkDictSelId,
 
@@ -33,6 +31,7 @@ module MkId (
 #include "HsVersions.h"
 
 
+import BasicTypes      ( Arity )
 import TysPrim         ( openAlphaTyVars, alphaTyVar, alphaTy, 
                          intPrimTy, realWorldStatePrimTy
                        )
@@ -40,24 +39,21 @@ import TysWiredIn   ( charTy, mkListTy )
 import PrelNames       ( pREL_ERR, pREL_GHC )
 import PrelRules       ( primOpRule )
 import Rules           ( addRule )
-import Type            ( Type, ThetaType, mkDictTy, mkDictTys, mkTyConApp, mkTyVarTys,
-                         mkFunTys, mkFunTy, mkSigmaTy,
+import Type            ( Type, ThetaType, mkDictTy, mkPredTys, mkTyConApp, mkTyVarTys,
+                         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 +68,16 @@ 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, vanillaIdInfo, mkIdInfo,
-                         exactArity, setUnfoldingInfo, setCafInfo, setCprInfo,
-                         setArityInfo, setSpecInfo, setTyGenInfo,
+import IdInfo          ( IdInfo, noCafNoTyGenIdInfo,
+                         exactArity, setUnfoldingInfo, setCprInfo,
+                         setArityInfo, setSpecInfo,  setCgInfo,
                          mkStrictnessInfo, setStrictnessInfo,
-                         IdFlavour(..), CafInfo(..), CprInfo(..), TyGenInfo(..)
+                         GlobalIdDetails(..), CafInfo(..), CprInfo(..), 
+                         CgInfo(..), setCgArity
                        )
 import FieldLabel      ( mkFieldLabel, fieldLabelName, 
                          firstFieldLabelTag, allFieldLabelTags, fieldLabelType
@@ -95,7 +92,6 @@ import UnicodeUtil      ( stringToUtf8 )
 import Char             ( ord )
 \end{code}             
 
-
 %************************************************************************
 %*                                                                     *
 \subsection{Wired in Ids}
@@ -123,7 +119,7 @@ wiredInIds
     , rEC_CON_ERROR_ID
     , rEC_UPD_ERROR_ID
 
-       -- These two can't be defined in Haskell
+       -- These three can't be defined in Haskell
     , realWorldPrimId
     , unsafeCoerceId
     , getTagId
@@ -132,28 +128,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 = vanillaIdInfo `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 +137,10 @@ 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 = noCafNoTyGenIdInfo
+          `setCgArity`         arity
           `setArityInfo`       exactArity arity
           `setStrictnessInfo`  strict_info
           `setCprInfo`         cpr_info
@@ -174,20 +149,25 @@ 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            &&
+              arity <= mAX_CPR_SIZE    = ReturnsCPR
+            | otherwise                = NoCPRInfo
+       -- ReturnsCPR is only true for products that are real data types;
+       -- that is, not unboxed tuples or 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
@@ -231,24 +211,19 @@ 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 = noCafNoTyGenIdInfo
           `setUnfoldingInfo`   mkTopUnfolding (mkInlineMe wrap_rhs)
           `setCprInfo`         cpr_info
                -- The Cpr info can be important inside INLINE rhss, where the
                -- wrapper constructor isn't inlined
+          `setCgArity`         arity
+               -- The NoCaf-ness is set by noCafNoTyGenIdInfo
           `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
@@ -295,8 +270,8 @@ mkDataConWrapId data_con
     (tyvars, theta, ex_tyvars, ex_theta, orig_arg_tys, tycon) = dataConSig data_con
     all_tyvars   = tyvars ++ ex_tyvars
 
-    dict_tys     = mkDictTys theta
-    ex_dict_tys  = mkDictTys ex_theta
+    dict_tys     = mkPredTys theta
+    ex_dict_tys  = mkPredTys ex_theta
     all_arg_tys  = dict_tys ++ ex_dict_tys ++ orig_arg_tys
     result_ty    = mkTyConApp tycon (mkTyVarTys tyvars)
 
@@ -389,51 +364,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  = [mkPredTy pred | pred <- tycon_theta, 
+                                needed_dict pred]
+    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 = noCafNoTyGenIdInfo
+          `setCgInfo`          (CgInfo arity 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 +453,16 @@ 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)
+                                                      unpack_base
        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)
+
+           unpack_base = field_base + length arg_ids
+
+                               -- arity+1 avoids all shadowing
            maybe_the_arg_id  = assocMaybe (field_lbls `zip` arg_ids) field_label
            field_lbls        = dataConFieldLabels data_con
 
@@ -522,15 +535,14 @@ 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      = noCafNoTyGenIdInfo
+               `setCgArity`        1
                `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,14 +582,16 @@ 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 = noCafNoTyGenIdInfo
           `setSpecInfo`        rules
+          `setCgArity`         arity
           `setArityInfo`       exactArity arity
           `setStrictnessInfo`  strict_info
 
-    rules = addRule emptyCoreRules id (primOpRule prim_op)
+    rules = maybe emptyCoreRules (addRule emptyCoreRules id)
+               (primOpRule prim_op)
 
 
 -- For each ccall we manufacture a separate CCallOpId, giving it
@@ -594,7 +608,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 +617,8 @@ mkCCallOpId uniq ccall ty
     name    = mkCCallName uniq occ_str
     prim_op = CCallOp ccall
 
-    info = mkIdInfo (PrimOpId prim_op)
+    info = noCafNoTyGenIdInfo
+          `setCgArity`         arity
           `setArityInfo`       exactArity arity
           `setStrictnessInfo`  strict_info
 
@@ -616,11 +631,14 @@ mkCCallOpId uniq ccall ty
 
 %************************************************************************
 %*                                                                     *
-\subsection{DictFuns}
+\subsection{DictFuns and default methods}
 %*                                                                     *
 %************************************************************************
 
 \begin{code}
+mkDefaultMethodId dm_name ty
+  = mkVanillaGlobal dm_name ty noCafNoTyGenIdInfo
+
 mkDictFunId :: Name            -- Name to use for the dict fun;
            -> Class 
            -> [TyVar]
@@ -629,12 +647,9 @@ 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 noCafNoTyGenIdInfo
   where
     dfun_ty = mkSigmaTy inst_tyvars dfun_theta (mkDictTy clas inst_tys)
-    info = vanillaIdInfo `setTyGenInfo` TyGenNever
-             -- 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,8 +701,7 @@ another gun with which to shoot yourself in the foot.
 unsafeCoerceId
   = pcMiscPrelId unsafeCoerceIdKey pREL_GHC SLIT("unsafeCoerce#") ty info
   where
-    info = vanillaIdInfo
-          `setUnfoldingInfo` mkCompulsoryUnfolding rhs
+    info = noCafNoTyGenIdInfo `setUnfoldingInfo` mkCompulsoryUnfolding rhs
           
 
     ty  = mkForAllTys [openAlphaTyVar,openBetaTyVar]
@@ -705,8 +719,7 @@ evaluate its argument and call the dataToTag# primitive.
 getTagId
   = pcMiscPrelId getTagIdKey pREL_GHC SLIT("getTag#") ty info
   where
-    info = vanillaIdInfo
-          `setUnfoldingInfo`   mkCompulsoryUnfolding rhs
+    info = noCafNoTyGenIdInfo `setUnfoldingInfo` mkCompulsoryUnfolding rhs
        -- We don't provide a defn for this; you must inline it
 
     ty = mkForAllTys [alphaTyVar] (mkFunTy alphaTy intPrimTy)
@@ -724,7 +737,7 @@ nasty as-is, change it back to a literal (@Literal@).
 realWorldPrimId        -- :: State# RealWorld
   = pcMiscPrelId realWorldPrimIdKey pREL_GHC SLIT("realWorld#")
                 realWorldStatePrimTy
-                (noCafIdInfo `setUnfoldingInfo` mkOtherCon [])
+                (noCafNoTyGenIdInfo `setUnfoldingInfo` mkOtherCon [])
        -- The mkOtherCon makes it look that realWorld# is evaluated
        -- which in turn makes Simplify.interestingArg return True,
        -- which in turn makes INLINE things applied to realWorld# likely
@@ -777,8 +790,7 @@ aBSENT_ERROR_ID
 
 pAR_ERROR_ID
   = pcMiscPrelId parErrorIdKey pREL_ERR SLIT("parError")
-    (mkSigmaTy [openAlphaTyVar] [] openAlphaTy) noCafIdInfo
-
+    (mkSigmaTy [openAlphaTyVar] [] openAlphaTy) noCafNoTyGenIdInfo
 \end{code}
 
 
@@ -793,7 +805,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
@@ -805,16 +817,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 = noCafNoTyGenIdInfo 
                     `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 = vanillaIdInfo `setCafInfo` NoCafRefs
-
 (openAlphaTyVar:openBetaTyVar:_) = openAlphaTyVars
 openAlphaTy  = mkTyVarTy openAlphaTyVar
 openBetaTy   = mkTyVarTy openBetaTyVar