summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/backend/jvm/opt/InlinerHeuristics.scala
diff options
context:
space:
mode:
authorLukas Rytz <lukas.rytz@gmail.com>2015-08-24 21:25:19 +0200
committerLukas Rytz <lukas.rytz@gmail.com>2015-08-27 09:23:50 +0200
commit246f3eb69707db9ef8185e68408b3ddaba9ac17d (patch)
tree21e05619bb44a7bafe3f58e604cc2f7a2a2dd95a /src/compiler/scala/tools/nsc/backend/jvm/opt/InlinerHeuristics.scala
parent3e055f1cc19fffe69e4882c6b4f4d5019503a109 (diff)
downloadscala-246f3eb69707db9ef8185e68408b3ddaba9ac17d.tar.gz
scala-246f3eb69707db9ef8185e68408b3ddaba9ac17d.tar.bz2
scala-246f3eb69707db9ef8185e68408b3ddaba9ac17d.zip
Make sure to inline only callsites in classes being compiled
Avoid producing inline requests for callsites in classes on the classpath.
Diffstat (limited to 'src/compiler/scala/tools/nsc/backend/jvm/opt/InlinerHeuristics.scala')
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/opt/InlinerHeuristics.scala62
1 files changed, 33 insertions, 29 deletions
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 ba05608918..df2eb813d3 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/opt/InlinerHeuristics.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/InlinerHeuristics.scala
@@ -24,39 +24,43 @@ class InlinerHeuristics[BT <: BTypes](val bTypes: BT) {
* requests is allowed to have cycles, and the callsites can appear in any order.
*/
def selectCallsitesForInlining: Map[MethodNode, Set[InlineRequest]] = {
- callGraph.callsites.iterator.map({
- case (methodNode, callsites) =>
- val requests = callsites.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)
- }
+ // We should only return inlining requests for callsites being compiled (not for callsites in
+ // classes on the classpath). The call graph may contain callsites of classes parsed from the
+ // classpath. In order to get only the callsites being compiled, we start at the map of
+ // compilingClasses in the byteCodeRepository.
+ val compilingMethods = byteCodeRepository.compilingClasses.valuesIterator.flatMap(_.methods.iterator.asScala)
+ compilingMethods.map(methodNode => {
+ val requests = callGraph.callsites(methodNode).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
+ 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
- })
+ 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
+ })
- (methodNode, requests.map(InlineRequest(_, Nil)).toSet)
+ (methodNode, requests.map(InlineRequest(_, Nil)).toSet)
}).filterNot(_._2.isEmpty).toMap
}