From 6fb11686c955d451d107d9b749c55144cf8aa329 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Thu, 3 Feb 2022 19:04:59 +0100 Subject: [PATCH] Psi2ir: further reduce used stack for binary expressions --- .../kotlin/psi2ir/generators/CallGenerator.kt | 123 ++++++++++-------- .../psi2ir/intermediate/SimpleCallReceiver.kt | 6 +- 2 files changed, 72 insertions(+), 57 deletions(-) diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/CallGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/CallGenerator.kt index 0774e0df74b..d69415a8482 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/CallGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/CallGenerator.kt @@ -37,7 +37,6 @@ import org.jetbrains.kotlin.resolve.calls.tasks.isDynamic import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForObject import org.jetbrains.kotlin.resolve.descriptorUtil.classValueType import org.jetbrains.kotlin.types.KotlinType -import java.util.* class CallGenerator(statementGenerator: StatementGenerator) : StatementGeneratorExtension(statementGenerator) { fun generateCall(startOffset: Int, endOffset: Int, call: CallBuilder, origin: IrStatementOrigin? = null): IrExpression { @@ -312,63 +311,15 @@ class CallGenerator(statementGenerator: StatementGenerator) : StatementGenerator endOffset: Int, origin: IrStatementOrigin?, call: CallBuilder - ): IrExpression = - call.callReceiver.call { dispatchReceiverValue, extensionReceiverValue, contextReceiverValues -> - val irType = functionDescriptor.returnType!!.toIrType() - + ): IrExpression { + val builder = CallExpressionBuilder { dispatchReceiverValue, extensionReceiverValue, contextReceiverValues -> if (functionDescriptor.isDynamic()) { - fun makeDynamicOperatorExpression(operator: IrDynamicOperator) = - IrDynamicOperatorExpressionImpl( - startOffset, endOffset, - irType, - operator - ) - - fun makeDynamicOperatorExpressionWithArguments(operator: IrDynamicOperator, dynamicReceiver: IrExpression) = - makeDynamicOperatorExpression(operator).apply { - receiver = dynamicReceiver - arguments.addAll(call.getValueArgumentsInParameterOrder().mapIndexed { index: Int, arg: IrExpression? -> - arg ?: throw AssertionError("No argument in dynamic call $functionDescriptor at position $index") - }) - } - - val dynamicReceiver = getDynamicExpressionReceiver(dispatchReceiverValue, extensionReceiverValue, functionDescriptor) - - when { - call.original.isImplicitInvoke() -> - makeDynamicOperatorExpressionWithArguments(IrDynamicOperator.INVOKE, dynamicReceiver) - call.original.isImplicitGet() -> - makeDynamicOperatorExpressionWithArguments(IrDynamicOperator.ARRAY_ACCESS, dynamicReceiver) - call.original.isImplicitSet() -> - makeDynamicOperatorExpression(IrDynamicOperator.EQ).apply { - val args = call.getValueArgumentsInParameterOrder() - val arg0 = args[0] - ?: throw AssertionError("No index argument in dynamic array set: ${call.original.call.callElement.text}") - val arg1 = args[1] - ?: throw AssertionError("No value argument in dynamic array set: ${call.original.call.callElement.text}") - left = - makeDynamicOperatorExpression(IrDynamicOperator.ARRAY_ACCESS).apply { - left = dynamicReceiver - right = arg0 - } - right = arg1 - } - else -> - makeDynamicOperatorExpressionWithArguments( - IrDynamicOperator.INVOKE, - IrDynamicMemberExpressionImpl( - startOffset, endOffset, // TODO obtain more exact start/end offsets for explicit receiver expression - dynamicReceiver.type, - functionDescriptor.name.asString(), - dynamicReceiver - ) - ) - } + generateDynamicFunctionCall(startOffset, endOffset, functionDescriptor, call, dispatchReceiverValue, extensionReceiverValue) } else { val originalSymbol = context.symbolTable.referenceSimpleFunction(functionDescriptor.original) IrCallImpl.fromSymbolDescriptor( startOffset, endOffset, - irType, + functionDescriptor.returnType!!.toIrType(), originalSymbol, origin = origin, superQualifierSymbol = call.superQualifier?.let { context.symbolTable.referenceClass(it) } @@ -379,10 +330,74 @@ class CallGenerator(statementGenerator: StatementGenerator) : StatementGenerator extensionReceiver = extensionReceiverValue?.load() val contextReceivers = contextReceiverValues.map { it.load() } contextReceiversCount = contextReceivers.size - addParametersToCall(startOffset, endOffset, call, this, irType, contextReceivers) + addParametersToCall(startOffset, endOffset, call, this, type, contextReceivers) } } } + return with(call.callReceiver) { + when (this) { + is SimpleCallReceiver -> builder.withReceivers(dispatchReceiverValue, extensionReceiverValue, contextReceiverValues) + else -> call(builder) + } + } + } + + private fun generateDynamicFunctionCall( + startOffset: Int, + endOffset: Int, + functionDescriptor: FunctionDescriptor, + call: CallBuilder, + dispatchReceiverValue: IntermediateValue?, + extensionReceiverValue: IntermediateValue?, + ): IrDynamicOperatorExpressionImpl { + fun makeDynamicOperatorExpression(operator: IrDynamicOperator) = + IrDynamicOperatorExpressionImpl( + startOffset, endOffset, + functionDescriptor.returnType!!.toIrType(), + operator + ) + + fun makeDynamicOperatorExpressionWithArguments(operator: IrDynamicOperator, dynamicReceiver: IrExpression) = + makeDynamicOperatorExpression(operator).apply { + receiver = dynamicReceiver + arguments.addAll(call.getValueArgumentsInParameterOrder().mapIndexed { index: Int, arg: IrExpression? -> + arg ?: throw AssertionError("No argument in dynamic call $functionDescriptor at position $index") + }) + } + + val dynamicReceiver = getDynamicExpressionReceiver(dispatchReceiverValue, extensionReceiverValue, functionDescriptor) + + return when { + call.original.isImplicitInvoke() -> + makeDynamicOperatorExpressionWithArguments(IrDynamicOperator.INVOKE, dynamicReceiver) + call.original.isImplicitGet() -> + makeDynamicOperatorExpressionWithArguments(IrDynamicOperator.ARRAY_ACCESS, dynamicReceiver) + call.original.isImplicitSet() -> + makeDynamicOperatorExpression(IrDynamicOperator.EQ).apply { + val args = call.getValueArgumentsInParameterOrder() + val arg0 = args[0] + ?: throw AssertionError("No index argument in dynamic array set: ${call.original.call.callElement.text}") + val arg1 = args[1] + ?: throw AssertionError("No value argument in dynamic array set: ${call.original.call.callElement.text}") + left = + makeDynamicOperatorExpression(IrDynamicOperator.ARRAY_ACCESS).apply { + left = dynamicReceiver + right = arg0 + } + right = arg1 + } + else -> + makeDynamicOperatorExpressionWithArguments( + IrDynamicOperator.INVOKE, + IrDynamicMemberExpressionImpl( + startOffset, endOffset, // TODO obtain more exact start/end offsets for explicit receiver expression + dynamicReceiver.type, + functionDescriptor.name.asString(), + dynamicReceiver + ) + ) + } + } private fun addParametersToCall( startOffset: Int, diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/SimpleCallReceiver.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/SimpleCallReceiver.kt index 6ad30c0e71b..0daa24ef06e 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/SimpleCallReceiver.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/SimpleCallReceiver.kt @@ -19,9 +19,9 @@ package org.jetbrains.kotlin.psi2ir.intermediate import org.jetbrains.kotlin.ir.expressions.IrExpression class SimpleCallReceiver( - private val dispatchReceiverValue: IntermediateValue?, - private val extensionReceiverValue: IntermediateValue?, - private val contextReceiverValues: List + val dispatchReceiverValue: IntermediateValue?, + val extensionReceiverValue: IntermediateValue?, + val contextReceiverValues: List ) : CallReceiver { override fun call(builder: CallExpressionBuilder): IrExpression { return builder.withReceivers(dispatchReceiverValue, extensionReceiverValue, contextReceiverValues)