JVM_IR allow remapped variables in inplace arguments transformation

This commit is contained in:
Dmitry Petrov
2021-09-05 17:30:36 +03:00
committed by TeamCityServer
parent 09c8ca860a
commit e28d4a1877
8 changed files with 59 additions and 14 deletions
@@ -52,11 +52,15 @@ class InplaceArgumentsMethodTransformer : MethodTransformer() {
val argStartMarker: AbstractInsnNode, val argStartMarker: AbstractInsnNode,
val argEndMarker: AbstractInsnNode, val argEndMarker: AbstractInsnNode,
val calls: List<CallContext>, val calls: List<CallContext>,
val storeInsn: VarInsnNode val storeInsn: VarInsnNode?
) { ) {
val loadOpcode = storeInsn.opcode - Opcodes.ISTORE + Opcodes.ILOAD val loadOpcode =
if (storeInsn != null)
storeInsn.opcode - Opcodes.ISTORE + Opcodes.ILOAD
else
-1
val varIndex = storeInsn.`var` val varIndex = storeInsn?.`var` ?: -1
} }
private fun parseMethodOrNull(methodNode: MethodNode): MethodContext? { private fun parseMethodOrNull(methodNode: MethodNode): MethodContext? {
@@ -114,11 +118,19 @@ class InplaceArgumentsMethodTransformer : MethodTransformer() {
calls.add(parseCall(methodNode, insn, iter)) calls.add(parseCall(methodNode, insn, iter))
insn.isInplaceArgumentEndMarker() -> { insn.isInplaceArgumentEndMarker() -> {
val next = insn.next val next = insn.next
if (next is VarInsnNode && next.opcode in Opcodes.ISTORE..Opcodes.ASTORE) { return when {
iter.next() next is VarInsnNode && next.opcode in Opcodes.ISTORE..Opcodes.ASTORE -> {
return ArgContext(start, insn, calls, next) iter.next()
} else { ArgContext(start, insn, calls, next)
throw ParseErrorException() }
insn.previous.isInplaceArgumentStartMarker() -> {
// Empty argument - a remapped variable.
// For such argument varIndex would be '-1', so it would not be associated with any LOAD instruction.
ArgContext(start, insn, calls, null)
}
else -> {
throw ParseErrorException()
}
} }
} }
insn.isInplaceCallEndMarker() || insn.isInplaceArgumentStartMarker() -> insn.isInplaceCallEndMarker() || insn.isInplaceArgumentStartMarker() ->
@@ -3428,6 +3428,12 @@ public class FirBytecodeTextTestGenerated extends AbstractFirBytecodeTextTest {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/bytecodeText/inlineArgsInPlace"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/bytecodeText/inlineArgsInPlace"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
} }
@Test
@TestMetadata("kotlinMathMax.kt")
public void testKotlinMathMax() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/inlineArgsInPlace/kotlinMathMax.kt");
}
@Test @Test
@TestMetadata("println.kt") @TestMetadata("println.kt")
public void testPrintln() throws Exception { public void testPrintln() throws Exception {
@@ -32,8 +32,8 @@ fun box(): String {
// 0 INEG // 0 INEG
// 0 INVOKESTATIC kotlin/UInt.constructor-impl // 0 INVOKESTATIC kotlin/UInt.constructor-impl
// 0 INVOKE\w+ kotlin/UInt.(un)?box-impl // 0 INVOKE\w+ kotlin/UInt.(un)?box-impl
// 21 ILOAD // 15 ILOAD
// 13 ISTORE // 7 ISTORE
// 1 IADD // 1 IADD
// 0 ISUB // 0 ISUB
// 0 IINC // 0 IINC
@@ -42,8 +42,8 @@ fun box(): String {
// 1 INEG // 1 INEG
// 0 INVOKESTATIC kotlin/UInt.constructor-impl // 0 INVOKESTATIC kotlin/UInt.constructor-impl
// 0 INVOKE\w+ kotlin/UInt.(un)?box-impl // 0 INVOKE\w+ kotlin/UInt.(un)?box-impl
// 25 ILOAD // 19 ILOAD
// 15 ISTORE // 9 ISTORE
// 1 IADD // 1 IADD
// 0 ISUB // 0 ISUB
// 0 IINC // 0 IINC
@@ -40,8 +40,8 @@ fun box(): String {
// 0 INEG // 0 INEG
// 0 INVOKESTATIC kotlin/UInt.constructor-impl // 0 INVOKESTATIC kotlin/UInt.constructor-impl
// 0 INVOKE\w+ kotlin/UInt.(un)?box-impl // 0 INVOKE\w+ kotlin/UInt.(un)?box-impl
// 12 ILOAD // 8 ILOAD
// 9 ISTORE // 5 ISTORE
// 0 IADD // 0 IADD
// 0 ISUB // 0 ISUB
// 1 IINC // 1 IINC
@@ -0,0 +1,15 @@
// WITH_RUNTIME
fun vectorReductionMax(vA: DoubleArray): Double {
val n = vA.size
var x = Double.NEGATIVE_INFINITY
for (i in 0 until n) {
x = kotlin.math.max(x, vA[i])
}
return x
}
// JVM_IR_TEMPLATES
// Make sure there's no intermediate variable created for 'vA[i]' argument of kotlin.math.max.
// 2 DLOAD
// 2 DSTORE
@@ -3284,6 +3284,12 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/bytecodeText/inlineArgsInPlace"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true); KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/bytecodeText/inlineArgsInPlace"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
} }
@Test
@TestMetadata("kotlinMathMax.kt")
public void testKotlinMathMax() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/inlineArgsInPlace/kotlinMathMax.kt");
}
@Test @Test
@TestMetadata("println.kt") @TestMetadata("println.kt")
public void testPrintln() throws Exception { public void testPrintln() throws Exception {
@@ -3428,6 +3428,12 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/bytecodeText/inlineArgsInPlace"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/bytecodeText/inlineArgsInPlace"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
} }
@Test
@TestMetadata("kotlinMathMax.kt")
public void testKotlinMathMax() throws Exception {
runTest("compiler/testData/codegen/bytecodeText/inlineArgsInPlace/kotlinMathMax.kt");
}
@Test @Test
@TestMetadata("println.kt") @TestMetadata("println.kt")
public void testPrintln() throws Exception { public void testPrintln() throws Exception {