diff options
author | Lukas Rytz <lukas.rytz@gmail.com> | 2015-01-19 10:00:04 +0100 |
---|---|---|
committer | Lukas Rytz <lukas.rytz@gmail.com> | 2015-03-11 12:53:34 -0700 |
commit | 37f7b76710c72360577250f07bd8b5cf55e527cc (patch) | |
tree | 606593339c410b055f1b2ca99502d67ba721c1c1 /src/compiler/scala/tools/nsc/backend/jvm/GenBCode.scala | |
parent | 0d8b32469ec655f35a31843e1843b8a580e772d1 (diff) | |
download | scala-37f7b76710c72360577250f07bd8b5cf55e527cc.tar.gz scala-37f7b76710c72360577250f07bd8b5cf55e527cc.tar.bz2 scala-37f7b76710c72360577250f07bd8b5cf55e527cc.zip |
Integrate the inliner into the backend pipeline
The current heuristics are simple: attempt to inline every method
annotated `@inline`. Cycles in the inline request graph are broken
in a determinisitc manner. Inlining is then performed starting at the
leaves of the inline request graph, i.e., with those callsites where
the target method has no callsites to inline.
This expansion strategy can make a method grow arbitrarily. We will
most likely have to add some thresholds and / or other measures to
prevent size issues.
Diffstat (limited to 'src/compiler/scala/tools/nsc/backend/jvm/GenBCode.scala')
-rw-r--r-- | src/compiler/scala/tools/nsc/backend/jvm/GenBCode.scala | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenBCode.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenBCode.scala index 9b3bd7648d..173aa0ca30 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GenBCode.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GenBCode.scala @@ -217,11 +217,26 @@ abstract class GenBCode extends BCodeSyncAndTry { class Worker2 { lazy val localOpt = new LocalOpt(settings) + 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) + } + } + bTypes.inliner.runInliner() + } + def localOptimizations(classNode: ClassNode): Unit = { BackendStats.timed(BackendStats.methodOptTimer)(localOpt.methodOptimizations(classNode)) } def run() { + if (settings.YoptInlinerEnabled) runGlobalOptimizations() + while (true) { val item = q2.poll if (item.isPoison) { @@ -269,7 +284,12 @@ abstract class GenBCode extends BCodeSyncAndTry { var arrivalPos = 0 - /* + /** + * The `run` method is overridden because the backend has a different data flow than the default + * phase: the backend does not transform compilation units one by one, but on all units in the + * same run. This allows cross-unit optimizations and running some stages of the backend + * concurrently on multiple units. + * * A run of the BCodePhase phase comprises: * * (a) set-up steps (most notably supporting maps in `BCodeTypes`, |