Defer inlining of Eq for primitive types
authorBen Gamari <bgamari.foss@gmail.com>
Thu, 24 Mar 2016 10:24:32 +0000 (11:24 +0100)
committerBen Gamari <ben@smart-cactus.org>
Thu, 24 Mar 2016 15:14:37 +0000 (16:14 +0100)
commit0bd0c31e833055eb3e86177f70c4b4d93d5a1c11
treec2cdcd784978b6e48b31910ec0623ecfb75911f9
parent371608f1cdaf20c49eb6c5ec165b9eb08b745a89
Defer inlining of Eq for primitive types

Summary:
This is one solution to #11688, wherein (==) was inlined to soon
defeating a rewrite rule provided by bytestring. Since the RHSs of Eq's
methods are simple, there is little to be gained and much to be lost by
inlining them early.

For instance, the bytestring library provides,

```lang=haskell
break :: (Word8 -> Bool) -> ByteString -> (ByteString, ByteString)
breakByte :: Word8 -> ByteString -> (ByteString, ByteString)
```

and a rule

```
forall x. break ((==) x) = breakByte x
```

since `breakByte` implments an optimized version of `break (== x)` for
known `x :: Word8`. If we allow `(==)` to be inlined too early, we will
prevent this rule from firing. This was the cause of #11688.

This patch just defers the `Eq` methods, although it's likely worthwhile
giving `Ord` this same treatment. This regresses compiler allocations
for T9661 by about 8% due to the additional inlining that we now require
the simplifier to perform.

Updates the `bytestring` submodule to include updated rewrite rules
which match on `eqWord8` instead of `(==)`.

Test Plan:
 * Validate, examine performance impact

Reviewers: simonpj, hvr, austin

Subscribers: thomie

Differential Revision: https://phabricator.haskell.org/D1980

GHC Trac Issues: #11688
libraries/base/GHC/Char.hs
libraries/base/GHC/Float.hs
libraries/base/GHC/Int.hs
libraries/base/GHC/Word.hs
libraries/ghc-prim/GHC/Classes.hs
testsuite/tests/perf/compiler/all.T