JVM IR: Optimize field initializers in secondary constructors

This commit is contained in:
Steven Schäfer
2020-04-23 11:55:29 +02:00
committed by max-kammerer
parent fed6272de4
commit cb3a4727cf
8 changed files with 51 additions and 2 deletions
@@ -26809,6 +26809,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/secondaryConstructors/enums.kt");
}
@TestMetadata("fieldInitializerOptimization.kt")
public void testFieldInitializerOptimization() throws Exception {
runTest("compiler/testData/codegen/box/secondaryConstructors/fieldInitializerOptimization.kt");
}
@TestMetadata("generics.kt")
public void testGenerics() throws Exception {
runTest("compiler/testData/codegen/box/secondaryConstructors/generics.kt");
@@ -558,10 +558,9 @@ class ExpressionCodegen(
override fun visitSetField(expression: IrSetField, data: BlockInfo): PromisedValue {
val expressionValue = expression.value
// Do not add redundant field initializers that initialize to default values.
val inPrimaryConstructor = irFunction is IrConstructor && irFunction.isPrimary
val inClassInit = irFunction.origin == JvmLoweredDeclarationOrigin.CLASS_STATIC_INITIALIZER
val isFieldInitializer = expression.origin == IrStatementOrigin.INITIALIZE_FIELD
val skip = (inPrimaryConstructor || inClassInit) && isFieldInitializer && expressionValue is IrConst<*> &&
val skip = (irFunction is IrConstructor || inClassInit) && isFieldInitializer && expressionValue is IrConst<*> &&
isDefaultValueForType(expression.symbol.owner.type.asmType, expressionValue.value)
return if (skip) unitValue else super.visitSetField(expression, data)
}
@@ -0,0 +1,20 @@
// IGNORE_BACKEND: JS
// IGNORE_BACKEND: JS_IR
open class Base {
open fun setup() {}
init { setup() }
}
class Derived : Base {
constructor() : super()
override fun setup() { x = 1 }
// Technically, this field initializer comes after the superclass
// constructor is called. However, we optimize away field initializers
// which set fields to their default value, which is why x ends up with
// value 1 after the constructor call.
var x = 0
}
fun box(): String = if (Derived().x == 1) "OK" else "Fail"
@@ -28395,6 +28395,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTest("compiler/testData/codegen/box/secondaryConstructors/enums.kt");
}
@TestMetadata("fieldInitializerOptimization.kt")
public void testFieldInitializerOptimization() throws Exception {
runTest("compiler/testData/codegen/box/secondaryConstructors/fieldInitializerOptimization.kt");
}
@TestMetadata("generics.kt")
public void testGenerics() throws Exception {
runTest("compiler/testData/codegen/box/secondaryConstructors/generics.kt");
@@ -27212,6 +27212,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTest("compiler/testData/codegen/box/secondaryConstructors/enums.kt");
}
@TestMetadata("fieldInitializerOptimization.kt")
public void testFieldInitializerOptimization() throws Exception {
runTest("compiler/testData/codegen/box/secondaryConstructors/fieldInitializerOptimization.kt");
}
@TestMetadata("generics.kt")
public void testGenerics() throws Exception {
runTest("compiler/testData/codegen/box/secondaryConstructors/generics.kt");
@@ -26809,6 +26809,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/secondaryConstructors/enums.kt");
}
@TestMetadata("fieldInitializerOptimization.kt")
public void testFieldInitializerOptimization() throws Exception {
runTest("compiler/testData/codegen/box/secondaryConstructors/fieldInitializerOptimization.kt");
}
@TestMetadata("generics.kt")
public void testGenerics() throws Exception {
runTest("compiler/testData/codegen/box/secondaryConstructors/generics.kt");
@@ -21690,6 +21690,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/secondaryConstructors/enums.kt");
}
@TestMetadata("fieldInitializerOptimization.kt")
public void testFieldInitializerOptimization() throws Exception {
runTest("compiler/testData/codegen/box/secondaryConstructors/fieldInitializerOptimization.kt");
}
@TestMetadata("generics.kt")
public void testGenerics() throws Exception {
runTest("compiler/testData/codegen/box/secondaryConstructors/generics.kt");
@@ -21750,6 +21750,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/secondaryConstructors/enums.kt");
}
@TestMetadata("fieldInitializerOptimization.kt")
public void testFieldInitializerOptimization() throws Exception {
runTest("compiler/testData/codegen/box/secondaryConstructors/fieldInitializerOptimization.kt");
}
@TestMetadata("generics.kt")
public void testGenerics() throws Exception {
runTest("compiler/testData/codegen/box/secondaryConstructors/generics.kt");