X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Fcompiler%2FbasicTypes%2FMkId.lhs;h=50e981b0a48a04e2fada281902e347977cd46311;hb=8e67f5502e2e316245806ee3735a2f41a844b611;hp=1da519af6f517115fdaafd0d1ecb8cd33d2abe75;hpb=19108ede05d6528d0b66edb2bcf031e8da9522e2;p=ghc-hetmet.git diff --git a/ghc/compiler/basicTypes/MkId.lhs b/ghc/compiler/basicTypes/MkId.lhs index 1da519a..50e981b 100644 --- a/ghc/compiler/basicTypes/MkId.lhs +++ b/ghc/compiler/basicTypes/MkId.lhs @@ -16,7 +16,7 @@ module MkId ( mkDictFunId, mkDefaultMethodId, mkDictSelId, - mkDataConWorkId, mkDataConWrapId, + mkDataConIds, mkRecordSelId, mkPrimOpId, mkFCallId, @@ -30,7 +30,7 @@ module MkId ( 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 + pAT_ERROR_ID, eRROR_ID ) where #include "HsVersions.h" @@ -43,57 +43,52 @@ import TysPrim ( openAlphaTyVars, alphaTyVar, alphaTy, import TysWiredIn ( charTy, mkListTy ) import PrelRules ( primOpRules ) import Rules ( addRule ) -import TcType ( Type, ThetaType, mkDictTy, mkPredTys, mkTyConApp, - mkTyVarTys, mkClassPred, tcEqPred, +import Type ( TyThing(..) ) +import TcType ( Type, ThetaType, mkDictTy, mkPredTys, mkPredTy, + mkTyConApp, mkTyVarTys, mkClassPred, tcEqPred, mkFunTys, mkFunTy, mkSigmaTy, tcSplitSigmaTy, isUnLiftedType, mkForAllTys, mkTyVarTy, tyVarsOfType, - tcSplitFunTys, tcSplitForAllTys, mkPredTy + tcSplitFunTys, tcSplitForAllTys ) import CoreUtils ( exprType ) -import CoreUnfold ( mkTopUnfolding, mkCompulsoryUnfolding, mkOtherCon ) -import Literal ( Literal(..), nullAddrLit ) +import CoreUnfold ( mkTopUnfolding, mkCompulsoryUnfolding ) +import Literal ( nullAddrLit, mkStringLit ) import TyCon ( TyCon, isNewTyCon, tyConTyVars, tyConDataCons, - tyConTheta, isProductTyCon, isDataTyCon, isRecursiveTyCon ) -import Class ( Class, classTyCon, classTyVars, classSelIds ) + tyConStupidTheta, isProductTyCon, isDataTyCon, isRecursiveTyCon ) +import Class ( Class, classTyCon, classSelIds ) import Var ( Id, TyVar, Var ) import VarSet ( isEmptyVarSet ) -import Name ( mkFCallName, Name ) -import PrimOp ( PrimOp, primOpSig, mkPrimOpIdName ) +import Name ( mkFCallName, mkWiredInName, Name, BuiltInSyntax(..) ) +import OccName ( mkOccFS, varName ) +import PrimOp ( PrimOp, primOpSig, primOpOcc, primOpTag ) import ForeignCall ( ForeignCall ) -import DataCon ( DataCon, - dataConFieldLabels, dataConRepArity, dataConTyCon, - dataConArgTys, dataConRepType, - dataConOrigArgTys, - dataConTheta, - dataConSig, dataConStrictMarks, dataConWorkId, - splitProductType +import DataCon ( DataCon, DataConIds(..), dataConTyVars, + dataConFieldLabels, dataConRepArity, + dataConRepArgTys, dataConRepType, dataConStupidTheta, + dataConSig, dataConStrictMarks, dataConExStricts, + splitProductType, isVanillaDataCon ) -import Id ( idType, mkGlobalId, mkVanillaGlobal, mkSysLocal, mkLocalId, - mkTemplateLocals, mkTemplateLocalsNum, setIdLocalExported, - mkTemplateLocal, idNewStrictness, idName +import Id ( idType, mkGlobalId, mkVanillaGlobal, mkSysLocal, + mkTemplateLocals, mkTemplateLocalsNum, mkExportedLocalId, + mkTemplateLocal, idName ) import IdInfo ( IdInfo, noCafIdInfo, setUnfoldingInfo, setArityInfo, setSpecInfo, setCafInfo, setAllStrictnessInfo, vanillaIdInfo, GlobalIdDetails(..), CafInfo(..) ) -import NewDemand ( mkStrictSig, strictSigResInfo, DmdResult(..), +import NewDemand ( mkStrictSig, DmdResult(..), mkTopDmdType, topDmd, evalDmd, lazyDmd, retCPR, Demand(..), Demands(..) ) -import FieldLabel ( mkFieldLabel, fieldLabelName, - firstFieldLabelTag, allFieldLabelTags, fieldLabelType - ) import DmdAnal ( dmdAnalTopRhs ) import CoreSyn -import Unique ( mkBuiltinUnique ) +import Unique ( mkBuiltinUnique, mkPrimOpIdUnique ) import Maybes import PrelNames -import Maybe ( isJust ) import Util ( dropList, isSingleton ) import Outputable import FastString import ListSetOps ( assoc, assocMaybe ) -import UnicodeUtil ( stringToUtf8 ) import List ( nubBy ) \end{code} @@ -147,57 +142,6 @@ ghcPrimIds %* * %************************************************************************ -\begin{code} -mkDataConWorkId :: Name -> DataCon -> Id - -- Makes the *worker* for the data constructor; that is, the function - -- that takes the reprsentation arguments and builds the constructor. -mkDataConWorkId wkr_name data_con - = mkGlobalId (DataConWorkId data_con) wkr_name - (dataConRepType data_con) info - where - info = noCafIdInfo - `setArityInfo` arity - `setAllStrictnessInfo` Just strict_sig - - arity = dataConRepArity data_con - strict_sig = mkStrictSig (mkTopDmdType (replicate arity topDmd) cpr_info) - -- Notice that we do *not* say the worker is strict - -- even if the data constructor is declared strict - -- e.g. data T = MkT !(Int,Int) - -- Why? Because the *wrapper* is strict (and its unfolding has case - -- expresssions that do the evals) but the *worker* itself is not. - -- If we pretend it is strict then when we see - -- case x of y -> $wMkT y - -- the simplifier thinks that y is "sure to be evaluated" (because - -- $wMkT is strict) and drops the case. No, $wMkT is not strict. - -- - -- When the simplifer sees a pattern - -- case e of MkT x -> ... - -- it uses the dataConRepStrictness of MkT to mark x as evaluated; - -- but that's fine... dataConRepStrictness comes from the data con - -- not from the worker Id. - - tycon = dataConTyCon data_con - cpr_info | isProductTyCon tycon && - 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. @@ -235,45 +179,95 @@ Notice that 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 :: Name -> DataCon -> Maybe Id --- Only make a wrapper Id if necessary +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 -mkDataConWrapId wrap_name data_con - | is_newtype || any isMarkedStrict strict_marks - = -- We need a wrapper function - Just (mkGlobalId (DataConWrapId data_con) wrap_name wrap_ty info) + | any isMarkedStrict all_strict_marks -- Algebraic, needs wrapper + = AlgDC (Just alg_wrap_id) wrk_id - | otherwise - = Nothing -- The common case, where there is no point in - -- having a wrapper function. Not only is this efficient, - -- but it also ensures that the wrapper is replaced - -- by the worker (becuase it *is* the wroker) - -- even when there are no args. E.g. in - -- f (:) x - -- the (:) *is* the worker. - -- 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.) + | otherwise -- Algebraic, no wrapper + = AlgDC Nothing wrk_id where - (tyvars, _, ex_tyvars, ex_theta, orig_arg_tys, tycon) = dataConSig data_con - is_newtype = isNewTyCon tycon - all_tyvars = tyvars ++ ex_tyvars - work_id = dataConWorkId data_con - - common_info = noCafIdInfo -- The NoCaf-ness is set by noCafIdInfo - `setArityInfo` arity - -- It's important to specify the arity, so that partial - -- applications are treated as values - - info | is_newtype = common_info `setUnfoldingInfo` newtype_unf - | otherwise = common_info `setUnfoldingInfo` data_unf - `setAllStrictnessInfo` Just wrap_sig - - wrap_sig = mkStrictSig (mkTopDmdType arg_dmds res_info) - res_info = strictSigResInfo (idNewStrictness work_id) - arg_dmds = map mk_dmd strict_marks + (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 @@ -285,42 +279,19 @@ mkDataConWrapId wrap_name data_con -- ...(let w = C x in ...(w p q)...)... -- we want to see that w is strict in its two arguments - newtype_unf = ASSERT( null ex_tyvars && null ex_dict_args && - 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) - - data_unf = mkTopUnfolding $ Note InlineMe $ - mkLams all_tyvars $ - mkLams ex_dict_args $ mkLams id_args $ - foldr mk_case con_app - (zip (ex_dict_args++id_args) strict_marks) i3 [] + 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 work_id) - (map varToCoreExpr (all_tyvars ++ reverse rep_ids)) + con_app i rep_ids = mkApps (Var wrk_id) + (map varToCoreExpr (tyvars ++ reverse rep_ids)) - ex_dict_tys = mkPredTys ex_theta - all_arg_tys = ex_dict_tys ++ orig_arg_tys - result_ty = mkTyConApp tycon (mkTyVarTys tyvars) - - wrap_ty = mkForAllTys all_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. - - mkLocals i tys = (zipWith mkTemplateLocal [i..i+n-1] tys, i+n) - where - n = length tys - - (ex_dict_args,i2) = mkLocals 1 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 + (dict_args,i2) = mkLocals 1 dict_tys + (id_args,i3) = mkLocals i2 orig_arg_tys + alg_arity = i3-1 mk_case :: (Id, StrictnessMark) -- Arg, strictness @@ -334,15 +305,32 @@ mkDataConWrapId wrap_name data_con MarkedStrict | isUnLiftedType (idType arg) -> body i (arg:rep_args) | otherwise -> - Case (Var arg) arg [(DEFAULT,[], body i (arg:rep_args))] + 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 [(DataAlt con, con_args, - body i' (reverse con_args ++ rep_args))] + 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} @@ -391,15 +379,11 @@ Similarly for (recursive) newtypes unN = /\b -> \n:N -> (coerce (forall a. a->a) n) \begin{code} -mkRecordSelId tycon field_label +mkRecordSelId tycon field_label field_ty -- 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 = mkGlobalId (RecordSelId field_label) (fieldLabelName field_label) selector_ty info - field_ty = fieldLabelType 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 @@ -417,14 +401,12 @@ mkRecordSelId tycon field_label -- -- NB: this code relies on the fact that DataCons are quantified over -- the identical type variables as their parent TyCon - tycon_theta = tyConTheta tycon -- The context on the data decl - -- eg data (Eq a, Ord b) => T a b = ... - needed_preds = [pred | (DataAlt dc, _, _) <- the_alts, pred <- dataConTheta dc] - dict_tys = map mkPredTy (nubBy tcEqPred needed_preds) + 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 = map mkPredTy field_theta + 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 @@ -459,19 +441,20 @@ mkRecordSelId tycon field_label `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 length_tycon_theta + -- 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! - 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 + 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 alts = map mk_maybe_alt data_cons - the_alts = catMaybes alts + the_alts = catMaybes alts -- Already sorted by data-con no_default = all isJust alts -- No default needed default_alt | no_default = [] @@ -486,7 +469,7 @@ mkRecordSelId tycon field_label Lam data_id $ sel_body sel_body | isNewTyCon tycon = mk_result (mkNewTypeBody tycon field_ty (Var data_id)) - | otherwise = Case (Var data_id) data_id (default_alt ++ the_alts) + | 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 @@ -497,20 +480,28 @@ mkRecordSelId tycon field_label -- foo = /\a. \t:T. case t of { MkT f -> f a } 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 - Just the_arg_id -> Just (mkReboxingAlt uniqs data_con arg_ids body) - where - body = mk_result (Var the_arg_id) + Just the_arg_id -> Just (mkReboxingAlt uniqs data_con (arg_prefix ++ arg_src_ids) $ + mk_result (Var the_arg_id)) where - arg_ids = mkTemplateLocalsNum field_base (dataConOrigArgTys data_con) - -- No need to instantiate; same tyvars in datacon as tycon + (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 = field_base + length arg_ids + unpack_base = arg_base' + length dc_theta uniqs = map mkBuiltinUnique [unpack_base..] - -- arity+1 avoids all shadowing - maybe_the_arg_id = assocMaybe (field_lbls `zip` arg_ids) field_label + 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 @@ -533,7 +524,7 @@ mkRecordSelId tycon field_label mkReboxingAlt :: [Unique] -- Uniques for the new Ids -> DataCon - -> [Var] -- Source-level args + -> [Var] -- Source-level args, including existential dicts -> CoreExpr -- RHS -> CoreAlt @@ -548,7 +539,7 @@ mkReboxingAlt us con args rhs (DataAlt con, args', mkLets binds rhs) where - stricts = dataConStrictMarks con + stricts = dataConExStricts con ++ dataConStrictMarks con go [] stricts us = ([], []) @@ -613,10 +604,7 @@ mkDictSelId name clas -- 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 = noCafIdInfo + info = noCafIdInfo `setArityInfo` 1 `setUnfoldingInfo` mkTopUnfolding rhs `setAllStrictnessInfo` Just strict_sig @@ -633,21 +621,19 @@ mkDictSelId name clas | otherwise = Eval (Prod [ if the_arg_id == id then evalDmd else Abs | id <- arg_ids ]) - tyvars = classTyVars clas - 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 - pred = mkClassPred clas tyvar_tys + pred = mkClassPred clas (mkTyVarTys tyvars) (dict_id:arg_ids) = mkTemplateLocals (mkPredTy pred : arg_tys) rhs | isNewTyCon tycon = mkLams tyvars $ Lam dict_id $ mkNewTypeBody tycon (head arg_tys) (Var 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)] mkNewTypeBody tycon result_ty result_expr @@ -673,7 +659,9 @@ mkPrimOpId prim_op where (tyvars,arg_tys,res_ty, arity, strict_sig) = primOpSig prim_op ty = mkForAllTys tyvars (mkFunTys arg_tys res_ty) - name = mkPrimOpIdName prim_op + name = mkWiredInName gHC_PRIM (primOpOcc prim_op) + (mkPrimOpIdUnique (primOpTag prim_op)) + Nothing (AnId id) UserSyntax id = mkGlobalId (PrimOpId prim_op) name ty info info = noCafIdInfo @@ -746,12 +734,11 @@ 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 (setIdLocalExported) so +BUT make sure they are *exported* LocalIds (mkExportedLocalId) so that they aren't discarded by the occurrence analyser. \begin{code} -mkDefaultMethodId dm_name ty - = setIdLocalExported (mkLocalId dm_name ty) +mkDefaultMethodId dm_name ty = mkExportedLocalId dm_name ty mkDictFunId :: Name -- Name to use for the dict fun; -> [TyVar] @@ -761,7 +748,7 @@ mkDictFunId :: Name -- Name to use for the dict fun; -> Id mkDictFunId dfun_name inst_tyvars dfun_theta clas inst_tys - = setIdLocalExported (mkLocalId dfun_name dfun_ty) + = mkExportedLocalId dfun_name dfun_ty where dfun_ty = mkSigmaTy inst_tyvars dfun_theta (mkDictTy clas inst_tys) @@ -771,7 +758,7 @@ mkDictFunId dfun_name inst_tyvars dfun_theta clas inst_tys (class_tyvars, sc_theta, _, _) = classBigSig clas not_const (clas, tys) = not (isEmptyVarSet (tyVarsOfTypes tys)) - sc_theta' = substClasses (mkTopTyVarSubst class_tyvars inst_tys) sc_theta + 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 @@ -817,6 +804,29 @@ they can unify with both unlifted and lifted types. Hence we provide 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 = pcMiscPrelId unsafeCoerceName ty info @@ -848,7 +858,8 @@ seqId ty = mkForAllTys [alphaTyVar,openBetaTyVar] (mkFunTy alphaTy (mkFunTy openBetaTy openBetaTy)) [x,y] = mkTemplateLocals [alphaTy, openBetaTy] - rhs = mkLams [alphaTyVar,openBetaTyVar,x,y] (Case (Var x) x [(DEFAULT, [], Var y)]) +-- 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 @@ -881,8 +892,8 @@ This comes up in strictness analysis \begin{code} realWorldPrimId -- :: State# RealWorld = pcMiscPrelId realWorldName realWorldStatePrimTy - (noCafIdInfo `setUnfoldingInfo` mkOtherCon []) - -- The mkOtherCon makes it look that realWorld# is evaluated + (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 @@ -924,15 +935,15 @@ mkRuntimeErrorApp mkRuntimeErrorApp err_id res_ty err_msg = mkApps (Var err_id) [Type res_ty, err_string] where - err_string = Lit (MachStr (mkFastString (stringToUtf8 err_msg))) + 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 -nON_EXHAUSTIVE_GUARDS_ERROR_ID = mkRuntimeErrorId nonExhaustiveGuardsErrorName 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