JVM don't siplify CFG in TemporaryVariablesEliminationTransformer
This commit is contained in:
committed by
TeamCityServer
parent
7e943ab757
commit
fbcb07e3a2
+1
-4
@@ -10,10 +10,7 @@ import org.jetbrains.kotlin.codegen.optimization.common.isStoreOperation
|
|||||||
import org.jetbrains.kotlin.utils.SmartSet
|
import org.jetbrains.kotlin.utils.SmartSet
|
||||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||||
import org.jetbrains.org.objectweb.asm.Type
|
import org.jetbrains.org.objectweb.asm.Type
|
||||||
import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode
|
import org.jetbrains.org.objectweb.asm.tree.*
|
||||||
import org.jetbrains.org.objectweb.asm.tree.IincInsnNode
|
|
||||||
import org.jetbrains.org.objectweb.asm.tree.MethodNode
|
|
||||||
import org.jetbrains.org.objectweb.asm.tree.VarInsnNode
|
|
||||||
|
|
||||||
|
|
||||||
// A temporary val is a local variables that is:
|
// A temporary val is a local variables that is:
|
||||||
|
|||||||
-57
@@ -5,7 +5,6 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.codegen.optimization.temporaryVals
|
package org.jetbrains.kotlin.codegen.optimization.temporaryVals
|
||||||
|
|
||||||
import org.jetbrains.kotlin.codegen.optimization.DeadCodeEliminationMethodTransformer
|
|
||||||
import org.jetbrains.kotlin.codegen.optimization.common.InsnSequence
|
import org.jetbrains.kotlin.codegen.optimization.common.InsnSequence
|
||||||
import org.jetbrains.kotlin.codegen.optimization.common.removeUnusedLocalVariables
|
import org.jetbrains.kotlin.codegen.optimization.common.removeUnusedLocalVariables
|
||||||
import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer
|
import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer
|
||||||
@@ -17,11 +16,8 @@ import kotlin.math.max
|
|||||||
|
|
||||||
class TemporaryVariablesEliminationTransformer : MethodTransformer() {
|
class TemporaryVariablesEliminationTransformer : MethodTransformer() {
|
||||||
private val temporaryValsAnalyzer = TemporaryValsAnalyzer()
|
private val temporaryValsAnalyzer = TemporaryValsAnalyzer()
|
||||||
private val deadCodeElimination = DeadCodeEliminationMethodTransformer()
|
|
||||||
|
|
||||||
override fun transform(internalClassName: String, methodNode: MethodNode) {
|
override fun transform(internalClassName: String, methodNode: MethodNode) {
|
||||||
simplifyControlFlow(methodNode)
|
|
||||||
|
|
||||||
val cfg = ControlFlowGraph(methodNode)
|
val cfg = ControlFlowGraph(methodNode)
|
||||||
processLabels(cfg)
|
processLabels(cfg)
|
||||||
|
|
||||||
@@ -209,36 +205,6 @@ class TemporaryVariablesEliminationTransformer : MethodTransformer() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun simplifyControlFlow(methodNode: MethodNode) {
|
|
||||||
val insnList = methodNode.instructions
|
|
||||||
var needsDCE = false
|
|
||||||
|
|
||||||
for (insn in insnList.toArray()) {
|
|
||||||
if (insn.opcode == Opcodes.NOP) {
|
|
||||||
// Remove NOPs not preceded by LABEL or LINENUMBER instructions.
|
|
||||||
val prev = insn.previous ?: continue
|
|
||||||
if (prev.type == AbstractInsnNode.LABEL || prev.type == AbstractInsnNode.LINE) continue
|
|
||||||
|
|
||||||
insnList.remove(insn)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if (insn.opcode == Opcodes.GOTO) {
|
|
||||||
// If we have a GOTO instruction that leads to another GOTO, replace corresponding label.
|
|
||||||
val jumpInsn = insn as JumpInsnNode
|
|
||||||
val newLabel = jumpInsn.getFinalLabel()
|
|
||||||
if (newLabel != jumpInsn.label) {
|
|
||||||
needsDCE = true
|
|
||||||
}
|
|
||||||
jumpInsn.label = newLabel
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (needsDCE) {
|
|
||||||
deadCodeElimination.transform("<fake>", methodNode)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Suppress("DuplicatedCode")
|
@Suppress("DuplicatedCode")
|
||||||
private fun simplifyKnownSafeCallPatterns(cfg: ControlFlowGraph) {
|
private fun simplifyKnownSafeCallPatterns(cfg: ControlFlowGraph) {
|
||||||
val insnList = cfg.methodNode.instructions
|
val insnList = cfg.methodNode.instructions
|
||||||
@@ -361,29 +327,6 @@ class TemporaryVariablesEliminationTransformer : MethodTransformer() {
|
|||||||
cfg.methodNode.maxStack += maxStackIncrement
|
cfg.methodNode.maxStack += maxStackIncrement
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun JumpInsnNode.getFinalLabel(): LabelNode {
|
|
||||||
var label = this.label
|
|
||||||
var insn = label.next
|
|
||||||
while (true) {
|
|
||||||
when {
|
|
||||||
insn.type == AbstractInsnNode.LABEL || insn.type == AbstractInsnNode.LINE -> {
|
|
||||||
insn = insn.next ?: break
|
|
||||||
}
|
|
||||||
insn.opcode == Opcodes.GOTO -> {
|
|
||||||
val newLabel = (insn as JumpInsnNode).label
|
|
||||||
if (newLabel == label) return newLabel
|
|
||||||
label = newLabel
|
|
||||||
insn = label.next ?: break
|
|
||||||
}
|
|
||||||
insn.opcode == Opcodes.NOP -> {
|
|
||||||
insn = insn.next ?: break
|
|
||||||
}
|
|
||||||
else -> break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return label
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun AbstractInsnNode.matchOpcodes(vararg opcodes: Int): Boolean {
|
private fun AbstractInsnNode.matchOpcodes(vararg opcodes: Int): Boolean {
|
||||||
var insn = this
|
var insn = this
|
||||||
for (i in opcodes.indices) {
|
for (i in opcodes.indices) {
|
||||||
|
|||||||
Reference in New Issue
Block a user