[project @ 2001-10-17 11:26:04 by simonpj]
[ghc-hetmet.git] / ghc / compiler / basicTypes / MkId.lhs
index f1483e9..7fc7804 100644 (file)
@@ -22,7 +22,7 @@ module MkId (
 
        -- And some particular Ids; see below for why they are wired in
        wiredInIds,
-       unsafeCoerceId, realWorldPrimId,
+       unsafeCoerceId, realWorldPrimId, nullAddrId,
        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
@@ -32,11 +32,11 @@ module MkId (
 
 
 import BasicTypes      ( Arity, StrictnessMark(..), isMarkedUnboxed, isMarkedStrict )
-import TysPrim         ( openAlphaTyVars, alphaTyVar, alphaTy, 
+import TysPrim         ( openAlphaTyVars, alphaTyVar, alphaTy, betaTyVar, betaTy,
                          intPrimTy, realWorldStatePrimTy, addrPrimTy
                        )
 import TysWiredIn      ( charTy, mkListTy )
-import PrelRules       ( primOpRule )
+import PrelRules       ( primOpRules )
 import Rules           ( addRule )
 import TcType          ( Type, ThetaType, mkDictTy, mkPredTys, mkTyConApp,
                          mkTyVarTys, mkClassPred, tcEqPred,
@@ -47,7 +47,7 @@ import TcType         ( Type, ThetaType, mkDictTy, mkPredTys, mkTyConApp,
 import Module          ( Module )
 import CoreUtils       ( mkInlineMe )
 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 )
@@ -121,10 +121,13 @@ wiredInIds
     , rEC_CON_ERROR_ID
     , rEC_UPD_ERROR_ID
 
-       -- These three can't be defined in Haskell
+       -- These can't be defined in Haskell, but they have
+       -- perfectly reasonable unfoldings in Core
     , realWorldPrimId
     , unsafeCoerceId
+    , nullAddrId
     , getTagId
+    , seqId
     ]
 \end{code}
 
@@ -146,8 +149,24 @@ mkDataConId work_name data_con
           `setArityInfo`               arity
           `setNewStrictnessInfo`       Just strict_sig
 
-    arity = dataConRepArity data_con
+    arity      = dataConRepArity data_con
+
     strict_sig = mkStrictSig (mkTopDmdType (replicate arity topDmd) cpr_info)
+       -- Notice that we do *not* say the worker is strict
+       -- even if the data constructor is declared strict
+       --      e.g.    data T = MkT !(Int,Int)
+       -- Why?  Because the *wrapper* is strict (and its unfolding has case
+       -- expresssions that do the evals) but the *worker* itself is not.
+       -- If we pretend it is strict then when we see
+       --      case x of y -> $wMkT y
+       -- the simplifier thinks that y is "sure to be evaluated" (because
+       -- $wMkT is strict) and drops the case.  No, $wMkT is not strict.
+       --
+       -- When the simplifer sees a pattern 
+       --      case e of MkT x -> ...
+       -- it uses the dataConRepStrictness of MkT to mark x as evaluated;
+       -- but that's fine... dataConRepStrictness comes from the data con
+       -- not from the worker Id.
 
     tycon = dataConTyCon data_con
     cpr_info | isProductTyCon tycon && 
@@ -222,9 +241,7 @@ mkDataConWrapId data_con
                -- applications are treated as values
           `setNewStrictnessInfo`       Just wrap_sig
 
-    wrap_ty = mkForAllTys all_tyvars $
-             mkFunTys all_arg_tys
-             result_ty
+    wrap_ty = mkForAllTys all_tyvars (mkFunTys all_arg_tys result_ty)
 
     res_info = strictSigResInfo (idNewStrictness work_id)
     wrap_sig = mkStrictSig (mkTopDmdType (replicate arity topDmd) res_info)
@@ -420,7 +437,6 @@ mkRecordSelId tycon field_label unpack_id unpackUtf8_id
           `setArityInfo`         arity
           `setUnfoldingInfo`     mkTopUnfolding rhs_w_str
           `setNewStrictnessInfo` Just strict_sig
-       -- Unfolding and strictness added by dmdAnalTopId
 
        -- 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
@@ -619,8 +635,7 @@ mkPrimOpId prim_op
           `setNewStrictnessInfo`       Just (mkNewStrictnessInfo id arity strict_info NoCPRInfo)
        -- Until we modify the primop generation code
 
-    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
@@ -740,7 +755,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 PrelGHC.hi-boot, 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
@@ -751,6 +771,7 @@ they can unify with both unlifted and lifted types.  Hence we provide
 another gun with which to shoot yourself in the foot.
 
 \begin{code}
+-- unsafeCoerce# :: forall a b. a -> b
 unsafeCoerceId
   = pcMiscPrelId unsafeCoerceIdKey pREL_GHC SLIT("unsafeCoerce#") ty info
   where
@@ -762,8 +783,27 @@ unsafeCoerceId
     [x] = mkTemplateLocals [openAlphaTy]
     rhs = mkLams [openAlphaTyVar,openBetaTyVar,x] $
          Note (Coerce openBetaTy openAlphaTy) (Var x)
-\end{code}
 
+-- nullAddr# :: Addr#
+-- The reason is is here is because we don't provide 
+-- a way to write this literal in Haskell.
+nullAddrId 
+  = pcMiscPrelId nullAddrIdKey pREL_GHC SLIT("nullAddr#") addrPrimTy info
+  where
+    info = noCafNoTyGenIdInfo `setUnfoldingInfo` 
+          mkCompulsoryUnfolding (Lit nullAddrLit)
+
+seqId
+  = pcMiscPrelId seqIdKey pREL_GHC SLIT("seq") ty info
+  where
+    info = noCafNoTyGenIdInfo `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)])
+\end{code}
 
 @getTag#@ is another function which can't be defined in Haskell.  It needs to
 evaluate its argument and call the dataToTag# primitive.
@@ -873,8 +913,6 @@ pcMiscPrelId key mod str ty info
 pc_bottoming_Id key mod name ty
  = pcMiscPrelId key mod name ty bottoming_info
  where
-    
-    arity         = 1
     strict_sig    = mkStrictSig (mkTopDmdType [evalDmd] BotRes)
     bottoming_info = noCafNoTyGenIdInfo `setNewStrictnessInfo` Just strict_sig
        -- these "bottom" out, no matter what their arguments