RULES in binary

Lennart Kolmodin kolmodin at
Mon Jul 27 09:47:56 UTC 2015

2015-07-26 23:06 GMT+02:00 Joachim Breitner <mail at>:

> Hi,
> Am Sonntag, den 26.07.2015, 22:50 +0200 schrieb Lennart Kolmodin:
> > This trick relies so much on that the user's code has been inlined
> > properly that it probably very rarely fires in a real application. It
> > does wonders in the unrealistic micro benchmark, though :)
> what is the name of the rule? Can you find it on this list:

The rules;

"<$> to <*>" forall f g.
  (<$>) f g = returnG f <*> g

"readN/readN merge" forall n m f g.
  apG (readN n f) (readN m g) = readN (n+m) (\bs -> f bs $ g (B.unsafeDrop
n bs))

"returnG/readN swap" [~1] forall f.
  returnG f = readN 0 (const f)

"readN 0/returnG swapback" [1] forall f.
  readN 0 f = returnG (f B.empty) #-}

>From your list (all of stackage with -ddump-rule-firings? brilliant! :));
399 Rule fired: <$> to <*>
106 Rule fired: readN/readN merge
1373 Rule fired: returnG/readN swap
2351 Rule fired: readN 0/returnG swapback

The "readN/readN merge" rule is what gives the speedup, the other rules are
needed just to get the code lined up for the merge rule to fire.
So it fired 106 times. That's not a lot. When compiling one of the binary
benchmarks it fires 33 times.
It might fire less often than it could, because the "<$> to <*>" rule might
not get to fire as often as it wants (just like the warning says).
But, I can't slap a INLINE or NOINLINE on <$> though, since it's not part
of the binary library.
So even if it does fire for some program out there, I'm still inclined to
remove the rules. It's a little bit too much black magic.


> Greetings,
> Joachim
> --
> Joachim “nomeata” Breitner
>   mail at joachim-breitner.de
>   Jabber: nomeata at  • GPG-Key: 0xF0FBF51F
>   Debian Developer: nomeata at
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the ghc-devs mailing list