[project @ 2005-02-25 13:06:31 by simonpj]
[ghc-hetmet.git] / ghc / compiler / basicTypes / MkId.lhs
index 871b77d..50e981b 100644 (file)
@@ -13,88 +13,85 @@ have a standard form, namely:
 
 \begin{code}
 module MkId (
 
 \begin{code}
 module MkId (
-       mkSpecPragmaId, mkWorkerId,
-
        mkDictFunId, mkDefaultMethodId,
        mkDictFunId, mkDefaultMethodId,
-       mkDictSelId,
+       mkDictSelId, 
+
+       mkDataConIds,
+       mkRecordSelId, 
+       mkPrimOpId, mkFCallId,
 
 
-       mkDataConId, mkDataConWrapId,
-       mkRecordSelId,
-       mkPrimOpId, mkCCallOpId,
+       mkReboxingAlt, mkNewTypeBody,
 
        -- And some particular Ids; see below for why they are wired in
 
        -- And some particular Ids; see below for why they are wired in
-       wiredInIds,
-       unsafeCoerceId, realWorldPrimId,
-       eRROR_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"
 
 
     ) where
 
 #include "HsVersions.h"
 
 
+import BasicTypes      ( Arity, StrictnessMark(..), isMarkedUnboxed, isMarkedStrict )
 import TysPrim         ( openAlphaTyVars, alphaTyVar, alphaTy, 
 import TysPrim         ( openAlphaTyVars, alphaTyVar, alphaTy, 
-                         intPrimTy, realWorldStatePrimTy
+                         realWorldStatePrimTy, addrPrimTy
                        )
                        )
-import TysWiredIn      ( boolTy, charTy, mkListTy )
-import PrelMods                ( pREL_ERR, pREL_GHC )
-import PrelRules       ( primOpRule )
+import TysWiredIn      ( charTy, mkListTy )
+import PrelRules       ( primOpRules )
 import Rules           ( addRule )
 import Rules           ( addRule )
-import Type            ( Type, ClassContext, mkDictTy, mkTyConApp, mkTyVarTys,
-                         mkFunTys, mkFunTy, mkSigmaTy, classesToPreds,
-                         isUnLiftedType, mkForAllTys, mkTyVarTy, tyVarsOfType, tyVarsOfTypes,
-                         splitSigmaTy, splitFunTy_maybe, splitAlgTyConApp,
-                         splitFunTys, splitForAllTys, unUsgTy,
-                         mkUsgTy, UsageAnn(..)
+import Type            ( TyThing(..) )
+import TcType          ( Type, ThetaType, mkDictTy, mkPredTys, mkPredTy, 
+                         mkTyConApp, mkTyVarTys, mkClassPred, tcEqPred,
+                         mkFunTys, mkFunTy, mkSigmaTy, tcSplitSigmaTy, 
+                         isUnLiftedType, mkForAllTys, mkTyVarTy, tyVarsOfType,
+                         tcSplitFunTys, tcSplitForAllTys
                        )
                        )
-import PprType         ( pprParendType )
-import Module          ( Module )
-import CoreUtils       ( mkInlineMe )
-import CoreUnfold      ( mkTopUnfolding, mkCompulsoryUnfolding, mkOtherCon )
-import Subst           ( mkTopTyVarSubst, substClasses )
-import TyCon           ( TyCon, isNewTyCon, tyConTyVars, tyConDataCons, isDataTyCon, isProductTyCon, isUnboxedTupleTyCon )
-import Class           ( Class, classBigSig, classTyCon, classTyVars, classSelIds )
-import Var             ( Id, TyVar )
+import CoreUtils       ( exprType )
+import CoreUnfold      ( mkTopUnfolding, mkCompulsoryUnfolding )
+import Literal         ( nullAddrLit, mkStringLit )
+import TyCon           ( TyCon, isNewTyCon, tyConTyVars, tyConDataCons,
+                          tyConStupidTheta, isProductTyCon, isDataTyCon, isRecursiveTyCon )
+import Class           ( Class, classTyCon, classSelIds )
+import Var             ( Id, TyVar, Var )
 import VarSet          ( isEmptyVarSet )
 import VarSet          ( isEmptyVarSet )
-import Name            ( mkDerivedName, mkWiredInIdName, mkLocalName, 
-                         mkWorkerOcc, mkSuperDictSelOcc, mkCCallName,
-                         Name, NamedThing(..),
-                       )
-import OccName         ( mkSrcVarOcc )
-import PrimOp          ( PrimOp(DataToTagOp, CCallOp), 
-                         primOpSig, mkPrimOpIdName,
-                         CCall, pprCCallOp
-                       )
-import Demand          ( wwStrict, wwPrim )
-import DataCon         ( DataCon, StrictnessMark(..), 
-                         dataConFieldLabels, dataConRepArity, dataConTyCon,
-                         dataConArgTys, dataConRepType, dataConRepStrictness, dataConName,
-                         dataConSig, dataConStrictMarks, dataConId
+import Name            ( mkFCallName, mkWiredInName, Name, BuiltInSyntax(..) )
+import OccName         ( mkOccFS, varName )
+import PrimOp          ( PrimOp, primOpSig, primOpOcc, primOpTag )
+import ForeignCall     ( ForeignCall )
+import DataCon         ( DataCon, DataConIds(..), dataConTyVars,
+                         dataConFieldLabels, dataConRepArity, 
+                         dataConRepArgTys, dataConRepType, dataConStupidTheta, 
+                         dataConSig, dataConStrictMarks, dataConExStricts, 
+                         splitProductType, isVanillaDataCon
                        )
                        )
-import Id              ( idType, mkId,
-                         mkVanillaId, mkTemplateLocals,
-                         mkTemplateLocal, setInlinePragma, idCprInfo
+import Id              ( idType, mkGlobalId, mkVanillaGlobal, mkSysLocal, 
+                         mkTemplateLocals, mkTemplateLocalsNum, mkExportedLocalId,
+                         mkTemplateLocal, idName
                        )
                        )
-import IdInfo          ( IdInfo, vanillaIdInfo, mkIdInfo,
-                         exactArity, setUnfoldingInfo, setCafInfo, setCprInfo,
-                         setArityInfo, setInlinePragInfo, setSpecInfo,
-                         mkStrictnessInfo, setStrictnessInfo,
-                         IdFlavour(..), InlinePragInfo(..), CafInfo(..), StrictnessInfo(..), CprInfo(..)
-                       )
-import FieldLabel      ( FieldLabel, FieldLabelTag, mkFieldLabel, fieldLabelName, 
-                         firstFieldLabelTag, allFieldLabelTags, fieldLabelType
+import IdInfo          ( IdInfo, noCafIdInfo,  setUnfoldingInfo, 
+                         setArityInfo, setSpecInfo, setCafInfo,
+                         setAllStrictnessInfo, vanillaIdInfo,
+                         GlobalIdDetails(..), CafInfo(..)
                        )
                        )
+import NewDemand       ( mkStrictSig, DmdResult(..),
+                         mkTopDmdType, topDmd, evalDmd, lazyDmd, retCPR,
+                         Demand(..), Demands(..) )
+import DmdAnal         ( dmdAnalTopRhs )
 import CoreSyn
 import CoreSyn
+import Unique          ( mkBuiltinUnique, mkPrimOpIdUnique )
 import Maybes
 import Maybes
-import BasicTypes      ( Arity )
-import Unique
-import Maybe            ( isJust )
+import PrelNames
+import Util             ( dropList, isSingleton )
 import Outputable
 import Outputable
-import Util            ( assoc )
-import List            ( nub )
+import FastString
+import ListSetOps      ( assoc, assocMaybe )
+import List            ( nubBy )
 \end{code}             
 
 \end{code}             
 
-
 %************************************************************************
 %*                                                                     *
 \subsection{Wired in Ids}
 %************************************************************************
 %*                                                                     *
 \subsection{Wired in Ids}
@@ -108,82 +105,43 @@ wiredInIds
        -- is 'open'; that is can be unified with an unboxed type
        -- 
        -- [The interface file format now carry such information, but there's
        -- is 'open'; that is can be unified with an unboxed type
        -- 
        -- [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
-    , 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 two can't be defined in Haskell
-    , realWorldPrimId
-    , unsafeCoerceId
-    , getTagId
+       -- no way yet of expressing at the definition site for these 
+       -- 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}
 
 %************************************************************************
 %*                                                                     *
     ]
 \end{code}
 
 %************************************************************************
 %*                                                                     *
-\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
-  = mkVanillaId dm_name ty
-
-mkWorkerId uniq unwrkr ty
-  = mkVanillaId (mkDerivedName mkWorkerOcc (getName unwrkr) uniq) ty
-\end{code}
-
-%************************************************************************
-%*                                                                     *
 \subsection{Data constructors}
 %*                                                                     *
 %************************************************************************
 
 \subsection{Data constructors}
 %*                                                                     *
 %************************************************************************
 
-\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
-  = mkId work_name (dataConRepType data_con) info
-  where
-    info = mkIdInfo (DataConId data_con)
-          `setArityInfo`       exactArity arity
-          `setStrictnessInfo`  strict_info
-          `setCprInfo`         cpr_info
-
-    arity = dataConRepArity data_con
-
-    strict_info = StrictnessInfo (dataConRepStrictness data_con) False
-
-    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.
-\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.
 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.
@@ -221,94 +179,125 @@ Notice that
   Making an explicit case expression allows the simplifier to eliminate
   it in the (common) case where the constructor arg is already evaluated.
 
   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 = mkId (dataConName data_con) wrap_ty info
-    work_id = dataConId data_con
-
-    info = mkIdInfo (DataConWrapId data_con)
-          `setUnfoldingInfo`   mkTopUnfolding cpr_info (mkInlineMe wrap_rhs)
-          `setCprInfo`         cpr_info
-               -- The Cpr info can be important inside INLINE rhss, where the
-               -- wrapper constructor isn't inlined
-          `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
-
-    wrap_ty = mkForAllTys all_tyvars $
-             mkFunTys all_arg_tys
-             result_ty
-
-    cpr_info = idCprInfo work_id
-
-    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 contex
-               -- e.g.         newtype Eq a => T a = MkT (...)
-
-              mkLams tyvars $ mkLams dict_args $ Lam id_arg1 $
-              Note (Coerce result_ty (head orig_arg_tys)) (Var id_arg1)
-
-{-     I nuked this because map (:) xs would create a
-       new local lambda for the (:) in core-to-stg.  
-       There isn't a defn for the worker!
-
-            | null dict_args && all not_marked_strict 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,
-                               -- which is a bit sad.  (We could match on the wrappers,
-                               -- but that makes it less likely that rules will match
-                               -- when we bring bits of unfoldings together
--}
-
-            | 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))
 
 
-    (tyvars, theta, ex_tyvars, ex_theta, orig_arg_tys, tycon) = dataConSig data_con
-    all_tyvars   = tyvars ++ ex_tyvars
-
-    dict_tys     = [mkDictTy clas tys | (clas,tys) <- theta]
-    ex_dict_tys  = [mkDictTy clas tys | (clas,tys) <- ex_theta]
-    all_arg_tys  = dict_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
+\begin{code}
+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
 
 
-    (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
+  | any isMarkedStrict all_strict_marks                -- Algebraic, needs wrapper
+  = AlgDC (Just alg_wrap_id) wrk_id
 
 
-    strict_marks  = dataConStrictMarks data_con
-    not_marked_strict NotMarkedStrict = True
-    not_marked_strict other          = False
+  | otherwise                                  -- Algebraic, no wrapper
+  = AlgDC Nothing wrk_id
+  where
+    (tyvars, theta, orig_arg_tys, tycon, res_tys) = dataConSig data_con
+
+    dict_tys    = mkPredTys theta
+    all_arg_tys = dict_tys ++ orig_arg_tys
+    result_ty   = mkTyConApp tycon res_tys
+
+    wrap_ty = mkForAllTys 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
+               `setUnfoldingInfo`      evaldUnfolding  -- Record that it's evaluated,
+                                                       -- even if arity = 0
+
+    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.
 
 
+    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
+
+       ----------- 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( isVanillaDataCon data_con &&
+                          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 tyvars $ 
+             mkLams dict_args $ mkLams id_args $
+             foldr mk_case con_app 
+                   (zip (dict_args ++ id_args) all_strict_marks)
+                   i3 []
+
+    con_app i rep_ids = mkApps (Var wrk_id)
+                              (map varToCoreExpr (tyvars ++ reverse rep_ids))
+
+    (dict_args,i2) = mkLocals 1  dict_tys
+    (id_args,i3)   = mkLocals i2 orig_arg_tys
+    alg_arity     = i3-1
 
     mk_case 
 
     mk_case 
-          :: (Id, StrictnessMark)      -- arg, strictness
-          -> (Int -> [Id] -> CoreExpr) -- body
-          -> Int                       -- next rep arg id
-          -> [Id]                      -- rep args so far
+          :: (Id, StrictnessMark)      -- Arg, strictness
+          -> (Int -> [Id] -> CoreExpr) -- Body
+          -> Int                       -- Next rep arg id
+          -> [Id]                      -- Rep args so far, reversed
           -> CoreExpr
     mk_case (arg,strict) body i rep_args
          = case strict of
           -> CoreExpr
     mk_case (arg,strict) body i rep_args
          = case strict of
@@ -316,13 +305,32 @@ mkDataConWrapId data_con
                MarkedStrict 
                   | isUnLiftedType (idType arg) -> body i (arg:rep_args)
                   | otherwise ->
                MarkedStrict 
                   | isUnLiftedType (idType arg) -> body i (arg:rep_args)
                   | otherwise ->
-                       Case (Var arg) arg [(DEFAULT,[], body i (arg:rep_args))]
-
-               MarkedUnboxed con tys ->
-                  Case (Var arg) arg [(DataAlt con, con_args,
-                                       body i' (reverse con_args++rep_args))]
-                  where n_tys = length tys
-                        (con_args,i') = mkLocals i tys
+                       Case (Var arg) arg result_ty [(DEFAULT,[], body i (arg:rep_args))]
+
+               MarkedUnboxed
+                  -> case splitProductType "do_unbox" (idType arg) of
+                          (tycon, tycon_args, con, tys) ->
+                                  Case (Var arg) arg result_ty  
+                                       [(DataAlt con, 
+                                         con_args,
+                                         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}
 
 
 \end{code}
 
 
@@ -343,63 +351,220 @@ We're going to build a record selector unfolding that looks like this:
                                    T2 ... x ... -> x
                                    other        -> error "..."
 
                                    T2 ... x ... -> x
                                    other        -> error "..."
 
+Similarly for newtypes
+
+       newtype N a = MkN { unN :: a->a }
+
+       unN :: N a -> a -> a
+       unN n = coerce (a->a) n
+       
+We need to take a little care if the field has a polymorphic type:
+
+       data R = R { f :: forall a. a->a }
+
+Then we want
+
+       f :: forall a. R -> a -> a
+       f = /\ a \ r = case r of
+                         R f -> f a
+
+(not f :: R -> forall a. a->a, which gives the type inference mechanism 
+problems at call sites)
+
+Similarly for (recursive) newtypes
+
+       newtype N = MkN { unN :: forall a. a->a }
+
+       unN :: forall b. N -> b -> b
+       unN = /\b -> \n:N -> (coerce (forall a. a->a) n)
+
 \begin{code}
 \begin{code}
-mkRecordSelId tycon field_label
-       -- Assumes that all fields with the same field label
-       -- have the same type
+mkRecordSelId tycon field_label field_ty
+       -- Assumes that all fields with the same field label have the same type
   = sel_id
   where
   = sel_id
   where
-    sel_id     = mkId (fieldLabelName field_label) selector_ty info
-
-    field_ty   = fieldLabelType field_label
-    field_name = fieldLabelName field_label
+    sel_id     = mkGlobalId (RecordSelId tycon field_label) field_label selector_ty info
     data_cons  = tyConDataCons tycon
     tyvars     = tyConTyVars tycon     -- These scope over the types in 
                                        -- the FieldLabels of constructors of this type
     data_cons  = tyConDataCons tycon
     tyvars     = tyConTyVars tycon     -- These scope over the types in 
                                        -- the FieldLabels of constructors of this type
-
-    data_ty   = mkTyConApp tycon (mkTyVarTys tyvars)
+    data_ty   = mkTyConApp tycon tyvar_tys
     tyvar_tys = mkTyVarTys tyvars
 
     tyvar_tys = mkTyVarTys tyvars
 
+       -- 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
+    needed_preds = [pred | (DataAlt dc, _, _) <- the_alts, pred <- dataConStupidTheta dc]
+    dict_tys     = mkPredTys (nubBy tcEqPred needed_preds)
+    n_dict_tys   = length dict_tys
+
+    (field_tyvars,field_theta,field_tau) = tcSplitSigmaTy field_ty
+    field_dict_tys                      = mkPredTys 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
+
     selector_ty :: Type
     selector_ty :: Type
-    selector_ty  = mkForAllTys tyvars (mkFunTy data_ty field_ty)
+    selector_ty  = mkForAllTys tyvars $ mkForAllTys field_tyvars $
+                  mkFunTys dict_tys  $  mkFunTys field_dict_tys $
+                  mkFunTy data_ty field_tau
       
       
-    info = mkIdInfo (RecordSelId field_label)
-          `setArityInfo`       exactArity 1
-          `setUnfoldingInfo`   unfolding       
-          `setCafInfo`         NoCafRefs
-       -- ToDo: consider adding further IdInfo
-
-    unfolding = mkTopUnfolding NoCPRInfo sel_rhs
+    arity = 1 + n_dict_tys + n_field_dict_tys
+
+    (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 max_dict_tys
+       -- 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!
+    dict_ids       = mkTemplateLocalsNum  1               dict_tys
+    max_dict_tys    = length (tyConStupidTheta tycon)
+    field_dict_base = max_dict_tys + 1
+    field_dict_ids  = mkTemplateLocalsNum  field_dict_base field_dict_tys
+    dict_id_base    = field_dict_base + n_field_dict_tys
+    data_id        = mkTemplateLocal      dict_id_base    data_ty
+    arg_base       = dict_id_base + 1
 
 
-       
-    [data_id] = mkTemplateLocals [data_ty]
     alts      = map mk_maybe_alt data_cons
     alts      = map mk_maybe_alt data_cons
-    the_alts  = catMaybes alts
-    default_alt | all isJust alts = [] -- No default needed
-               | otherwise       = [(DEFAULT, [], error_expr)]
+    the_alts  = catMaybes alts         -- Already sorted by data-con
+
+    no_default = all isJust alts       -- No default needed
+    default_alt | no_default = []
+               | otherwise  = [(DEFAULT, [], error_expr)]
 
 
-    sel_rhs | isNewTyCon tycon = new_sel_rhs
-           | otherwise        = data_sel_rhs
+       -- The default branch may have CAF refs, because it calls recSelError etc.
+    caf_info    | no_default = NoCafRefs
+               | otherwise  = MayHaveCafRefs
 
 
-    data_sel_rhs = mkLams tyvars $ Lam data_id $
-                    Case (Var data_id) data_id (the_alts ++ default_alt)
+    sel_rhs = mkLams tyvars   $ mkLams field_tyvars $ 
+             mkLams dict_ids $ mkLams field_dict_ids $
+             Lam data_id     $ sel_body
 
 
-    new_sel_rhs  = mkLams tyvars $ Lam data_id $
-                   Note (Coerce (unUsgTy field_ty) (unUsgTy data_ty)) (Var data_id)
+    sel_body | isNewTyCon tycon = mk_result (mkNewTypeBody tycon field_ty (Var data_id))
+            | otherwise        = Case (Var data_id) data_id field_tau (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 
 
     mk_maybe_alt data_con 
-         = case maybe_the_arg_id of
+       = ASSERT( dc_tyvars == tyvars )
+               -- The only non-vanilla case we allow is when we have an existential
+               -- context that binds no type variables, thus
+               --      data T a = (?v::Int) => MkT a
+               -- In the non-vanilla case, the pattern must bind type variables and
+               -- the context stuff; hence the arg_prefix binding below
+
+         case maybe_the_arg_id of
                Nothing         -> Nothing
                Nothing         -> Nothing
-               Just the_arg_id -> Just (DataAlt data_con, arg_ids, Var the_arg_id)
-         where
-           arg_ids          = mkTemplateLocals (dataConArgTys data_con tyvar_tys)
-                                   -- The first one will shadow data_id, but who cares
-           field_lbls       = dataConFieldLabels data_con
-           maybe_the_arg_id = assocMaybe (field_lbls `zip` arg_ids) field_label
-
-    error_expr = mkApps (Var rEC_SEL_ERROR_ID) [Type (unUsgTy field_ty), mkStringLit full_msg]
-       -- preserves invariant that type args are *not* usage-annotated on top.  KSW 1999-04.
+               Just the_arg_id -> Just (mkReboxingAlt uniqs data_con (arg_prefix ++ arg_src_ids) $
+                                        mk_result (Var the_arg_id))
+       where
+           (dc_tyvars, dc_theta, dc_arg_tys, _, _) = dataConSig data_con
+           arg_src_ids = mkTemplateLocalsNum arg_base dc_arg_tys
+           arg_base'   = arg_base + length arg_src_ids
+           arg_prefix  | isVanillaDataCon data_con = []
+                       | otherwise = tyvars ++ mkTemplateLocalsNum arg_base' (mkPredTys dc_theta)
+
+           unpack_base = arg_base' + length dc_theta
+           uniqs = map mkBuiltinUnique [unpack_base..]
+
+           maybe_the_arg_id  = assocMaybe (field_lbls `zip` arg_src_ids) field_label
+           field_lbls        = dataConFieldLabels data_con
+
+    error_expr = mkRuntimeErrorApp rEC_SEL_ERROR_ID field_tau full_msg
     full_msg   = showSDoc (sep [text "No match in record selector", ppr sel_id]) 
     full_msg   = showSDoc (sep [text "No match in record selector", ppr sel_id]) 
+
+
+-- (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
+--
+-- 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.
+
+mkReboxingAlt
+  :: [Unique]                  -- Uniques for the new Ids
+  -> DataCon
+  -> [Var]                     -- Source-level args, including existential dicts
+  -> CoreExpr                  -- RHS
+  -> CoreAlt
+
+mkReboxingAlt us con args rhs
+  | not (any isMarkedUnboxed stricts)
+  = (DataAlt con, args, rhs)
+
+  | otherwise
+  = let
+       (binds, args') = go args stricts us
+    in
+    (DataAlt con, args', mkLets binds rhs)
+
+  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}
 
 
 \end{code}
 
 
@@ -412,42 +577,72 @@ mkRecordSelId tycon field_label
 Selecting a field for a dictionary.  If there is just one field, then
 there's nothing to do.  
 
 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}
 
 \begin{code}
-mkDictSelId name clas ty
-  = sel_id
+mkDictSelId :: Name -> Class -> Id
+mkDictSelId name clas
+  = mkGlobalId (ClassOpId clas) name sel_ty info
   where
   where
-    sel_id    = mkId name ty info
-    field_lbl = mkFieldLabel name ty tag
-    tag       = assoc "MkId.mkDictSelId" (classSelIds clas `zip` allFieldLabelTags) sel_id
-
-    info      = mkIdInfo (RecordSelId field_lbl)
-               `setArityInfo`      exactArity 1
-               `setUnfoldingInfo`  unfolding
-               `setCafInfo`        NoCafRefs
-               
+    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
+       --      C a -> C a
+       -- for a single-op class (after all, the selector is the identity)
+       -- But it's type must expose the representation of the dictionary
+       -- to gat (say)         C a -> (a -> a)
+
+    info = noCafIdInfo
+               `setArityInfo`          1
+               `setUnfoldingInfo`      mkTopUnfolding rhs
+               `setAllStrictnessInfo`  Just strict_sig
+
        -- We no longer use 'must-inline' on record selectors.  They'll
        -- inline like crazy if they scrutinise a constructor
 
        -- We no longer use 'must-inline' on record selectors.  They'll
        -- inline like crazy if they scrutinise a constructor
 
-    unfolding = mkTopUnfolding NoCPRInfo rhs
-
-    tyvars  = classTyVars clas
+       -- 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 ])
 
     tycon      = classTyCon clas
     [data_con] = tyConDataCons tycon
 
     tycon      = classTyCon clas
     [data_con] = tyConDataCons tycon
-    tyvar_tys  = mkTyVarTys tyvars
-    arg_tys    = dataConArgTys data_con tyvar_tys
-    the_arg_id = arg_ids !! (tag - firstFieldLabelTag)
+    tyvars     = dataConTyVars data_con
+    arg_tys    = dataConRepArgTys data_con
+    the_arg_id = assoc "MkId.mkDictSelId" (map idName (classSelIds clas) `zip` arg_ids) name
 
 
-    dict_ty    = mkDictTy clas tyvar_tys
-    (dict_id:arg_ids) = mkTemplateLocals (dict_ty : arg_tys)
+    pred             = mkClassPred clas (mkTyVarTys tyvars)
+    (dict_id:arg_ids) = mkTemplateLocals (mkPredTy pred : arg_tys)
 
 
-    rhs | isNewTyCon tycon = mkLams tyvars $ Lam dict_id $
-                            Note (Coerce (head arg_tys) dict_ty) (Var dict_id)
+    rhs | isNewTyCon tycon = mkLams tyvars $ Lam dict_id $ 
+                            mkNewTypeBody tycon (head arg_tys) (Var dict_id)
        | otherwise        = mkLams tyvars $ Lam dict_id $
        | otherwise        = mkLams tyvars $ Lam dict_id $
-                            Case (Var dict_id) dict_id
+                            Case (Var dict_id) dict_id (idType the_arg_id)
                                  [(DataAlt data_con, arg_ids, Var the_arg_id)]
                                  [(DataAlt data_con, arg_ids, Var the_arg_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 (exprType result_expr)) result_expr
+  | otherwise                  -- Normal case
+  = result_expr
 \end{code}
 
 
 \end{code}
 
 
@@ -462,17 +657,19 @@ mkPrimOpId :: PrimOp -> Id
 mkPrimOpId prim_op 
   = id
   where
 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)
     ty   = mkForAllTys tyvars (mkFunTys arg_tys res_ty)
-    name = mkPrimOpIdName prim_op id
-    id   = mkId name ty info
+    name = mkWiredInName gHC_PRIM (primOpOcc prim_op) 
+                        (mkPrimOpIdUnique (primOpTag prim_op))
+                        Nothing (AnId id) UserSyntax
+    id   = mkGlobalId (PrimOpId prim_op) name ty info
                
                
-    info = mkIdInfo (PrimOpId prim_op)
+    info = noCafIdInfo
           `setSpecInfo`        rules
           `setSpecInfo`        rules
-          `setArityInfo`       exactArity arity
-          `setStrictnessInfo`  strict_info
+          `setArityInfo`       arity
+          `setAllStrictnessInfo` Just strict_sig
 
 
-    rules = addRule id emptyCoreRules (primOpRule prim_op)
+    rules = foldl (addRule id) emptyCoreRules (primOpRules prim_op)
 
 
 -- For each ccall we manufacture a separate CCallOpId, giving it
 
 
 -- For each ccall we manufacture a separate CCallOpId, giving it
@@ -484,57 +681,84 @@ mkPrimOpId prim_op
 -- details of the ccall, type and all.  This means that the interface 
 -- file reader can reconstruct a suitable Id
 
 -- details of the ccall, type and all.  This means that the interface 
 -- file reader can reconstruct a suitable Id
 
-mkCCallOpId :: Unique -> CCall -> Type -> Id
-mkCCallOpId uniq ccall ty
+mkFCallId :: Unique -> ForeignCall -> Type -> Id
+mkFCallId uniq fcall ty
   = ASSERT( isEmptyVarSet (tyVarsOfType ty) )
        -- A CCallOpId should have no free type variables; 
        -- when doing substitutions won't substitute over it
   = 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 (FCallId fcall) name ty info
   where
   where
-    occ_str = showSDocIface (braces (pprCCallOp ccall <+> 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!
 
        -- The "occurrence name" of a ccall is the full info about the
        -- ccall; it is encoded, but may have embedded spaces etc!
 
-    name    = mkCCallName uniq occ_str
-    prim_op = CCallOp ccall
+    name = mkFCallName uniq occ_str
 
 
-    info = mkIdInfo (PrimOpId prim_op)
-          `setArityInfo`       exactArity arity
-          `setStrictnessInfo`  strict_info
+    info = noCafIdInfo
+          `setArityInfo`               arity
+          `setAllStrictnessInfo`       Just strict_sig
 
 
-    (_, tau)    = splitForAllTys ty
-    (arg_tys, _) = splitFunTys tau
+    (_, tau)    = tcSplitForAllTys ty
+    (arg_tys, _) = tcSplitFunTys tau
     arity       = length arg_tys
     arity       = length arg_tys
-    strict_info  = mkStrictnessInfo (take arity (repeat wwPrim), False)
+    strict_sig   = mkStrictSig (mkTopDmdType (replicate arity evalDmd) TopRes)
 \end{code}
 
 
 %************************************************************************
 %*                                                                     *
 \end{code}
 
 
 %************************************************************************
 %*                                                                     *
-\subsection{DictFuns}
+\subsection{DictFuns and default methods}
 %*                                                                     *
 %************************************************************************
 
 %*                                                                     *
 %************************************************************************
 
+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 (mkExportedLocalId) so 
+that they aren't discarded by the occurrence analyser.
+
 \begin{code}
 \begin{code}
+mkDefaultMethodId dm_name ty = mkExportedLocalId dm_name ty
+
 mkDictFunId :: Name            -- Name to use for the dict fun;
 mkDictFunId :: Name            -- Name to use for the dict fun;
-           -> Class 
            -> [TyVar]
            -> [TyVar]
+           -> ThetaType
+           -> Class 
            -> [Type]
            -> [Type]
-           -> ClassContext
            -> Id
 
            -> Id
 
-mkDictFunId dfun_name clas inst_tyvars inst_tys inst_decl_theta
-  = mkVanillaId dfun_name dfun_ty
+mkDictFunId dfun_name inst_tyvars dfun_theta clas inst_tys
+  = mkExportedLocalId dfun_name dfun_ty
   where
   where
-    (class_tyvars, sc_theta, _, _) = classBigSig clas
-    sc_theta' = substClasses (mkTopTyVarSubst class_tyvars inst_tys) sc_theta
-
-    dfun_theta = classesToPreds inst_decl_theta
+    dfun_ty = mkSigmaTy inst_tyvars dfun_theta (mkDictTy clas inst_tys)
 
 {-  1 dec 99: disable the Mark Jones optimisation for the sake
     of compatibility with Hugs.
     See `types/InstEnv' for a discussion related to this.
 
 
 {-  1 dec 99: disable the Mark Jones optimisation for the sake
     of compatibility with Hugs.
     See `types/InstEnv' for a discussion related to this.
 
+    (class_tyvars, sc_theta, _, _) = classBigSig clas
+    not_const (clas, tys) = not (isEmptyVarSet (tyVarsOfTypes tys))
+    sc_theta' = substClasses (zipTopTvSubst class_tyvars inst_tys) sc_theta
     dfun_theta = case inst_decl_theta of
                   []    -> []  -- If inst_decl_theta is empty, then we don't
                                -- want to have any dict arguments, so that we can
     dfun_theta = case inst_decl_theta of
                   []    -> []  -- If inst_decl_theta is empty, then we don't
                                -- want to have any dict arguments, so that we can
@@ -555,9 +779,6 @@ mkDictFunId dfun_name clas inst_tyvars inst_tys inst_decl_theta
                                --   instance Wob b => Baz T b where..
                                -- Now sc_theta' has Foo T
 -}
                                --   instance Wob b => Baz T b where..
                                -- Now sc_theta' has Foo T
 -}
-    dfun_ty = mkSigmaTy inst_tyvars dfun_theta (mkDictTy clas inst_tys)
-
-    not_const (clas, tys) = not (isEmptyVarSet (tyVarsOfTypes tys))
 \end{code}
 
 
 \end{code}
 
 
@@ -567,7 +788,12 @@ mkDictFunId dfun_name clas inst_tyvars inst_tys inst_decl_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
 
 unsafeCoerce# isn't so much a PrimOp as a phantom identifier, that
 just gets expanded into a type coercion wherever it occurs.  Hence we
@@ -578,11 +804,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}
 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) UserSyntax
+
+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
 unsafeCoerceId
-  = pcMiscPrelId unsafeCoerceIdKey pREL_GHC SLIT("unsafeCoerce#") ty info
+  = pcMiscPrelId unsafeCoerceName ty info
   where
   where
-    info = vanillaIdInfo
-          `setUnfoldingInfo` mkCompulsoryUnfolding rhs
+    info = noCafIdInfo `setUnfoldingInfo` mkCompulsoryUnfolding rhs
           
 
     ty  = mkForAllTys [openAlphaTyVar,openBetaTyVar]
           
 
     ty  = mkForAllTys [openAlphaTyVar,openBetaTyVar]
@@ -590,40 +839,67 @@ unsafeCoerceId
     [x] = mkTemplateLocals [openAlphaTy]
     rhs = mkLams [openAlphaTyVar,openBetaTyVar,x] $
          Note (Coerce openBetaTy openAlphaTy) (Var x)
     [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
   where
-    info = vanillaIdInfo
-          `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]
+-- gaw 2004
+    rhs = mkLams [alphaTyVar,openBetaTyVar,x,y] (Case (Var x) x openBetaTy [(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@).
 
 \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
 \begin{code}
 realWorldPrimId        -- :: State# RealWorld
-  = pcMiscPrelId realWorldPrimIdKey pREL_GHC SLIT("realWorld#")
-                realWorldStatePrimTy
-                (noCafIdInfo `setUnfoldingInfo` mkOtherCon [])
-       -- The mkOtherCon makes it look that realWorld# is evaluated
+  = pcMiscPrelId realWorldName realWorldStatePrimTy
+                (noCafIdInfo `setUnfoldingInfo` evaldUnfolding)
+       -- The evaldUnfolding 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
        -- 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}
 
 
 \end{code}
 
 
@@ -649,31 +925,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}
 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
-rEC_SEL_ERROR_ID
-  = generic_ERROR_ID recSelErrIdKey SLIT("patError")
-pAT_ERROR_ID
-  = generic_ERROR_ID patErrorIdKey SLIT("patError")
-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) noCafIdInfo
+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 (mkStringLit 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}
 
 
 \end{code}
 
 
@@ -684,42 +968,33 @@ pAR_ERROR_ID
 %************************************************************************
 
 \begin{code}
 %************************************************************************
 
 \begin{code}
-pcMiscPrelId :: Unique{-IdKey-} -> Module -> FAST_STRING -> Type -> IdInfo -> Id
-pcMiscPrelId key mod str ty info
-  = let
-       name = mkWiredInIdName key mod (mkSrcVarOcc str) imp
-       imp  = mkId 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.
 
     -- 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
  where
-    bottoming_info = noCafIdInfo 
-                    `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
+    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
 
 (openAlphaTyVar:openBetaTyVar:_) = openAlphaTyVars
 openAlphaTy  = mkTyVarTy openAlphaTyVar
 openBetaTy   = mkTyVarTy openBetaTyVar
-
-errorTy  :: Type
-errorTy  = mkUsgTy UsMany $
-           mkSigmaTy [openAlphaTyVar] [] (mkFunTys [mkUsgTy UsOnce (mkListTy charTy)] 
-                                                   (mkUsgTy UsMany 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}
 
 \end{code}