FIX #1738: KPush rule of FC must take dataConEqTheta into account
[ghc-hetmet.git] / compiler / simplCore / Simplify.lhs
index ac1f790..d05e4a1 100644 (file)
@@ -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}