import PrelRules ( primOpRules )
import Rules ( addRule )
import Type ( TyThing(..) )
-import TcType ( Type, ThetaType, mkDictTy, mkPredTys, mkTyConApp,
- mkTyVarTys, mkClassPred, tcEqPred,
+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 CoreUnfold ( mkTopUnfolding, mkCompulsoryUnfolding )
import Literal ( nullAddrLit, mkStringLit )
import TyCon ( TyCon, isNewTyCon, tyConTyVars, tyConDataCons,
tyConStupidTheta, isProductTyCon, isDataTyCon, isRecursiveTyCon )
import ForeignCall ( ForeignCall )
import DataCon ( DataCon, DataConIds(..), dataConTyVars,
dataConFieldLabels, dataConRepArity,
- dataConRepArgTys, dataConRepType,
- dataConStupidTheta, dataConOrigArgTys,
+ dataConRepArgTys, dataConRepType, dataConStupidTheta,
dataConSig, dataConStrictMarks, dataConExStricts,
splitProductType, isVanillaDataCon
)
import Unique ( mkBuiltinUnique, mkPrimOpIdUnique )
import Maybes
import PrelNames
-import Maybe ( isJust )
import Util ( dropList, isSingleton )
import Outputable
import FastString
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
MarkedStrict
| isUnLiftedType (idType arg) -> body i (arg:rep_args)
| otherwise ->
--- gaw 2004
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) ->
--- gaw 2004
- Case (Var arg) arg result_ty [(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
-- NB: this code relies on the fact that DataCons are quantified over
-- the identical type variables as their parent TyCon
needed_preds = [pred | (DataAlt dc, _, _) <- the_alts, pred <- dataConStupidTheta dc]
- dict_tys = map mkPredTy (nubBy tcEqPred needed_preds)
+ 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
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 = []
-- 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 $
+ Just the_arg_id -> Just (mkReboxingAlt uniqs data_con (arg_prefix ++ arg_src_ids) $
mk_result (Var the_arg_id))
where
- arg_ids = ASSERT( isVanillaDataCon data_con )
- mkTemplateLocalsNum arg_base (dataConOrigArgTys data_con)
- -- Records can't be existential, so no existential tyvars or dicts
- -- Vanilla data con => tycon's tyvars will do
+ (dc_tyvars, dc_theta, dc_arg_tys, _, _) = dataConSig data_con
+ arg_src_ids = mkTemplateLocalsNum arg_base dc_arg_tys
+ arg_base' = arg_base + length arg_src_ids
+ arg_prefix | isVanillaDataCon data_con = []
+ | otherwise = tyvars ++ mkTemplateLocalsNum arg_base' (mkPredTys dc_theta)
- unpack_base = arg_base + length arg_ids
+ unpack_base = arg_base' + length dc_theta
uniqs = map mkBuiltinUnique [unpack_base..]
- 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
mkReboxingAlt
:: [Unique] -- Uniques for the new Ids
-> DataCon
- -> [Var] -- Source-level args
+ -> [Var] -- Source-level args, including existential dicts
-> CoreExpr -- RHS
-> CoreAlt
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}
\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