id,summary,reporter,owner,description,type,status,priority,milestone,component,version,resolution,keywords,cc,os,architecture,failure,difficulty,testcase,blockedby,blocking,related
2940,Do CSE after CorePrep,simonpj,simonpj,"Common sub-expression analysis is deliberately conservative, but it's really ''too'' conservative: we are missing obvious opportunities.  Consider
{{{
{-# OPTIONS_GHC -XBangPatterns -XMagicHash #-}

module Foo where

import GHC.Base

-- CorePrep evaluates (reverse xs) twice
f xs = let !v1 = reverse (reverse xs)
       	   !v2 = filter id (reverse xs)
       in (v1, v2)

-- Even CSE inside CorePrep would not get this right;
-- the strict evaluation of (reverse xs) doesn't scope
-- over the non-strict version
g xs = reverse (reverse xs) ++ filter id (reverse xs)


-- Duplicate evaluation of (x +# 1#)
h :: Int# -> ( Int, Int )
h x = ( I# (x +# 1#), I# ((x +# 1#) *# 2#) )
}}}
If you compile this you'll see that there are obvious missed CSE opportunities in `f`, `g` and `h`; but they only show up after `CorePrep`.  

I guess the right thing is to CSE after `CorePrep`, but then CSE would have to maintain the `CorePrep` invariants, which isn't trivial.  Something to think about.

Simon",bug,new,lowest,7.6.2,Compiler,6.10.1,,,felix.lequen@…,Unknown/Multiple,Unknown/Multiple,Runtime performance bug,Unknown,,,,
