From 11614455e71530292c1ed98dc4fbda5efee0b84d Mon Sep 17 00:00:00 2001 From: Lukas Rytz Date: Mon, 23 Nov 2015 15:26:45 +0100 Subject: Fix in "consumersOfOutputsFrom" query in prod-cons analysis Fix the "consumersOfOutputsFrom" in the prod-cons analysis to support dummy instructions: - UninitializedLocalProducer - ParameterProducer - ExceptionProducer --- .../jvm/analysis/ProdConsAnalyzerImpl.scala | 31 +++++++++++++++------- 1 file changed, 21 insertions(+), 10 deletions(-) (limited to 'src/compiler') diff --git a/src/compiler/scala/tools/nsc/backend/jvm/analysis/ProdConsAnalyzerImpl.scala b/src/compiler/scala/tools/nsc/backend/jvm/analysis/ProdConsAnalyzerImpl.scala index f7ec55f305..894799bf36 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/analysis/ProdConsAnalyzerImpl.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/analysis/ProdConsAnalyzerImpl.scala @@ -94,8 +94,13 @@ trait ProdConsAnalyzerImpl { inputValues(insn).iterator.flatMap(v => v.insns.asScala).toSet } - def consumersOfOutputsFrom(insn: AbstractInsnNode): Set[AbstractInsnNode] = - _consumersOfOutputsFrom.get(insn).map(v => v.indices.flatMap(v.apply)(collection.breakOut): Set[AbstractInsnNode]).getOrElse(Set.empty) + def consumersOfOutputsFrom(insn: AbstractInsnNode): Set[AbstractInsnNode] = insn match { + case _: UninitializedLocalProducer => Set.empty + case ParameterProducer(local) => consumersOfValueAt(methodNode.instructions.getFirst, local) + case ExceptionProducer(handlerLabel, handlerFrame) => consumersOfValueAt(handlerLabel, handlerFrame.stackTop) + case _ => + _consumersOfOutputsFrom.get(insn).map(v => v.indices.flatMap(v.apply)(collection.breakOut): Set[AbstractInsnNode]).getOrElse(Set.empty) + } /** * Returns the potential initial producer instructions of a value in the frame of `insn`. @@ -151,9 +156,15 @@ trait ProdConsAnalyzerImpl { inputValueSlots(insn).flatMap(slot => initialProducersForValueAt(insn, slot)).toSet } - def ultimateConsumersOfOutputsFrom(insn: AbstractInsnNode): Set[AbstractInsnNode] = { - lazy val next = insn.getNext - outputValueSlots(insn).flatMap(slot => ultimateConsumersOfValueAt(next, slot)).toSet + def ultimateConsumersOfOutputsFrom(insn: AbstractInsnNode): Set[AbstractInsnNode] = insn match { + case _: UninitializedLocalProducer => Set.empty + case _ => + lazy val next = insn match { + case _: ParameterProducer => methodNode.instructions.getFirst + case ExceptionProducer(handlerLabel, _) => handlerLabel + case _ => insn.getNext + } + outputValueSlots(insn).flatMap(slot => ultimateConsumersOfValueAt(next, slot)).toSet } private def isCopyOperation(insn: AbstractInsnNode): Boolean = { @@ -378,7 +389,7 @@ trait ProdConsAnalyzerImpl { private def outputValueSlots(insn: AbstractInsnNode): Seq[Int] = insn match { case ParameterProducer(local) => Seq(local) case UninitializedLocalProducer(local) => Seq(local) - case ExceptionProducer(frame) => Seq(frame.stackTop) + case ExceptionProducer(_, frame) => Seq(frame.stackTop) case _ => if (insn.getOpcode == -1) return Seq.empty if (isStore(insn)) { @@ -443,9 +454,9 @@ abstract class InitialProducer extends AbstractInsnNode(-1) { override def accept(cv: MethodVisitor): Unit = throw new UnsupportedOperationException } -case class ParameterProducer(local: Int) extends InitialProducer -case class UninitializedLocalProducer(local: Int) extends InitialProducer -case class ExceptionProducer[V <: Value](handlerFrame: Frame[V]) extends InitialProducer +case class ParameterProducer(local: Int) extends InitialProducer +case class UninitializedLocalProducer(local: Int) extends InitialProducer +case class ExceptionProducer[V <: Value](handlerLabel: LabelNode, handlerFrame: Frame[V]) extends InitialProducer class InitialProducerSourceInterpreter extends SourceInterpreter { override def newParameterValue(isInstanceMethod: Boolean, local: Int, tp: Type): SourceValue = { @@ -457,6 +468,6 @@ class InitialProducerSourceInterpreter extends SourceInterpreter { } override def newExceptionValue(tryCatchBlockNode: TryCatchBlockNode, handlerFrame: Frame[_ <: Value], exceptionType: Type): SourceValue = { - new SourceValue(1, ExceptionProducer(handlerFrame)) + new SourceValue(1, ExceptionProducer(tryCatchBlockNode.handler, handlerFrame)) } } -- cgit v1.2.3