From e8933738acf60c4bf09d29ec881ce293344d90c2 Mon Sep 17 00:00:00 2001 From: Svyatoslav Kuzmich Date: Tue, 14 May 2019 19:10:16 +0300 Subject: [PATCH] [JS IR BE] Remove conservative unit materialization Remove UnitMaterializationLowering Remove Unit insertion in BridgeConstruction Fix codegen for when expressions without else branch --- .../lower/UnitMaterializationLowering.kt | 45 ------------------- .../kotlin/ir/backend/js/JsLoweringPhases.kt | 11 +---- .../backend/js/lower/BridgesConstruction.kt | 15 +------ .../IrElementToJsExpressionTransformer.kt | 14 +++++- .../js/transformers/irToJs/jsAstUtils.kt | 5 ++- 5 files changed, 17 insertions(+), 73 deletions(-) delete mode 100644 compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/UnitMaterializationLowering.kt diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/UnitMaterializationLowering.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/UnitMaterializationLowering.kt deleted file mode 100644 index 08f85a5978f..00000000000 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/UnitMaterializationLowering.kt +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors. - * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. - */ - -package org.jetbrains.kotlin.backend.common.lower - -import org.jetbrains.kotlin.backend.common.BackendContext -import org.jetbrains.kotlin.backend.common.FileLoweringPass -import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET -import org.jetbrains.kotlin.ir.declarations.IrFile -import org.jetbrains.kotlin.ir.expressions.IrCall -import org.jetbrains.kotlin.ir.expressions.IrExpression -import org.jetbrains.kotlin.ir.expressions.impl.IrCompositeImpl -import org.jetbrains.kotlin.ir.expressions.impl.IrGetObjectValueImpl -import org.jetbrains.kotlin.ir.symbols.IrClassSymbol -import org.jetbrains.kotlin.ir.types.classifierOrFail -import org.jetbrains.kotlin.ir.types.isUnit -import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid -import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid - -class UnitMaterializationLowering(context: BackendContext) : FileLoweringPass { - - private val unitType = context.irBuiltIns.unitType - private val unitValue - get() = IrGetObjectValueImpl( - UNDEFINED_OFFSET, - UNDEFINED_OFFSET, - unitType, - unitType.classifierOrFail as IrClassSymbol - ) - - override fun lower(irFile: IrFile) { - irFile.transformChildrenVoid(object : IrElementTransformerVoid() { - override fun visitCall(expression: IrCall): IrExpression { - expression.transformChildrenVoid(this) - return if (expression.type.isUnit()) expression.let { - IrCompositeImpl(it.startOffset, it.endOffset, it.type, it.origin, listOf(it, unitValue)) - } - else expression - } - }) - } - -} \ No newline at end of file diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsLoweringPhases.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsLoweringPhases.kt index b3a72f73ccd..46e233aca75 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsLoweringPhases.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsLoweringPhases.kt @@ -133,13 +133,6 @@ private val tailrecLoweringPhase = makeJsModulePhase( description = "Replace `tailrec` callsites with equivalent loop" ) -private val unitMaterializationLoweringPhase = makeJsModulePhase( - ::UnitMaterializationLowering, - name = "UnitMaterializationLowering", - description = "Insert Unit object where it is supposed to be", - prerequisite = setOf(tailrecLoweringPhase) -) - private val enumClassConstructorLoweringPhase = makeJsModulePhase( ::EnumClassConstructorLowering, name = "EnumClassConstructorLowering", @@ -201,8 +194,7 @@ private val innerClassConstructorCallsLoweringPhase = makeJsModulePhase( private val suspendFunctionsLoweringPhase = makeJsModulePhase( ::JsSuspendFunctionsLowering, name = "SuspendFunctionsLowering", - description = "Transform suspend functions into CoroutineImpl instance and build state machine", - prerequisite = setOf(unitMaterializationLoweringPhase) + description = "Transform suspend functions into CoroutineImpl instance and build state machine" ) private val privateMembersLoweringPhase = makeJsModulePhase( @@ -389,7 +381,6 @@ val jsPhases = namedIrModulePhase( enumClassLoweringPhase then enumUsageLoweringPhase then returnableBlockLoweringPhase then - unitMaterializationLoweringPhase then suspendFunctionsLoweringPhase then privateMembersLoweringPhase then callableReferenceLoweringPhase then diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/BridgesConstruction.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/BridgesConstruction.kt index 5eabd459696..5ccbd34f408 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/BridgesConstruction.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/BridgesConstruction.kt @@ -105,8 +105,6 @@ class BridgesConstruction(val context: JsIrBackendContext) : ClassLoweringPass { } } - private val unitValue = JsIrBuilder.buildGetObjectValue(context.irBuiltIns.unitType, context.irBuiltIns.unitClass) - // Ported from from jvm.lower.BridgeLowering private fun createBridge( function: IrSimpleFunction, @@ -168,18 +166,7 @@ class BridgesConstruction(val context: JsIrBackendContext) : ClassLoweringPass { call.putValueArgument(i, irCastIfNeeded(irGet(valueParameter), delegateTo.valueParameters[i].type)) } - // This is required for Unit materialization - // TODO: generalize for boxed types and inline classes - // TODO: use return type in signature too - val returnValue = if (delegateTo.returnType.isUnit() && !function.returnType.isUnit()) { - irComposite(resultType = irFunction.returnType) { - +call - +unitValue - } - } else { - call - } - +irReturn(returnValue) + +irReturn(call) }.apply { irFunction.body = this } diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/IrElementToJsExpressionTransformer.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/IrElementToJsExpressionTransformer.kt index 3b27e0b9c48..5930565b5bd 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/IrElementToJsExpressionTransformer.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/IrElementToJsExpressionTransformer.kt @@ -5,12 +5,14 @@ package org.jetbrains.kotlin.ir.backend.js.transformers.irToJs +import org.jetbrains.kotlin.backend.common.ir.isElseBranch import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.ir.backend.js.utils.* import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrConstructor import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction import org.jetbrains.kotlin.ir.expressions.* +import org.jetbrains.kotlin.ir.types.isUnit import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.js.backend.ast.* import org.jetbrains.kotlin.util.OperatorNameConventions @@ -309,8 +311,16 @@ class IrElementToJsExpressionTransformer : BaseIrElementToJsNodeTransformer IrWhen.toJsNode( tr: BaseIrElementToJsNodeTransformer, data: JsGenerationContext, - node: (JsExpression, T, T?) -> T + node: (JsExpression, T, T?) -> T, + implicitElse: T? = null ): T? = - branches.foldRight(null) { br, n -> + branches.foldRight(implicitElse) { br, n -> val body = br.result.accept(tr, data) if (isElseBranch(br)) body else {