Optimize named funs and fun-wrapped macros #1973
Conversation
We forgot to do this in the BSM optimization branch, and this is as good a time as any to get it fixed.
@jhogberg this is very exciting as we could leverage this in a few places! Just to clarify, will the optimization apply even if the function is used over multiple branches but never escaped? Take this nonsensical code just as an example: Fun = fun(X) -> erlang:display({value, X}) end,
case SomeCondition of
true -> Fun(Value), ok;
false -> Fun(Value), error
end. Follow up question, does it also apply for function captures such as |
Yep. The optimization is completely turned off if it's escapes however, and it makes no attempt to delay fun creation until needed. This would be relatively straightforward to do but we haven't found a practical use for it yet and there are a few wrinkles where it could generate worse code.
Yes, it applies to anything that creates local funs. I'll look into that, thanks for pointing it out! |
Cf. 42b87be which removes the abstraction @josevalim mentions but unfortunately breaks HiPE. |
I was too lazy to find my own patch. |
3378eed
to
f22cd26
As far as I can tell the problems with HiPE would only occur when mixing
Chances are I'm wrong though. Do you have any sneaky test cases to share from the last time this was an issue? I've pushed an update that short-circuits direct calls to intermediate functions as it's a neat optimization in its own right, and we'll need it anyway when expanding this pass. Thanks again for pointing this out! |
That's what my patch tried to remove years ago, and HiPE was the only thing blocking that removal. |
Indeed. HiPE should add these intermediate functions when needed instead of imposing restrictions on the compiler, |
f22cd26
to
f630de6
If a fun is defined locally and only used for calls, it can be replaced with direct calls to the relevant function. This greatly speeds up "named functions" (which rely on make_fun to recreate themselves) and macros that wrap their body in a fun.
f630de6
to
31a4c1d
This PR optimizes local fun usage by calling their implementation directly when possible, avoiding the creation of fun objects. This greatly speeds up macros that wrap their body in a fun, as well as "named funs" whose current implementation requires them to recreate themselves when used, even for something as simple as recursion.
https://bugs.erlang.org/browse/ERL-639