[project @ 2001-07-23 10:54:46 by simonpj]
[ghc-hetmet.git] / ghc / compiler / basicTypes / MkId.lhs
index 878868f..b3c6be3 100644 (file)
@@ -13,15 +13,12 @@ have a standard form, namely:
 
 \begin{code}
 module MkId (
-       mkSpecPragmaId, mkWorkerId,
-
        mkDictFunId, mkDefaultMethodId,
        mkDictSelId,
 
-       mkDataConId,
-       mkRecordSelId,
-       mkNewTySelId,
-       mkPrimitiveId,
+       mkDataConId, mkDataConWrapId,
+       mkRecordSelId, rebuildConArgs,
+       mkPrimOpId, mkFCallId,
 
        -- And some particular Ids; see below for why they are wired in
        wiredInIds,
@@ -34,60 +31,68 @@ module MkId (
 #include "HsVersions.h"
 
 
+import BasicTypes      ( Arity, StrictnessMark(..), isMarkedUnboxed, isMarkedStrict )
 import TysPrim         ( openAlphaTyVars, alphaTyVar, alphaTy, 
                          intPrimTy, realWorldStatePrimTy
                        )
-import TysWiredIn      ( boolTy, charTy, mkListTy )
-import PrelMods                ( pREL_ERR, pREL_GHC )
-import Type            ( Type, ThetaType,
-                         mkDictTy, mkTyConApp, mkTyVarTys, mkFunTys, mkFunTy, mkSigmaTy,
-                         isUnLiftedType, mkForAllTys, mkTyVarTy, tyVarsOfTypes,
-                         splitSigmaTy, splitFunTy_maybe, splitAlgTyConApp,
-                         splitFunTys, splitForAllTys, unUsgTy,
-                         mkUsgTy, UsageAnn(..)
+import TysWiredIn      ( charTy, mkListTy )
+import PrelNames       ( pREL_ERR, pREL_GHC )
+import PrelRules       ( primOpRule )
+import Rules           ( addRule )
+import TcType          ( Type, ThetaType, mkDictTy, mkPredTys, mkTyConApp,
+                         mkTyVarTys, mkClassPred, tcEqPred,
+                         mkFunTys, mkFunTy, mkSigmaTy, tcSplitSigmaTy, 
+                         isUnLiftedType, mkForAllTys, mkTyVarTy, tyVarsOfType,
+                         tcSplitFunTys, tcSplitForAllTys, mkPredTy
                        )
 import Module          ( Module )
-import CoreUnfold      ( mkTopUnfolding, mkCompulsoryUnfolding )
-import Subst           ( mkTopTyVarSubst, substTheta )
-import TyCon           ( TyCon, isNewTyCon, tyConDataCons, isDataTyCon )
-import Class           ( Class, classBigSig, classTyCon, classTyVars, classSelIds )
+import CoreUtils       ( exprType, mkInlineMe )
+import CoreUnfold      ( mkTopUnfolding, mkCompulsoryUnfolding, mkOtherCon )
+import Literal         ( Literal(..) )
+import TyCon           ( TyCon, isNewTyCon, tyConTyVars, tyConDataCons,
+                          tyConTheta, isProductTyCon, isDataTyCon, isRecursiveTyCon )
+import Class           ( Class, classTyCon, classTyVars, classSelIds )
 import Var             ( Id, TyVar )
 import VarSet          ( isEmptyVarSet )
-import Const           ( Con(..) )
-import Name            ( mkDerivedName, mkWiredInIdName, mkLocalName, 
-                         mkWorkerOcc, mkSuperDictSelOcc,
-                         Name, NamedThing(..),
-                       )
-import OccName         ( mkSrcVarOcc )
+import Name            ( mkWiredInName, mkFCallName, Name )
+import OccName         ( mkVarOcc )
 import PrimOp          ( PrimOp(DataToTagOp), primOpSig, mkPrimOpIdName )
-import Demand          ( wwStrict )
-import DataCon         ( DataCon, StrictnessMark(..), dataConStrictMarks, dataConFieldLabels, 
-                         dataConArgTys, dataConSig, dataConRawArgTys
+import ForeignCall     ( ForeignCall )
+import DataCon         ( DataCon, 
+                         dataConFieldLabels, dataConRepArity, dataConTyCon,
+                         dataConArgTys, dataConRepType, dataConRepStrictness, 
+                         dataConInstOrigArgTys,
+                          dataConName, dataConTheta,
+                         dataConSig, dataConStrictMarks, dataConId,
+                         splitProductType
                        )
-import Id              ( idType, mkId,
-                         mkVanillaId, mkTemplateLocals,
-                         mkTemplateLocal, setInlinePragma
+import Id              ( idType, mkGlobalId, mkVanillaGlobal, mkSysLocal,
+                         mkTemplateLocals, mkTemplateLocalsNum,
+                         mkTemplateLocal, idNewStrictness, idName
                        )
-import IdInfo          ( vanillaIdInfo, mkIdInfo,
-                         exactArity, setUnfoldingInfo, setCafInfo,
-                         setArityInfo, setInlinePragInfo,
-                         mkStrictnessInfo, setStrictnessInfo,
-                         IdFlavour(..), InlinePragInfo(..), CafInfo(..), IdInfo
+import IdInfo          ( IdInfo, noCafNoTyGenIdInfo,
+                         exactArity, setUnfoldingInfo, setCprInfo,
+                         setArityInfo, setSpecInfo,  setCgInfo,
+                         mkNewStrictnessInfo, setNewStrictnessInfo,
+                         GlobalIdDetails(..), CafInfo(..), CprInfo(..), 
+                         CgInfo(..), setCgArity
                        )
-import FieldLabel      ( FieldLabel, FieldLabelTag, mkFieldLabel, fieldLabelName, 
-                         firstFieldLabelTag, allFieldLabelTags
+import NewDemand       ( mkStrictSig, strictSigResInfo, DmdResult(..),
+                         mkTopDmdType, topDmd, evalDmd )
+import FieldLabel      ( mkFieldLabel, fieldLabelName, 
+                         firstFieldLabelTag, allFieldLabelTags, fieldLabelType
                        )
 import CoreSyn
+import Unique          ( mkBuiltinUnique )
 import Maybes
-import BasicTypes      ( Arity )
-import Unique
+import PrelNames
 import Maybe            ( isJust )
 import Outputable
-import Util            ( assoc )
-import List            ( nub )
+import ListSetOps      ( assoc, assocMaybe )
+import UnicodeUtil      ( stringToUtf8 )
+import Char             ( ord )
 \end{code}             
 
-
 %************************************************************************
 %*                                                                     *
 \subsection{Wired in Ids}
@@ -101,8 +106,9 @@ wiredInIds
        -- 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]
+       -- 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
@@ -114,7 +120,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
@@ -123,41 +129,51 @@ 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
-  = mkVanillaId dm_name ty
-
-mkWorkerId uniq unwrkr ty
-  = mkVanillaId (mkDerivedName mkWorkerOcc (getName unwrkr) uniq) ty
-\end{code}
-
-%************************************************************************
-%*                                                                     *
 \subsection{Data constructors}
 %*                                                                     *
 %************************************************************************
 
 \begin{code}
-mkDataConId :: DataCon -> Id
-mkDataConId data_con
-  = mkId (getName data_con)
-        id_ty
-        (dataConInfo data_con)
+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
+  = id 
   where
-    (tyvars, theta, ex_tyvars, ex_theta, arg_tys, tycon) = dataConSig data_con
-    id_ty = mkSigmaTy (tyvars ++ ex_tyvars) 
-                     (theta ++ ex_theta)
-                     (mkFunTys arg_tys (mkTyConApp tycon (mkTyVarTys tyvars)))
+    id = mkGlobalId (DataConId data_con) work_name (dataConRepType data_con) info
+    info = noCafNoTyGenIdInfo
+          `setCgArity`                 arity
+          `setArityInfo`               arity
+          `setNewStrictnessInfo`       Just strict_sig
+
+    arity = dataConRepArity data_con
+    strict_sig = mkStrictSig id arity (mkTopDmdType (dataConRepStrictness data_con) cpr_info)
+
+    tycon = dataConTyCon data_con
+    cpr_info | isProductTyCon tycon && 
+              isDataTyCon tycon    &&
+              arity > 0            &&
+              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
+
+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
+any strict args, unboxes any args that are going to be flattened, and calls
+the worker.
+
 We're going to build a constructor that looks like:
 
        data (Data a, C b) =>  T a b = T1 !a !Int b
@@ -192,61 +208,94 @@ Notice that
   it in the (common) case where the constructor arg is already evaluated.
 
 \begin{code}
-dataConInfo :: DataCon -> IdInfo
-
-dataConInfo data_con
-  = mkIdInfo (ConstantId (DataCon data_con))
-    `setArityInfo` exactArity (n_dicts + n_ex_dicts + n_id_args)
-    `setUnfoldingInfo` unfolding
+mkDataConWrapId data_con
+  = wrap_id
   where
-        unfolding = mkTopUnfolding (Note InlineMe con_rhs)
-       -- The dictionary constructors of a class don't get a binding,
-       -- but they are always saturated, so they should always be inlined.
-
-       (tyvars, theta, ex_tyvars, ex_theta, orig_arg_tys, tycon) 
-          = dataConSig data_con
-       rep_arg_tys = dataConRawArgTys 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]
-
-       n_dicts      = length dict_tys
-       n_ex_dicts   = length ex_dict_tys
-       n_id_args    = length orig_arg_tys
-       n_rep_args   = length rep_arg_tys
-
-       result_ty    = mkTyConApp tycon (mkTyVarTys tyvars)
-
-       mkLocals i n tys   = (zipWith mkTemplateLocal [i..i+n-1] tys, i+n)
-       (dict_args, i1)    = mkLocals 1  n_dicts    dict_tys
-       (ex_dict_args,i2)  = mkLocals i1 n_ex_dicts ex_dict_tys
-       (id_args,i3)       = mkLocals i2 n_id_args  orig_arg_tys
-
-       (id_arg1:_) = id_args           -- Used for newtype only
-       strict_marks  = dataConStrictMarks data_con
-
-       con_app i rep_ids
-                | isNewTyCon tycon 
-               = ASSERT( length orig_arg_tys == 1 )
-                 Note (Coerce result_ty (head orig_arg_tys)) (Var id_arg1)
-               | otherwise
-               = mkConApp data_con 
-                       (map Type (mkTyVarTys all_tyvars) ++ 
-                        map Var (reverse rep_ids))
-
-       con_rhs = mkLams all_tyvars $ mkLams dict_args $ 
-                 mkLams ex_dict_args $ mkLams id_args $
-                 foldr mk_case con_app 
+    wrap_id = mkGlobalId (DataConWrapId data_con) (dataConName data_con) wrap_ty info
+    work_id = dataConId data_con
+
+    info = noCafNoTyGenIdInfo
+          `setUnfoldingInfo`   mkTopUnfolding (mkInlineMe wrap_rhs)
+          `setCgArity`         arity
+               -- The NoCaf-ness is set by noCafNoTyGenIdInfo
+          `setArityInfo`       arity
+               -- It's important to specify the arity, so that partial
+               -- applications are treated as values
+          `setNewStrictnessInfo`       Just wrap_sig
+
+    wrap_ty = mkForAllTys all_tyvars $
+             mkFunTys all_arg_tys
+             result_ty
+
+    res_info = strictSigResInfo (idNewStrictness work_id)
+    wrap_sig = mkStrictSig wrap_id arity (mkTopDmdType (replicate arity topDmd) res_info)
+       -- The Cpr info can be important inside INLINE rhss, where the
+       -- wrapper constructor isn't inlined
+       -- But we are sloppy about the argument demands, because we expect 
+       -- to inline the constructor very vigorously.
+
+    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 context
+               -- e.g.         newtype Eq a => T a = MkT (...)
+               mkLams tyvars $ mkLams dict_args $ Lam id_arg1 $ 
+               mkNewTypeBody tycon result_ty id_arg1
+
+            | null dict_args && not (any isMarkedStrict 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,
+                               -- (We could match on the wrappers,
+                               -- but that makes it less likely that rules will match
+                               -- when we bring bits of unfoldings together.)
+               --
+               -- NB:  because of this special case, (map (:) ys) turns into
+               --      (map $w: ys), and thence into (map (\x xs. $w: x xs) ys)
+               --      in core-to-stg.  The top-level defn for (:) is never used.
+               --      This is somewhat of a bore, but I'm currently leaving it 
+               --      as is, so that there still is a top level curried (:) for
+               --      the interpreter to call.
+
+            | 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 []
 
-       mk_case 
-          :: (Id, StrictnessMark)      -- arg, strictness
-          -> (Int -> [Id] -> CoreExpr) -- body
-          -> Int                       -- next rep arg id
-          -> [Id]                      -- rep args so far
+    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     = 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)
+
+    mkLocals i tys = (zipWith mkTemplateLocal [i..i+n-1] tys, i+n)
+                  where
+                    n = length tys
+
+    (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
+
+    strict_marks  = dataConStrictMarks data_con
+
+    mk_case 
+          :: (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
+    mk_case (arg,strict) body i rep_args
          = case strict of
                NotMarkedStrict -> body i (arg:rep_args)
                MarkedStrict 
@@ -254,11 +303,13 @@ dataConInfo data_con
                   | otherwise ->
                        Case (Var arg) arg [(DEFAULT,[], body i (arg:rep_args))]
 
-               MarkedUnboxed con tys ->
-                  Case (Var arg) arg [(DataCon con, con_args,
-                                       body i' (reverse con_args++rep_args))]
-                  where n_tys = length tys
-                        (con_args,i') = mkLocals i (length tys) tys
+               MarkedUnboxed
+                  -> case splitProductType "do_unbox" (idType arg) of
+                          (tycon, tycon_args, con, tys) ->
+                                  Case (Var arg) arg [(DataAlt con, con_args,
+                                       body i' (reverse con_args ++ rep_args))]
+                             where 
+                               (con_args, i') = mkLocals i tys
 \end{code}
 
 
@@ -279,83 +330,197 @@ We're going to build a record selector unfolding that looks like this:
                                    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 newtypes
+
+       newtype N = MkN { unN :: forall a. a->a }
+
+       unN :: forall a. N -> a -> a
+       unN = /\a -> \n:N -> coerce (a->a) n
+
 \begin{code}
-mkRecordSelId field_label selector_ty
-  = ASSERT( null theta && isDataTyCon tycon )
-    sel_id
+mkRecordSelId tycon field_label unpack_id unpackUtf8_id
+       -- Assumes that all fields with the same field label have the same type
+       --
+       -- Annoyingly, we have to pass in the unpackCString# Id, because
+       -- we can't conjure it up out of thin air
+  = sel_id
   where
-    sel_id = mkId (fieldLabelName field_label) selector_ty info
-
-    info = mkIdInfo (RecordSelId field_label)
-          `setArityInfo`       exactArity 1
+    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
+    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 [ tcEqPred pred p
+                         | (DataAlt dc, _, _) <- the_alts, p <- dataConTheta dc]
+    n_dict_tys = length dict_tys
+
+    (field_tyvars,field_theta,field_tau) = tcSplitSigmaTy 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
+
+    selector_ty :: Type
+    selector_ty  = mkForAllTys tyvars $ mkForAllTys field_tyvars $
+                  mkFunTys dict_tys  $  mkFunTys field_dict_tys $
+                  mkFunTy data_ty field_tau
+      
+    arity = 1 + n_dict_tys + n_field_dict_tys
+    info = noCafNoTyGenIdInfo
+          `setCgInfo`          (CgInfo arity caf_info)
+          `setArityInfo`       arity
           `setUnfoldingInfo`   unfolding       
-          
        -- ToDo: consider adding further IdInfo
 
     unfolding = mkTopUnfolding sel_rhs
 
-    (tyvars, theta, tau)  = splitSigmaTy selector_ty
-    (data_ty,rhs_ty)      = expectJust "StdIdInfoRec" (splitFunTy_maybe tau)
-                                       -- tau is of form (T a b c -> field-type)
-    (tycon, _, data_cons) = splitAlgTyConApp data_ty
-    tyvar_tys            = mkTyVarTys tyvars
-       
-    [data_id] = mkTemplateLocals [data_ty]
+       -- 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 $ Lam data_id $
-               Case (Var data_id) data_id (the_alts ++ default_alt)
+    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 = mkNewTypeBody tycon field_tau data_id
+            | otherwise        = Case (Var data_id) data_id (default_alt ++ the_alts)
 
     mk_maybe_alt data_con 
          = case maybe_the_arg_id of
                Nothing         -> Nothing
-               Just the_arg_id -> Just (DataCon 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 rhs_ty), mkStringLit full_msg]
-       -- preserves invariant that type args are *not* usage-annotated on top.  KSW 1999-04.
+               Just the_arg_id -> Just (DataAlt data_con, real_args, mkLets binds body)
+                 where
+                   body               = mkVarApps (mkVarApps (Var the_arg_id) field_tyvars) field_dict_ids
+                   strict_marks       = dataConStrictMarks data_con
+                   (binds, real_args) = rebuildConArgs arg_ids strict_marks
+                                                       (map mkBuiltinUnique [unpack_base..])
+       where
+            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
+
+    error_expr = mkApps (Var rEC_SEL_ERROR_ID) [Type field_tau, err_string]
+    err_string
+        | all safeChar full_msg
+            = App (Var unpack_id) (Lit (MachStr (_PK_ full_msg)))
+        | otherwise
+            = App (Var unpackUtf8_id) (Lit (MachStr (_PK_ (stringToUtf8 (map ord full_msg)))))
+        where
+        safeChar c = c >= '\1' && c <= '\xFF'
+        -- TODO: Putting this Unicode stuff here is ugly. Find a better
+        -- generic place to make string literals. This logic is repeated
+        -- in DsUtils.
     full_msg   = showSDoc (sep [text "No match in record selector", ppr sel_id]) 
-\end{code}
 
 
-%************************************************************************
-%*                                                                     *
-\subsection{Newtype field selectors}
-%*                                                                     *
-%************************************************************************
+-- This rather ugly function converts the unpacked data con 
+-- arguments back into their packed form.
 
-Possibly overkill to do it this way:
+rebuildConArgs
+  :: [Id]                      -- Source-level args
+  -> [StrictnessMark]          -- Strictness annotations (per-arg)
+  -> [Unique]                  -- Uniques for the new Ids
+  -> ([CoreBind], [Id])                -- A binding for each source-level arg, plus
+                               -- a list of the representation-level arguments 
+-- e.g.   data T = MkT Int !Int
+--
+-- rebuild [x::Int, y::Int] [Not, Unbox]
+--  = ([ y = I# t ], [x,t])
 
-\begin{code}
-mkNewTySelId field_label selector_ty = sel_id
-  where
-    sel_id = mkId (fieldLabelName field_label) selector_ty info
-                 
+rebuildConArgs []        stricts us = ([], [])
 
-    info = mkIdInfo (RecordSelId field_label)
-          `setArityInfo`       exactArity 1    
-          `setUnfoldingInfo`   unfolding
-          
-       -- ToDo: consider adding further IdInfo
+-- Type variable case
+rebuildConArgs (arg:args) stricts us 
+  | isTyVar arg
+  = let (binds, args') = rebuildConArgs args stricts us
+    in  (binds, arg:args')
 
-    unfolding = mkTopUnfolding sel_rhs
+-- Term variable case
+rebuildConArgs (arg:args) (str:stricts) us
+  | isMarkedUnboxed str
+  = let
+       arg_ty  = idType arg
 
-    (tyvars, theta, tau)  = splitSigmaTy selector_ty
-    (data_ty,rhs_ty)      = expectJust "StdIdInfoRec" (splitFunTy_maybe tau)
-                                       -- tau is of form (T a b c -> field-type)
-    (tycon, _, data_cons) = splitAlgTyConApp data_ty
-    tyvar_tys            = mkTyVarTys tyvars
-       
-    [data_id] = mkTemplateLocals [data_ty]
-    sel_rhs   = mkLams tyvars $ Lam data_id $
-               Note (Coerce (unUsgTy rhs_ty) (unUsgTy data_ty)) (Var data_id)
+       (_, tycon_args, pack_con, con_arg_tys)
+                = splitProductType "rebuildConArgs" arg_ty
+
+       unpacked_args  = zipWith (mkSysLocal SLIT("rb")) us con_arg_tys
+       (binds, args') = rebuildConArgs args stricts (drop (length 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') = rebuildConArgs args stricts us
+    in  (binds, arg:args')
 \end{code}
 
 
@@ -366,17 +531,28 @@ mkNewTySelId field_label selector_ty = sel_id
 %************************************************************************
 
 Selecting a field for a dictionary.  If there is just one field, then
-there's nothing to do.
+there's nothing to do.  
+
+ToDo: unify with mkRecordSelId.
 
 \begin{code}
-mkDictSelId name clas ty
-  = sel_id
+mkDictSelId :: Name -> Class -> Id
+mkDictSelId name clas
+  = mkGlobalId (RecordSelId field_lbl) name sel_ty info
   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)
+    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)
+
+    field_lbl = mkFieldLabel name tycon sel_ty tag
+    tag       = assoc "MkId.mkDictSelId" (map idName (classSelIds clas) `zip` allFieldLabelTags) name
+
+    info      = noCafNoTyGenIdInfo
+               `setCgArity`        1
+               `setArityInfo`      1
                `setUnfoldingInfo`  unfolding
                
        -- We no longer use 'must-inline' on record selectors.  They'll
@@ -392,14 +568,20 @@ mkDictSelId name clas ty
     arg_tys    = dataConArgTys data_con tyvar_tys
     the_arg_id = arg_ids !! (tag - firstFieldLabelTag)
 
-    dict_ty    = mkDictTy clas tyvar_tys
-    (dict_id:arg_ids) = mkTemplateLocals (dict_ty : arg_tys)
+    pred             = mkClassPred clas tyvar_tys
+    (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) dict_id
        | otherwise        = mkLams tyvars $ Lam dict_id $
                             Case (Var dict_id) dict_id
-                                 [(DataCon data_con, arg_ids, Var the_arg_id)]
+                                 [(DataAlt data_con, arg_ids, Var the_arg_id)]
+
+mkNewTypeBody tycon result_ty result_id
+  | isRecursiveTyCon tycon     -- Recursive case; use a coerce
+  = Note (Coerce result_ty (idType result_id)) (Var result_id)
+  | otherwise                  -- Normal case
+  = Var result_id
 \end{code}
 
 
@@ -410,36 +592,71 @@ mkDictSelId name clas ty
 %************************************************************************
 
 \begin{code}
-mkPrimitiveId :: PrimOp -> Id
-mkPrimitiveId prim_op 
+mkPrimOpId :: PrimOp -> Id
+mkPrimOpId prim_op 
   = id
   where
-    (tyvars,arg_tys,res_ty) = primOpSig 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
-    id   = mkId name ty info
+    name = mkPrimOpIdName prim_op
+    id   = mkGlobalId (PrimOpId prim_op) name ty info
                
-    info = mkIdInfo (ConstantId (PrimOp prim_op))
-          `setUnfoldingInfo`   unfolding
-
-    unfolding = mkCompulsoryUnfolding rhs
-               -- The mkCompulsoryUnfolding says that this Id absolutely 
-               -- must be inlined.  It's only used for primitives, 
-               -- because we don't want to make a closure for each of them.
-
-    args = mkTemplateLocals arg_tys
-    rhs =  mkLams tyvars $ mkLams args $
-          mkPrimApp prim_op (map Type (mkTyVarTys tyvars) ++ map Var args)
+    info = noCafNoTyGenIdInfo
+          `setSpecInfo`        rules
+          `setCgArity`         arity
+          `setArityInfo`       arity
+          `setNewStrictnessInfo`       Just (mkNewStrictnessInfo id arity strict_info NoCPRInfo)
+       -- Until we modify the primop generation code
+
+    rules = maybe emptyCoreRules (addRule emptyCoreRules id)
+               (primOpRule prim_op)
+
+
+-- For each ccall we manufacture a separate CCallOpId, giving it
+-- a fresh unique, a type that is correct for this particular ccall,
+-- and a CCall structure that gives the correct details about calling
+-- convention etc.  
+--
+-- The *name* of this Id is a local name whose OccName gives the full
+-- details of the ccall, type and all.  This means that the interface 
+-- file reader can reconstruct a suitable Id
+
+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
+    id
+  where
+    id = mkGlobalId (FCallId fcall) name ty info
+    occ_str = showSDocIface (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!
+
+    name = mkFCallName uniq occ_str
+
+    info = noCafNoTyGenIdInfo
+          `setCgArity`                 arity
+          `setArityInfo`               arity
+          `setNewStrictnessInfo`       Just strict_sig
+
+    (_, tau)    = tcSplitForAllTys ty
+    (arg_tys, _) = tcSplitFunTys tau
+    arity       = length arg_tys
+    strict_sig   = mkStrictSig id arity (mkTopDmdType (replicate arity evalDmd) TopRes)
 \end{code}
 
 
 %************************************************************************
 %*                                                                     *
-\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]
@@ -447,17 +664,18 @@ mkDictFunId :: Name               -- Name to use for the dict fun;
            -> ThetaType
            -> Id
 
-mkDictFunId dfun_name clas inst_tyvars inst_tys inst_decl_theta
-  = mkVanillaId dfun_name dfun_ty
+mkDictFunId dfun_name clas inst_tyvars inst_tys dfun_theta
+  = mkVanillaGlobal dfun_name dfun_ty noCafNoTyGenIdInfo
   where
-    (class_tyvars, sc_theta, _, _) = classBigSig clas
-    sc_theta' = substTheta (mkTopTyVarSubst class_tyvars inst_tys) sc_theta
-
-    dfun_theta = 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.
 
+    (class_tyvars, sc_theta, _, _) = classBigSig clas
+    not_const (clas, tys) = not (isEmptyVarSet (tyVarsOfTypes tys))
+    sc_theta' = substClasses (mkTopTyVarSubst 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
@@ -478,9 +696,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
 -}
-    dfun_ty = mkSigmaTy inst_tyvars dfun_theta (mkDictTy clas inst_tys)
-
-    not_const (clas, tys) = not (isEmptyVarSet (tyVarsOfTypes tys))
 \end{code}
 
 
@@ -504,8 +719,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]
@@ -523,15 +737,15 @@ 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)
     [x,y] = mkTemplateLocals [alphaTy,alphaTy]
     rhs = mkLams [alphaTyVar,x] $
-         Case (Var x) y [ (DEFAULT, [], 
-                  Con (PrimOp DataToTagOp) [Type alphaTy, Var y]) ]
+         Case (Var x) y [ (DEFAULT, [], mkApps (Var dataToTagId) [Type alphaTy, Var y]) ]
+
+dataToTagId = mkPrimOpId DataToTagOp
 \end{code}
 
 @realWorld#@ used to be a magic literal, \tr{void#}.  If things get
@@ -541,7 +755,11 @@ nasty as-is, change it back to a literal (@Literal@).
 realWorldPrimId        -- :: State# RealWorld
   = pcMiscPrelId realWorldPrimIdKey pREL_GHC SLIT("realWorld#")
                 realWorldStatePrimTy
-                noCafIdInfo
+                (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
+       -- to be inlined
 \end{code}
 
 
@@ -569,10 +787,10 @@ 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_SEL_ERROR_ID
+  = generic_ERROR_ID recSelErrIdKey SLIT("recSelError")
 rEC_CON_ERROR_ID
   = generic_ERROR_ID recConErrorIdKey SLIT("recConError")
 rEC_UPD_ERROR_ID
@@ -590,8 +808,7 @@ aBSENT_ERROR_ID
 
 pAR_ERROR_ID
   = pcMiscPrelId parErrorIdKey pREL_ERR SLIT("parError")
-    (mkSigmaTy [openAlphaTyVar] [] openAlphaTy) noCafIdInfo
-
+    (mkSigmaTy [openAlphaTyVar] [] openAlphaTy) noCafNoTyGenIdInfo
 \end{code}
 
 
@@ -605,8 +822,8 @@ pAR_ERROR_ID
 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...
+       name = mkWiredInName mod (mkVarOcc str) key
+       imp  = mkVanillaGlobal name ty info -- the usual case...
     in
     imp
     -- We lie and say the thing is imported; otherwise, we get into
@@ -616,26 +833,23 @@ pcMiscPrelId key mod str ty info
     -- will be in "the right place" to be in scope.
 
 pc_bottoming_Id key mod name ty
- = pcMiscPrelId key mod name ty bottoming_info
+ = id
  where
-    bottoming_info = noCafIdInfo 
-                    `setStrictnessInfo` mkStrictnessInfo ([wwStrict], True)
-                    
+    id = pcMiscPrelId key mod name ty bottoming_info
+    arity         = 1
+    strict_sig    = mkStrictSig id arity (mkTopDmdType [evalDmd] BotRes)
+    bottoming_info = noCafNoTyGenIdInfo `setNewStrictnessInfo` Just strict_sig
        -- 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
 
 errorTy  :: Type
-errorTy  = mkUsgTy UsMany $
-           mkSigmaTy [openAlphaTyVar] [] (mkFunTys [mkUsgTy UsOnce (mkListTy charTy)] 
-                                                   (mkUsgTy UsMany openAlphaTy))
+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.