-- The continuation type
SimplCont(..), DupFlag(..), LetRhsFlag(..),
contIsDupable, contResultType, contIsTrivial, contArgs, dropArgs,
- countValArgs, countArgs,
+ countValArgs, countArgs, splitInlineCont,
mkBoringStop, mkLazyArgStop, mkRhsStop, contIsRhsOrArg,
interestingCallContext, interestingArgContext,
import Var ( isCoVar )
import NewDemand
import SimplMonad
-import Type
+import Type ( Type, funArgTy, mkForAllTys, mkTyVarTys,
+ splitTyConApp_maybe, tyConAppArgs )
import TyCon
import DataCon
import Unify ( dataConCannotMatch )
mkRhsStop :: OutType -> SimplCont
mkRhsStop ty = Stop ty AnRhs (canUpdateInPlace ty)
-contIsRhsOrArg (Stop {}) = True
-contIsRhsOrArg (StrictBind {}) = True
-contIsRhsOrArg (StrictArg {}) = True
-contIsRhsOrArg other = False
+-------------------
+contIsRhsOrArg (Stop {}) = True
+contIsRhsOrArg (StrictBind {}) = True
+contIsRhsOrArg (StrictArg {}) = True
+contIsRhsOrArg other = False
-------------------
contIsDupable :: SimplCont -> Bool
dropArgs 0 cont = cont
dropArgs n (ApplyTo _ _ _ cont) = dropArgs (n-1) cont
dropArgs n other = pprPanic "dropArgs" (ppr n <+> ppr other)
+
+--------------------
+splitInlineCont :: SimplCont -> Maybe (SimplCont, SimplCont)
+-- Returns Nothing if the continuation should dissolve an InlineMe Note
+-- Return Just (c1,c2) otherwise,
+-- where c1 is the continuation to put inside the InlineMe
+-- and c2 outside
+
+-- Example: (__inline_me__ (/\a. e)) ty
+-- Here we want to do the beta-redex without dissolving the InlineMe
+-- See test simpl017 (and Trac #1627) for a good example of why this is important
+
+splitInlineCont (ApplyTo dup (Type ty) se c)
+ | Just (c1, c2) <- splitInlineCont c = Just (ApplyTo dup (Type ty) se c1, c2)
+splitInlineCont cont@(Stop ty _ _) = Just (mkBoringStop ty, cont)
+splitInlineCont cont@(StrictBind bndr _ _ se _) = Just (mkBoringStop (substTy se (idType bndr)), cont)
+splitInlineCont cont@(StrictArg _ fun_ty _ _) = Just (mkBoringStop (funArgTy fun_ty), cont)
+splitInlineCont other = Nothing
+ -- NB: the calculation of the type for mkBoringStop is an annoying
+ -- duplication of the same calucation in mkDupableCont
\end{code}
-- See notes with SimplMonad.inlineMode
simplNote env InlineMe e cont
- | contIsRhsOrArg cont -- Totally boring continuation; see notes above
+ | Just (inside, outside) <- splitInlineCont cont -- Boring boring continuation; see notes above
= do { -- Don't inline inside an INLINE expression
- e' <- simplExpr (setMode inlineMode env) e
- ; rebuild env (mkInlineMe e') cont }
+ e' <- simplExprC (setMode inlineMode env) e inside
+ ; rebuild env (mkInlineMe e') outside }
| otherwise -- Dissolve the InlineMe note if there's
-- an interesting context of any kind to combine with