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.DescriptorUtils
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassOrAny
|
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassOrAny
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.kotlin.types.TypeProjectionImpl
|
|
||||||
import org.jetbrains.kotlin.types.TypeSubstitutor
|
import org.jetbrains.kotlin.types.TypeSubstitutor
|
||||||
import org.jetbrains.kotlin.types.Variance
|
import org.jetbrains.kotlin.types.Variance
|
||||||
import org.jetbrains.kotlin.types.typeUtil.makeNullable
|
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()
|
descriptorSubstituteMap.clear()
|
||||||
irElement.acceptChildrenVoid(DescriptorCollector())
|
irElement.acceptChildrenVoid(DescriptorCollector())
|
||||||
// Transform calls to object that might be returned from inline function call.
|
// Transform calls to object that might be returned from inline function call.
|
||||||
@@ -595,18 +594,6 @@ internal class DeepCopyIrTreeWithDescriptors(val targetScope: ScopeWithIr,
|
|||||||
}
|
}
|
||||||
return newTypeArguments
|
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
|
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 currentClass get() = scopeStack.lastOrNull { it.scope.scopeOwner is ClassDescriptor }
|
||||||
protected val currentFunction get() = scopeStack.lastOrNull { it.scope.scopeOwner is FunctionDescriptor }
|
protected val currentFunction get() = scopeStack.lastOrNull { it.scope.scopeOwner is FunctionDescriptor }
|
||||||
protected val currentProperty get() = scopeStack.lastOrNull { it.scope.scopeOwner is PropertyDescriptor }
|
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.DeepCopyIrTreeWithDescriptors
|
||||||
import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
|
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.Context
|
||||||
import org.jetbrains.kotlin.backend.konan.descriptors.isFunctionInvoke
|
import org.jetbrains.kotlin.backend.konan.descriptors.isFunctionInvoke
|
||||||
import org.jetbrains.kotlin.backend.konan.descriptors.needsInlining
|
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.IrElementTransformerVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.hasDefaultValue
|
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 irCall = super.visitCall(expression) as IrCall
|
||||||
val functionDescriptor = irCall.descriptor as FunctionDescriptor
|
val functionDescriptor = irCall.descriptor as FunctionDescriptor
|
||||||
if (functionDescriptor.needsInlining) {
|
if (functionDescriptor.needsInlining) {
|
||||||
copyIrElement = DeepCopyIrTreeWithDescriptors(currentScope!!, context)
|
|
||||||
val functionDeclaration = getFunctionDeclaration(irCall)
|
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.
|
copyIrElement = DeepCopyIrTreeWithDescriptors(currentScope!!, context) // Create DeepCopy for current scope.
|
||||||
return inlineFunction(irCall, functionDeclaration) // Return newly created IrInlineBody instead of IrCall.
|
functionDeclaration.transformChildrenVoid(this) // Process recursive inline.
|
||||||
|
return inlineFunction(irCall, functionDeclaration) // Return newly created IrInlineBody instead of IrCall.
|
||||||
}
|
}
|
||||||
|
|
||||||
return irCall
|
return irCall
|
||||||
@@ -75,19 +82,17 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoidW
|
|||||||
//-------------------------------------------------------------------------//
|
//-------------------------------------------------------------------------//
|
||||||
|
|
||||||
private fun inlineFunction(irCall: IrCall, functionDeclaration: IrFunction): IrExpression {
|
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 copyFunctionDeclaration = copyIrElement!!.copy( // Create copy of original function.
|
||||||
val parameterSubstituteMap = evaluatedParameters.parameters
|
irElement = functionDeclaration, // Descriptors will be copied too.
|
||||||
val evaluationStatements = evaluatedParameters.statements
|
typeSubstitutor = createTypeSubstitutor(irCall) // Type parameters will be substituted with type arguments.
|
||||||
|
|
||||||
val typeArgumentsMap = (irCall as IrMemberAccessExpressionBase).typeArguments
|
|
||||||
val copyFunctionDeclaration = copyIrElement!!.copy( // Create copy of original function.
|
|
||||||
functionDeclaration,
|
|
||||||
typeArgumentsMap
|
|
||||||
) as IrFunction
|
) as IrFunction
|
||||||
|
|
||||||
val statements = (copyFunctionDeclaration.body as IrBlockBody).statements
|
val statements = (copyFunctionDeclaration.body as IrBlockBody).statements
|
||||||
val returnType = copyFunctionDeclaration.descriptor.returnType!!
|
val returnType = copyFunctionDeclaration.descriptor.returnType!!
|
||||||
val inlineFunctionBody = IrInlineFunctionBody(
|
val inlineFunctionBody = IrInlineFunctionBody(
|
||||||
startOffset = copyFunctionDeclaration.startOffset,
|
startOffset = copyFunctionDeclaration.startOffset,
|
||||||
endOffset = copyFunctionDeclaration.endOffset,
|
endOffset = copyFunctionDeclaration.endOffset,
|
||||||
@@ -98,10 +103,9 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoidW
|
|||||||
)
|
)
|
||||||
|
|
||||||
val transformer = ParameterSubstitutor(parameterSubstituteMap)
|
val transformer = ParameterSubstitutor(parameterSubstituteMap)
|
||||||
inlineFunctionBody.transformChildrenVoid(transformer) // Replace parameters with expression.
|
inlineFunctionBody.transformChildrenVoid(transformer) // Replace value parameters with arguments.
|
||||||
inlineFunctionBody.statements.addAll(0, evaluationStatements)
|
inlineFunctionBody.statements.addAll(0, evaluationStatements) // Insert evaluation statements.
|
||||||
|
return inlineFunctionBody // Replace call site with InlineFunctionBody.
|
||||||
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(
|
private class ParameterWithArgument(
|
||||||
val parameterDescriptor: ValueDescriptor,
|
val parameterDescriptor: ValueDescriptor,
|
||||||
val argument : IrExpression
|
val argument : IrExpression
|
||||||
@@ -219,9 +236,9 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoidW
|
|||||||
|
|
||||||
//-------------------------------------------------------------------------//
|
//-------------------------------------------------------------------------//
|
||||||
|
|
||||||
private class EvaluatedParameters(
|
private class ParameterEvaluationResult(
|
||||||
val parameters: MutableMap<ValueDescriptor, IrExpression>,
|
val parameterSubstituteMap: MutableMap<ValueDescriptor, IrExpression>,
|
||||||
val statements: MutableList<IrStatement>
|
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 parametersOld = buildParameterToArgumentMap(irCall, functionDeclaration) // Create map call_site_argument -> inline_function_parameter.
|
||||||
val parametersNew = mutableMapOf<ValueDescriptor, IrExpression> ()
|
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.
|
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.
|
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