X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Fcompiler%2FbasicTypes%2FMkId.lhs;h=477d63c541a828018f910467b2b13669c5d86625;hb=d069cec2bd92d4156aeab80f7eb1f222a82e4103;hp=87b49efda8a41ca420b833bc3a3a777fb7631604;hpb=cae34044d89a87bd3da83b0e867b4a5d6994079a;p=ghc-hetmet.git diff --git a/ghc/compiler/basicTypes/MkId.lhs b/ghc/compiler/basicTypes/MkId.lhs index 87b49ef..477d63c 100644 --- a/ghc/compiler/basicTypes/MkId.lhs +++ b/ghc/compiler/basicTypes/MkId.lhs @@ -13,14 +13,12 @@ have a standard form, namely: \begin{code} module MkId ( - mkSpecPragmaId, mkWorkerId, - mkDictFunId, mkDefaultMethodId, mkDictSelId, mkDataConId, mkDataConWrapId, - mkRecordSelId, - mkPrimOpId, mkCCallOpId, + mkRecordSelId, rebuildConArgs, + mkPrimOpId, mkFCallId, -- And some particular Ids; see below for why they are wired in wiredInIds, @@ -33,71 +31,68 @@ module MkId ( #include "HsVersions.h" +import BasicTypes ( Arity ) import TysPrim ( openAlphaTyVars, alphaTyVar, alphaTy, intPrimTy, realWorldStatePrimTy ) -import TysWiredIn ( boolTy, charTy, mkListTy ) +import TysWiredIn ( charTy, mkListTy ) import PrelNames ( pREL_ERR, pREL_GHC ) import PrelRules ( primOpRule ) import Rules ( addRule ) -import Type ( Type, ClassContext, mkDictTy, mkDictTys, mkTyConApp, mkTyVarTys, - mkFunTys, mkFunTy, mkSigmaTy, classesToPreds, - isUnLiftedType, mkForAllTys, mkTyVarTy, tyVarsOfType, tyVarsOfTypes, - splitSigmaTy, splitFunTy_maybe, - splitFunTys, splitForAllTys, unUsgTy, - mkUsgTy, UsageAnn(..) +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 CoreUtils ( exprType, mkInlineMe ) import CoreUnfold ( mkTopUnfolding, mkCompulsoryUnfolding, mkOtherCon ) import Literal ( Literal(..) ) -import TyCon ( TyCon, isNewTyCon, tyConTyVars, tyConDataCons, isDataTyCon, - tyConTheta, isProductTyCon, isUnboxedTupleTyCon ) -import Class ( Class, classBigSig, classTyCon, classTyVars, classSelIds ) +import TyCon ( TyCon, isNewTyCon, tyConTyVars, tyConDataCons, + tyConTheta, isProductTyCon, isDataTyCon, isRecursiveTyCon ) +import Class ( Class, classTyCon, classTyVars, classSelIds ) import Var ( Id, TyVar ) 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, mkStrictnessInfo ) -import DataCon ( DataCon, StrictnessMark(..), +import Name ( mkWiredInName, mkFCallName, Name ) +import OccName ( mkVarOcc ) +import PrimOp ( PrimOp(DataToTagOp), primOpSig, mkPrimOpIdName ) +import ForeignCall ( ForeignCall ) +import Demand ( wwStrict, wwPrim, mkStrictnessInfo, + StrictnessMark(..), isMarkedUnboxed, isMarkedStrict ) +import DataCon ( DataCon, dataConFieldLabels, dataConRepArity, dataConTyCon, dataConArgTys, dataConRepType, dataConRepStrictness, dataConInstOrigArgTys, dataConName, dataConTheta, dataConSig, dataConStrictMarks, dataConId, - maybeMarkedUnboxed, splitProductType_maybe + splitProductType ) -import Id ( idType, mkId, - mkVanillaId, mkTemplateLocals, - mkTemplateLocal, setInlinePragma, idCprInfo +import Id ( idType, mkGlobalId, mkVanillaGlobal, mkSysLocal, + mkTemplateLocals, mkTemplateLocalsNum, + mkTemplateLocal, idCprInfo, idName ) -import IdInfo ( IdInfo, vanillaIdInfo, mkIdInfo, - exactArity, setUnfoldingInfo, setCafInfo, setCprInfo, - setArityInfo, setInlinePragInfo, setSpecInfo, +import IdInfo ( IdInfo, noCafNoTyGenIdInfo, + exactArity, setUnfoldingInfo, setCprInfo, + setArityInfo, setSpecInfo, setCgInfo, mkStrictnessInfo, setStrictnessInfo, - IdFlavour(..), InlinePragInfo(..), CafInfo(..), StrictnessInfo(..), CprInfo(..) + GlobalIdDetails(..), CafInfo(..), CprInfo(..), + CgInfo(..), setCgArity ) -import FieldLabel ( FieldLabel, FieldLabelTag, mkFieldLabel, fieldLabelName, +import FieldLabel ( mkFieldLabel, fieldLabelName, firstFieldLabelTag, allFieldLabelTags, fieldLabelType ) import CoreSyn +import Unique ( mkBuiltinUnique ) import Maybes -import Unique +import PrelNames import Maybe ( isJust ) import Outputable -import Util ( assoc ) +import ListSetOps ( assoc, assocMaybe ) import UnicodeUtil ( stringToUtf8 ) import Char ( ord ) \end{code} - %************************************************************************ %* * \subsection{Wired in Ids} @@ -111,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 @@ -124,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 @@ -133,24 +129,6 @@ wiredInIds %************************************************************************ %* * -\subsection{Easy ones} -%* * -%************************************************************************ - -\begin{code} -mkSpecPragmaId occ uniq ty loc - = mkId (mkLocalName uniq occ loc) ty (mkIdInfo SpecPragmaId) - -- Maybe a SysLocal? But then we'd lose the location - -mkDefaultMethodId dm_name rec_c ty - = mkVanillaId dm_name ty - -mkWorkerId uniq unwrkr ty - = mkVanillaId (mkDerivedName mkWorkerOcc (getName unwrkr) uniq) ty -\end{code} - -%************************************************************************ -%* * \subsection{Data constructors} %* * %************************************************************************ @@ -160,9 +138,10 @@ mkDataConId :: Name -> DataCon -> Id -- Makes the *worker* for the data constructor; that is, the function -- that takes the reprsentation arguments and builds the constructor. mkDataConId work_name data_con - = mkId work_name (dataConRepType data_con) info + = mkGlobalId (DataConId data_con) work_name (dataConRepType data_con) info where - info = mkIdInfo (DataConId data_con) + info = noCafNoTyGenIdInfo + `setCgArity` arity `setArityInfo` exactArity arity `setStrictnessInfo` strict_info `setCprInfo` cpr_info @@ -171,20 +150,25 @@ mkDataConId work_name data_con strict_info = mkStrictnessInfo (dataConRepStrictness data_con, False) + tycon = dataConTyCon data_con cpr_info | isProductTyCon tycon && - not (isUnboxedTupleTyCon tycon) && - arity > 0 = ReturnsCPR - | otherwise = NoCPRInfo - where - tycon = dataConTyCon data_con - -- Newtypes don't have a worker at all - -- - -- If we are a product with 0 args we must be void(like) - -- We can't create an unboxed tuple with 0 args for this - -- and since Void has only one, constant value it should - -- just mean returning a pointer to a pre-existing cell. - -- So we won't really gain from doing anything fancy - -- and we treat this case as Top. + isDataTyCon tycon && + arity > 0 && + arity <= mAX_CPR_SIZE = ReturnsCPR + | otherwise = NoCPRInfo + -- ReturnsCPR is only true for products that are real data types; + -- that is, not unboxed tuples or [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 @@ -228,21 +212,19 @@ Notice that mkDataConWrapId data_con = wrap_id where - wrap_id = mkId (dataConName data_con) wrap_ty info + wrap_id = mkGlobalId (DataConWrapId data_con) (dataConName data_con) wrap_ty info work_id = dataConId data_con - info = mkIdInfo (DataConWrapId data_con) + info = noCafNoTyGenIdInfo `setUnfoldingInfo` mkTopUnfolding (mkInlineMe wrap_rhs) `setCprInfo` cpr_info -- The Cpr info can be important inside INLINE rhss, where the -- wrapper constructor isn't inlined + `setCgArity` arity + -- The NoCaf-ness is set by noCafNoTyGenIdInfo `setArityInfo` exactArity arity -- It's important to specify the arity, so that partial -- applications are treated as values - `setCafInfo` NoCafRefs - -- The wrapper Id ends up in STG code as an argument, - -- sometimes before its definition, so we want to - -- signal that it has no CAFs wrap_ty = mkForAllTys all_tyvars $ mkFunTys all_arg_tys @@ -254,11 +236,10 @@ mkDataConWrapId data_con = 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 - mkLams tyvars $ mkLams dict_args $ Lam id_arg1 $ - Note (Coerce result_ty (head orig_arg_tys)) (Var id_arg1) - - | null dict_args && all not_marked_strict strict_marks + | 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. @@ -289,8 +270,8 @@ mkDataConWrapId data_con (tyvars, theta, ex_tyvars, ex_theta, orig_arg_tys, tycon) = dataConSig data_con all_tyvars = tyvars ++ ex_tyvars - dict_tys = mkDictTys theta - ex_dict_tys = mkDictTys ex_theta + dict_tys = mkPredTys theta + ex_dict_tys = mkPredTys ex_theta all_arg_tys = dict_tys ++ ex_dict_tys ++ orig_arg_tys result_ty = mkTyConApp tycon (mkTyVarTys tyvars) @@ -305,15 +286,12 @@ mkDataConWrapId data_con (id_arg1:_) = id_args -- Used for newtype only strict_marks = dataConStrictMarks data_con - not_marked_strict NotMarkedStrict = True - not_marked_strict other = False - 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 @@ -323,11 +301,13 @@ mkDataConWrapId data_con | 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 - (con_args,i') = mkLocals i 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} @@ -383,71 +363,109 @@ mkRecordSelId tycon field_label unpack_id unpackUtf8_id -- we can't conjure it up out of thin air = sel_id where - sel_id = mkId (fieldLabelName field_label) selector_ty info - + sel_id = mkGlobalId (RecordSelId field_label) (fieldLabelName field_label) selector_ty info field_ty = fieldLabelType field_label data_cons = tyConDataCons tycon tyvars = tyConTyVars tycon -- These scope over the types in -- the FieldLabels of constructors of this type - tycon_theta = tyConTheta tycon -- The context on the data decl - -- eg data (Eq a, Ord b) => T a b = ... - (field_tyvars,field_tau) = splitForAllTys field_ty - data_ty = mkTyConApp tycon tyvar_tys tyvar_tys = mkTyVarTys tyvars + tycon_theta = tyConTheta tycon -- The context on the data decl + -- eg data (Eq a, Ord b) => T a b = ... + dict_tys = [mkPredTy pred | pred <- tycon_theta, + needed_dict pred] + needed_dict pred = or [ 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 - dict_tys = [mkDictTy cls tys | (cls, tys) <- tycon_theta, needed_dict (cls, tys)] - needed_dict pred = or [ pred `elem` (dataConTheta dc) - | (DataAlt dc, _, _) <- the_alts] selector_ty :: Type selector_ty = mkForAllTys tyvars $ mkForAllTys field_tyvars $ - mkFunTys dict_tys $ mkFunTy data_ty field_tau + mkFunTys dict_tys $ mkFunTys field_dict_tys $ + mkFunTy data_ty field_tau - info = mkIdInfo (RecordSelId field_label) - `setArityInfo` exactArity (1 + length dict_tys) + arity = 1 + n_dict_tys + n_field_dict_tys + info = noCafNoTyGenIdInfo + `setCgInfo` (CgInfo arity caf_info) + `setArityInfo` exactArity arity `setUnfoldingInfo` unfolding - `setCafInfo` NoCafRefs -- ToDo: consider adding further IdInfo unfolding = mkTopUnfolding sel_rhs - - (data_id:dict_ids) = mkTemplateLocals (data_ty:dict_tys) + -- Allocate Ids. We do it a funny way round because field_dict_tys is + -- almost always empty. Also note that we use length_tycon_theta + -- rather than n_dict_tys, because the latter gives an infinite loop: + -- n_dict tys depends on the_alts, which depens on arg_ids, which depends + -- on arity, which depends on n_dict tys. Sigh! Mega sigh! + field_dict_base = length tycon_theta + 1 + dict_id_base = field_dict_base + n_field_dict_tys + field_base = dict_id_base + 1 + dict_ids = mkTemplateLocalsNum 1 dict_tys + field_dict_ids = mkTemplateLocalsNum field_dict_base field_dict_tys + data_id = mkTemplateLocal dict_id_base data_ty + alts = map mk_maybe_alt data_cons the_alts = catMaybes alts - default_alt | all isJust alts = [] -- No default needed - | otherwise = [(DEFAULT, [], error_expr)] - sel_rhs = mkLams tyvars $ mkLams field_tyvars $ - mkLams dict_ids $ Lam data_id $ - sel_body + no_default = all isJust alts -- No default needed + default_alt | no_default = [] + | otherwise = [(DEFAULT, [], error_expr)] + + -- the default branch may have CAF refs, because it calls recSelError etc. + caf_info | no_default = NoCafRefs + | otherwise = MayHaveCafRefs - sel_body | isNewTyCon tycon = Note (Coerce (unUsgTy field_tau) (unUsgTy data_ty)) (Var data_id) - | otherwise = 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 + + 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 (DataAlt data_con, real_args, expr) + Just the_arg_id -> Just (DataAlt data_con, real_args, mkLets binds body) where - body = mkVarApps (Var the_arg_id) field_tyvars - strict_marks = dataConStrictMarks data_con - (expr, real_args) = rebuildConArgs data_con arg_ids strict_marks body - (length arg_ids + 1) + 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 = mkTemplateLocals (dataConInstOrigArgTys data_con tyvar_tys) - -- The first one will shadow data_id, but who cares + arg_ids = mkTemplateLocalsNum field_base (dataConInstOrigArgTys data_con tyvar_tys) + + unpack_base = field_base + length arg_ids + + -- arity+1 avoids all shadowing maybe_the_arg_id = assocMaybe (field_lbls `zip` arg_ids) field_label field_lbls = dataConFieldLabels data_con - error_expr = mkApps (Var rEC_SEL_ERROR_ID) [Type (unUsgTy field_tau), err_string] - -- preserves invariant that type args are *not* usage-annotated on top. KSW 1999-04. + 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))) @@ -461,41 +479,46 @@ mkRecordSelId tycon field_label unpack_id unpackUtf8_id full_msg = showSDoc (sep [text "No match in record selector", ppr sel_id]) --- this rather ugly function converts the unpacked data con arguments back into --- their packed form. It is almost the same as the version in DsUtils, except that --- we use template locals here rather than newDsId (ToDo: merge these). +-- This rather ugly function converts the unpacked data con +-- arguments back into their packed form. rebuildConArgs - :: DataCon -- the con we're matching on - -> [Id] -- the source-level args - -> [StrictnessMark] -- the strictness annotations (per-arg) - -> CoreExpr -- the body - -> Int -- template local - -> (CoreExpr, [Id]) - -rebuildConArgs con [] stricts body i = (body, []) -rebuildConArgs con (arg:args) stricts body i | isTyVar arg - = let (body', args') = rebuildConArgs con args stricts body i - in (body',arg:args') -rebuildConArgs con (arg:args) (str:stricts) body i - = case maybeMarkedUnboxed str of - Just (pack_con1, _) -> - case splitProductType_maybe (idType arg) of - Just (_, tycon_args, pack_con, con_arg_tys) -> - ASSERT( pack_con == pack_con1 ) - let unpacked_args = zipWith mkTemplateLocal [i..] con_arg_tys - (body', real_args) = rebuildConArgs con args stricts body - (i + length con_arg_tys) - in - ( - Let (NonRec arg (mkConApp pack_con - (map Type tycon_args ++ - map Var unpacked_args))) body', - unpacked_args ++ real_args - ) - - _ -> let (body', args') = rebuildConArgs con args stricts body i - in (body', arg:args') + :: [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]) + +rebuildConArgs [] stricts us = ([], []) + +-- Type variable case +rebuildConArgs (arg:args) stricts us + | isTyVar arg + = let (binds, args') = rebuildConArgs args stricts us + in (binds, arg:args') + +-- Term variable case +rebuildConArgs (arg:args) (str:stricts) us + | isMarkedUnboxed str + = let + arg_ty = idType arg + + (_, 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} @@ -513,17 +536,22 @@ ToDo: unify with mkRecordSelId. \begin{code} mkDictSelId :: Name -> Class -> Id mkDictSelId name clas - = sel_id + = mkGlobalId (RecordSelId field_lbl) name sel_ty info where - ty = exprType rhs - sel_id = mkId name ty info - field_lbl = mkFieldLabel name tycon ty tag - tag = assoc "MkId.mkDictSelId" (classSelIds clas `zip` allFieldLabelTags) sel_id - - info = mkIdInfo (RecordSelId field_lbl) + 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` exactArity 1 `setUnfoldingInfo` unfolding - `setCafInfo` NoCafRefs -- We no longer use 'must-inline' on record selectors. They'll -- inline like crazy if they scrutinise a constructor @@ -538,14 +566,20 @@ mkDictSelId name clas 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 [(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} @@ -562,15 +596,17 @@ mkPrimOpId prim_op where (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 (PrimOpId prim_op) + info = noCafNoTyGenIdInfo `setSpecInfo` rules + `setCgArity` arity `setArityInfo` exactArity arity `setStrictnessInfo` strict_info - rules = addRule id emptyCoreRules (primOpRule prim_op) + rules = maybe emptyCoreRules (addRule emptyCoreRules id) + (primOpRule prim_op) -- For each ccall we manufacture a separate CCallOpId, giving it @@ -582,26 +618,26 @@ mkPrimOpId prim_op -- 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 - mkId name ty info + mkGlobalId (FCallId fcall) name ty info where - occ_str = showSDocIface (braces (pprCCallOp ccall <+> ppr ty)) + 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 = mkCCallName uniq occ_str - prim_op = CCallOp ccall + name = mkFCallName uniq occ_str - info = mkIdInfo (PrimOpId prim_op) + info = noCafNoTyGenIdInfo + `setCgArity` arity `setArityInfo` exactArity arity `setStrictnessInfo` strict_info - (_, tau) = splitForAllTys ty - (arg_tys, _) = splitFunTys tau + (_, tau) = tcSplitForAllTys ty + (arg_tys, _) = tcSplitFunTys tau arity = length arg_tys strict_info = mkStrictnessInfo (take arity (repeat wwPrim), False) \end{code} @@ -609,22 +645,25 @@ mkCCallOpId uniq ccall ty %************************************************************************ %* * -\subsection{DictFuns} +\subsection{DictFuns and default methods} %* * %************************************************************************ \begin{code} +mkDefaultMethodId dm_name ty + = mkVanillaGlobal dm_name ty noCafNoTyGenIdInfo + mkDictFunId :: Name -- Name to use for the dict fun; -> Class -> [TyVar] -> [Type] - -> ClassContext + -> 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 - 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. @@ -653,7 +692,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) \end{code} @@ -677,8 +715,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] @@ -696,8 +733,7 @@ evaluate its argument and call the dataToTag# primitive. getTagId = pcMiscPrelId getTagIdKey pREL_GHC SLIT("getTag#") ty info where - info = vanillaIdInfo - `setUnfoldingInfo` mkCompulsoryUnfolding rhs + info = noCafNoTyGenIdInfo `setUnfoldingInfo` mkCompulsoryUnfolding rhs -- We don't provide a defn for this; you must inline it ty = mkForAllTys [alphaTyVar] (mkFunTy alphaTy intPrimTy) @@ -715,7 +751,7 @@ nasty as-is, change it back to a literal (@Literal@). realWorldPrimId -- :: State# RealWorld = pcMiscPrelId realWorldPrimIdKey pREL_GHC SLIT("realWorld#") realWorldStatePrimTy - (noCafIdInfo `setUnfoldingInfo` mkOtherCon []) + (noCafNoTyGenIdInfo `setUnfoldingInfo` mkOtherCon []) -- The mkOtherCon makes it look that realWorld# is evaluated -- which in turn makes Simplify.interestingArg return True, -- which in turn makes INLINE things applied to realWorld# likely @@ -768,8 +804,7 @@ aBSENT_ERROR_ID pAR_ERROR_ID = pcMiscPrelId parErrorIdKey pREL_ERR SLIT("parError") - (mkSigmaTy [openAlphaTyVar] [] openAlphaTy) noCafIdInfo - + (mkSigmaTy [openAlphaTyVar] [] openAlphaTy) noCafNoTyGenIdInfo \end{code} @@ -783,8 +818,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 @@ -796,24 +831,20 @@ pcMiscPrelId key mod str ty info pc_bottoming_Id key mod name ty = pcMiscPrelId key mod name ty bottoming_info where - bottoming_info = noCafIdInfo + bottoming_info = noCafNoTyGenIdInfo `setStrictnessInfo` mkStrictnessInfo ([wwStrict], True) - + -- these "bottom" out, no matter what their arguments generic_ERROR_ID u n = pc_bottoming_Id u pREL_ERR n errorTy --- Very useful... -noCafIdInfo = vanillaIdInfo `setCafInfo` NoCafRefs - (openAlphaTyVar:openBetaTyVar:_) = openAlphaTyVars openAlphaTy = mkTyVarTy openAlphaTyVar openBetaTy = mkTyVarTy openBetaTyVar 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.