From 0e2c23a34654da667c6a6c88149b090307bdb2ba Mon Sep 17 00:00:00 2001 From: Lukas Rytz Date: Wed, 16 Sep 2015 14:54:49 +0200 Subject: 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. --- src/compiler/scala/tools/nsc/backend/jvm/opt/CallGraph.scala | 5 ++--- src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala | 3 +-- src/compiler/scala/tools/nsc/backend/jvm/opt/LocalOpt.scala | 2 +- 3 files changed, 4 insertions(+), 6 deletions(-) (limited to 'src') 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 */ -- cgit v1.2.3