From 6568efbac80cfe30836ee0ef9e29b40cf225740d Mon Sep 17 00:00:00 2001 From: Konstantin Anisimov Date: Mon, 10 Apr 2017 14:26:53 +0700 Subject: [PATCH] Move TypeSybstitutor creation in InlineFunction Property "currentFile" expected to return IrFile Print warning if deserializer failed to bring function declaration --- .../common/DeepCopyIrTreeWithDescriptoros.kt | 17 +---- .../IrElementTransformerVoidWithContext.kt | 2 +- .../backend/konan/lower/FunctionInlining.kt | 63 ++++++++++++------- 3 files changed, 43 insertions(+), 39 deletions(-) diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/common/DeepCopyIrTreeWithDescriptoros.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/common/DeepCopyIrTreeWithDescriptoros.kt index 432ffa29baa..730f43d8e17 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/common/DeepCopyIrTreeWithDescriptoros.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/common/DeepCopyIrTreeWithDescriptoros.kt @@ -39,7 +39,6 @@ import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassOrAny import org.jetbrains.kotlin.types.KotlinType -import org.jetbrains.kotlin.types.TypeProjectionImpl import org.jetbrains.kotlin.types.TypeSubstitutor import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.types.typeUtil.makeNullable @@ -53,9 +52,9 @@ internal class DeepCopyIrTreeWithDescriptors(val targetScope: ScopeWithIr, //-------------------------------------------------------------------------// - fun copy(irElement: IrElement, typeArgumentsMap: Map ?): IrElement { + fun copy(irElement: IrElement, typeSubstitutor: TypeSubstitutor?): IrElement { - typeSubstitutor = createTypeSubstitutor(typeArgumentsMap) + this.typeSubstitutor = typeSubstitutor descriptorSubstituteMap.clear() irElement.acceptChildrenVoid(DescriptorCollector()) // Transform calls to object that might be returned from inline function call. @@ -595,18 +594,6 @@ internal class DeepCopyIrTreeWithDescriptors(val targetScope: ScopeWithIr, } return newTypeArguments } - - //-------------------------------------------------------------------------// - - private fun createTypeSubstitutor(typeArgumentsMap: Map ?): TypeSubstitutor? { - - if (typeArgumentsMap == null) return null - val substitutionContext = typeArgumentsMap.entries.associate { - (typeParameter, typeArgument) -> - typeParameter.typeConstructor to TypeProjectionImpl(typeArgument) - } - return TypeSubstitutor.create(substitutionContext) - } } diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/common/IrElementTransformerVoidWithContext.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/common/IrElementTransformerVoidWithContext.kt index b1e53315d9a..94ed32b1d90 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/common/IrElementTransformerVoidWithContext.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/common/IrElementTransformerVoidWithContext.kt @@ -72,7 +72,7 @@ abstract internal class IrElementTransformerVoidWithContext : IrElementTransform return result } - protected val currentFile get() = scopeStack.lastOrNull { it.scope.scopeOwner is PackageFragmentDescriptor } + protected val currentFile get() = scopeStack.lastOrNull { it.irElement is IrFile }!!.irElement as IrFile protected val currentClass get() = scopeStack.lastOrNull { it.scope.scopeOwner is ClassDescriptor } protected val currentFunction get() = scopeStack.lastOrNull { it.scope.scopeOwner is FunctionDescriptor } protected val currentProperty get() = scopeStack.lastOrNull { it.scope.scopeOwner is PropertyDescriptor } diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FunctionInlining.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FunctionInlining.kt index 3bee8609e1c..617764ac168 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FunctionInlining.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FunctionInlining.kt @@ -18,6 +18,7 @@ package org.jetbrains.kotlin.backend.konan.lower import org.jetbrains.kotlin.backend.common.DeepCopyIrTreeWithDescriptors import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext +import org.jetbrains.kotlin.backend.common.reportWarning import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.backend.konan.descriptors.isFunctionInvoke import org.jetbrains.kotlin.backend.konan.descriptors.needsInlining @@ -39,6 +40,8 @@ import org.jetbrains.kotlin.ir.util.getArguments import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.resolve.descriptorUtil.hasDefaultValue +import org.jetbrains.kotlin.types.TypeProjectionImpl +import org.jetbrains.kotlin.types.TypeSubstitutor //-----------------------------------------------------------------------------// @@ -61,12 +64,16 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoidW val irCall = super.visitCall(expression) as IrCall val functionDescriptor = irCall.descriptor as FunctionDescriptor if (functionDescriptor.needsInlining) { - copyIrElement = DeepCopyIrTreeWithDescriptors(currentScope!!, context) val functionDeclaration = getFunctionDeclaration(irCall) - if (functionDeclaration == null) return irCall + if (functionDeclaration == null) { + val message = "Failed to obtain inline function declaration" + context.reportWarning(message, currentFile, irCall) + return irCall + } - functionDeclaration.transformChildrenVoid(this) // Process recursive inline. - return inlineFunction(irCall, functionDeclaration) // Return newly created IrInlineBody instead of IrCall. + copyIrElement = DeepCopyIrTreeWithDescriptors(currentScope!!, context) // Create DeepCopy for current scope. + functionDeclaration.transformChildrenVoid(this) // Process recursive inline. + return inlineFunction(irCall, functionDeclaration) // Return newly created IrInlineBody instead of IrCall. } return irCall @@ -75,19 +82,17 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoidW //-------------------------------------------------------------------------// private fun inlineFunction(irCall: IrCall, functionDeclaration: IrFunction): IrExpression { + val parameterEvaluationResult = evaluateParameters(irCall, functionDeclaration) // Evaluate expressions passed as arguments. + val parameterSubstituteMap = parameterEvaluationResult.parameterSubstituteMap // As a result we get parameter -> argument map + val evaluationStatements = parameterEvaluationResult.evaluationStatements // And list of evaluation statements - val evaluatedParameters = evaluateParameters(irCall, functionDeclaration) - val parameterSubstituteMap = evaluatedParameters.parameters - val evaluationStatements = evaluatedParameters.statements - - val typeArgumentsMap = (irCall as IrMemberAccessExpressionBase).typeArguments - val copyFunctionDeclaration = copyIrElement!!.copy( // Create copy of original function. - functionDeclaration, - typeArgumentsMap + val copyFunctionDeclaration = copyIrElement!!.copy( // Create copy of original function. + irElement = functionDeclaration, // Descriptors will be copied too. + typeSubstitutor = createTypeSubstitutor(irCall) // Type parameters will be substituted with type arguments. ) as IrFunction - val statements = (copyFunctionDeclaration.body as IrBlockBody).statements - val returnType = copyFunctionDeclaration.descriptor.returnType!! + val statements = (copyFunctionDeclaration.body as IrBlockBody).statements + val returnType = copyFunctionDeclaration.descriptor.returnType!! val inlineFunctionBody = IrInlineFunctionBody( startOffset = copyFunctionDeclaration.startOffset, endOffset = copyFunctionDeclaration.endOffset, @@ -98,10 +103,9 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoidW ) val transformer = ParameterSubstitutor(parameterSubstituteMap) - inlineFunctionBody.transformChildrenVoid(transformer) // Replace parameters with expression. - inlineFunctionBody.statements.addAll(0, evaluationStatements) - - return inlineFunctionBody // Replace call site with InlineFunctionBody. + inlineFunctionBody.transformChildrenVoid(transformer) // Replace value parameters with arguments. + inlineFunctionBody.statements.addAll(0, evaluationStatements) // Insert evaluation statements. + return inlineFunctionBody // Replace call site with InlineFunctionBody. } //-------------------------------------------------------------------------// @@ -212,6 +216,19 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoidW //-------------------------------------------------------------------------// + private fun createTypeSubstitutor(irCall: IrCall): TypeSubstitutor? { + + val typeArgumentsMap = (irCall as IrMemberAccessExpressionBase).typeArguments + if (typeArgumentsMap == null) return null + val substitutionContext = typeArgumentsMap.entries.associate { + (typeParameter, typeArgument) -> + typeParameter.typeConstructor to TypeProjectionImpl(typeArgument) + } + return TypeSubstitutor.create(substitutionContext) + } + + //-------------------------------------------------------------------------// + private class ParameterWithArgument( val parameterDescriptor: ValueDescriptor, val argument : IrExpression @@ -219,9 +236,9 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoidW //-------------------------------------------------------------------------// - private class EvaluatedParameters( - val parameters: MutableMap, - val statements: MutableList + private class ParameterEvaluationResult( + val parameterSubstituteMap: MutableMap, + val evaluationStatements : MutableList ) //---------------------------------------------------------------------// @@ -262,7 +279,7 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoidW //-------------------------------------------------------------------------// - private fun evaluateParameters(irCall: IrCall, functionDeclaration: IrFunction): EvaluatedParameters { + private fun evaluateParameters(irCall: IrCall, functionDeclaration: IrFunction): ParameterEvaluationResult { val parametersOld = buildParameterToArgumentMap(irCall, functionDeclaration) // Create map call_site_argument -> inline_function_parameter. val parametersNew = mutableMapOf () @@ -286,7 +303,7 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoidW val getVal = IrGetValueImpl(startOffset, endOffset, newVar.descriptor) // Create new IR element representing access the new variable. parametersNew[parameterDescriptor] = getVal // Parameter will be replaced with the new variable. } - return EvaluatedParameters(parametersNew, statements) + return ParameterEvaluationResult(parametersNew, statements) } }