From cb3a4727cfd854d3ecde78a99fc9317da5417a6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steven=20Sch=C3=A4fer?= Date: Thu, 23 Apr 2020 11:55:29 +0200 Subject: [PATCH] JVM IR: Optimize field initializers in secondary constructors --- .../ir/FirBlackBoxCodegenTestGenerated.java | 5 +++++ .../backend/jvm/codegen/ExpressionCodegen.kt | 3 +-- .../fieldInitializerOptimization.kt | 20 +++++++++++++++++++ .../codegen/BlackBoxCodegenTestGenerated.java | 5 +++++ .../LightAnalysisModeTestGenerated.java | 5 +++++ .../ir/IrBlackBoxCodegenTestGenerated.java | 5 +++++ .../IrJsCodegenBoxTestGenerated.java | 5 +++++ .../semantics/JsCodegenBoxTestGenerated.java | 5 +++++ 8 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 compiler/testData/codegen/box/secondaryConstructors/fieldInitializerOptimization.kt diff --git a/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java index 2caf70fa5c6..9424f74e985 100644 --- a/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java @@ -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"); diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt index 3fc3c6ef42c..3bca08e5e41 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.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) } diff --git a/compiler/testData/codegen/box/secondaryConstructors/fieldInitializerOptimization.kt b/compiler/testData/codegen/box/secondaryConstructors/fieldInitializerOptimization.kt new file mode 100644 index 00000000000..d4523fcea62 --- /dev/null +++ b/compiler/testData/codegen/box/secondaryConstructors/fieldInitializerOptimization.kt @@ -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" diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 98b8c17af24..fcedd261961 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -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"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 531a3451469..dd50b51d3ce 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -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"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index c630d775d2c..2e816e6c21a 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -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"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java index 7419ae23236..e9084eed1b6 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java @@ -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"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index b6d148036ca..773649f7c05 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -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");