diff options
author | Lukas Rytz <lukas.rytz@gmail.com> | 2015-03-30 14:07:23 +0200 |
---|---|---|
committer | Lukas Rytz <lukas.rytz@gmail.com> | 2015-04-01 08:34:20 +0200 |
commit | fa110edd473ac5bbdb66fbd5a51fa2685c0dcf21 (patch) | |
tree | 9e927368e5e5e035819005022c74f012ca15e029 /src/compiler/scala/tools/nsc/backend/jvm/GenBCode.scala | |
parent | 6cf17ccd0101514a603a8c191438bdc2764838f9 (diff) | |
download | scala-fa110edd473ac5bbdb66fbd5a51fa2685c0dcf21.tar.gz scala-fa110edd473ac5bbdb66fbd5a51fa2685c0dcf21.tar.bz2 scala-fa110edd473ac5bbdb66fbd5a51fa2685c0dcf21.zip |
Eliminate unreachable code before inlining a method
Running an ASM analyzer returns null frames for unreachable
instructions in the analyzed method. The inliner (and other components
of the optimizer) require unreachable code to be eliminated to avoid
null frames.
Before this change, unreachable code was eliminated before building
the call graph, but not again before inlining: the inliner assumed
that methods in the call graph have no unreachable code.
This invariant can break when inlining a method. Example:
def f = throw e
def g = f; println()
When building the call graph, both f and g contain no unreachable
code. After inlining f, the println() call becomes unreachable. This
breaks the inliner's assumption if it tries to inline a call to g.
This change intruduces a cache to remember methods that have no
unreachable code. This allows invoking DCE every time no dead code is
required, and bail out fast. This also simplifies following the
control flow in the optimizer (call DCE whenever no dead code is
required).
Diffstat (limited to 'src/compiler/scala/tools/nsc/backend/jvm/GenBCode.scala')
-rw-r--r-- | src/compiler/scala/tools/nsc/backend/jvm/GenBCode.scala | 8 |
1 files changed, 3 insertions, 5 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenBCode.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenBCode.scala index be1595dc29..4bfd70bf1e 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GenBCode.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GenBCode.scala @@ -215,17 +215,15 @@ abstract class GenBCode extends BCodeSyncAndTry { * - converting the plain ClassNode to byte array and placing it on queue-3 */ class Worker2 { - lazy val localOpt = new LocalOpt(settings) + // This instance is removed in a future commit that refactors LocalOpt + lazy val localOpt = new LocalOpt(settings, collection.mutable.Set()) def runGlobalOptimizations(): Unit = { import scala.collection.convert.decorateAsScala._ q2.asScala foreach { case Item2(_, _, plain, _, _) => // skip mirror / bean: wd don't inline into tem, and they are not used in the plain class - if (plain != null) { - localOpt.minimalRemoveUnreachableCode(plain) - callGraph.addClass(plain) - } + if (plain != null) callGraph.addClass(plain) } bTypes.inliner.runInliner() } |