-
Notifications
You must be signed in to change notification settings - Fork 3.1k
By default, only run DCE on methods with an ATHROW. #6044
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Removes the three work queues in the backend. Splits up the backend in two main components - CodeGen, which has a Global - PostProcessor, which has a BTypes (but no Global) CodeGen generates asm.ClassNodes and stores them in postProcessor.generatedClasses. The code generator is invoketd through BCodePhase.apply. The postProcessor then runs the optimizer, computes the InnerClass table and adds the lambdaDeserialize method if necessary. It finally serializes the classes into a byte array and writes them to disk. The implementation of classfile writing still depends on Global. It is passed in as an argument to the postProcessor. A later commit will move it to a context without Global and make it thread-safe.
BTypes is the component that's shared between CodeGen and PostProcessor.
Remove implicit conversion from LazyVar[T] to T
GenBCode started to run a local DCE optimization on all methods to afford simplicity in code generation of `Nothing`-typed expressions. Benchmarks show this was costing 1-2% of compile times. This commit selectively run DCE on methods with the problematic THROW, even under `-opt:l:none`. It then changes `-opt:l:default` to the empty set of optimizations. An existing test for this code gen quirk is updated to show with either explicitly enabled or selective targeted DCE, clean code is generated.
(Based on top of #6012) |
I'm looking into the test failure. |
ASM is inserting an unreachable frame into:
Which gets the
|
Code gen continues to generate code (the return statement) after the while loop, but that code is unreachable, so asm replaces it by |
Maybe its too ambitious, but we could modify (or extend) |
The replacing of unreachable code happens when computing stack map frames. First, frames (of reachable labels) are computed in a fixpoint algorithm. Then, code after unreachable labels is replaced (https://github.com/scala/scala-asm/blob/master/src/main/java/scala/tools/asm/MethodWriter.java#L1501). It would be non-trivial to remove the code and fix up all indicies. They do something similar for handling long jumps ( We could remove the asm instructions and re-run the classfile writer, but that also sounds non-optimal. As an alternative approach, we should try whether a home-grown DCE is faster the current |
I was thinking we'd abort writing that method, run our existing DCE, and restart the method writer. This assumes it is possible to do a "rollback" in the ClassWriter/MethodWriter. If methods with dead code are rare, the rollback need not be efficient. |
The DCE detection in ASM is probably faster than ours because it uses I think it safe to use |
I'll close this PR while we experiment with these alternative approaches. Let me know if you'd like to do this work, otherwise I'll come back to it next month. |
If the technique of using
with use of
|
GenBCode started to run a local DCE optimization on all methods to afford
simplicity in code generation of
Nothing
-typed expressions.Benchmarks show this was costing 1-2% of compile times.
This commit selectively run DCE on methods with the problematic THROW, even
under
-opt:l:none
. It then changes-opt:l:default
to the empty set ofoptimizations.
An existing test for this code gen quirk is updated to show with either
explicitly enabled or selective targeted DCE, clean code is generated.