X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Fcompiler%2FbasicTypes%2FMkId.lhs;h=067693521126122df226606419c1a7771cb14de5;hb=531d0d264fafd66aece5ca38d2bfcd266a8fd3e5;hp=e18985c45e6d309643f5b7b02b7718d520765882;hpb=cb4c09e45216fac8eb941a5e114de47a60fe4b46;p=ghc-hetmet.git diff --git a/ghc/compiler/basicTypes/MkId.lhs b/ghc/compiler/basicTypes/MkId.lhs index e18985c..0676935 100644 --- a/ghc/compiler/basicTypes/MkId.lhs +++ b/ghc/compiler/basicTypes/MkId.lhs @@ -36,31 +36,29 @@ module MkId ( 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 Type ( Type, ThetaType, mkDictTy, mkDictTys, mkTyConApp, mkTyVarTys, + mkFunTys, mkFunTy, mkSigmaTy, splitSigmaTy, + isUnLiftedType, mkForAllTys, mkTyVarTy, tyVarsOfType, + splitFunTys, splitForAllTys, 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 ) +import Class ( Class, classTyCon, classTyVars, classSelIds ) import Var ( Id, TyVar ) import VarSet ( isEmptyVarSet ) -import Name ( mkDerivedName, mkWiredInIdName, mkLocalName, - mkWorkerOcc, mkSuperDictSelOcc, mkCCallName, - Name, NamedThing(..), +import Name ( mkWiredInName, mkLocalName, + mkWorkerOcc, mkCCallName, + Name, NamedThing(..), getSrcLoc ) -import OccName ( mkSrcVarOcc ) +import OccName ( mkVarOcc ) import PrimOp ( PrimOp(DataToTagOp, CCallOp), primOpSig, mkPrimOpIdName, CCall, pprCCallOp @@ -75,24 +73,24 @@ import DataCon ( DataCon, StrictnessMark(..), maybeMarkedUnboxed, splitProductType_maybe ) import Id ( idType, mkId, - mkVanillaId, mkTemplateLocals, - mkTemplateLocal, setInlinePragma, idCprInfo + mkVanillaId, mkTemplateLocals, mkTemplateLocalsNum, + mkTemplateLocal, idCprInfo ) -import IdInfo ( IdInfo, vanillaIdInfo, mkIdInfo, +import IdInfo ( IdInfo, constantIdInfo, mkIdInfo, exactArity, setUnfoldingInfo, setCafInfo, setCprInfo, - setArityInfo, setInlinePragInfo, setSpecInfo, + setArityInfo, setSpecInfo, setTyGenInfo, mkStrictnessInfo, setStrictnessInfo, - IdFlavour(..), InlinePragInfo(..), CafInfo(..), StrictnessInfo(..), CprInfo(..) + IdFlavour(..), CafInfo(..), CprInfo(..), TyGenInfo(..) ) -import FieldLabel ( FieldLabel, FieldLabelTag, mkFieldLabel, fieldLabelName, +import FieldLabel ( mkFieldLabel, fieldLabelName, firstFieldLabelTag, allFieldLabelTags, fieldLabelType ) import CoreSyn 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} @@ -111,8 +109,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 @@ -139,14 +138,22 @@ wiredInIds \begin{code} mkSpecPragmaId occ uniq ty loc - = mkId (mkLocalName uniq occ loc) ty (mkIdInfo SpecPragmaId) + = mkId (mkLocalName uniq occ loc) ty (mkIdInfo SpecPragmaId NoCafRefs) -- Maybe a SysLocal? But then we'd lose the location mkDefaultMethodId dm_name rec_c ty - = mkVanillaId dm_name ty + = mkId dm_name ty info + where + info = constantIdInfo `setTyGenInfo` TyGenNever + -- type is wired-in (see comment at TcClassDcl.tcClassSig), so + -- do not generalise it +mkWorkerId :: Unique -> Id -> Type -> Id +-- A worker gets a local name. CoreTidy will globalise it if necessary. mkWorkerId uniq unwrkr ty - = mkVanillaId (mkDerivedName mkWorkerOcc (getName unwrkr) uniq) ty + = mkVanillaId wkr_name ty + where + wkr_name = mkLocalName uniq (mkWorkerOcc (getOccName unwrkr)) (getSrcLoc unwrkr) \end{code} %************************************************************************ @@ -162,7 +169,7 @@ mkDataConId :: Name -> DataCon -> Id mkDataConId work_name data_con = mkId work_name (dataConRepType data_con) info where - info = mkIdInfo (DataConId data_con) + info = mkIdInfo (DataConId data_con) NoCafRefs `setArityInfo` exactArity arity `setStrictnessInfo` strict_info `setCprInfo` cpr_info @@ -171,20 +178,13 @@ 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 = ReturnsCPR + | otherwise = NoCPRInfo + -- ReturnsCPR is only true for products that are real data types; + -- that is, not unboxed tuples or newtypes \end{code} The wrapper for a constructor is an ordinary top-level binding that evaluates @@ -231,7 +231,7 @@ mkDataConWrapId data_con wrap_id = mkId (dataConName data_con) wrap_ty info work_id = dataConId data_con - info = mkIdInfo (DataConWrapId data_con) + info = mkIdInfo (DataConWrapId data_con) NoCafRefs `setUnfoldingInfo` mkTopUnfolding (mkInlineMe wrap_rhs) `setCprInfo` cpr_info -- The Cpr info can be important inside INLINE rhss, where the @@ -239,10 +239,9 @@ mkDataConWrapId data_con `setArityInfo` exactArity arity -- It's important to specify the arity, so that partial -- applications are treated as values - `setCafInfo` NoCafRefs - -- The wrapper Id ends up in STG code as an argument, - -- sometimes before its definition, so we want to - -- signal that it has no CAFs + `setTyGenInfo` TyGenNever + -- No point generalising its type, since it gets eagerly inlined + -- away anyway wrap_ty = mkForAllTys all_tyvars $ mkFunTys all_arg_tys @@ -258,10 +257,6 @@ mkDataConWrapId data_con 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 @@ -270,10 +265,16 @@ mkDataConWrapId data_con -- becomes -- f $w: x -- This is really important in rule matching, - -- which is a bit sad. (We could match on the wrappers, + -- (We could match on the wrappers, -- but that makes it less likely that rules will match - -- when we bring bits of unfoldings together --} + -- 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 $ @@ -387,68 +388,95 @@ mkRecordSelId tycon field_label unpack_id unpackUtf8_id 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 = [mkDictTy cls tys | (cls, tys) <- tycon_theta, + needed_dict (cls, tys)] + needed_dict pred = or [ pred `elem` (dataConTheta dc) + | (DataAlt dc, _, _) <- the_alts] + n_dict_tys = length dict_tys + + (field_tyvars,field_theta,field_tau) = splitSigmaTy field_ty + field_dict_tys = map mkPredTy field_theta + n_field_dict_tys = length field_dict_tys + -- If the field has a universally quantified type we have to + -- be a bit careful. Suppose we have + -- data R = R { op :: forall a => Foo a => a -> a } + -- Then we can't give op the type + -- op :: R -> forall a. Foo a => a -> a + -- because the typechecker doesn't understand foralls to the + -- right of an arrow. The "right" type to give it is + -- op :: forall a. Foo a => a -> a + -- But then we must generat 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 = mkIdInfo (RecordSelId field_label) caf_info + `setArityInfo` exactArity arity `setUnfoldingInfo` unfolding - `setCafInfo` NoCafRefs + `setTyGenInfo` TyGenNever -- ToDo: consider adding further IdInfo unfolding = mkTopUnfolding sel_rhs - - (data_id:dict_ids) = mkTemplateLocals (data_ty:dict_tys) + -- Allocate Ids. We do it a funny way round because field_dict_tys is + -- almost always empty + dict_ids = mkTemplateLocalsNum 1 dict_tys + field_dict_ids = mkTemplateLocalsNum (n_dict_tys+1) field_dict_tys + data_id = mkTemplateLocal arity 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 | isNewTyCon tycon = new_sel_rhs - | otherwise = data_sel_rhs + 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 - data_sel_rhs = mkLams tyvars $ mkLams field_tyvars $ - mkLams dict_ids $ 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 $ mkLams field_tyvars $ Lam data_id $ - Note (Coerce (unUsgTy field_tau) (unUsgTy data_ty)) (Var data_id) + sel_body | isNewTyCon tycon = Note (Coerce field_tau data_ty) (Var data_id) + | otherwise = Case (Var data_id) data_id (the_alts ++ default_alt) mk_maybe_alt data_con = case maybe_the_arg_id of Nothing -> Nothing Just the_arg_id -> Just (DataAlt data_con, real_args, expr) where - body = mkVarApps (Var the_arg_id) field_tyvars + body = mkVarApps (mkVarApps (Var the_arg_id) field_tyvars) field_dict_ids strict_marks = dataConStrictMarks data_con (expr, real_args) = rebuildConArgs data_con arg_ids strict_marks body - (length arg_ids + 1) + (length arg_ids + 1) where - arg_ids = mkTemplateLocals (dataConInstOrigArgTys data_con tyvar_tys) - -- The first one will shadow data_id, but who cares + arg_ids = mkTemplateLocalsNum (arity+1) (dataConInstOrigArgTys data_con tyvar_tys) + -- 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))) @@ -521,10 +549,10 @@ mkDictSelId name clas field_lbl = mkFieldLabel name tycon ty tag tag = assoc "MkId.mkDictSelId" (classSelIds clas `zip` allFieldLabelTags) sel_id - info = mkIdInfo (RecordSelId field_lbl) + info = mkIdInfo (RecordSelId field_lbl) NoCafRefs `setArityInfo` exactArity 1 `setUnfoldingInfo` unfolding - `setCafInfo` NoCafRefs + `setTyGenInfo` TyGenNever -- We no longer use 'must-inline' on record selectors. They'll -- inline like crazy if they scrutinise a constructor @@ -563,15 +591,15 @@ 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 + name = mkPrimOpIdName prim_op id = mkId name ty info - info = mkIdInfo (PrimOpId prim_op) + info = mkIdInfo (PrimOpId prim_op) NoCafRefs `setSpecInfo` rules `setArityInfo` exactArity arity `setStrictnessInfo` strict_info - rules = addRule id emptyCoreRules (primOpRule prim_op) + rules = addRule emptyCoreRules id (primOpRule prim_op) -- For each ccall we manufacture a separate CCallOpId, giving it @@ -597,7 +625,7 @@ mkCCallOpId uniq ccall ty name = mkCCallName uniq occ_str prim_op = CCallOp ccall - info = mkIdInfo (PrimOpId prim_op) + info = mkIdInfo (PrimOpId prim_op) NoCafRefs `setArityInfo` exactArity arity `setStrictnessInfo` strict_info @@ -619,13 +647,18 @@ 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 + = mkId dfun_name dfun_ty info where - dfun_theta = classesToPreds inst_decl_theta + dfun_ty = mkSigmaTy inst_tyvars dfun_theta (mkDictTy clas inst_tys) + info = mkIdInfo DictFunId MayHaveCafRefs + `setTyGenInfo` TyGenNever + -- type is wired-in (see comment at TcClassDcl.tcClassSig), so + -- do not generalise it + -- An imported dfun may refer to CAFs, so we assume the worst {- 1 dec 99: disable the Mark Jones optimisation for the sake of compatibility with Hugs. @@ -654,7 +687,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} @@ -678,8 +710,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 = constantIdInfo `setUnfoldingInfo` mkCompulsoryUnfolding rhs ty = mkForAllTys [openAlphaTyVar,openBetaTyVar] @@ -697,7 +728,7 @@ evaluate its argument and call the dataToTag# primitive. getTagId = pcMiscPrelId getTagIdKey pREL_GHC SLIT("getTag#") ty info where - info = vanillaIdInfo + info = constantIdInfo `setUnfoldingInfo` mkCompulsoryUnfolding rhs -- We don't provide a defn for this; you must inline it @@ -784,7 +815,7 @@ 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 + name = mkWiredInName mod (mkVarOcc str) key imp = mkId name ty info -- the usual case... in imp @@ -805,16 +836,15 @@ pc_bottoming_Id key mod name ty generic_ERROR_ID u n = pc_bottoming_Id u pREL_ERR n errorTy -- Very useful... -noCafIdInfo = vanillaIdInfo `setCafInfo` NoCafRefs +noCafIdInfo = constantIdInfo `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.