X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=compiler%2FsimplCore%2FSimplify.lhs;h=d05e4a11e49b4ed805511170c4c8b369477c144b;hb=4f56b4074079380d4b115a05d5aa71004f716710;hp=ac1f7900461a0919299311581a61d8073150ee94;hpb=9670d6643e55adeb15f998a0efd5799d499ea2a4;p=ghc-hetmet.git diff --git a/compiler/simplCore/Simplify.lhs b/compiler/simplCore/Simplify.lhs index ac1f790..d05e4a1 100644 --- a/compiler/simplCore/Simplify.lhs +++ b/compiler/simplCore/Simplify.lhs @@ -4,6 +4,13 @@ \section[Simplify]{The main module of the simplifier} \begin{code} +{-# OPTIONS -w #-} +-- The above warning supression flag is a temporary kludge. +-- While working on this module you are encouraged to remove it and fix +-- any warnings in the module. See +-- http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#Warnings +-- for details + module Simplify ( simplTopBinds, simplExpr ) where #include "HsVersions.h" @@ -415,6 +422,8 @@ That's what the 'go' loop in prepareRhs does prepareRhs :: SimplEnv -> OutExpr -> SimplM (SimplEnv, OutExpr) -- Adds new floats to the env iff that allows us to return a good RHS prepareRhs env (Cast rhs co) -- Note [Float coercions] + | (ty1, ty2) <- coercionKind co -- Do *not* do this if rhs has an unlifted type + , not (isUnLiftedType ty1) -- see Note [Float coercions (unlifted)] = do { (env', rhs') <- makeTrivial env rhs ; return (env', Cast rhs' co) } @@ -467,6 +476,22 @@ and lead to further optimisation. Example: go n = case x of { T m -> go (n-m) } -- This case should optimise +Note [Float coercions (unlifted)] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +BUT don't do [Float coercions] if 'e' has an unlifted type. +This *can* happen: + + foo :: Int = (error (# Int,Int #) "urk") + `cast` CoUnsafe (# Int,Int #) Int + +If do the makeTrivial thing to the error call, we'll get + foo = case error (# Int,Int #) "urk" of v -> v `cast` ... +But 'v' isn't in scope! + +These strange casts can happen as a result of case-of-case + bar = case (case x of { T -> (# 2,3 #); F -> error "urk" }) of + (# p,q #) -> p+q + \begin{code} makeTrivial :: SimplEnv -> OutExpr -> SimplM (SimplEnv, OutExpr) @@ -892,10 +917,10 @@ simplNote env (SCC cc) e cont -- 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 @@ -952,6 +977,8 @@ completeCall env var cont -- the wrapper didn't occur for things that have specialisations till a -- later phase, so but now we just try RULES first -- + -- Note [Self-recursive rules] + -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- You might think that we shouldn't apply rules for a loop breaker: -- doing so might give rise to an infinite loop, because a RULE is -- rather like an extra equation for the function: @@ -1653,25 +1680,27 @@ knownAlt env scrut args bndr (DataAlt dc, bs, rhs) cont ; env <- simplNonRecX env bndr bndr_rhs ; -- pprTrace "knownCon2" (ppr bs $$ ppr rhs $$ ppr (seIdSubst env)) $ simplExprF env rhs cont } - --- Ugh! -bind_args env dead_bndr [] _ = return env - -bind_args env dead_bndr (b:bs) (Type ty : args) - = ASSERT( isTyVar b ) - bind_args (extendTvSubst env b ty) dead_bndr bs args - -bind_args env dead_bndr (b:bs) (arg : args) - = ASSERT( isId b ) - do { let b' = if dead_bndr then b else zapOccInfo b - -- Note that the binder might be "dead", because it doesn't occur - -- in the RHS; and simplNonRecX may therefore discard it via postInlineUnconditionally - -- Nevertheless we must keep it if the case-binder is alive, because it may - -- be used in the con_app. See Note [zapOccInfo] - ; env <- simplNonRecX env b' arg - ; bind_args env dead_bndr bs args } - -bind_args _ _ _ _ = panic "bind_args" + where + -- Ugh! + bind_args env dead_bndr [] _ = return env + + bind_args env dead_bndr (b:bs) (Type ty : args) + = ASSERT( isTyVar b ) + bind_args (extendTvSubst env b ty) dead_bndr bs args + + bind_args env dead_bndr (b:bs) (arg : args) + = ASSERT( isId b ) + do { let b' = if dead_bndr then b else zapOccInfo b + -- Note that the binder might be "dead", because it doesn't occur + -- in the RHS; and simplNonRecX may therefore discard it via postInlineUnconditionally + -- Nevertheless we must keep it if the case-binder is alive, because it may + -- be used in the con_app. See Note [zapOccInfo] + ; env <- simplNonRecX env b' arg + ; bind_args env dead_bndr bs args } + + bind_args _ _ _ _ = + pprPanic "bind_args" $ ppr dc $$ ppr bs $$ ppr args $$ + text "scrut:" <+> ppr scrut \end{code}