summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukas Rytz <lukas.rytz@gmail.com>2015-08-20 16:06:31 +0200
committerLukas Rytz <lukas.rytz@gmail.com>2015-08-27 09:23:49 +0200
commit40ef6d4abb1ee68c8f0f9579b40e228ac973d092 (patch)
treefd53b68daec9acb9a90a02eed84acbf961501178
parent617c0923bd6b5d1642d04a03508f063d503776b6 (diff)
downloadscala-40ef6d4abb1ee68c8f0f9579b40e228ac973d092.tar.gz
scala-40ef6d4abb1ee68c8f0f9579b40e228ac973d092.tar.bz2
scala-40ef6d4abb1ee68c8f0f9579b40e228ac973d092.zip
move current inliner heuristic to the InlinerHeuristics class
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala48
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/opt/InlinerHeuristics.scala49
2 files changed, 50 insertions, 47 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala
index 035be3acdd..cc5a4de4e4 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala
@@ -26,6 +26,7 @@ class Inliner[BT <: BTypes](val btypes: BT) {
import callGraph._
val heuristics: InlinerHeuristics[btypes.type] = new InlinerHeuristics(btypes)
+ import heuristics._
def eliminateUnreachableCodeAndUpdateCallGraph(methodNode: MethodNode, definingClass: InternalName): Unit = {
localOpt.minimalRemoveUnreachableCode(methodNode, definingClass) foreach {
@@ -87,53 +88,6 @@ class Inliner[BT <: BTypes](val btypes: BT) {
}
}
- /**
- * Select callsites from the call graph that should be inlined. The resulting list of inlining
- * requests is allowed to have cycles, and the callsites can appear in any order.
- */
- def selectCallsitesForInlining: List[Callsite] = {
- callsites.valuesIterator.flatMap(_.valuesIterator.filter({
- case callsite @ Callsite(_, _, _, Right(Callee(callee, calleeDeclClass, safeToInline, _, annotatedInline, _, warning)), _, _, _, pos) =>
- val res = doInlineCallsite(callsite)
-
- if (!res) {
- if (annotatedInline && btypes.compilerSettings.YoptWarningEmitAtInlineFailed) {
- // if the callsite is annotated @inline, we report an inline warning even if the underlying
- // reason is, for example, mixed compilation (which has a separate -Yopt-warning flag).
- def initMsg = s"${BackendReporting.methodSignature(calleeDeclClass.internalName, callee)} is annotated @inline but cannot be inlined"
- def warnMsg = warning.map(" Possible reason:\n" + _).getOrElse("")
- if (doRewriteTraitCallsite(callsite))
- backendReporting.inlinerWarning(pos, s"$initMsg: the trait method call could not be rewritten to the static implementation method." + warnMsg)
- else if (!safeToInline)
- backendReporting.inlinerWarning(pos, s"$initMsg: the method is not final and may be overridden." + warnMsg)
- else
- backendReporting.inlinerWarning(pos, s"$initMsg." + warnMsg)
- } else if (warning.isDefined && warning.get.emitWarning(compilerSettings)) {
- // when annotatedInline is false, and there is some warning, the callsite metadata is possibly incomplete.
- backendReporting.inlinerWarning(pos, s"there was a problem determining if method ${callee.name} can be inlined: \n"+ warning.get)
- }
- }
-
- res
-
- case Callsite(ins, _, _, Left(warning), _, _, _, pos) =>
- if (warning.emitWarning(compilerSettings))
- backendReporting.inlinerWarning(pos, s"failed to determine if ${ins.name} should be inlined:\n$warning")
- false
- })).toList
- }
-
- /**
- * The current inlining heuristics are simple: inline calls to methods annotated @inline.
- */
- def doInlineCallsite(callsite: Callsite): Boolean = callsite match {
- case Callsite(_, _, _, Right(Callee(callee, calleeDeclClass, safeToInline, _, annotatedInline, _, warning)), _, _, _, pos) =>
- if (compilerSettings.YoptInlineHeuristics.value == "everything") safeToInline
- else annotatedInline && safeToInline
-
- case _ => false
- }
-
def rewriteFinalTraitMethodInvocations(): Unit = {
// Rewriting final trait method callsites to the implementation class enables inlining.
// We cannot just iterate over the values of the `callsites` map because the rewrite changes the
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/opt/InlinerHeuristics.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/InlinerHeuristics.scala
index 09bb59cd4d..35f839aa1b 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/opt/InlinerHeuristics.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/InlinerHeuristics.scala
@@ -11,6 +11,55 @@ import scala.tools.nsc.backend.jvm.BTypes.InternalName
class InlinerHeuristics[BT <: BTypes](val bTypes: BT) {
import bTypes._
+ import inliner._
+ import callGraph._
+
+ /**
+ * Select callsites from the call graph that should be inlined. The resulting list of inlining
+ * requests is allowed to have cycles, and the callsites can appear in any order.
+ */
+ def selectCallsitesForInlining: List[Callsite] = {
+ callsites.valuesIterator.flatMap(_.valuesIterator.filter({
+ case callsite @ Callsite(_, _, _, Right(Callee(callee, calleeDeclClass, safeToInline, _, annotatedInline, _, warning)), _, _, _, pos) =>
+ val res = doInlineCallsite(callsite)
+
+ if (!res) {
+ if (annotatedInline && bTypes.compilerSettings.YoptWarningEmitAtInlineFailed) {
+ // if the callsite is annotated @inline, we report an inline warning even if the underlying
+ // reason is, for example, mixed compilation (which has a separate -Yopt-warning flag).
+ def initMsg = s"${BackendReporting.methodSignature(calleeDeclClass.internalName, callee)} is annotated @inline but cannot be inlined"
+ def warnMsg = warning.map(" Possible reason:\n" + _).getOrElse("")
+ if (doRewriteTraitCallsite(callsite))
+ backendReporting.inlinerWarning(pos, s"$initMsg: the trait method call could not be rewritten to the static implementation method." + warnMsg)
+ else if (!safeToInline)
+ backendReporting.inlinerWarning(pos, s"$initMsg: the method is not final and may be overridden." + warnMsg)
+ else
+ backendReporting.inlinerWarning(pos, s"$initMsg." + warnMsg)
+ } else if (warning.isDefined && warning.get.emitWarning(compilerSettings)) {
+ // when annotatedInline is false, and there is some warning, the callsite metadata is possibly incomplete.
+ backendReporting.inlinerWarning(pos, s"there was a problem determining if method ${callee.name} can be inlined: \n"+ warning.get)
+ }
+ }
+
+ res
+
+ case Callsite(ins, _, _, Left(warning), _, _, _, pos) =>
+ if (warning.emitWarning(compilerSettings))
+ backendReporting.inlinerWarning(pos, s"failed to determine if ${ins.name} should be inlined:\n$warning")
+ false
+ })).toList
+ }
+
+ /**
+ * The current inlining heuristics are simple: inline calls to methods annotated @inline.
+ */
+ def doInlineCallsite(callsite: Callsite): Boolean = callsite match {
+ case Callsite(_, _, _, Right(Callee(callee, calleeDeclClass, safeToInline, _, annotatedInline, _, warning)), _, _, _, pos) =>
+ if (compilerSettings.YoptInlineHeuristics.value == "everything") safeToInline
+ else annotatedInline && safeToInline
+
+ case _ => false
+ }
/*
// using http://lihaoyi.github.io/Ammonite/