summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukas Rytz <lukas.rytz@gmail.com>2015-09-16 14:54:49 +0200
committerLukas Rytz <lukas.rytz@gmail.com>2015-09-17 22:05:06 +0200
commit0e2c23a34654da667c6a6c88149b090307bdb2ba (patch)
tree1adfc926db757af567845d2a8abee0ae3bae3ee4
parent7877ccda89a74c942107f955f3a217d9dab35a8e (diff)
downloadscala-0e2c23a34654da667c6a6c88149b090307bdb2ba.tar.gz
scala-0e2c23a34654da667c6a6c88149b090307bdb2ba.tar.bz2
scala-0e2c23a34654da667c6a6c88149b090307bdb2ba.zip
Don't run unreachable code elimination when building the call graph
It's not necessary to run it for building the call graph. DCE will be run anyway later down the pipeline.
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/opt/CallGraph.scala5
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala3
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/opt/LocalOpt.scala2
3 files changed, 4 insertions, 6 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 535a46f362..aea4058752 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/opt/CallGraph.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/CallGraph.scala
@@ -95,7 +95,6 @@ class CallGraph[BT <: BTypes](val btypes: BT) {
// For now we run a NullnessAnalyzer. It is used to determine if the receiver of an instance
// call is known to be not-null, in which case we don't have to emit a null check when inlining.
// It is also used to get the stack height at the call site.
- localOpt.minimalRemoveUnreachableCode(methodNode, definingClass.internalName)
val analyzer = {
if (compilerSettings.YoptNullnessTracking) new AsmAnalyzer(methodNode, definingClass.internalName, new NullnessAnalyzer)
@@ -117,7 +116,7 @@ class CallGraph[BT <: BTypes](val btypes: BT) {
lazy val prodCons = new ProdConsAnalyzer(methodNode, definingClass.internalName)
methodNode.instructions.iterator.asScala foreach {
- case call: MethodInsnNode =>
+ case call: MethodInsnNode if analyzer.frameAt(call) != null => // skips over unreachable code
val callee: Either[OptimizerWarning, Callee] = for {
(method, declarationClass) <- byteCodeRepository.methodNode(call.owner, call.name, call.desc): Either[OptimizerWarning, (MethodNode, InternalName)]
(declarationClassNode, source) <- byteCodeRepository.classNodeAndSource(declarationClass): Either[OptimizerWarning, (ClassNode, Source)]
@@ -153,7 +152,7 @@ class CallGraph[BT <: BTypes](val btypes: BT) {
callsitePosition = callsitePositions.getOrElse(call, NoPosition)
)
- case LambdaMetaFactoryCall(indy, samMethodType, implMethod, instantiatedMethodType) =>
+ case LambdaMetaFactoryCall(indy, samMethodType, implMethod, instantiatedMethodType) if analyzer.frameAt(indy) != null =>
val lmf = LambdaMetaFactoryCall(indy, samMethodType, implMethod, instantiatedMethodType)
val capturedArgInfos = computeCapturedArgInfos(lmf, prodCons)
methodClosureInstantiations += indy -> ClosureInstantiation(
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 36ace2f4f9..4c36377128 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala
@@ -143,8 +143,7 @@ class Inliner[BT <: BTypes](val btypes: BT) {
// VerifyError. We run a `SourceInterpreter` to find all producer instructions of the
// receiver value and add a cast to the self type after each.
if (!selfTypeOk) {
- // there's no need to run eliminateUnreachableCode here. building the call graph does that
- // already, no code can become unreachable in the meantime.
+ localOpt.minimalRemoveUnreachableCode(callsite.callsiteMethod, callsite.callsiteClass.internalName)
val analyzer = new AsmAnalyzer(callsite.callsiteMethod, callsite.callsiteClass.internalName, new Analyzer(new SourceInterpreter))
val receiverValue = analyzer.frameAt(callsite.callsiteInstruction).peekStack(traitMethodArgumentTypes.length)
for (i <- receiverValue.insns.asScala) {
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/opt/LocalOpt.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/LocalOpt.scala
index fe398ce652..684ef30adf 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/opt/LocalOpt.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/LocalOpt.scala
@@ -87,7 +87,7 @@ class LocalOpt[BT <: BTypes](val btypes: BT) {
*
* This implementation only removes instructions that are unreachable for an ASM analyzer /
* interpreter. This ensures that future analyses will not produce `null` frames. The inliner
- * and call graph builder depend on this property.
+ * depends on this property.
*
* @return A set containing the eliminated instructions
*/