diff --git a/ghc/compiler/coreSyn/CoreUnfold.lhs b/ghc/compiler/coreSyn/CoreUnfold.lhs index 4c76eaf269cea66f61c840fb94e8272eec4b17fb..54fb90550c1030613e1fadd174370b98fad89ad4 100644 --- a/ghc/compiler/coreSyn/CoreUnfold.lhs +++ b/ghc/compiler/coreSyn/CoreUnfold.lhs @@ -9,12 +9,12 @@ syntax (namely @CoreExpr@s). The type @Unfolding@ sits ``above'' simply-Core-expressions unfoldings, capturing ``higher-level'' things we know about a binding, usually things that the simplifier found out (e.g., ``it's a -literal''). In the corner of a @SimpleUnfolding@ unfolding, you will +literal''). In the corner of a @CoreUnfolding@ unfolding, you will find, unsurprisingly, a Core expression. \begin{code} module CoreUnfold ( - SimpleUnfolding(..), Unfolding(..), UnfoldingGuidance(..), -- types + Unfolding(..), UnfoldingGuidance(..), -- types FormSummary(..), mkFormSummary, whnfOrBottom, exprSmallEnoughToDup, exprIsTrivial, @@ -46,6 +46,7 @@ import BinderInfo ( BinderInfo, isOneFunOcc, isOneSafeFunOcc ) import PragmaInfo ( PragmaInfo(..) ) import CoreSyn +import Literal ( Literal ) import CoreUtils ( unTagBinders ) import OccurAnal ( occurAnalyseGlobalExpr ) import CoreUtils ( coreExprType ) @@ -72,20 +73,20 @@ import Outputable data Unfolding = NoUnfolding - | CoreUnfolding SimpleUnfolding + | OtherLit [Literal] -- It ain't one of these + | OtherCon [Id] -- It ain't one of these - | MagicUnfolding - Unique -- Unique of the Id whose magic unfolding this is - MagicUnfoldingFun - - -data SimpleUnfolding - = SimpleUnfolding -- An unfolding with redundant cached information + | CoreUnfolding -- An unfolding with redundant cached information FormSummary -- Tells whether the template is a WHNF or bottom UnfoldingGuidance -- Tells about the *size* of the template. SimplifiableCoreExpr -- Template + | MagicUnfolding + Unique -- Unique of the Id whose magic unfolding this is + MagicUnfoldingFun +\end{code} +\begin{code} noUnfolding = NoUnfolding mkUnfolding inline_prag expr @@ -93,7 +94,7 @@ mkUnfolding inline_prag expr -- strictness mangling (depends on there being no CSE) ufg = calcUnfoldingGuidance inline_prag opt_UnfoldingCreationThreshold expr occ = occurAnalyseGlobalExpr expr - cuf = CoreUnfolding (SimpleUnfolding (mkFormSummary expr) ufg occ) + cuf = CoreUnfolding (mkFormSummary expr) ufg occ cont = case occ of { Var _ -> cuf; _ -> cuf } in @@ -103,7 +104,7 @@ mkMagicUnfolding :: Unique -> Unfolding mkMagicUnfolding tag = MagicUnfolding tag (mkMagicUnfoldingFun tag) getUnfoldingTemplate :: Unfolding -> CoreExpr -getUnfoldingTemplate (CoreUnfolding (SimpleUnfolding _ _ expr)) +getUnfoldingTemplate (CoreUnfolding _ _ expr) = unTagBinders expr getUnfoldingTemplate other = panic "getUnfoldingTemplate" diff --git a/ghc/compiler/simplCore/ConFold.lhs b/ghc/compiler/simplCore/ConFold.lhs index fdc3ecaa58be8ae8e2353e0290bd6fe6cab6ae93..7c09ad11daa92058fd2f8a7cf42abb474a1b818e 100644 --- a/ghc/compiler/simplCore/ConFold.lhs +++ b/ghc/compiler/simplCore/ConFold.lhs @@ -13,7 +13,7 @@ module ConFold ( completePrim ) where #include "HsVersions.h" import CoreSyn -import CoreUnfold ( Unfolding, SimpleUnfolding ) +import CoreUnfold ( Unfolding ) import Id ( idType ) import Literal ( mkMachInt, mkMachWord, Literal(..) ) import PrimOp ( PrimOp(..) ) @@ -90,7 +90,7 @@ completePrim env SeqOp [TyArg ty, LitArg lit] = returnSmpl (Lit (mkMachInt 1)) completePrim env op@SeqOp args@[TyArg ty, VarArg var] - | isEvaluated (lookupRhsInfo env var) = returnSmpl (Lit (mkMachInt 1)) -- var is eval'd + | isEvaluated (lookupUnfolding env var) = returnSmpl (Lit (mkMachInt 1)) -- var is eval'd | otherwise = returnSmpl (Prim op args) -- var not eval'd \end{code} diff --git a/ghc/compiler/simplCore/SimplCase.lhs b/ghc/compiler/simplCore/SimplCase.lhs index 6417701517d223d29dfc7bb2f618a902985cb612..bbbd9d5b4f7f9eb102db7014d8cd364575acf79c 100644 --- a/ghc/compiler/simplCore/SimplCase.lhs +++ b/ghc/compiler/simplCore/SimplCase.lhs @@ -15,7 +15,7 @@ import {-# SOURCE #-} Simplify ( simplBind, simplExpr ) import BinderInfo -- too boring to try to select things... import CmdLineOpts ( SimplifierSwitch(..) ) import CoreSyn -import CoreUnfold ( Unfolding, SimpleUnfolding ) +import CoreUnfold ( Unfolding(..) ) import CoreUtils ( coreAltsType, nonErrorRHSs, maybeErrorApp, unTagBindersAlts, unTagBinders, coreExprType ) @@ -330,8 +330,8 @@ completeCase env scrut alts rhs_c -- If the scrutinee is a variable, look it up to see what we know about it scrut_form = case scrut of - Var v -> lookupRhsInfo env v - other -> NoRhsInfo + Var v -> lookupUnfolding env v + other -> NoUnfolding -- If the scrut is already eval'd then there's no worry about -- eliminating the case @@ -368,9 +368,10 @@ completeCase env scrut alts rhs_c -- the scrutinee. Remember that the rhs is as yet unsimplified. rhs1_is_scrutinee = case (scrut, rhs1) of (Var scrut_var, Var rhs_var) - -> case (runEager $ lookupId env rhs_var) of - VarArg rhs_var' -> rhs_var' == scrut_var - other -> False + -> case (lookupIdSubst env rhs_var) of + Nothing -> rhs_var == scrut_var + Just (SubstVar rhs_var') -> rhs_var' == scrut_var + other -> False other -> False is_elem x ys = isIn "completeCase" x ys @@ -592,7 +593,7 @@ simplDefault :: SimplEnv -> OutExpr -- Simplified scrutinee -> InDefault -- Default alternative to be completed - -> RhsInfo -- Gives form of scrutinee + -> Unfolding -- Gives form of scrutinee -> (SimplEnv -> InExpr -> SmplM OutExpr) -- Old rhs handler -> SmplM OutDefault @@ -604,11 +605,11 @@ simplDefault env (Var scrut_var) (BindDefault binder@(_,occ_info) rhs) info_from_this_case rhs_c = simplBinder env binder `thenSmpl` \ (env1, binder') -> let - env2 = extendEnvGivenRhsInfo env1 binder' occ_info info_from_this_case + env2 = extendEnvGivenUnfolding env1 binder' occ_info info_from_this_case -- Add form details for the default binder - scrut_info = lookupRhsInfo env scrut_var - env3 = extendEnvGivenRhsInfo env2 binder' occ_info scrut_info + scrut_info = lookupUnfolding env scrut_var + env3 = extendEnvGivenUnfolding env2 binder' occ_info scrut_info new_env = extendEnvGivenNewRhs env3 scrut_var (Var binder') in rhs_c new_env rhs `thenSmpl` \ rhs' -> @@ -618,7 +619,7 @@ simplDefault env scrut (BindDefault binder@(_,occ_info) rhs) info_from_this_case rhs_c = simplBinder env binder `thenSmpl` \ (env1, binder') -> let - new_env = extendEnvGivenRhsInfo env1 binder' occ_info info_from_this_case + new_env = extendEnvGivenUnfolding env1 binder' occ_info info_from_this_case in rhs_c new_env rhs `thenSmpl` \ rhs' -> returnSmpl (BindDefault binder' rhs') diff --git a/ghc/compiler/simplCore/SimplEnv.lhs b/ghc/compiler/simplCore/SimplEnv.lhs index 31e6eff1758895040bd383fd8d62035e9d2882f5..18c4aec68244b3c132036e1a74c6e84693b9e94b 100644 --- a/ghc/compiler/simplCore/SimplEnv.lhs +++ b/ghc/compiler/simplCore/SimplEnv.lhs @@ -6,7 +6,7 @@ \begin{code} module SimplEnv ( nullSimplEnv, - getEnvs, setTyEnv, setIdEnv, notInScope, setSubstEnvs, + getEnvs, setTyEnv, setIdEnv, notInScope, setSubstEnvs, zapSubstEnvs, bindTyVar, bindTyVars, simplTy, @@ -15,9 +15,9 @@ module SimplEnv ( bindIdToAtom, bindIdToExpr, markDangerousOccs, - lookupRhsInfo, isEvaluated, + lookupUnfolding, isEvaluated, extendEnvGivenBinding, extendEnvGivenNewRhs, - extendEnvGivenRhsInfo, + extendEnvGivenUnfolding, lookForConstructor, @@ -30,7 +30,7 @@ module SimplEnv ( SwitchChecker, SimplEnv, UnfoldConApp, - RhsInfo(..), + SubstInfo(..), InId, InBinder, InBinding, InType, OutId, OutBinder, OutBinding, OutType, @@ -50,16 +50,16 @@ import CmdLineOpts ( switchIsOn, intSwitchSet, opt_UnfoldingCreationThreshold, ) import CoreSyn import CoreUnfold ( mkFormSummary, couldBeSmallEnoughToInline, whnfOrBottom, - Unfolding(..), SimpleUnfolding(..), FormSummary(..), + Unfolding(..), FormSummary(..), calcUnfoldingGuidance ) import CoreUtils ( coreExprCc ) -import CostCentre ( CostCentre, subsumedCosts, costsAreSubsumed, noCostCentreAttached ) +import CostCentre ( CostCentre, isCurrentCostCentre, useCurrentCostCentre, costsAreSubsumed, noCostCentreAttached ) import FiniteMap -- lots of things import Id ( getInlinePragma, nullIdEnv, growIdEnvList, lookupIdEnv, delOneFromIdEnv, addOneToIdEnv, modifyIdEnv, modifyIdEnv_Directly, IdEnv, IdSet, Id ) -import Literal ( Literal{-instances-} ) +import Literal ( Literal ) import Maybes ( expectJust ) import OccurAnal ( occurAnalyseExpr ) import PprCore -- various instances @@ -152,7 +152,8 @@ type SimplValEnv = (IdEnv StuffAboutId, -- Domain includes *all* in-scope -- they *must* be substituted for the given OutArg data SubstInfo - = SubstArg OutArg -- The Id maps to an already-substituted atom + = SubstVar OutId -- The Id maps to an already-substituted atom + | SubstLit Literal -- ...ditto literal | SubstExpr -- Id maps to an as-yet-unsimplified expression (TyVarEnv Type) -- ...hence we need to capture the substitution (IdEnv SubstInfo) -- environments too @@ -168,17 +169,7 @@ type StuffAboutId = (OutId, -- Always has the same unique as the -- We keep this info so we can modify it when -- something changes. - RhsInfo) -- Info about what it is bound to -\end{code} - -The @RhsInfo@ part tells about the value to which the @OutId@ is bound. - -\begin{code} -data RhsInfo = NoRhsInfo - | OtherLit [Literal] -- It ain't one of these - | OtherCon [Id] -- It ain't one of these - | OutUnfolding CostCentre - SimpleUnfolding -- Already-simplified unfolding + Unfolding) -- Info about what it is bound to \end{code} @@ -186,7 +177,10 @@ data RhsInfo = NoRhsInfo nullSimplEnv :: SwitchChecker -> SimplEnv nullSimplEnv sw_chkr - = SimplEnv sw_chkr subsumedCosts (emptyTyVarSet, emptyTyVarEnv) (nullIdEnv, nullIdEnv) nullConApps + = SimplEnv sw_chkr useCurrentCostCentre + (emptyTyVarSet, emptyTyVarEnv) + (nullIdEnv, nullIdEnv) + nullConApps getEnvs :: SimplEnv -> (SimplTypeEnv, SimplValEnv) getEnvs (SimplEnv _ _ ty_env id_env _) = (ty_env, id_env) @@ -203,6 +197,10 @@ setSubstEnvs :: SimplEnv -> TyVarEnv Type -> IdEnv SubstInfo -> SimplEnv setSubstEnvs (SimplEnv chkr encl_cc (in_scope_tyvars, _) (in_scope_ids, _) con_apps) ty_subst id_subst = SimplEnv chkr encl_cc (in_scope_tyvars, ty_subst) (in_scope_ids, id_subst) con_apps + +zapSubstEnvs :: SimplEnv -> SimplEnv +zapSubstEnvs (SimplEnv chkr encl_cc (in_scope_tyvars, _) (in_scope_ids, _) con_apps) + = SimplEnv chkr encl_cc (in_scope_tyvars, emptyTyVarEnv) (in_scope_ids, nullIdEnv) con_apps \end{code} @@ -270,7 +268,7 @@ switchOffInlining :: SimplEnv -> SimplEnv switchOffInlining (SimplEnv chkr encl_cc ty_env (in_scope_ids, id_subst) con_apps) = SimplEnv chkr encl_cc ty_env (mapUFM forget in_scope_ids, id_subst) nullConApps where - forget (id, binder_info, rhs_info) = (id, noBinderInfo, NoRhsInfo) + forget (id, binder_info, rhs_info) = (id, noBinderInfo, NoUnfolding) \end{code} @@ -348,12 +346,12 @@ bindIdToAtom :: SimplEnv bindIdToAtom (SimplEnv chkr encl_cc ty_env (in_scope_ids, id_subst) con_apps) (in_id,occ_info) atom - = SimplEnv chkr encl_cc ty_env (in_scope_ids', id_subst') con_apps + = SimplEnv chkr encl_cc ty_env id_env' con_apps where - id_subst' = addOneToIdEnv id_subst in_id (SubstArg atom) - in_scope_ids' = case atom of - LitArg _ -> in_scope_ids - VarArg out_id -> modifyOccInfo in_scope_ids (uniqueOf out_id) occ_info + id_env' = case atom of + LitArg lit -> (in_scope_ids, addOneToIdEnv id_subst in_id (SubstLit lit)) + VarArg id -> (modifyOccInfo in_scope_ids (uniqueOf id) occ_info, + addOneToIdEnv id_subst in_id (SubstVar id)) bindIdToExpr :: SimplEnv -> InBinder @@ -381,32 +379,32 @@ bindIdToExpr (SimplEnv chkr encl_cc ty_env@(_, ty_subst) (in_scope_ids, id_subst lookupIdSubst :: SimplEnv -> InId -> Maybe SubstInfo lookupIdSubst (SimplEnv _ _ _ (_, id_subst) _) id = lookupIdEnv id_subst id -lookupOutIdEnv :: SimplEnv -> OutId -> Maybe (OutId,BinderInfo,RhsInfo) +lookupOutIdEnv :: SimplEnv -> OutId -> Maybe (OutId, BinderInfo, Unfolding) lookupOutIdEnv (SimplEnv _ _ _ (in_scope_ids, _) _) id = lookupIdEnv in_scope_ids id -lookupRhsInfo :: SimplEnv -> OutId -> RhsInfo -lookupRhsInfo env id +lookupUnfolding :: SimplEnv -> OutId -> Unfolding +lookupUnfolding env id = case lookupOutIdEnv env id of Just (_,_,info) -> info - Nothing -> NoRhsInfo + Nothing -> NoUnfolding -modifyOutEnvItem :: (OutId, BinderInfo, RhsInfo) - -> (OutId, BinderInfo, RhsInfo) - -> (OutId, BinderInfo, RhsInfo) +modifyOutEnvItem :: (OutId, BinderInfo, Unfolding) + -> (OutId, BinderInfo, Unfolding) + -> (OutId, BinderInfo, Unfolding) modifyOutEnvItem (id, occ, info1) (_, _, info2) = case (info1, info2) of (OtherLit ls1, OtherLit ls2) -> (id,occ, OtherLit (ls1++ls2)) (OtherCon cs1, OtherCon cs2) -> (id,occ, OtherCon (cs1++cs2)) - (_, NoRhsInfo) -> (id,occ, info1) + (_, NoUnfolding) -> (id,occ, info1) other -> (id,occ, info2) \end{code} \begin{code} -isEvaluated :: RhsInfo -> Bool +isEvaluated :: Unfolding -> Bool isEvaluated (OtherLit _) = True isEvaluated (OtherCon _) = True -isEvaluated (OutUnfolding _ (SimpleUnfolding ValueForm _ expr)) = True +isEvaluated (CoreUnfolding ValueForm _ expr) = True isEvaluated other = False \end{code} @@ -416,8 +414,8 @@ isEvaluated other = False mkSimplUnfoldingGuidance chkr out_id rhs = calcUnfoldingGuidance (getInlinePragma out_id) opt_UnfoldingCreationThreshold rhs -extendEnvGivenRhsInfo :: SimplEnv -> OutId -> BinderInfo -> RhsInfo -> SimplEnv -extendEnvGivenRhsInfo env@(SimplEnv chkr encl_cc ty_env (in_scope_ids, id_subst) con_apps) +extendEnvGivenUnfolding :: SimplEnv -> OutId -> BinderInfo -> Unfolding -> SimplEnv +extendEnvGivenUnfolding env@(SimplEnv chkr encl_cc ty_env (in_scope_ids, id_subst) con_apps) out_id occ_info rhs_info = SimplEnv chkr encl_cc ty_env (new_in_scope_ids, id_subst) con_apps where @@ -630,7 +628,7 @@ extendEnvGivenBinding env@(SimplEnv chkr encl_cc ty_env (in_scope_ids, id_subst) -- The "interesting" free variables we want occurrence info for are those -- in the OutIdEnv that have only a single occurrence right now. (fv_occ_info, template) = _scc_ "eegnr.occ-anal" - occurAnalyseExpr is_interesting rhs + occurAnalyseExpr is_interesting rhs_w_cc is_interesting v = _scc_ "eegnr.mkidset" case lookupIdEnv in_scope_ids v of @@ -638,15 +636,16 @@ extendEnvGivenBinding env@(SimplEnv chkr encl_cc ty_env (in_scope_ids, id_subst) other -> False -- Compute unfolding details - rhs_info = OutUnfolding unf_cc (SimpleUnfolding form guidance template) + rhs_info = CoreUnfolding form guidance template form = _scc_ "eegnr.form_sum" mkFormSummary rhs guidance = _scc_ "eegnr.guidance" mkSimplUnfoldingGuidance chkr out_id rhs - -- Compute cost centre for thing - unf_cc | noCostCentreAttached expr_cc = encl_cc - | otherwise = expr_cc - where - expr_cc = coreExprCc rhs + -- Attach a cost centre to the RHS if necessary + rhs_w_cc | isCurrentCostCentre encl_cc + || not (noCostCentreAttached (coreExprCc rhs)) + = rhs + | otherwise + = SCC encl_cc rhs \end{code} diff --git a/ghc/compiler/simplCore/SimplMonad.lhs b/ghc/compiler/simplCore/SimplMonad.lhs index 80b02480c8ca77bb594f9d88b9bc09c3b996230d..85cc2fb7accfbb6fa468428701816eb3c1b0d2e4 100644 --- a/ghc/compiler/simplCore/SimplMonad.lhs +++ b/ghc/compiler/simplCore/SimplMonad.lhs @@ -21,7 +21,6 @@ module SimplMonad ( #include "HsVersions.h" import Id ( GenId, mkSysLocal, mkIdWithNewUniq, Id ) -import CoreUnfold ( SimpleUnfolding ) import SimplEnv import SrcLoc ( noSrcLoc ) import TyVar ( TyVar ) diff --git a/ghc/compiler/simplCore/SimplPgm.lhs b/ghc/compiler/simplCore/SimplPgm.lhs index f3f2f7edaa9aa538ac38bed9a8b4a818426162c8..e365817dfcd7ffff7188c891abec3ab11a3dbe11 100644 --- a/ghc/compiler/simplCore/SimplPgm.lhs +++ b/ghc/compiler/simplCore/SimplPgm.lhs @@ -12,7 +12,6 @@ import CmdLineOpts ( opt_D_verbose_core2core, opt_D_dump_simpl_iterations, switchIsOn, SimplifierSwitch(..), SwitchResult ) import CoreSyn -import CoreUnfold ( SimpleUnfolding ) import Id ( mkIdEnv, lookupIdEnv, IdEnv ) import Maybes ( catMaybes ) diff --git a/ghc/compiler/simplCore/SimplUtils.lhs b/ghc/compiler/simplCore/SimplUtils.lhs index 03ee2bd1e0b2be4f4101c9e5130786f78efb45a2..c72b2c43aaf21e1f855c4005df03f1a5ffe78504 100644 --- a/ghc/compiler/simplCore/SimplUtils.lhs +++ b/ghc/compiler/simplCore/SimplUtils.lhs @@ -24,7 +24,7 @@ module SimplUtils ( import BinderInfo import CmdLineOpts ( opt_DoEtaReduction, SimplifierSwitch(..) ) import CoreSyn -import CoreUnfold ( SimpleUnfolding, mkFormSummary, exprIsTrivial, FormSummary(..) ) +import CoreUnfold ( mkFormSummary, exprIsTrivial, FormSummary(..) ) import Id ( idType, isBottomingId, mkSysLocal, addInlinePragma, addIdDemandInfo, idWantsToBeINLINEd, dataConArgTys, Id, diff --git a/ghc/compiler/simplCore/SimplVar.lhs b/ghc/compiler/simplCore/SimplVar.lhs index f35b42da7854d0e5a06cfa7a99ab1507abede29d..498549379b7ac3a029821a3fc3f01eed45ded52d 100644 --- a/ghc/compiler/simplCore/SimplVar.lhs +++ b/ghc/compiler/simplCore/SimplVar.lhs @@ -16,18 +16,17 @@ import {-# SOURCE #-} Simplify ( simplExpr ) import CmdLineOpts ( switchIsOn, SimplifierSwitch(..) ) import CoreSyn import CoreUnfold ( Unfolding(..), UnfoldingGuidance(..), - SimpleUnfolding(..), FormSummary, whnfOrBottom, smallEnoughToInline ) -import Specialise ( substSpecEnvRhs ) +import CoreUtils ( coreExprCc ) import BinderInfo ( BinderInfo, noBinderInfo, okToInline ) -import CostCentre ( CostCentre, isCurrentCostCentre ) +import CostCentre ( CostCentre, noCostCentreAttached, isCurrentCostCentre ) import Id ( idType, getIdInfo, getIdUnfolding, getIdSpecialisation, setIdSpecialisation, idMustBeINLINEd, idHasNoFreeTyVars, mkIdWithNewUniq, mkIdWithNewType, - elemIdEnv, isNullIdEnv, addOneToIdEnv + IdEnv, lookupIdEnv, delOneFromIdEnv, elemIdEnv, isNullIdEnv, addOneToIdEnv ) import SpecEnv ( lookupSpecEnv, substSpecEnv, isEmptySpecEnv ) import OccurAnal ( occurAnalyseGlobalExpr ) @@ -38,7 +37,7 @@ import SimplMonad import Type ( instantiateTy, mkTyVarTy ) import TyCon ( tyConFamilySize ) import TyVar ( TyVar, cloneTyVar, - isEmptyTyVarEnv, addToTyVarEnv, + isEmptyTyVarEnv, addToTyVarEnv, delFromTyVarEnv, addOneToTyVarSet, elementOfTyVarSet ) import Maybes ( maybeToBool ) @@ -72,49 +71,59 @@ completeVar env var args result_ty -- Look for an unfolding. There's a binding for the -- thing, but perhaps we want to inline it anyway - | ( maybeToBool maybe_unfolding_info + | has_unfolding && (not essential_unfoldings_only || idMustBeINLINEd var) -- If "essential_unfoldings_only" is true we do no inlinings at all, -- EXCEPT for things that absolutely have to be done -- (see comments with idMustBeINLINEd) && ok_to_inline - && costCentreOk (getEnclosingCC env) (getEnclosingCC unf_env) + && costCentreOk (getEnclosingCC env) (coreExprCc unf_template) + = +{- + pprTrace "Unfolding" (ppr var) $ + simplCount `thenSmpl` \ n -> + (if n > 1000 then + pprTrace "Ticks > 1000 and unfolding" (sep [space, int n, ppr var]) + else + id ) - = -- pprTrace "Unfolding" (ppr var) $ - unfold var unf_env unf_template args result_ty - + (if n>4000 then + returnSmpl (mkGenApp (Var var) args) + else +-} + tickUnfold var `thenSmpl_` + simplExpr unf_env unf_template args result_ty | otherwise = returnSmpl (mkGenApp (Var var') args) where - info_from_env = lookupOutIdEnv env var - var' = case info_from_env of - Just (var', _, _) -> var' - Nothing -> var - - unfolding_from_id = getIdUnfolding var + (var', occ_info, unfolding) = case lookupOutIdEnv env var of + Just stuff -> stuff + Nothing -> (var, noBinderInfo, getIdUnfolding var) ---------- Magic unfolding stuff - maybe_magic_result = case unfolding_from_id of + maybe_magic_result = case unfolding of MagicUnfolding _ magic_fn -> applyMagicUnfoldingFun magic_fn env args other -> Nothing Just magic_result = maybe_magic_result - maybe_unfolding_info - = case (info_from_env, unfolding_from_id) of - - (Just (_, occ_info, OutUnfolding enc_cc unf), _) - -> Just (occ_info, setEnclosingCC env enc_cc, unf) - - (_, CoreUnfolding unf) - -> Just (noBinderInfo, env, unf) - - other -> Nothing - - Just (occ_info, unf_env, simple_unfolding) = maybe_unfolding_info - SimpleUnfolding form guidance unf_template = simple_unfolding + ---------- Unfolding stuff + has_unfolding = case unfolding of + CoreUnfolding _ _ _ -> True + other -> False + + CoreUnfolding form guidance unf_template = unfolding + unf_env = zapSubstEnvs env + -- The template is already simplified, so don't re-substitute. + -- This is VITAL. Consider + -- let x = e in + -- let y = \z -> ...x... in + -- \ x -> ...y... + -- We'll clone the inner \x, adding x->x' in the id_subst + -- Then when we inline y, we must *not* replace x by x' in + -- the inlined copy!! ---------- Specialisation stuff (ty_args, remaining_args) = initialTyArgs args @@ -130,26 +139,10 @@ completeVar env var args result_ty small_enough = smallEnoughToInline var arg_evals is_case_scrutinee guidance arg_evals = [is_evald arg | arg <- args, isValArg arg] - is_evald (VarArg v) = isEvaluated (lookupRhsInfo env v) + is_evald (VarArg v) = isEvaluated (lookupUnfolding env v) is_evald (LitArg l) = True --- Perform the unfolding -unfold var unf_env unf_template args result_ty - = -{- - simplCount `thenSmpl` \ n -> - (if n > 1000 then - pprTrace "Ticks > 1000 and unfolding" (sep [space, int n, ppr var]) - else - id - ) - (if n>4000 then - returnSmpl (mkGenApp (Var var) args) - else --} - tickUnfold var `thenSmpl_` - simplExpr unf_env unf_template args result_ty -- costCentreOk checks that it's ok to inline this thing @@ -162,7 +155,7 @@ unfold var unf_env unf_template args result_ty -- regardless of whether E is a WHNF or not. costCentreOk cc_encl cc_rhs - = isCurrentCostCentre cc_encl || not (isCurrentCostCentre cc_rhs) + = isCurrentCostCentre cc_encl || not (noCostCentreAttached cc_rhs) \end{code} @@ -184,7 +177,7 @@ simplBinder env (id, _) && empty_ty_subst -- No type substitution to do inside the Id && isNullIdEnv id_subst -- No id substitution to do inside the Id = let - env' = setIdEnv env (addOneToIdEnv in_scope_ids id id, id_subst) + env' = setIdEnv env (new_in_scope_ids id, id_subst) in returnSmpl (env', id) @@ -207,7 +200,7 @@ simplBinder env (id, _) if not_in_scope then -- No need to clone let - env' = setIdEnv env (addOneToIdEnv in_scope_ids id id2, id_subst) + env' = setIdEnv env (new_in_scope_ids id2, id_subst) in returnSmpl (env', id2) else @@ -215,21 +208,24 @@ simplBinder env (id, _) getUniqueSmpl `thenSmpl` \ uniq -> let id3 = mkIdWithNewUniq id2 uniq - env' = setIdEnv env (addOneToIdEnv in_scope_ids id3 id3, - addOneToIdEnv id_subst id (VarArg id3)) + env' = setIdEnv env (new_in_scope_ids id3, + addOneToIdEnv id_subst id (SubstVar id3)) in returnSmpl (env', id3) ) where ((in_scope_tyvars, ty_subst), (in_scope_ids, id_subst)) = getEnvs env - empty_ty_subst = isEmptyTyVarEnv ty_subst - not_in_scope = not (id `elemIdEnv` in_scope_ids) - ty = idType id - ty' = instantiateTy ty_subst ty + empty_ty_subst = isEmptyTyVarEnv ty_subst + not_in_scope = not (id `elemIdEnv` in_scope_ids) - spec_env = getIdSpecialisation id - spec_env' = substSpecEnv ty_subst (substSpecEnvRhs ty_subst id_subst) spec_env + new_in_scope_ids id' = addOneToIdEnv in_scope_ids id' (id', noBinderInfo, NoUnfolding) + + ty = idType id + ty' = instantiateTy ty_subst ty + + spec_env = getIdSpecialisation id + spec_env' = substSpecEnv ty_subst (substSpecEnvRhs ty_subst id_subst) spec_env simplBinders :: SimplEnv -> [InBinder] -> SmplM (SimplEnv, [OutId]) simplBinders env binders = mapAccumLSmpl simplBinder env binders @@ -258,3 +254,34 @@ simplTyBinder env tyvar simplTyBinders :: SimplEnv -> [TyVar] -> SmplM (SimplEnv, [TyVar]) simplTyBinders env binders = mapAccumLSmpl simplTyBinder env binders \end{code} + + +substSpecEnvRhs applies a substitution to the RHS's of a SpecEnv +It exploits the known structure of a SpecEnv's RHS to have fewer +equations. + +\begin{code} +substSpecEnvRhs te ve rhs + = go te ve rhs + where + go te ve (App f (TyArg ty)) = App (go te ve f) (TyArg (instantiateTy te ty)) + go te ve (App f (VarArg v)) = App (go te ve f) (case lookupIdEnv ve v of + Just (SubstVar v') -> VarArg v' + Just (SubstLit l) -> LitArg l + Nothing -> VarArg v) + go te ve (Var v) = case lookupIdEnv ve v of + Just (SubstVar v') -> Var v' + Just (SubstLit l) -> Lit l + Nothing -> Var v + + -- These equations are a bit half baked, because + -- they don't deal properly wih capture. + -- But I'm sure it'll never matter... sigh. + go te ve (Lam b@(TyBinder tyvar) e) = Lam b (go te' ve e) + where + te' = delFromTyVarEnv te tyvar + + go te ve (Lam b@(ValBinder v) e) = Lam b (go te ve' e) + where + ve' = delOneFromIdEnv ve v +\end{code} diff --git a/ghc/compiler/simplCore/Simplify.lhs b/ghc/compiler/simplCore/Simplify.lhs index 37e42fc5c9e2a6f12beb2347a1681a3b6aa59e6a..f4eef9f930460dc01cb93c0f3edba9072b8b6b6d 100644 --- a/ghc/compiler/simplCore/Simplify.lhs +++ b/ghc/compiler/simplCore/Simplify.lhs @@ -11,7 +11,7 @@ module Simplify ( simplTopBinds, simplExpr, simplBind ) where import BinderInfo import CmdLineOpts ( SimplifierSwitch(..) ) import ConFold ( completePrim ) -import CoreUnfold ( Unfolding, SimpleUnfolding, mkFormSummary, +import CoreUnfold ( Unfolding, mkFormSummary, exprIsTrivial, whnfOrBottom, inlineUnconditionally, FormSummary(..) ) @@ -247,16 +247,16 @@ the more sophisticated stuff. \begin{code} simplExpr env (Var var) args result_ty - = case (runEager $ lookupIdSubst env var) of + = case lookupIdSubst env var of Just (SubstExpr ty_subst id_subst expr) -> simplExpr (setSubstEnvs env ty_subst id_subst) expr args result_ty - Just (SubstArg (LitArg lit)) -- A boring old literal + Just (SubstLit lit) -- A boring old literal -> ASSERT( null args ) returnSmpl (Lit lit) - Just (SubstArg (VarArg var')) -- More interesting! An id! + Just (SubstVar var') -- More interesting! An id! -> completeVar env var' args result_ty Nothing -- Not in the substitution; hand off to completeVar @@ -1330,9 +1330,10 @@ simplArg env (TyArg ty) = simplTy env ty `appEager` \ ty' -> returnEager (TyArg ty') simplArg env arg@(VarArg id) = case lookupIdSubst env id of - Just (SubstArg arg') -> returnEager arg' - Just (SubstExpr _) -> panic "simplArg" - Nothing -> case lookupOutIdEnv env id of + Just (SubstVar id') -> returnEager (VarArg id') + Just (SubstLit lit) -> returnEager (LitArg lit) + Just (SubstExpr _ __) -> panic "simplArg" + Nothing -> case lookupOutIdEnv env id of Just (id', _, _) -> returnEager (VarArg id') Nothing -> returnEager arg \end{code} diff --git a/ghc/compiler/specialise/Specialise.lhs b/ghc/compiler/specialise/Specialise.lhs index cb5638c739ee96209f6da07939018f7bde6ce2d3..9886e6bcf778a1772a0d07de7550c7d06d1648c0 100644 --- a/ghc/compiler/specialise/Specialise.lhs +++ b/ghc/compiler/specialise/Specialise.lhs @@ -6,8 +6,7 @@ \begin{code} module Specialise ( specProgram, - idSpecVars, - substSpecEnvRhs + idSpecVars ) where #include "HsVersions.h" @@ -1211,33 +1210,6 @@ idSpecVars id get_spec (Lam _ b) = get_spec b get_spec (Var v) = v --- substSpecEnvRhs applies a substitution to the RHS's of a SpecEnv --- It's placed here because Specialise.lhs built that RHS, so --- it knows its structure. (Fully general subst - -substSpecEnvRhs te ve rhs - = go te ve rhs - where - go te ve (App f (TyArg ty)) = App (go te ve f) (TyArg (instantiateTy te ty)) - go te ve (App f (VarArg v)) = App (go te ve f) (case lookupIdEnv ve v of - Just arg' -> arg' - Nothing -> VarArg v) - go te ve (Var v) = case lookupIdEnv ve v of - Just (VarArg v') -> Var v' - Just (LitArg l) -> Lit l - Nothing -> Var v - - -- These equations are a bit half baked, because - -- they don't deal properly wih capture. - -- But I'm sure it'll never matter... sigh. - go te ve (Lam b@(TyBinder tyvar) e) = Lam b (go te' ve e) - where - te' = delFromTyVarEnv te tyvar - - go te ve (Lam b@(ValBinder v) e) = Lam b (go te ve' e) - where - ve' = delOneFromIdEnv ve v - ---------------------------------------- type SpecM a = UniqSM a diff --git a/ghc/compiler/stranal/SaAbsInt.lhs b/ghc/compiler/stranal/SaAbsInt.lhs index a9e2bce751ad920dbef771655d71de68eb7afa60..bc3f8c80125dc71a4c61925da501088d36003429 100644 --- a/ghc/compiler/stranal/SaAbsInt.lhs +++ b/ghc/compiler/stranal/SaAbsInt.lhs @@ -17,7 +17,7 @@ module SaAbsInt ( import CmdLineOpts ( opt_AllStrict, opt_NumbersStrict ) import CoreSyn -import CoreUnfold ( Unfolding(..), SimpleUnfolding(..), FormSummary ) +import CoreUnfold ( Unfolding(..), FormSummary ) import CoreUtils ( unTagBinders ) import Id ( idType, getIdStrictness, getIdUnfolding, dataConTyCon, dataConArgTys, Id @@ -404,7 +404,7 @@ absId anal var env (Just abs_val, _, _) -> abs_val -- Bound in the environment - (Nothing, NoStrictnessInfo, CoreUnfolding (SimpleUnfolding _ _ unfolding)) -> + (Nothing, NoStrictnessInfo, CoreUnfolding _ _ unfolding) -> -- We have an unfolding for the expr -- Assume the unfolding has no free variables since it -- came from inside the Id