Inject implicit bindings before the simplifier (Trac #2070)
authorsimonpj@microsoft.com <unknown>
Tue, 5 Feb 2008 16:55:07 +0000 (16:55 +0000)
committersimonpj@microsoft.com <unknown>
Tue, 5 Feb 2008 16:55:07 +0000 (16:55 +0000)
commit5952ef0dfd1a9eec38bd2756b37d040feb2b09d8
treee8792ba2f14da7aef4fdd1b24de3682ae01b5798
parentbddd4b23e32532091a64bdb1c432dfbc8ca84645
Inject implicit bindings before the simplifier (Trac #2070)

With constructor unpacking, it's possible for constructors and record
selectors to have non-trivial code, which should be optimised before
being fed to the code generator.  Example:

  data Foo = Foo { get :: {-# UNPACK #-} !Int }

Then we do not want to get this:
  T2070.get =
    \ (tpl_B1 :: T2070.Foo) ->
    case tpl_B1 of tpl1_B2 { T2070.Foo rb_B4 ->
        let {
          ipv_B3 [Just S] :: GHC.Base.Int
          [Str: DmdType m]
          ipv_B3 = GHC.Base.I# rb_B4
        } in  ipv_B3 }

If this goes through to codegen, we'll generate bad code.  Admittedly,
this only matters when the selector is used in a curried way (e.g
map get xs), but nevertheless it's silly.

This patch injects the implicit bindings in SimplCore, before the
simplifier runs.  That slows the simplifier a little, because it has
to look at some extra bindings; but it's probably a slight effect.
If it turns out to matter I suppose we can always inject them later,
e.g. just before the final simplification.

An unexpected (to me) consequence is that we get some specialisation rules
for class-method selectors.  E.g. we get a rule
RULE  (==) Int dInt = eqInt
There's no harm in this, but not much benefit either, because the
same result will happen when we inline (==) and dInt, but it's perhaps
more direct.
compiler/main/TidyPgm.lhs
compiler/simplCore/SimplCore.lhs