JVM_IR simplify null check on trivially initialized vals only
This commit is contained in:
committed by
TeamCityServer
parent
ae1288948a
commit
aea2db97c5
+6
@@ -39842,6 +39842,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
|||||||
runTest("compiler/testData/codegen/box/safeCall/safeCallEqPrimitive.kt");
|
runTest("compiler/testData/codegen/box/safeCall/safeCallEqPrimitive.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("safeCallIOnUninitializedNonNullValue.kt")
|
||||||
|
public void testSafeCallIOnUninitializedNonNullValue() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/safeCall/safeCallIOnUninitializedNonNullValue.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("safeCallNotEqPrimitive.kt")
|
@TestMetadata("safeCallNotEqPrimitive.kt")
|
||||||
public void testSafeCallNotEqPrimitive() throws Exception {
|
public void testSafeCallNotEqPrimitive() throws Exception {
|
||||||
|
|||||||
+3
-1
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.ir.expressions.impl.*
|
|||||||
import org.jetbrains.kotlin.ir.types.*
|
import org.jetbrains.kotlin.ir.types.*
|
||||||
import org.jetbrains.kotlin.ir.util.dump
|
import org.jetbrains.kotlin.ir.util.dump
|
||||||
import org.jetbrains.kotlin.ir.util.hasAnnotation
|
import org.jetbrains.kotlin.ir.util.hasAnnotation
|
||||||
|
import org.jetbrains.kotlin.ir.util.isTrivial
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
|
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
|
||||||
@@ -83,6 +84,7 @@ class JvmSafeCallChainFoldingLowering(val context: JvmBackendContext) : FileLowe
|
|||||||
// c
|
// c
|
||||||
// }
|
// }
|
||||||
// which can be further simplified depending on the nullability of subexpressions in 'a?.foo() ?: b?.bar()?.qux() ?: c'.
|
// which can be further simplified depending on the nullability of subexpressions in 'a?.foo() ?: b?.bar()?.qux() ?: c'.
|
||||||
|
// We should perform such simplification carefully, since a value of a non-null type can be uninitialized at runtime.
|
||||||
// In bytecode this produces a chain of temporary STORE-LOAD and IFNULL checks that can be optimized to a compact sequence
|
// In bytecode this produces a chain of temporary STORE-LOAD and IFNULL checks that can be optimized to a compact sequence
|
||||||
// of stack operations and IFNULL checks.
|
// of stack operations and IFNULL checks.
|
||||||
|
|
||||||
@@ -119,7 +121,7 @@ class JvmSafeCallChainFoldingLowering(val context: JvmBackendContext) : FileLowe
|
|||||||
IrConstImpl.boolean(startOffset, endOffset, context.irBuiltIns.booleanType, false)
|
IrConstImpl.boolean(startOffset, endOffset, context.irBuiltIns.booleanType, false)
|
||||||
|
|
||||||
private fun irValNotNull(startOffset: Int, endOffset: Int, irVariable: IrVariable): IrExpression =
|
private fun irValNotNull(startOffset: Int, endOffset: Int, irVariable: IrVariable): IrExpression =
|
||||||
if (irVariable.type.isJvmNullable())
|
if (irVariable.type.isJvmNullable() || irVariable.initializer?.isTrivial() != true)
|
||||||
IrGetValueImpl(startOffset, endOffset, irVariable.symbol).irEqEqNull().irNot()
|
IrGetValueImpl(startOffset, endOffset, irVariable.symbol).irEqEqNull().irNot()
|
||||||
else
|
else
|
||||||
irTrue(startOffset, endOffset)
|
irTrue(startOffset, endOffset)
|
||||||
|
|||||||
+18
@@ -0,0 +1,18 @@
|
|||||||
|
abstract class Base() {
|
||||||
|
init {
|
||||||
|
foo()
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract fun foo()
|
||||||
|
}
|
||||||
|
|
||||||
|
class Derived(val x: String) : Base() {
|
||||||
|
override fun foo() {
|
||||||
|
x?.length
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
Derived("")
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+1
-1
@@ -14,5 +14,5 @@ class A(val x: String) {
|
|||||||
|
|
||||||
// JVM_IR_TEMPLATES
|
// JVM_IR_TEMPLATES
|
||||||
// 4 IFNULL
|
// 4 IFNULL
|
||||||
// 0 IFNONNULL
|
// 2 IFNONNULL
|
||||||
// 0 ACONST_NULL
|
// 0 ACONST_NULL
|
||||||
|
|||||||
+2
-2
@@ -6,8 +6,8 @@ fun test(na: A?) =
|
|||||||
na?.b?.c?.s
|
na?.b?.c?.s
|
||||||
|
|
||||||
// JVM_IR_TEMPLATES
|
// JVM_IR_TEMPLATES
|
||||||
// 1 DUP
|
// 3 DUP
|
||||||
// 1 IFNULL
|
// 3 IFNULL
|
||||||
// 0 IFNONNULL
|
// 0 IFNONNULL
|
||||||
// 1 ACONST_NULL
|
// 1 ACONST_NULL
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,6 @@ fun test(an: A?) = an?.b?.c?.s
|
|||||||
|
|
||||||
// JVM_IR_TEMPLATES
|
// JVM_IR_TEMPLATES
|
||||||
// 0 ASTORE
|
// 0 ASTORE
|
||||||
// 1 IFNULL
|
// 3 IFNULL
|
||||||
// 0 IFNONNULL
|
// 0 IFNONNULL
|
||||||
// 1 ACONST_NULL
|
// 1 ACONST_NULL
|
||||||
+1
-1
@@ -13,5 +13,5 @@ object Host {
|
|||||||
// JVM_IR_TEMPLATES
|
// JVM_IR_TEMPLATES
|
||||||
// 0 ASTORE
|
// 0 ASTORE
|
||||||
// 1 ACONST_NULL
|
// 1 ACONST_NULL
|
||||||
// 1 IFNULL
|
// 3 IFNULL
|
||||||
// 0 IFNONNULL
|
// 0 IFNONNULL
|
||||||
+1
-1
@@ -17,5 +17,5 @@ fun test(an: A?) = an?.b?.c?.s
|
|||||||
// JVM_IR_TEMPLATES
|
// JVM_IR_TEMPLATES
|
||||||
// 0 ASTORE
|
// 0 ASTORE
|
||||||
// 1 ACONST_NULL
|
// 1 ACONST_NULL
|
||||||
// 1 IFNULL
|
// 3 IFNULL
|
||||||
// 0 IFNONNULL
|
// 0 IFNONNULL
|
||||||
Vendored
+1
-1
@@ -3,7 +3,7 @@ fun test(a: Any?, b: Any?, c: String) =
|
|||||||
|
|
||||||
// JVM_IR_TEMPLATES
|
// JVM_IR_TEMPLATES
|
||||||
// 2 IFNULL
|
// 2 IFNULL
|
||||||
// 0 IFNONNULL
|
// 1 IFNONNULL
|
||||||
// 0 ACONST_NULL
|
// 0 ACONST_NULL
|
||||||
|
|
||||||
// JVM_TEMPLATES
|
// JVM_TEMPLATES
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ fun test(a: Any?) =
|
|||||||
// 0 valueOf
|
// 0 valueOf
|
||||||
|
|
||||||
// JVM_IR_TEMPLATES
|
// JVM_IR_TEMPLATES
|
||||||
// 1 DUP
|
// 2 DUP
|
||||||
// 1 IFNULL
|
// 2 IFNULL
|
||||||
// 0 ACONST_NULL
|
// 0 ACONST_NULL
|
||||||
// 0 IFNONNULL
|
// 0 IFNONNULL
|
||||||
|
|
||||||
|
|||||||
+6
@@ -39686,6 +39686,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
runTest("compiler/testData/codegen/box/safeCall/safeCallEqPrimitive.kt");
|
runTest("compiler/testData/codegen/box/safeCall/safeCallEqPrimitive.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("safeCallIOnUninitializedNonNullValue.kt")
|
||||||
|
public void testSafeCallIOnUninitializedNonNullValue() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/safeCall/safeCallIOnUninitializedNonNullValue.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("safeCallNotEqPrimitive.kt")
|
@TestMetadata("safeCallNotEqPrimitive.kt")
|
||||||
public void testSafeCallNotEqPrimitive() throws Exception {
|
public void testSafeCallNotEqPrimitive() throws Exception {
|
||||||
|
|||||||
+6
@@ -39842,6 +39842,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
runTest("compiler/testData/codegen/box/safeCall/safeCallEqPrimitive.kt");
|
runTest("compiler/testData/codegen/box/safeCall/safeCallEqPrimitive.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("safeCallIOnUninitializedNonNullValue.kt")
|
||||||
|
public void testSafeCallIOnUninitializedNonNullValue() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/safeCall/safeCallIOnUninitializedNonNullValue.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("safeCallNotEqPrimitive.kt")
|
@TestMetadata("safeCallNotEqPrimitive.kt")
|
||||||
public void testSafeCallNotEqPrimitive() throws Exception {
|
public void testSafeCallNotEqPrimitive() throws Exception {
|
||||||
|
|||||||
+5
@@ -31768,6 +31768,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
runTest("compiler/testData/codegen/box/safeCall/safeCallEqPrimitive.kt");
|
runTest("compiler/testData/codegen/box/safeCall/safeCallEqPrimitive.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("safeCallIOnUninitializedNonNullValue.kt")
|
||||||
|
public void testSafeCallIOnUninitializedNonNullValue() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/safeCall/safeCallIOnUninitializedNonNullValue.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("safeCallNotEqPrimitive.kt")
|
@TestMetadata("safeCallNotEqPrimitive.kt")
|
||||||
public void testSafeCallNotEqPrimitive() throws Exception {
|
public void testSafeCallNotEqPrimitive() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/safeCall/safeCallNotEqPrimitive.kt");
|
runTest("compiler/testData/codegen/box/safeCall/safeCallNotEqPrimitive.kt");
|
||||||
|
|||||||
js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java
Generated
+5
@@ -26918,6 +26918,11 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes
|
|||||||
runTest("compiler/testData/codegen/box/safeCall/safeCallEqPrimitive.kt");
|
runTest("compiler/testData/codegen/box/safeCall/safeCallEqPrimitive.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("safeCallIOnUninitializedNonNullValue.kt")
|
||||||
|
public void testSafeCallIOnUninitializedNonNullValue() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/safeCall/safeCallIOnUninitializedNonNullValue.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("safeCallNotEqPrimitive.kt")
|
@TestMetadata("safeCallNotEqPrimitive.kt")
|
||||||
public void testSafeCallNotEqPrimitive() throws Exception {
|
public void testSafeCallNotEqPrimitive() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/safeCall/safeCallNotEqPrimitive.kt");
|
runTest("compiler/testData/codegen/box/safeCall/safeCallNotEqPrimitive.kt");
|
||||||
|
|||||||
Generated
+5
@@ -26324,6 +26324,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
|||||||
runTest("compiler/testData/codegen/box/safeCall/safeCallEqPrimitive.kt");
|
runTest("compiler/testData/codegen/box/safeCall/safeCallEqPrimitive.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("safeCallIOnUninitializedNonNullValue.kt")
|
||||||
|
public void testSafeCallIOnUninitializedNonNullValue() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/safeCall/safeCallIOnUninitializedNonNullValue.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("safeCallNotEqPrimitive.kt")
|
@TestMetadata("safeCallNotEqPrimitive.kt")
|
||||||
public void testSafeCallNotEqPrimitive() throws Exception {
|
public void testSafeCallNotEqPrimitive() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/safeCall/safeCallNotEqPrimitive.kt");
|
runTest("compiler/testData/codegen/box/safeCall/safeCallNotEqPrimitive.kt");
|
||||||
|
|||||||
Generated
+5
@@ -26249,6 +26249,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
|||||||
runTest("compiler/testData/codegen/box/safeCall/safeCallEqPrimitive.kt");
|
runTest("compiler/testData/codegen/box/safeCall/safeCallEqPrimitive.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("safeCallIOnUninitializedNonNullValue.kt")
|
||||||
|
public void testSafeCallIOnUninitializedNonNullValue() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/safeCall/safeCallIOnUninitializedNonNullValue.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("safeCallNotEqPrimitive.kt")
|
@TestMetadata("safeCallNotEqPrimitive.kt")
|
||||||
public void testSafeCallNotEqPrimitive() throws Exception {
|
public void testSafeCallNotEqPrimitive() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/safeCall/safeCallNotEqPrimitive.kt");
|
runTest("compiler/testData/codegen/box/safeCall/safeCallNotEqPrimitive.kt");
|
||||||
|
|||||||
js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java
Generated
+5
@@ -15618,6 +15618,11 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest
|
|||||||
runTest("compiler/testData/codegen/box/safeCall/safeCallEqPrimitive.kt");
|
runTest("compiler/testData/codegen/box/safeCall/safeCallEqPrimitive.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("safeCallIOnUninitializedNonNullValue.kt")
|
||||||
|
public void testSafeCallIOnUninitializedNonNullValue() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/safeCall/safeCallIOnUninitializedNonNullValue.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("safeCallNotEqPrimitive.kt")
|
@TestMetadata("safeCallNotEqPrimitive.kt")
|
||||||
public void testSafeCallNotEqPrimitive() throws Exception {
|
public void testSafeCallNotEqPrimitive() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/safeCall/safeCallNotEqPrimitive.kt");
|
runTest("compiler/testData/codegen/box/safeCall/safeCallNotEqPrimitive.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user