Is it possible to build 'composite' methods, to benefit from JVM TCO? #17899
Replies: 0 comments 12 replies
-
AFAIK not on the JVM - @densh might have something more for you on what is going on in scala-native.
|
Beta Was this translation helpful? Give feedback.
-
@k0ala, it is possible, and you won't even need to jump back into There are several issues with such transformation though:
I was thinking about implementing such a transformation when I started working on Dotty. Given the restrictions, I thought that it makes sense to do it in those two cases:
In first case, user explicitly requested this, in second case, you're side-stepping the separate compilation issue. Additionally, it may be lot safer to do this in linker, as call-graph would be able to find the calls even between different classes. It would severely hit debuggability though. |
Beta Was this translation helpful? Give feedback.
-
@felixmulder I meant that the compiler should rewrite such a constellation into a single composite tail-recursive method, so that the (current) JVM is able to optimize it. But I'll also look into scala-native, thanks. @DarkDimius Interesting. What do you think are major obstacles to this approach? |
Beta Was this translation helpful? Give feedback.
-
We have some other transformations which are higher priority for us. |
Beta Was this translation helpful? Give feedback.
-
@k0ala - ah well then, as Dmitry mentions - that would be possible. @DarkDimius - is this something to consider for linker? |
Beta Was this translation helpful? Give feedback.
-
@felixmulder, yes, this is a nice idea. |
Beta Was this translation helpful? Give feedback.
-
Related discussion happened in comments here: http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6316156 |
Beta Was this translation helpful? Give feedback.
-
@felixmulder Speaking of Native, as soon as we fix scala-native/scala-native#122, LLVM should optimise tail calls for us. |
Beta Was this translation helpful? Give feedback.
-
@DarkDimius Interesting links about inlining/unrolling. Could it make sense to make the composite method only a kind of dispatcher, with most of the bodies of the functions "outsourced"? So that would yield something like
This would reduce the size of the method, and although it would cause the creation of stack frames when calling a body, there would always be only one stack frame on top of the loop (i.e. no StackOverflow). The different bodies could then also get inlined, or at least those that get called most frequently. The outsourcing might be difficult though. |
Beta Was this translation helpful? Give feedback.
-
/cc @wheaties, who is experimenting in this space https://github.com/wheaties/TwoTails |
Beta Was this translation helpful? Give feedback.
-
@k0ala that's a technique I'm going to explore once I get the base case of what I'm writing worked out. @DarkDimius are you saying labels are not easily optimized? |
Beta Was this translation helpful? Give feedback.
-
@wheaties, lablels are gotos, vm does not know about labels. But VM knows a lot about egg, method size, and does not actually count number of executed instructions inside the method. By creating a huge method that contains bodies of all the methods in the recursive group, you would quickly hit some constants in the JIT that would make a lot of important optimisations not performed, most important of which is inlining. Note that even the current tailrec we can stop VM from applying some optimisations, see for example here: https://shipilev.net/blog/2014/java-scala-divided-we-fail/ |
Beta Was this translation helpful? Give feedback.
-
A comment in TailRec states that
Is it possible to build a self-recursive composite method out of mutually recursive methods, in order to benefit from the self-recursive tail call optimization of the JVM? i.e. when the following is detected:
then to replace it with something like this:
N.B. I am not familiar with the compiler internals at all, just wondering whether such a thing is possible, as I would love for Scala to have better TCO 😄
Beta Was this translation helpful? Give feedback.
All reactions