From 68560c60f334c4c8b0d1f4a56a2f255225ae7827 Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Fri, 9 Jul 2021 13:08:13 +0300 Subject: [PATCH] JVM use FastMethodAnalyzer when possible --- .../RedundantLocalsEliminationMethodTransformer.kt | 4 ++-- .../coroutines/SpilledVariableFieldTypesAnalysis.kt | 6 +++--- .../jetbrains/kotlin/codegen/inline/MethodInlinerUtil.kt | 5 +++-- .../boxing/PopBackwardPropagationTransformer.kt | 9 ++++++--- .../codegen/optimization/common/ControlFlowGraph.kt | 5 +++-- .../optimization/common/CustomFramesMethodAnalyzer.kt | 2 +- .../codegen/optimization/common/FastMethodAnalyzer.kt | 4 ++-- 7 files changed, 20 insertions(+), 15 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/RedundantLocalsEliminationMethodTransformer.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/RedundantLocalsEliminationMethodTransformer.kt index a563df6bc68..6ec778c6d94 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/RedundantLocalsEliminationMethodTransformer.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/RedundantLocalsEliminationMethodTransformer.kt @@ -6,7 +6,7 @@ package org.jetbrains.kotlin.codegen.coroutines import org.jetbrains.kotlin.codegen.optimization.boxing.isUnitInstance -import org.jetbrains.kotlin.codegen.optimization.common.MethodAnalyzer +import org.jetbrains.kotlin.codegen.optimization.common.FastMethodAnalyzer import org.jetbrains.kotlin.codegen.optimization.common.asSequence import org.jetbrains.kotlin.codegen.optimization.common.removeAll import org.jetbrains.kotlin.codegen.optimization.fixStack.top @@ -85,7 +85,7 @@ private class UnitSourceInterpreter(private val localVariables: Set) : Basi } fun run(internalClassName: String, methodNode: MethodNode): Array?> { - val frames = MethodAnalyzer(internalClassName, methodNode, this).analyze() + val frames = FastMethodAnalyzer(internalClassName, methodNode, this).analyze() // The ASM analyzer does not visit POP instructions, so we do so here. for ((insn, frame) in methodNode.instructions.asSequence().zip(frames.asSequence())) { if (frame != null && insn.opcode == Opcodes.POP) { diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/SpilledVariableFieldTypesAnalysis.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/SpilledVariableFieldTypesAnalysis.kt index eab4bea44fd..8ac216224b9 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/SpilledVariableFieldTypesAnalysis.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/SpilledVariableFieldTypesAnalysis.kt @@ -6,7 +6,7 @@ package org.jetbrains.kotlin.codegen.coroutines import org.jetbrains.kotlin.codegen.StackValue -import org.jetbrains.kotlin.codegen.optimization.common.MethodAnalyzer +import org.jetbrains.kotlin.codegen.optimization.common.FastMethodAnalyzer import org.jetbrains.kotlin.codegen.optimization.common.OptimizationBasicInterpreter import org.jetbrains.org.objectweb.asm.Label import org.jetbrains.org.objectweb.asm.Opcodes @@ -130,11 +130,11 @@ internal fun performSpilledVariableFieldTypesAnalysis( thisName: String ): Array?> { val interpreter = IntLikeCoerceInterpreter() - MethodAnalyzer(thisName, methodNode, interpreter).analyze() + FastMethodAnalyzer(thisName, methodNode, interpreter).analyze() for ((insn, type) in interpreter.needsToBeCoerced) { methodNode.instructions.insert(insn, withInstructionAdapter { coerceInt(type, this) }) } - return MethodAnalyzer(thisName, methodNode, OptimizationBasicInterpreter()).analyze() + return FastMethodAnalyzer(thisName, methodNode, OptimizationBasicInterpreter()).analyze() } private fun coerceInt(to: Type, v: InstructionAdapter) { diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInlinerUtil.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInlinerUtil.kt index ac56f28a20f..580ff1f7ea8 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInlinerUtil.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInlinerUtil.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.codegen.inline +import org.jetbrains.kotlin.codegen.optimization.common.FastMethodAnalyzer import org.jetbrains.kotlin.codegen.optimization.common.InsnSequence import org.jetbrains.kotlin.codegen.optimization.common.isMeaningful import org.jetbrains.kotlin.codegen.optimization.nullCheck.isCheckParameterIsNotNull @@ -136,7 +137,7 @@ internal class Aload0Interpreter(private val node: MethodNode) : BasicInterprete internal fun AbstractInsnNode.isAload0() = opcode == Opcodes.ALOAD && (this as VarInsnNode).`var` == 0 internal fun analyzeMethodNodeWithInterpreter(node: MethodNode, interpreter: BasicInterpreter): Array?> { - val analyzer = object : Analyzer(interpreter) { + val analyzer = object : FastMethodAnalyzer("fake", node, interpreter) { override fun newFrame(nLocals: Int, nStack: Int): Frame { return object : Frame(nLocals, nStack) { @@ -151,7 +152,7 @@ internal fun analyzeMethodNodeWithInterpreter(node: MethodNode, interpreter: Bas } try { - return analyzer.analyze("fake", node) + return analyzer.analyze() } catch (e: AnalyzerException) { throw RuntimeException(e) } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/boxing/PopBackwardPropagationTransformer.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/boxing/PopBackwardPropagationTransformer.kt index 00360890a1e..bcbafac784d 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/boxing/PopBackwardPropagationTransformer.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/boxing/PopBackwardPropagationTransformer.kt @@ -17,13 +17,16 @@ package org.jetbrains.kotlin.codegen.optimization.boxing import org.jetbrains.kotlin.codegen.optimization.OptimizationMethodVisitor +import org.jetbrains.kotlin.codegen.optimization.common.FastMethodAnalyzer import org.jetbrains.kotlin.codegen.optimization.common.isLoadOperation import org.jetbrains.kotlin.codegen.optimization.fixStack.peekWords import org.jetbrains.kotlin.codegen.optimization.fixStack.top import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer import org.jetbrains.org.objectweb.asm.Opcodes -import org.jetbrains.org.objectweb.asm.tree.* -import org.jetbrains.org.objectweb.asm.tree.analysis.Analyzer +import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode +import org.jetbrains.org.objectweb.asm.tree.FieldInsnNode +import org.jetbrains.org.objectweb.asm.tree.InsnNode +import org.jetbrains.org.objectweb.asm.tree.MethodNode import org.jetbrains.org.objectweb.asm.tree.analysis.Frame import org.jetbrains.org.objectweb.asm.tree.analysis.SourceInterpreter import org.jetbrains.org.objectweb.asm.tree.analysis.SourceValue @@ -52,7 +55,7 @@ class PopBackwardPropagationTransformer : MethodTransformer() { private val dontTouchInsnIndices = BitSet(insns.size) fun transform() { - val frames = Analyzer(HazardsTrackingInterpreter()).analyze("fake", methodNode) + val frames = FastMethodAnalyzer("fake", methodNode, HazardsTrackingInterpreter()).analyze() for ((i, insn) in insns.withIndex()) { val frame = frames[i] ?: continue when (insn.opcode) { diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/common/ControlFlowGraph.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/common/ControlFlowGraph.kt index d52e67726d2..3a13567066f 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/common/ControlFlowGraph.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/common/ControlFlowGraph.kt @@ -12,8 +12,8 @@ import org.jetbrains.org.objectweb.asm.tree.analysis.BasicValue class ControlFlowGraph private constructor(private val insns: InsnList) { - private val edges: Array> = Array(insns.size()) { arrayListOf() } - private val backwardEdges: Array> = Array(insns.size()) { arrayListOf() } + private val edges: Array> = Array(insns.size()) { ArrayList() } + private val backwardEdges: Array> = Array(insns.size()) { ArrayList() } fun getSuccessorsIndices(insn: AbstractInsnNode): List = getSuccessorsIndices(insns.indexOf(insn)) fun getSuccessorsIndices(index: Int): List = edges[index] @@ -30,6 +30,7 @@ class ControlFlowGraph private constructor(private val insns: InsnList) { graph.backwardEdges[to].add(from) } + // TODO custom analyzer, no need to analyze data flow object : MethodAnalyzer("fake", node, OptimizationBasicInterpreter()) { override fun visitControlFlowEdge(insn: Int, successor: Int): Boolean { addEdge(insn, successor) diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/common/CustomFramesMethodAnalyzer.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/common/CustomFramesMethodAnalyzer.kt index 73513222c4f..83f9198e63a 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/common/CustomFramesMethodAnalyzer.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/common/CustomFramesMethodAnalyzer.kt @@ -24,6 +24,6 @@ import org.jetbrains.org.objectweb.asm.tree.analysis.Value class CustomFramesMethodAnalyzer( owner: String, method: MethodNode, interpreter: Interpreter, private val frameFactory: (Int, Int) -> Frame -) : MethodAnalyzer(owner, method, interpreter) { +) : FastMethodAnalyzer(owner, method, interpreter) { override fun newFrame(nLocals: Int, nStack: Int) = frameFactory(nLocals, nStack) } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/common/FastMethodAnalyzer.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/common/FastMethodAnalyzer.kt index e0d55bff5e5..fb4c3647e46 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/common/FastMethodAnalyzer.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/common/FastMethodAnalyzer.kt @@ -45,7 +45,7 @@ import org.jetbrains.org.objectweb.asm.tree.analysis.Interpreter import org.jetbrains.org.objectweb.asm.tree.analysis.Value @Suppress("DuplicatedCode") -class FastMethodAnalyzer( +open class FastMethodAnalyzer( private val owner: String, val method: MethodNode, private val interpreter: Interpreter @@ -87,7 +87,7 @@ class FastMethodAnalyzer( private val queue = IntArray(nInsns) private var top = 0 - private fun newFrame(nLocals: Int, nStack: Int): Frame = + protected open fun newFrame(nLocals: Int, nStack: Int): Frame = Frame(nLocals, nStack) fun analyze(): Array?> {