JVM_IR KT-50193 remove temporary variable in argument null check
This commit is contained in:
committed by
TeamCityServer
parent
34c70ea04e
commit
42dd8aa12d
+37
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.codegen.optimization.temporaryVals
|
|||||||
import org.jetbrains.kotlin.codegen.optimization.common.InsnSequence
|
import org.jetbrains.kotlin.codegen.optimization.common.InsnSequence
|
||||||
import org.jetbrains.kotlin.codegen.optimization.common.isMeaningful
|
import org.jetbrains.kotlin.codegen.optimization.common.isMeaningful
|
||||||
import org.jetbrains.kotlin.codegen.optimization.common.removeUnusedLocalVariables
|
import org.jetbrains.kotlin.codegen.optimization.common.removeUnusedLocalVariables
|
||||||
|
import org.jetbrains.kotlin.codegen.optimization.nullCheck.isCheckExpressionValueIsNotNull
|
||||||
import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer
|
import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||||
import org.jetbrains.kotlin.utils.SmartList
|
import org.jetbrains.kotlin.utils.SmartList
|
||||||
@@ -206,6 +207,8 @@ class TemporaryVariablesEliminationTransformer(private val state: GenerationStat
|
|||||||
private fun optimizeTemporaryVals(cfg: ControlFlowGraph, temporaryVals: List<TemporaryVal>) {
|
private fun optimizeTemporaryVals(cfg: ControlFlowGraph, temporaryVals: List<TemporaryVal>) {
|
||||||
val insnList = cfg.methodNode.instructions
|
val insnList = cfg.methodNode.instructions
|
||||||
|
|
||||||
|
var maxStackIncrement = 0
|
||||||
|
|
||||||
for (tmp in temporaryVals) {
|
for (tmp in temporaryVals) {
|
||||||
if (tmp.loadInsns.isEmpty()) {
|
if (tmp.loadInsns.isEmpty()) {
|
||||||
// Drop unused temporary store
|
// Drop unused temporary store
|
||||||
@@ -270,8 +273,42 @@ class TemporaryVariablesEliminationTransformer(private val state: GenerationStat
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (tmp.loadInsns.size == 2) {
|
||||||
|
val storeInsn = tmp.storeInsn
|
||||||
|
|
||||||
|
if (storeInsn.matchOpcodes(Opcodes.ASTORE, Opcodes.ALOAD, Opcodes.LDC, Opcodes.INVOKESTATIC, Opcodes.ALOAD)) {
|
||||||
|
val aLoad1Insn = storeInsn.next
|
||||||
|
val ldcInsn = aLoad1Insn.next
|
||||||
|
val invokeStaticInsn = ldcInsn.next
|
||||||
|
val aLoad2Insn = invokeStaticInsn.next
|
||||||
|
|
||||||
|
if ((aLoad1Insn as VarInsnNode).`var` == tmp.index &&
|
||||||
|
(ldcInsn as LdcInsnNode).cst is String &&
|
||||||
|
invokeStaticInsn.isCheckExpressionValueIsNotNull() &&
|
||||||
|
(aLoad2Insn as VarInsnNode).`var` == tmp.index
|
||||||
|
) {
|
||||||
|
// Replace instruction sequence:
|
||||||
|
// ASTORE tmp
|
||||||
|
// ALOAD tmp
|
||||||
|
// LDC "expression"
|
||||||
|
// INVOKESTATIC <check-not-null-expression> (Ljava/lang/Object;Ljava/lang/String;)V
|
||||||
|
// ALOAD tmp
|
||||||
|
// with
|
||||||
|
// DUP
|
||||||
|
// LDC "expression
|
||||||
|
// INVOKESTATIC <check-not-null-expression> (Ljava/lang/Object;Ljava/lang/String;)V
|
||||||
|
insnList.remove(storeInsn)
|
||||||
|
insnList.remove(aLoad1Insn)
|
||||||
|
insnList.insertBefore(ldcInsn, InsnNode(Opcodes.DUP))
|
||||||
|
insnList.remove(aLoad2Insn)
|
||||||
|
maxStackIncrement = max(maxStackIncrement, 1)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cfg.methodNode.maxStack += maxStackIncrement
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("DuplicatedCode")
|
@Suppress("DuplicatedCode")
|
||||||
|
|||||||
+6
@@ -4663,6 +4663,12 @@ public class FirBytecodeTextTestGenerated extends AbstractFirBytecodeTextTest {
|
|||||||
public void testNoAssertionsForKotlin() throws Exception {
|
public void testNoAssertionsForKotlin() throws Exception {
|
||||||
runTest("compiler/testData/codegen/bytecodeText/notNullAssertions/noAssertionsForKotlin.kt");
|
runTest("compiler/testData/codegen/bytecodeText/notNullAssertions/noAssertionsForKotlin.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("noTemporaryVariableInNullCheckOnExpression.kt")
|
||||||
|
public void testNoTemporaryVariableInNullCheckOnExpression() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/bytecodeText/notNullAssertions/noTemporaryVariableInNullCheckOnExpression.kt");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
|
|||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
// FULL_JDK
|
||||||
|
|
||||||
|
fun use(a: Any) {}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
use(System.getProperty("abc"))
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1 ALOAD
|
||||||
|
// 0 ASTORE
|
||||||
+6
@@ -4519,6 +4519,12 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest {
|
|||||||
public void testNoAssertionsForKotlin() throws Exception {
|
public void testNoAssertionsForKotlin() throws Exception {
|
||||||
runTest("compiler/testData/codegen/bytecodeText/notNullAssertions/noAssertionsForKotlin.kt");
|
runTest("compiler/testData/codegen/bytecodeText/notNullAssertions/noAssertionsForKotlin.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("noTemporaryVariableInNullCheckOnExpression.kt")
|
||||||
|
public void testNoTemporaryVariableInNullCheckOnExpression() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/bytecodeText/notNullAssertions/noTemporaryVariableInNullCheckOnExpression.kt");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
|
|||||||
+6
@@ -4663,6 +4663,12 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest {
|
|||||||
public void testNoAssertionsForKotlin() throws Exception {
|
public void testNoAssertionsForKotlin() throws Exception {
|
||||||
runTest("compiler/testData/codegen/bytecodeText/notNullAssertions/noAssertionsForKotlin.kt");
|
runTest("compiler/testData/codegen/bytecodeText/notNullAssertions/noAssertionsForKotlin.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("noTemporaryVariableInNullCheckOnExpression.kt")
|
||||||
|
public void testNoTemporaryVariableInNullCheckOnExpression() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/bytecodeText/notNullAssertions/noTemporaryVariableInNullCheckOnExpression.kt");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
|
|||||||
Reference in New Issue
Block a user