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.