X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=compiler%2FcoreSyn%2FCoreSubst.lhs;h=14eccc61a40e33aacae4144fce51a83787b2bb16;hb=83361f58746ae08040079a6d809127bca2ae3f4c;hp=f1f02d9b9c9c7bd03540e8aa6383ac0078e38cc0;hpb=72462499b891d5779c19f3bda03f96e24f9554ae;p=ghc-hetmet.git diff --git a/compiler/coreSyn/CoreSubst.lhs b/compiler/coreSyn/CoreSubst.lhs index f1f02d9..14eccc6 100644 --- a/compiler/coreSyn/CoreSubst.lhs +++ b/compiler/coreSyn/CoreSubst.lhs @@ -13,7 +13,7 @@ module CoreSubst ( -- ** Substituting into expressions and related types deShadowBinds, substSpec, substRulesForImportedIds, substTy, substExpr, substBind, substUnfolding, - substInlineRuleGuidance, lookupIdSubst, lookupTvSubst, substIdOcc, + substInlineRuleInfo, lookupIdSubst, lookupTvSubst, substIdOcc, -- ** Operations on substitutions emptySubst, mkEmptySubst, mkSubst, mkOpenSubst, substInScope, isEmptySubst, @@ -48,6 +48,7 @@ import IdInfo import Unique import UniqSupply import Maybes +import BasicTypes ( isAlwaysActive ) import Outputable import PprCore () -- Instances import FastString @@ -227,10 +228,10 @@ lookupTvSubst (Subst _ _ tvs) v = lookupVarEnv tvs v `orElse` Type.mkTyVarTy v -- No left-right shadowing -- ie the substitution for (\x \y. e) a1 a2 -- so neither x nor y scope over a1 a2 -mkOpenSubst :: [(Var,CoreArg)] -> Subst -mkOpenSubst pairs = Subst (mkInScopeSet (exprsFreeVars (map snd pairs))) - (mkVarEnv [(id,e) | (id, e) <- pairs, isId id]) - (mkVarEnv [(tv,ty) | (tv, Type ty) <- pairs]) +mkOpenSubst :: InScopeSet -> [(Var,CoreArg)] -> Subst +mkOpenSubst in_scope pairs = Subst in_scope + (mkVarEnv [(id,e) | (id, e) <- pairs, isId id]) + (mkVarEnv [(tv,ty) | (tv, Type ty) <- pairs]) ------------------------------ isInScope :: Var -> Subst -> Bool @@ -509,27 +510,27 @@ substUnfolding subst (DFunUnfolding con args) substUnfolding subst unf@(CoreUnfolding { uf_tmpl = tmpl, uf_guidance = guide@(InlineRule {}) }) -- Retain an InlineRule! = seqExpr new_tmpl `seq` - new_mb_wkr `seq` - unf { uf_tmpl = new_tmpl, uf_guidance = guide { ug_ir_info = new_mb_wkr } } + new_info `seq` + unf { uf_tmpl = new_tmpl, uf_guidance = guide { ir_info = new_info } } where - new_tmpl = substExpr subst tmpl - new_mb_wkr = substInlineRuleGuidance subst (ug_ir_info guide) + new_tmpl = substExpr subst tmpl + new_info = substInlineRuleInfo subst (ir_info guide) substUnfolding _ (CoreUnfolding {}) = NoUnfolding -- Discard -- Always zap a CoreUnfolding, to save substitution work -substUnfolding _ unf = unf -- Otherwise no substitution to do +substUnfolding _ unf = unf -- NoUnfolding, OtherCon ------------------- -substInlineRuleGuidance :: Subst -> InlineRuleInfo -> InlineRuleInfo -substInlineRuleGuidance subst (InlWrapper wkr) +substInlineRuleInfo :: Subst -> InlineRuleInfo -> InlineRuleInfo +substInlineRuleInfo subst (InlWrapper wkr) = case lookupIdSubst subst wkr of Var w1 -> InlWrapper w1 other -> WARN( not (exprIsTrivial other), text "CoreSubst.substWorker:" <+> ppr wkr ) - InlUnSat -- Worker has got substituted away altogether + InlVanilla -- Worker has got substituted away altogether -- (This can happen if it's trivial, via -- postInlineUnconditionally, hence only warning) -substInlineRuleGuidance _ info = info +substInlineRuleInfo _ info = info ------------------ substIdOcc :: Subst -> Id -> Id @@ -667,6 +668,7 @@ simpleOptExpr expr | isId b -- let x = e in , safe_to_inline (idOccInfo b) || exprIsTrivial r' + , isAlwaysActive (idInlineActivation b) -- Note [Inline prag in simplOpt] = Left (extendIdSubst subst b r') | otherwise @@ -682,3 +684,22 @@ simpleOptExpr expr safe_to_inline (IAmALoopBreaker {}) = False safe_to_inline NoOccInfo = False \end{code} + +Note [Inline prag in simplOpt] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +If there's an INLINE/NOINLINE pragma that restricts the phase in +which the binder can be inlined, we don't inline here; after all, +we don't know what phase we're in. Here's an example + + foo :: Int -> Int -> Int + {-# INLINE foo #-} + foo m n = inner m + where + {-# INLINE [1] inner #-} + inner m = m+n + + bar :: Int -> Int + bar n = foo n 1 + +When inlining 'foo' in 'bar' we want the let-binding for 'inner' +to remain visible until Phase 1 \ No newline at end of file