Wibble to SetLevels.abstractVars
[ghc-hetmet.git] / compiler / simplCore / CSE.lhs
index 3cec4a1..3bcc177 100644 (file)
@@ -4,6 +4,13 @@
 \section{Common subexpression}
 
 \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 CSE (
        cseProgram
     ) where
@@ -19,9 +26,12 @@ import CoreSyn
 import VarEnv  
 import CoreLint                ( showPass, endPass )
 import Outputable
+import StaticFlags     ( opt_PprStyle_Debug )
 import BasicTypes      ( isAlwaysActive )
-import Util            ( mapAccumL, lengthExceeds )
+import Util            ( lengthExceeds )
 import UniqFM
+
+import Data.List
 \end{code}
 
 
@@ -107,8 +117,8 @@ Instead, we shoudl replace (f x) by (# a,b #).  That is, the "reverse mapping" i
        f x --> (# a,b #)
 That is why the CSEMap has pairs of expressions.
 
-Note [INLINE and NOINLINE]
-~~~~~~~~~~~~~~~~~~~~~~~~~~
+Note [CSE for INLINE and NOINLINE]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 We are careful to do no CSE inside functions that the user has marked as
 INLINE or NOINLINE.  In terms of Core, that means 
 
@@ -157,11 +167,11 @@ bar will be inlined (when it should not be). Even if we remove INLINE foo,
 we'd still like foo to be inlined if rhs is small. This won't happen
 with foo = bar.
 
-Not CSE-ing inside INLLINE also solves an annoying bug in CSE. Consider
+Not CSE-ing inside INLINE also solves an annoying bug in CSE. Consider
 a worker/wrapper, in which the worker has turned into a single variable:
        $wf = h
        f = \x -> ...$wf...
-Now CSE may transoform to
+Now CSE may transform to
        f = \x -> ...h...
 But the WorkerInfo for f still says $wf, which is now dead!  This won't
 happen now that we don't look inside INLINEs (which wrappers are).
@@ -206,7 +216,7 @@ do_one env (id, rhs)
     (env', id') = addBinder env id
     rhs' | isAlwaysActive (idInlinePragma id) = cseExpr env' rhs
         | otherwise                          = rhs
-               -- See Note [INLINE and NOINLINE]
+               -- See Note [CSE for INLINE and NOINLINE]
 
 tryForCSE :: CSEnv -> CoreExpr -> CoreExpr
 tryForCSE env (Type t) = Type t
@@ -221,8 +231,9 @@ cseExpr env (Type t)                   = Type t
 cseExpr env (Lit lit)             = Lit lit
 cseExpr env (Var v)               = Var (lookupSubst env v)
 cseExpr env (App f a)             = App (cseExpr env f) (tryForCSE env a)
-cseExpr evn (Note InlineMe e)     = Note InlineMe e    -- See Note [INLINE and NOINLINE]
+cseExpr env (Note InlineMe e)     = Note InlineMe e    -- See Note [CSE for INLINE and NOINLINE]
 cseExpr env (Note n e)            = Note n (cseExpr env e)
+cseExpr env (Cast e co)            = Cast (cseExpr env e) co
 cseExpr env (Lam b e)             = let (env', b') = addBinder env b
                                     in Lam b' (cseExpr env' e)
 cseExpr env (Let bind e)          = let (env', bind') = cseBind env bind
@@ -313,11 +324,14 @@ addCSEnvItem env expr expr' | exprIsBig expr = env
 extendCSEnv (CS cs in_scope sub) expr expr'
   = CS (addToUFM_C combine cs hash [(expr, expr')]) in_scope sub
   where
-    hash   = hashExpr expr
-    combine old new = WARN( result `lengthExceeds` 4, text "extendCSEnv: long list:" <+> ppr result )
-                     result
-                   where
-                     result = new ++ old
+    hash = hashExpr expr
+    combine old new 
+       = WARN( result `lengthExceeds` 4, short_msg $$ nest 2 long_msg ) result
+       where
+         result = new ++ old
+         short_msg = ptext SLIT("extendCSEnv: long list, length") <+> int (length result)
+         long_msg | opt_PprStyle_Debug = (text "hash code" <+> text (show hash)) $$ ppr result 
+                  | otherwise          = empty
 
 lookupSubst (CS _ _ sub) x = case lookupVarEnv sub x of
                               Just y  -> y
@@ -329,7 +343,7 @@ addBinder :: CSEnv -> Id -> (CSEnv, Id)
 addBinder env@(CS cs in_scope sub) v
   | not (v `elemInScopeSet` in_scope) = (CS cs (extendInScopeSet in_scope v)  sub,                    v)
   | isId v                           = (CS cs (extendInScopeSet in_scope v') (extendVarEnv sub v v'), v')
-  | not (isId v)                     = WARN( True, ppr v )
+  | otherwise                        = WARN( True, ppr v )
                                        (CS emptyUFM in_scope                 sub,                     v)
        -- This last case is the unusual situation where we have shadowing of
        -- a type variable; we have to discard the CSE mapping