[JS IR BE] Remove conservative unit materialization
Remove UnitMaterializationLowering Remove Unit insertion in BridgeConstruction Fix codegen for when expressions without else branch
This commit is contained in:
-45
@@ -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
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
|
||||
|
||||
+1
-14
@@ -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
|
||||
}
|
||||
|
||||
+12
-2
@@ -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<JsEx
|
||||
}
|
||||
|
||||
override fun visitWhen(expression: IrWhen, context: JsGenerationContext): JsExpression {
|
||||
// TODO check when w/o else branch and empty when
|
||||
return expression.toJsNode(this, context, ::JsConditional)!!
|
||||
val lastBranch = expression.branches.lastOrNull()
|
||||
val implicitElse =
|
||||
if (lastBranch == null || !isElseBranch(lastBranch))
|
||||
JsPrefixOperation(JsUnaryOperator.VOID, JsIntLiteral(0))
|
||||
else
|
||||
null
|
||||
|
||||
assert(implicitElse == null || expression.type.isUnit()) { "Non unit when-expression must have else branch" }
|
||||
|
||||
return expression.toJsNode(this, context, ::JsConditional, implicitElse)!!
|
||||
}
|
||||
|
||||
override fun visitTypeOperator(expression: IrTypeOperatorCall, data: JsGenerationContext): JsExpression {
|
||||
|
||||
+3
-2
@@ -23,9 +23,10 @@ fun jsVar(name: JsName, initializer: IrExpression?, context: JsGenerationContext
|
||||
fun <T : JsNode> IrWhen.toJsNode(
|
||||
tr: BaseIrElementToJsNodeTransformer<T, JsGenerationContext>,
|
||||
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 {
|
||||
|
||||
Reference in New Issue
Block a user