Monadify simplCore/SimplUtils: use do, return, standard monad functions and MonadUnique
[ghc-hetmet.git] / compiler / simplCore / CSE.lhs
index f8259c7..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 
 
@@ -161,7 +171,7 @@ 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,7 +231,7 @@ 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
@@ -314,13 +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 (length" <+> int (length result) <> comma 
-                                                       <+> text "hash code" <+> text (show hash) <> char ')')
-                                                       $$ nest 4 (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
@@ -332,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