diff options
author | Lukas Rytz <lukas.rytz@gmail.com> | 2016-02-14 11:01:37 +0100 |
---|---|---|
committer | Lukas Rytz <lukas.rytz@gmail.com> | 2016-02-15 10:40:23 +0100 |
commit | 363bad3de9a570746927b3fd9dd0d076cade7750 (patch) | |
tree | 184898c792215b0f34bd25709b1c167f0ae58786 /src/compiler | |
parent | c672d6892db662f15ea1a84cdbedf857e2a17b22 (diff) | |
download | scala-363bad3de9a570746927b3fd9dd0d076cade7750.tar.gz scala-363bad3de9a570746927b3fd9dd0d076cade7750.tar.bz2 scala-363bad3de9a570746927b3fd9dd0d076cade7750.zip |
SD-79 don't issue spurious inliner warnings under l:project
When enabling `-Yopt:inline-project` (or `-Yopt:l:project`), the inliner
would spuriously warn about callsites to methods marked `@inline` that
are read from the classpath (not being compiled currently).
This patch introduces yet another field to the `Callsite` class, which
is growing a bit too large. But the call graph representation will get
an overhaul when implementing the new inliner heuristics (2.12.0-M5), so
this is just a temporary fix that would be nice to have in M4.
Diffstat (limited to 'src/compiler')
4 files changed, 20 insertions, 15 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/opt/CallGraph.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/CallGraph.scala index 863bb2d10a..17255cb880 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/opt/CallGraph.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/CallGraph.scala @@ -132,12 +132,13 @@ class CallGraph[BT <: BTypes](val btypes: BT) { (declarationClassNode, source) <- byteCodeRepository.classNodeAndSource(declarationClass): Either[OptimizerWarning, (ClassNode, Source)] } yield { val declarationClassBType = classBTypeFromClassNode(declarationClassNode) - val CallsiteInfo(safeToInline, safeToRewrite, annotatedInline, annotatedNoInline, samParamTypes, warning) = analyzeCallsite(method, declarationClassBType, call.owner, source) + val CallsiteInfo(safeToInline, safeToRewrite, canInlineFromSource, annotatedInline, annotatedNoInline, samParamTypes, warning) = analyzeCallsite(method, declarationClassBType, call.owner, source) Callee( callee = method, calleeDeclarationClass = declarationClassBType, safeToInline = safeToInline, safeToRewrite = safeToRewrite, + canInlineFromSource = canInlineFromSource, annotatedInline = annotatedInline, annotatedNoInline = annotatedNoInline, samParamTypes = samParamTypes, @@ -255,7 +256,7 @@ class CallGraph[BT <: BTypes](val btypes: BT) { /** * Just a named tuple used as return type of `analyzeCallsite`. */ - private case class CallsiteInfo(safeToInline: Boolean, safeToRewrite: Boolean, + private case class CallsiteInfo(safeToInline: Boolean, safeToRewrite: Boolean, canInlineFromSource: Boolean, annotatedInline: Boolean, annotatedNoInline: Boolean, samParamTypes: IntMap[ClassBType], warning: Option[CalleeInfoWarning]) @@ -316,20 +317,21 @@ class CallGraph[BT <: BTypes](val btypes: BT) { !BytecodeUtils.isConstructor(calleeMethodNode) && !BytecodeUtils.isNativeMethod(calleeMethodNode) && !BytecodeUtils.hasCallerSensitiveAnnotation(calleeMethodNode), - safeToRewrite = canInlineFromSource && isRewritableTraitCall, // (2) - annotatedInline = methodInlineInfo.annotatedInline, - annotatedNoInline = methodInlineInfo.annotatedNoInline, - samParamTypes = samParamTypes(calleeMethodNode, receiverType), - warning = warning) + safeToRewrite = canInlineFromSource && isRewritableTraitCall, // (2) + canInlineFromSource = canInlineFromSource, + annotatedInline = methodInlineInfo.annotatedInline, + annotatedNoInline = methodInlineInfo.annotatedNoInline, + samParamTypes = samParamTypes(calleeMethodNode, receiverType), + warning = warning) case None => val warning = MethodInlineInfoMissing(calleeDeclarationClassBType.internalName, calleeMethodNode.name, calleeMethodNode.desc, calleeDeclarationClassBType.info.orThrow.inlineInfo.warning) - CallsiteInfo(false, false, false, false, IntMap.empty, Some(warning)) + CallsiteInfo(false, false, false, false, false, IntMap.empty, Some(warning)) } } catch { case Invalid(noInfo: NoClassBTypeInfo) => val warning = MethodInlineInfoError(calleeDeclarationClassBType.internalName, calleeMethodNode.name, calleeMethodNode.desc, noInfo) - CallsiteInfo(false, false, false, false, IntMap.empty, Some(warning)) + CallsiteInfo(false, false, false, false, false, IntMap.empty, Some(warning)) } } @@ -393,7 +395,7 @@ class CallGraph[BT <: BTypes](val btypes: BT) { * gathering the information about this callee. */ final case class Callee(callee: MethodNode, calleeDeclarationClass: ClassBType, - safeToInline: Boolean, safeToRewrite: Boolean, + safeToInline: Boolean, safeToRewrite: Boolean, canInlineFromSource: Boolean, annotatedInline: Boolean, annotatedNoInline: Boolean, samParamTypes: IntMap[ClassBType], calleeInfoWarning: Option[CalleeInfoWarning]) { diff --git a/src/compiler/scala/tools/nsc/backend/jvm/opt/ClosureOptimizer.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/ClosureOptimizer.scala index b8547e1dc6..58054f85ad 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/opt/ClosureOptimizer.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/ClosureOptimizer.scala @@ -358,11 +358,13 @@ class ClosureOptimizer[BT <: BTypes](val btypes: BT) { val callee = bodyMethod.map({ case (bodyMethodNode, bodyMethodDeclClass) => val bodyDeclClassType = classBTypeFromParsedClassfile(bodyMethodDeclClass) + val canInlineFromSource = compilerSettings.YoptInlineGlobal || bodyMethodIsBeingCompiled Callee( callee = bodyMethodNode, calleeDeclarationClass = bodyDeclClassType, - safeToInline = compilerSettings.YoptInlineGlobal || bodyMethodIsBeingCompiled, + safeToInline = canInlineFromSource, safeToRewrite = false, // the lambda body method is not a trait interface method + canInlineFromSource = canInlineFromSource, annotatedInline = false, annotatedNoInline = false, samParamTypes = callGraph.samParamTypes(bodyMethodNode, bodyDeclClassType), 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 f247e884ae..9847c9db58 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala @@ -83,7 +83,7 @@ class Inliner[BT <: BTypes](val btypes: BT) { * True for statically resolved trait callsites that should be rewritten to the static implementation method. */ def doRewriteTraitCallsite(callsite: Callsite) = callsite.callee match { - case Right(Callee(_, _, _, safeToRewrite, _, _, _, _)) => safeToRewrite + case Right(callee) => callee.safeToRewrite case _ => false } @@ -101,7 +101,7 @@ class Inliner[BT <: BTypes](val btypes: BT) { // If the callsite was eliminated by DCE, do nothing. if (!callGraph.containsCallsite(callsite)) return - val Right(Callee(callee, calleeDeclarationClass, _, _, annotatedInline, annotatedNoInline, samParamTypes, infoWarning)) = callsite.callee + val Right(Callee(callee, calleeDeclarationClass, _, _, canInlineFromSource, annotatedInline, annotatedNoInline, samParamTypes, infoWarning)) = callsite.callee val traitMethodArgumentTypes = asm.Type.getArgumentTypes(callee.desc) @@ -159,6 +159,7 @@ class Inliner[BT <: BTypes](val btypes: BT) { calleeDeclarationClass = implClassBType, safeToInline = true, safeToRewrite = false, + canInlineFromSource = canInlineFromSource, annotatedInline = annotatedInline, annotatedNoInline = annotatedNoInline, samParamTypes = staticCallSamParamTypes, 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 89a768fd9c..7e35d0e7f0 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/opt/InlinerHeuristics.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/InlinerHeuristics.scala @@ -41,7 +41,7 @@ class InlinerHeuristics[BT <: BTypes](val bTypes: BT) { compilingMethods.map(methodNode => { var requests = Set.empty[InlineRequest] callGraph.callsites(methodNode).valuesIterator foreach { - case callsite @ Callsite(_, _, _, Right(Callee(callee, calleeDeclClass, safeToInline, _, calleeAnnotatedInline, _, _, callsiteWarning)), _, _, _, pos, _, _) => + case callsite @ Callsite(_, _, _, Right(Callee(callee, calleeDeclClass, safeToInline, _, canInlineFromSource, calleeAnnotatedInline, _, _, callsiteWarning)), _, _, _, pos, _, _) => inlineRequest(callsite) match { case Some(Right(req)) => requests += req case Some(Left(w)) => @@ -52,7 +52,7 @@ class InlinerHeuristics[BT <: BTypes](val bTypes: BT) { } case None => - if (calleeAnnotatedInline && !callsite.annotatedNoInline && bTypes.compilerSettings.YoptWarningEmitAtInlineFailed) { + if (canInlineFromSource && calleeAnnotatedInline && !callsite.annotatedNoInline && 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" |