JVM_IR don't move inplace arguments with variable stores

KT-49370
KT-49407
This commit is contained in:
Dmitry Petrov
2021-10-25 15:55:57 +03:00
committed by teamcityserver
parent 45a4cea655
commit c441980c74
11 changed files with 109 additions and 8 deletions
@@ -6,10 +6,7 @@
package org.jetbrains.kotlin.codegen.inline
import org.jetbrains.kotlin.codegen.optimization.boxing.isMethodInsnWith
import org.jetbrains.kotlin.codegen.optimization.common.InsnSequence
import org.jetbrains.kotlin.codegen.optimization.common.findNextOrNull
import org.jetbrains.kotlin.codegen.optimization.common.removeUnusedLocalVariables
import org.jetbrains.kotlin.codegen.optimization.common.updateMaxStack
import org.jetbrains.kotlin.codegen.optimization.common.*
import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer
import org.jetbrains.org.objectweb.asm.Opcodes
import org.jetbrains.org.objectweb.asm.tree.*
@@ -239,9 +236,6 @@ class InplaceArgumentsMethodTransformer : MethodTransformer() {
transformCall(methodContext, call)
}
// If an inplace argument contains a non-local jump,
// moving such argument inside inline function body can interfere with stack normalization.
// TODO investigate complex cases
if (callContext.args.any { it.isUnsafeToMove(methodContext) }) {
// Do not transform such call, just strip call and argument markers.
val insnList = methodContext.methodNode.instructions
@@ -258,10 +252,15 @@ class InplaceArgumentsMethodTransformer : MethodTransformer() {
}
private fun ArgContext.isUnsafeToMove(methodContext: MethodContext): Boolean {
// The following operations make inplace argument unsafe to move:
// - non-local jump (moving such argument inside inline function body can interfere with stack normalization);
// - variable store (variables defined inside argument can interfere with variables in inline function body).
// TODO investigate whether it's possible to lift these restrictions.
val argInsns = InsnSequence(this.argStartMarker, this.argEndMarker)
val localLabels = argInsns.filterTo(HashSet()) { it is LabelNode }
return argInsns.any { insn ->
insn in methodContext.suspensionJumpLabels ||
insn.isStoreOperation() ||
insn in methodContext.suspensionJumpLabels ||
insn.opcode == Opcodes.GOTO && (insn as JumpInsnNode).label !in localLabels
}
}
@@ -18644,6 +18644,18 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/inlineArgsInPlace/kotlinReflect.kt");
}
@Test
@TestMetadata("kt49370.kt")
public void testKt49370() throws Exception {
runTest("compiler/testData/codegen/box/inlineArgsInPlace/kt49370.kt");
}
@Test
@TestMetadata("kt49407.kt")
public void testKt49407() throws Exception {
runTest("compiler/testData/codegen/box/inlineArgsInPlace/kt49407.kt");
}
@Test
@TestMetadata("mapSet.kt")
public void testMapSet() throws Exception {
@@ -0,0 +1,8 @@
// !OPT_IN: kotlin.ExperimentalStdlibApi
// WITH_RUNTIME
// IGNORE_BACKEND: WASM
fun box(): String {
1L.mod("123a".indexOfAny("a".toCharArray()))
return "OK"
}
@@ -0,0 +1,6 @@
// WITH_RUNTIME
fun box(): String {
val x: Array<Array<*>> = arrayOf(arrayOf(0.plus(-1L).mod(5.mod(-47)).rem(1)))
return "OK"
}
@@ -18518,6 +18518,18 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTest("compiler/testData/codegen/box/inlineArgsInPlace/kotlinReflect.kt");
}
@Test
@TestMetadata("kt49370.kt")
public void testKt49370() throws Exception {
runTest("compiler/testData/codegen/box/inlineArgsInPlace/kt49370.kt");
}
@Test
@TestMetadata("kt49407.kt")
public void testKt49407() throws Exception {
runTest("compiler/testData/codegen/box/inlineArgsInPlace/kt49407.kt");
}
@Test
@TestMetadata("mapSet.kt")
public void testMapSet() throws Exception {
@@ -18644,6 +18644,18 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/inlineArgsInPlace/kotlinReflect.kt");
}
@Test
@TestMetadata("kt49370.kt")
public void testKt49370() throws Exception {
runTest("compiler/testData/codegen/box/inlineArgsInPlace/kt49370.kt");
}
@Test
@TestMetadata("kt49407.kt")
public void testKt49407() throws Exception {
runTest("compiler/testData/codegen/box/inlineArgsInPlace/kt49407.kt");
}
@Test
@TestMetadata("mapSet.kt")
public void testMapSet() throws Exception {
@@ -15360,6 +15360,16 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTest("compiler/testData/codegen/box/inlineArgsInPlace/kotlinReflect.kt");
}
@TestMetadata("kt49370.kt")
public void testKt49370() throws Exception {
runTest("compiler/testData/codegen/box/inlineArgsInPlace/kt49370.kt");
}
@TestMetadata("kt49407.kt")
public void testKt49407() throws Exception {
runTest("compiler/testData/codegen/box/inlineArgsInPlace/kt49407.kt");
}
@TestMetadata("mapSet.kt")
public void testMapSet() throws Exception {
runTest("compiler/testData/codegen/box/inlineArgsInPlace/mapSet.kt");
@@ -13414,6 +13414,16 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes
runTest("compiler/testData/codegen/box/inlineArgsInPlace/kotlinReflect.kt");
}
@TestMetadata("kt49370.kt")
public void testKt49370() throws Exception {
runTest("compiler/testData/codegen/box/inlineArgsInPlace/kt49370.kt");
}
@TestMetadata("kt49407.kt")
public void testKt49407() throws Exception {
runTest("compiler/testData/codegen/box/inlineArgsInPlace/kt49407.kt");
}
@TestMetadata("mapSet.kt")
public void testMapSet() throws Exception {
runTest("compiler/testData/codegen/box/inlineArgsInPlace/mapSet.kt");
@@ -12820,6 +12820,16 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/inlineArgsInPlace/kotlinReflect.kt");
}
@TestMetadata("kt49370.kt")
public void testKt49370() throws Exception {
runTest("compiler/testData/codegen/box/inlineArgsInPlace/kt49370.kt");
}
@TestMetadata("kt49407.kt")
public void testKt49407() throws Exception {
runTest("compiler/testData/codegen/box/inlineArgsInPlace/kt49407.kt");
}
@TestMetadata("mapSet.kt")
public void testMapSet() throws Exception {
runTest("compiler/testData/codegen/box/inlineArgsInPlace/mapSet.kt");
@@ -12146,6 +12146,16 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest
runTest("compiler/testData/codegen/box/inlineArgsInPlace/kotlinReflect.kt");
}
@TestMetadata("kt49370.kt")
public void testKt49370() throws Exception {
runTest("compiler/testData/codegen/box/inlineArgsInPlace/kt49370.kt");
}
@TestMetadata("kt49407.kt")
public void testKt49407() throws Exception {
runTest("compiler/testData/codegen/box/inlineArgsInPlace/kt49407.kt");
}
@TestMetadata("mapSet.kt")
public void testMapSet() throws Exception {
runTest("compiler/testData/codegen/box/inlineArgsInPlace/mapSet.kt");
@@ -14530,6 +14530,18 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/inlineArgsInPlace/kotlinReflect.kt");
}
@Test
@TestMetadata("kt49370.kt")
public void testKt49370() throws Exception {
runTest("compiler/testData/codegen/box/inlineArgsInPlace/kt49370.kt");
}
@Test
@TestMetadata("kt49407.kt")
public void testKt49407() throws Exception {
runTest("compiler/testData/codegen/box/inlineArgsInPlace/kt49407.kt");
}
@Test
@TestMetadata("mapSet.kt")
public void testMapSet() throws Exception {