JVM_IR don't move inplace arguments with variable stores
KT-49370 KT-49407
This commit is contained in:
committed by
teamcityserver
parent
45a4cea655
commit
c441980c74
+7
-8
@@ -6,10 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.codegen.inline
|
package org.jetbrains.kotlin.codegen.inline
|
||||||
|
|
||||||
import org.jetbrains.kotlin.codegen.optimization.boxing.isMethodInsnWith
|
import org.jetbrains.kotlin.codegen.optimization.boxing.isMethodInsnWith
|
||||||
import org.jetbrains.kotlin.codegen.optimization.common.InsnSequence
|
import org.jetbrains.kotlin.codegen.optimization.common.*
|
||||||
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.transformer.MethodTransformer
|
import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer
|
||||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||||
import org.jetbrains.org.objectweb.asm.tree.*
|
import org.jetbrains.org.objectweb.asm.tree.*
|
||||||
@@ -239,9 +236,6 @@ class InplaceArgumentsMethodTransformer : MethodTransformer() {
|
|||||||
transformCall(methodContext, call)
|
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) }) {
|
if (callContext.args.any { it.isUnsafeToMove(methodContext) }) {
|
||||||
// Do not transform such call, just strip call and argument markers.
|
// Do not transform such call, just strip call and argument markers.
|
||||||
val insnList = methodContext.methodNode.instructions
|
val insnList = methodContext.methodNode.instructions
|
||||||
@@ -258,10 +252,15 @@ class InplaceArgumentsMethodTransformer : MethodTransformer() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun ArgContext.isUnsafeToMove(methodContext: MethodContext): Boolean {
|
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 argInsns = InsnSequence(this.argStartMarker, this.argEndMarker)
|
||||||
val localLabels = argInsns.filterTo(HashSet()) { it is LabelNode }
|
val localLabels = argInsns.filterTo(HashSet()) { it is LabelNode }
|
||||||
return argInsns.any { insn ->
|
return argInsns.any { insn ->
|
||||||
insn in methodContext.suspensionJumpLabels ||
|
insn.isStoreOperation() ||
|
||||||
|
insn in methodContext.suspensionJumpLabels ||
|
||||||
insn.opcode == Opcodes.GOTO && (insn as JumpInsnNode).label !in localLabels
|
insn.opcode == Opcodes.GOTO && (insn as JumpInsnNode).label !in localLabels
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+12
@@ -18644,6 +18644,18 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
|||||||
runTest("compiler/testData/codegen/box/inlineArgsInPlace/kotlinReflect.kt");
|
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
|
@Test
|
||||||
@TestMetadata("mapSet.kt")
|
@TestMetadata("mapSet.kt")
|
||||||
public void testMapSet() throws Exception {
|
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"
|
||||||
|
}
|
||||||
+12
@@ -18518,6 +18518,18 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
runTest("compiler/testData/codegen/box/inlineArgsInPlace/kotlinReflect.kt");
|
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
|
@Test
|
||||||
@TestMetadata("mapSet.kt")
|
@TestMetadata("mapSet.kt")
|
||||||
public void testMapSet() throws Exception {
|
public void testMapSet() throws Exception {
|
||||||
|
|||||||
+12
@@ -18644,6 +18644,18 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
runTest("compiler/testData/codegen/box/inlineArgsInPlace/kotlinReflect.kt");
|
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
|
@Test
|
||||||
@TestMetadata("mapSet.kt")
|
@TestMetadata("mapSet.kt")
|
||||||
public void testMapSet() throws Exception {
|
public void testMapSet() throws Exception {
|
||||||
|
|||||||
+10
@@ -15360,6 +15360,16 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
runTest("compiler/testData/codegen/box/inlineArgsInPlace/kotlinReflect.kt");
|
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")
|
@TestMetadata("mapSet.kt")
|
||||||
public void testMapSet() throws Exception {
|
public void testMapSet() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/inlineArgsInPlace/mapSet.kt");
|
runTest("compiler/testData/codegen/box/inlineArgsInPlace/mapSet.kt");
|
||||||
|
|||||||
js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java
Generated
+10
@@ -13414,6 +13414,16 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes
|
|||||||
runTest("compiler/testData/codegen/box/inlineArgsInPlace/kotlinReflect.kt");
|
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")
|
@TestMetadata("mapSet.kt")
|
||||||
public void testMapSet() throws Exception {
|
public void testMapSet() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/inlineArgsInPlace/mapSet.kt");
|
runTest("compiler/testData/codegen/box/inlineArgsInPlace/mapSet.kt");
|
||||||
|
|||||||
Generated
+10
@@ -12820,6 +12820,16 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
|||||||
runTest("compiler/testData/codegen/box/inlineArgsInPlace/kotlinReflect.kt");
|
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")
|
@TestMetadata("mapSet.kt")
|
||||||
public void testMapSet() throws Exception {
|
public void testMapSet() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/inlineArgsInPlace/mapSet.kt");
|
runTest("compiler/testData/codegen/box/inlineArgsInPlace/mapSet.kt");
|
||||||
|
|||||||
js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java
Generated
+10
@@ -12146,6 +12146,16 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest
|
|||||||
runTest("compiler/testData/codegen/box/inlineArgsInPlace/kotlinReflect.kt");
|
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")
|
@TestMetadata("mapSet.kt")
|
||||||
public void testMapSet() throws Exception {
|
public void testMapSet() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/inlineArgsInPlace/mapSet.kt");
|
runTest("compiler/testData/codegen/box/inlineArgsInPlace/mapSet.kt");
|
||||||
|
|||||||
+12
@@ -14530,6 +14530,18 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
|||||||
runTest("compiler/testData/codegen/box/inlineArgsInPlace/kotlinReflect.kt");
|
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
|
@Test
|
||||||
@TestMetadata("mapSet.kt")
|
@TestMetadata("mapSet.kt")
|
||||||
public void testMapSet() throws Exception {
|
public void testMapSet() throws Exception {
|
||||||
|
|||||||
Reference in New Issue
Block a user