Simplify primitives for short cut fusion
Currently, there appear to be two production primitives, build
and augment
(although I may have missed some). There are multiple consumption primitives (at least: foldr
, head
, and
, or
, any
, and all
). The rule sets for some producers seem to forget to handle augment
, and the augment/augment
rule is omitted as "true, but not, I think, useful".
A number of other functions are instead rewritten into foldr
forms, and then written back if they don't fuse.
What to do:
Personally, I'd be very tempted to start by saying build g = augment g []
(or possibly even build g = extend [] g []
if I can ever get that idea to work) and cut the problem in half. The main problem I see with this is if other people are importing GHC.Exts
or GHC.Base
, writing things with build
, and expecting them to fuse. One way to deal with this, perhaps, is to hack a special rule into the RULES compiler to recognize GHC.Base.build
on the LHS of RULES and replace it with the appropriate augment
form, emitting a warning.
Where to go after that: the question remains whether it's best in general to rewrite a form to foldr
to make it fuse, or to fuse directly with augment
. The answer presumably depends, at least in part, on whether there are additional foldr
-based rules we may want to add that would take advantage of the effort put into the translation back from the foldr
form. I would conjecture that most such rules we could want would go beyond what the RULES system actually can do. That said, if we can find a way to use foldr
forms without the horrible pain of translating back from them, that would be a very good thing.
Trac metadata
Trac field | Value |
---|---|
Version | 7.8.3 |
Type | Task |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | libraries/base |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | ekmett, hvr |
Operating system | |
Architecture |