diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.kt
index 9f27b365067..3330dcf5d0e 100644
--- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.kt
+++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/MethodInliner.kt
@@ -647,7 +647,7 @@ class MethodInliner(
} else {
//given frame is null if and only if the corresponding instruction cannot be reached (dead code).
//clean dead code otherwise there is problems in unreachable finally block, don't touch label it cause try/catch/finally problems
- if (cur.type == AbstractInsnNode.LABEL) {
+ if (cur.nodeType == AbstractInsnNode.LABEL) {
//NB: Cause we generate exception table for default handler using gaps (see ExpressionCodegen.visitTryExpression)
//it may occurs that interval for default handler starts before catch start label, so this label seems as dead,
//but as result all this labels will be merged into one (see KT-5863)
@@ -856,9 +856,9 @@ class MethodInliner(
// - there's a local variable table entry for this variable
val usedIntegerVar = BooleanArray(node.maxLocals)
for (insn in insnArray) {
- if (insn.type == AbstractInsnNode.VAR_INSN && insn.opcode == Opcodes.ILOAD) {
+ if (insn.nodeType == AbstractInsnNode.VAR_INSN && insn.opcode == Opcodes.ILOAD) {
usedIntegerVar[(insn as VarInsnNode).`var`] = true
- } else if (insn.type == AbstractInsnNode.IINC_INSN) {
+ } else if (insn.nodeType == AbstractInsnNode.IINC_INSN) {
usedIntegerVar[(insn as IincInsnNode).`var`] = true
}
}
@@ -883,7 +883,7 @@ class MethodInliner(
if (p1.opcode != Opcodes.ISTORE) continue
val p2 = p1.next ?: break
- if (p2.type != AbstractInsnNode.LABEL) continue
+ if (p2.nodeType != AbstractInsnNode.LABEL) continue
val varIndex = (p1 as VarInsnNode).`var`
if (!usedIntegerVar[varIndex]) {
diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/inlineCodegenUtils.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/inlineCodegenUtils.kt
index 8da1c9268b1..8981c336036 100644
--- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/inlineCodegenUtils.kt
+++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/inlineCodegenUtils.kt
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.codegen.coroutines.unwrapInitialDescriptorForSuspend
import org.jetbrains.kotlin.codegen.optimization.common.InsnSequence
import org.jetbrains.kotlin.codegen.optimization.common.asSequence
import org.jetbrains.kotlin.codegen.optimization.common.intConstant
+import org.jetbrains.kotlin.codegen.optimization.common.nodeType
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapperBase
@@ -375,7 +376,7 @@ fun MethodNode.dumpBody(): String {
}
for ((i, insn) in this.instructions.toArray().withIndex()) {
- when (insn.type) {
+ when (insn.nodeType) {
AbstractInsnNode.INSN ->
pw.println("$i\t${Printer.OPCODES[insn.opcode]}")
AbstractInsnNode.INT_INSN ->
diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/NegatedJumpsMethodTransformer.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/NegatedJumpsMethodTransformer.kt
index 80f7e86b602..fe8d78f7f9b 100644
--- a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/NegatedJumpsMethodTransformer.kt
+++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/NegatedJumpsMethodTransformer.kt
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.codegen.optimization
+import org.jetbrains.kotlin.codegen.optimization.common.nodeType
import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer
import org.jetbrains.org.objectweb.asm.Opcodes
import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode
@@ -23,7 +24,7 @@ class NegatedJumpsMethodTransformer : MethodTransformer() {
// IF_ICMPGE L2 = negatedJumpInsn
// L1: = next2
for (insn in insnList.toArray()) {
- if (insn.type != AbstractInsnNode.JUMP_INSN || insn.opcode == Opcodes.GOTO) continue
+ if (insn.nodeType != AbstractInsnNode.JUMP_INSN || insn.opcode == Opcodes.GOTO) continue
val next1 = insn.next ?: continue
if (next1.opcode != Opcodes.GOTO) continue
val next2 = next1.next ?: continue
diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/OptimizationMethodVisitor.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/OptimizationMethodVisitor.kt
index 5da9b3a8db3..e2f179fbab6 100644
--- a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/OptimizationMethodVisitor.kt
+++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/OptimizationMethodVisitor.kt
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.codegen.optimization.boxing.PopBackwardPropagationTr
import org.jetbrains.kotlin.codegen.optimization.boxing.RedundantBoxingMethodTransformer
import org.jetbrains.kotlin.codegen.optimization.boxing.StackPeepholeOptimizationsTransformer
import org.jetbrains.kotlin.codegen.optimization.common.prepareForEmitting
+import org.jetbrains.kotlin.codegen.optimization.common.nodeType
import org.jetbrains.kotlin.codegen.optimization.nullCheck.RedundantNullCheckMethodTransformer
import org.jetbrains.kotlin.codegen.optimization.temporaryVals.TemporaryVariablesEliminationTransformer
import org.jetbrains.kotlin.codegen.optimization.transformer.CompositeMethodTransformer
@@ -107,8 +108,9 @@ class OptimizationMethodVisitor(
// by anything other than a jump-targeted label, so those instructions consume no extra memory.
// To avoid checking all jumps, here we assume all labels are potentially targeted.
// (Effectively, all of this means that adding line numbers should not inhibit optimization.)
- if ((it.type != AbstractInsnNode.LINE && it.type != AbstractInsnNode.FRAME && it.type != AbstractInsnNode.LABEL &&
- it.opcode != Opcodes.NOP) || it.next?.type == AbstractInsnNode.LABEL
+ val type = it.nodeType
+ if ((type != AbstractInsnNode.LINE && type != AbstractInsnNode.FRAME && type != AbstractInsnNode.LABEL &&
+ it.opcode != Opcodes.NOP) || it.next?.nodeType == AbstractInsnNode.LABEL
) result++
it = it.next
}
diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/boxing/StackPeepholeOptimizationsTransformer.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/boxing/StackPeepholeOptimizationsTransformer.kt
index d3821c73eec..48154760ebc 100644
--- a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/boxing/StackPeepholeOptimizationsTransformer.kt
+++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/boxing/StackPeepholeOptimizationsTransformer.kt
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.codegen.optimization.boxing
import org.jetbrains.kotlin.codegen.optimization.common.FastAnalyzer
import org.jetbrains.kotlin.codegen.optimization.common.findPreviousOrNull
+import org.jetbrains.kotlin.codegen.optimization.common.nodeType
import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer
import org.jetbrains.org.objectweb.asm.Opcodes
import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode
@@ -40,8 +41,8 @@ class StackPeepholeOptimizationsTransformer : MethodTransformer() {
fun AbstractInsnNode.previousMeaningful() =
findPreviousOrNull {
- it.opcode != Opcodes.NOP && it.type != AbstractInsnNode.LINE &&
- (it.type != AbstractInsnNode.LABEL || isMergeNode[instructions.indexOf(it)])
+ it.opcode != Opcodes.NOP && it.nodeType != AbstractInsnNode.LINE &&
+ (it.nodeType != AbstractInsnNode.LABEL || isMergeNode[instructions.indexOf(it)])
}
var insn: AbstractInsnNode?
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 3a89a1ef9ce..0c7e2a0c774 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
@@ -60,7 +60,7 @@ class ControlFlowGraph private constructor(private val insns: InsnList) {
val insnNode = method.instructions[insn]
val insnOpcode = insnNode.opcode
- when (insnNode.type) {
+ when (insnNode.nodeType) {
AbstractInsnNode.LABEL, AbstractInsnNode.LINE, AbstractInsnNode.FRAME ->
visitOpInsn(insn)
AbstractInsnNode.JUMP_INSN ->
diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/common/FastAnalyzer.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/common/FastAnalyzer.kt
index a1e763ab56d..bb6a233654f 100644
--- a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/common/FastAnalyzer.kt
+++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/common/FastAnalyzer.kt
@@ -96,7 +96,7 @@ abstract class FastAnalyzer>(
handler: F
) {
val insnOpcode = insnNode.opcode
- val insnType = insnNode.type
+ val insnType = insnNode.nodeType
if (insnType == AbstractInsnNode.LABEL ||
insnType == AbstractInsnNode.LINE ||
@@ -349,7 +349,7 @@ abstract class FastAnalyzer>(
fun findMergeNodes(method: MethodNode): BooleanArray {
val isMergeNode = BooleanArray(method.instructions.size())
for (insn in method.instructions) {
- when (insn.type) {
+ when (insn.nodeType) {
AbstractInsnNode.JUMP_INSN -> {
val jumpInsn = insn as JumpInsnNode
isMergeNode[method.instructions.indexOf(jumpInsn.label)] = true
diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/common/InstructionLivenessAnalyzer.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/common/InstructionLivenessAnalyzer.kt
index dfc2ea3ce1d..bef0b3e97f9 100644
--- a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/common/InstructionLivenessAnalyzer.kt
+++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/common/InstructionLivenessAnalyzer.kt
@@ -79,7 +79,7 @@ class InstructionLivenessAnalyzer(
val insnNode = method.instructions[insn]
val insnOpcode = insnNode.opcode
- when (insnNode.type) {
+ when (insnNode.nodeType) {
AbstractInsnNode.LABEL, AbstractInsnNode.LINE, AbstractInsnNode.FRAME ->
visitOpInsn(insn)
AbstractInsnNode.JUMP_INSN ->
diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/common/Util.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/common/Util.kt
index 6eaff8eb88a..3c272cd2b08 100644
--- a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/common/Util.kt
+++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/common/Util.kt
@@ -27,14 +27,14 @@ import org.jetbrains.org.objectweb.asm.tree.*
val AbstractInsnNode.isMeaningful: Boolean
get() =
- when (this.type) {
+ when (this.nodeType) {
AbstractInsnNode.LABEL, AbstractInsnNode.LINE, AbstractInsnNode.FRAME -> false
else -> true
}
val AbstractInsnNode.isBranchOrCall: Boolean
get() =
- when (this.type) {
+ when (this.nodeType) {
AbstractInsnNode.JUMP_INSN,
AbstractInsnNode.TABLESWITCH_INSN,
AbstractInsnNode.LOOKUPSWITCH_INSN,
@@ -42,6 +42,40 @@ val AbstractInsnNode.isBranchOrCall: Boolean
else -> false
}
+private val opcodeToNodeType = IntArray(IFNONNULL + 1) {
+ when (it) {
+ in NOP..DCONST_1, in IALOAD..SALOAD, in IASTORE..LXOR, in I2L..DCMPG, in IRETURN..RETURN,
+ ARRAYLENGTH, ATHROW, MONITORENTER, MONITOREXIT -> AbstractInsnNode.INSN
+ in BIPUSH..SIPUSH, NEWARRAY -> AbstractInsnNode.INT_INSN
+ in ILOAD..ALOAD, in ISTORE..ASTORE, RET -> AbstractInsnNode.VAR_INSN
+ NEW, ANEWARRAY, CHECKCAST, INSTANCEOF -> AbstractInsnNode.TYPE_INSN
+ in GETSTATIC..PUTFIELD -> AbstractInsnNode.FIELD_INSN
+ in INVOKEVIRTUAL..INVOKEINTERFACE -> AbstractInsnNode.METHOD_INSN
+ INVOKEDYNAMIC -> AbstractInsnNode.INVOKE_DYNAMIC_INSN
+ in IFEQ..JSR, IFNULL, IFNONNULL -> AbstractInsnNode.JUMP_INSN
+ LDC -> AbstractInsnNode.LDC_INSN
+ IINC -> AbstractInsnNode.IINC_INSN
+ TABLESWITCH -> AbstractInsnNode.TABLESWITCH_INSN
+ LOOKUPSWITCH -> AbstractInsnNode.LOOKUPSWITCH_INSN
+ MULTIANEWARRAY -> AbstractInsnNode.MULTIANEWARRAY_INSN
+ else -> -1
+ }
+}
+
+// Faster version of `AbstractInsnNode.getType`
+val AbstractInsnNode.nodeType: Int
+ get() {
+ return when (val opcode = this.opcode) {
+ -1 -> when (this) {
+ is LabelNode -> AbstractInsnNode.LABEL
+ is FrameNode -> AbstractInsnNode.FRAME
+ is LineNumberNode -> AbstractInsnNode.LINE
+ else -> -1
+ }
+ else -> opcodeToNodeType.getOrElse(opcode) { -1 }
+ }
+ }
+
class InsnSequence(val from: AbstractInsnNode, val to: AbstractInsnNode?) : Sequence {
constructor(insnList: InsnList) : this(insnList.first, null)
@@ -77,7 +111,7 @@ fun MethodNode.prepareForEmitting() {
while (!current.isMeaningful) {
val prev = current.previous
- if (current.type == AbstractInsnNode.LINE) {
+ if (current.nodeType == AbstractInsnNode.LINE) {
instructions.remove(current)
}
diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/temporaryVals/TemporaryVals.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/temporaryVals/TemporaryVals.kt
index 33671c129fa..4157acc9093 100644
--- a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/temporaryVals/TemporaryVals.kt
+++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/temporaryVals/TemporaryVals.kt
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.codegen.optimization.temporaryVals
import org.jetbrains.kotlin.codegen.optimization.OptimizationMethodVisitor
import org.jetbrains.kotlin.codegen.optimization.common.isMeaningful
import org.jetbrains.kotlin.codegen.optimization.common.isStoreOperation
+import org.jetbrains.kotlin.codegen.optimization.common.nodeType
import org.jetbrains.kotlin.utils.SmartSet
import org.jetbrains.org.objectweb.asm.Opcodes
import org.jetbrains.org.objectweb.asm.Opcodes.API_VERSION
@@ -53,7 +54,7 @@ class TemporaryValsAnalyzer {
potentiallyTemporaryStores.remove(p)
break
} else if (
- p.type == AbstractInsnNode.LABEL ||
+ p.nodeType == AbstractInsnNode.LABEL ||
p.opcode in Opcodes.IRETURN..Opcodes.RETURN ||
p.opcode == Opcodes.GOTO ||
p.opcode == Opcodes.ATHROW
diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/temporaryVals/TemporaryVariablesEliminationTransformer.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/temporaryVals/TemporaryVariablesEliminationTransformer.kt
index f4fa3cdc9b8..aad2ecdaba7 100644
--- a/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/temporaryVals/TemporaryVariablesEliminationTransformer.kt
+++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/optimization/temporaryVals/TemporaryVariablesEliminationTransformer.kt
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.codegen.inline.isSuspendInlineMarker
import org.jetbrains.kotlin.codegen.optimization.common.InsnSequence
import org.jetbrains.kotlin.codegen.optimization.common.isMeaningful
import org.jetbrains.kotlin.codegen.optimization.common.removeUnusedLocalVariables
+import org.jetbrains.kotlin.codegen.optimization.common.nodeType
import org.jetbrains.kotlin.codegen.optimization.nullCheck.isCheckExpressionValueIsNotNull
import org.jetbrains.kotlin.codegen.optimization.nullCheck.isCheckNotNullWithMessage
import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer
@@ -168,7 +169,7 @@ class TemporaryVariablesEliminationTransformer(private val state: GenerationStat
}
for (insn in insnList) {
- when (insn.type) {
+ when (insn.nodeType) {
AbstractInsnNode.LINE -> {
usedLabels.add((insn as LineNumberNode).start)
}
@@ -570,7 +571,7 @@ class TemporaryVariablesEliminationTransformer(private val state: GenerationStat
}
private fun AbstractInsnNode.isIntervening(context: ControlFlowGraph): Boolean =
- when (this.type) {
+ when (this.nodeType) {
AbstractInsnNode.LINE, AbstractInsnNode.FRAME ->
false
AbstractInsnNode.LABEL ->