KT-36813 Generate optimizable null checks in JVM_IR

This commit is contained in:
Dmitry Petrov
2020-03-03 16:54:57 +03:00
parent a52ef71d48
commit f678db2f89
9 changed files with 90 additions and 11 deletions
@@ -16403,6 +16403,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
public void testTrivialInstanceOf() throws Exception {
runTest("compiler/testData/codegen/box/nullCheckOptimization/trivialInstanceOf.kt");
}
@TestMetadata("varModifiedAfterCheck.kt")
public void testVarModifiedAfterCheck() throws Exception {
runTest("compiler/testData/codegen/box/nullCheckOptimization/varModifiedAfterCheck.kt");
}
}
@TestMetadata("compiler/testData/codegen/box/objectIntrinsics")
@@ -20,13 +20,11 @@ import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.builders.*
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.expressions.IrTypeOperator
import org.jetbrains.kotlin.ir.expressions.IrTypeOperatorCall
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.IrCompositeImpl
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.render
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
@@ -142,7 +140,7 @@ private class TypeOperatorLowering(private val context: JvmBackendContext) : Fil
val (startOffset, endOffset) = expression.extents()
val source = sourceViewFor(parent as IrDeclaration).subSequence(startOffset, endOffset).toString()
irLetS(expression.argument.transformVoid()) { valueSymbol ->
fun checkExpressionValue(valueSymbol: IrValueSymbol): IrExpression =
irComposite(resultType = expression.type) {
+irCall(checkExpressionValueIsNotNull).apply {
putValueArgument(0, irGet(valueSymbol.owner))
@@ -150,6 +148,14 @@ private class TypeOperatorLowering(private val context: JvmBackendContext) : Fil
}
+irGet(valueSymbol.owner)
}
val argument = expression.argument.transformVoid()
if (argument is IrGetValue) {
checkExpressionValue(argument.symbol)
} else {
irLetS(argument) { valueSymbol ->
checkExpressionValue(valueSymbol)
}
}
}
@@ -0,0 +1,59 @@
// TARGET_BACKEND: JVM
// FILE: varModifiedAfterCheck.kt
fun implicitCheck(s: String) {}
fun test1() {
var a = J.foo()
val b = a
a = J.bar()
if (b != null) {
if (a != null) {
throw AssertionError("a: $a")
}
}
}
fun test2() {
var a = J.foo()
val b = a
if (b != null) {
a = J.bar()
if (a != null) {
throw AssertionError("a: $a")
}
}
}
fun test3() {
var a = J.foo()
val b = a
a = J.bar()
implicitCheck(b)
if (a != null) {
throw AssertionError("a: $a")
}
}
fun test4() {
var a = J.foo()
val b = a
implicitCheck(b)
a = J.bar()
if (a != null) {
throw AssertionError("a: $a")
}
}
fun box(): String {
test1()
test2()
test3()
test4()
return "OK"
}
// FILE: J.java
public class J {
public static String foo() { return ""; }
public static String bar() { return null; }
}
@@ -1,5 +1,3 @@
// IGNORE_BACKEND: JVM_IR
// TODO KT-36813 Support code generated by JVM_IR in redundant null check optimization
// FILE: j/J.java
package j;
@@ -1,5 +1,3 @@
// IGNORE_BACKEND: JVM_IR
// TODO KT-36813 Support code generated by JVM_IR in redundant null check optimization
// FILE: j/J.java
package j;
@@ -1,6 +1,4 @@
// !API_VERSION: LATEST
// IGNORE_BACKEND: JVM_IR
// TODO KT-36813 Support code generated by JVM_IR in redundant null check optimization
// FILE: j/J.java
package j;
@@ -17548,6 +17548,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
public void testTrivialInstanceOf() throws Exception {
runTest("compiler/testData/codegen/box/nullCheckOptimization/trivialInstanceOf.kt");
}
@TestMetadata("varModifiedAfterCheck.kt")
public void testVarModifiedAfterCheck() throws Exception {
runTest("compiler/testData/codegen/box/nullCheckOptimization/varModifiedAfterCheck.kt");
}
}
@TestMetadata("compiler/testData/codegen/box/objectIntrinsics")
@@ -17548,6 +17548,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
public void testTrivialInstanceOf() throws Exception {
runTest("compiler/testData/codegen/box/nullCheckOptimization/trivialInstanceOf.kt");
}
@TestMetadata("varModifiedAfterCheck.kt")
public void testVarModifiedAfterCheck() throws Exception {
runTest("compiler/testData/codegen/box/nullCheckOptimization/varModifiedAfterCheck.kt");
}
}
@TestMetadata("compiler/testData/codegen/box/objectIntrinsics")
@@ -16403,6 +16403,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
public void testTrivialInstanceOf() throws Exception {
runTest("compiler/testData/codegen/box/nullCheckOptimization/trivialInstanceOf.kt");
}
@TestMetadata("varModifiedAfterCheck.kt")
public void testVarModifiedAfterCheck() throws Exception {
runTest("compiler/testData/codegen/box/nullCheckOptimization/varModifiedAfterCheck.kt");
}
}
@TestMetadata("compiler/testData/codegen/box/objectIntrinsics")