Move TypeSybstitutor creation in InlineFunction
Property "currentFile" expected to return IrFile Print warning if deserializer failed to bring function declaration
This commit is contained in:
committed by
KonstantinAnisimov
parent
8235c8b2be
commit
6568efbac8
+2
-15
@@ -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 <TypeParameterDescriptor, KotlinType>?): 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 <TypeParameterDescriptor, KotlinType>?): TypeSubstitutor? {
|
||||
|
||||
if (typeArgumentsMap == null) return null
|
||||
val substitutionContext = typeArgumentsMap.entries.associate {
|
||||
(typeParameter, typeArgument) ->
|
||||
typeParameter.typeConstructor to TypeProjectionImpl(typeArgument)
|
||||
}
|
||||
return TypeSubstitutor.create(substitutionContext)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
+1
-1
@@ -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 }
|
||||
|
||||
+40
-23
@@ -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<ValueDescriptor, IrExpression>,
|
||||
val statements: MutableList<IrStatement>
|
||||
private class ParameterEvaluationResult(
|
||||
val parameterSubstituteMap: MutableMap<ValueDescriptor, IrExpression>,
|
||||
val evaluationStatements : MutableList<IrStatement>
|
||||
)
|
||||
|
||||
//---------------------------------------------------------------------//
|
||||
@@ -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<ValueDescriptor, IrExpression> ()
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user