From 51801b9009ffc725220ba735ff9435ae3f5de1fd Mon Sep 17 00:00:00 2001 From: Igor Chevdar Date: Tue, 30 Jan 2018 14:02:47 +0300 Subject: [PATCH] DFG: added parameter types to Function --- .../backend/konan/optimizations/DFGBuilder.kt | 25 +++++++++++++------ .../konan/optimizations/DFGSerializer.kt | 15 +++++++---- .../backend/konan/optimizations/DataFlowIR.kt | 7 +++--- .../konan/optimizations/EscapeAnalysis.kt | 2 +- 4 files changed, 31 insertions(+), 18 deletions(-) diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/DFGBuilder.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/DFGBuilder.kt index 8b3c2892d7c..ca4f87d8047 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/DFGBuilder.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/DFGBuilder.kt @@ -55,12 +55,11 @@ import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.typeUtil.isNothing import org.jetbrains.kotlin.types.typeUtil.isUnit -import org.jetbrains.kotlin.types.typeUtil.makeNotNullable -private fun computeErasure(type: KotlinType, erasure: MutableList) { +private fun computeErasure(type: KotlinType, erasure: MutableList) { val descriptor = type.constructor.declarationDescriptor when (descriptor) { - is ClassDescriptor -> erasure += type.makeNotNullable() + is ClassDescriptor -> erasure += descriptor is TypeParameterDescriptor -> { descriptor.upperBounds.forEach { computeErasure(it, erasure) @@ -70,8 +69,8 @@ private fun computeErasure(type: KotlinType, erasure: MutableList) { } } -internal fun KotlinType.erasure(): List { - val result = mutableListOf() +internal fun KotlinType.erasure(): List { + val result = mutableListOf() computeErasure(this, result) return result } @@ -409,6 +408,7 @@ internal class ModuleDFGBuilder(val context: Context, val irModule: IrModuleFrag private val doResumeFunctionDescriptor = context.getInternalClass("CoroutineImpl").unsubstitutedMemberScope .getContributedFunctions(Name.identifier("doResume"), NoLookupLocation.FROM_BACKEND).single() private val getContinuationSymbol = context.ir.symbols.getContinuation + private val continuationType = getContinuationSymbol.descriptor.returnType!! private val arrayGetSymbol = context.ir.symbols.arrayGet private val arraySetSymbol = context.ir.symbols.arraySet @@ -440,6 +440,12 @@ internal class ModuleDFGBuilder(val context: Context, val irModule: IrModuleFrag { DataFlowIR.Node.Variable(mutableListOf(), false) } ) + private fun choosePrimary(erasure: List): ClassDescriptor { + if (erasure.size == 1) return erasure[0] + // A parameter with constraints - choose class if exists. + return erasure.singleOrNull { !it.isInterface } ?: context.builtIns.any + } + fun build(): DataFlowIR.Function { expressions.forEach { getNode(it) } val returnsNode = DataFlowIR.Node.Variable(returnValues.map { expressionToEdge(it) }, true) @@ -452,10 +458,13 @@ internal class ModuleDFGBuilder(val context: Context, val irModule: IrModuleFrag val allNodes = nodes.values + variables.values + templateParameters.values + returnsNode + throwsNode + (if (descriptor.isSuspend) listOf(continuationParameter!!) else emptyList()) + val parameterTypes = (allParameters.map { it.type } + (if (descriptor.isSuspend) listOf(continuationType) else emptyList())) + .map { symbolTable.mapClass(choosePrimary(it.erasure())) } + .toTypedArray() return DataFlowIR.Function( - symbol = symbolTable.mapFunction(descriptor), - numberOfParameters = templateParameters.size + if (descriptor.isSuspend) 1 else 0, - body = DataFlowIR.FunctionBody(allNodes.distinct().toList(), returnsNode, throwsNode) + symbol = symbolTable.mapFunction(descriptor), + parameterTypes = parameterTypes, + body = DataFlowIR.FunctionBody(allNodes.distinct().toList(), returnsNode, throwsNode) ) } diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/DFGSerializer.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/DFGSerializer.kt index 4807b7def42..3698ff50acd 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/DFGSerializer.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/DFGSerializer.kt @@ -663,13 +663,13 @@ internal object DFGSerializer { } } - class Function(val symbol: Int, val numberOfParameters: Int, val body: FunctionBody) { + class Function(val symbol: Int, val parameterTypes: IntArray, val body: FunctionBody) { - constructor(data: ArraySlice) : this(data.readInt(), data.readInt(), FunctionBody(data)) + constructor(data: ArraySlice) : this(data.readInt(), data.readIntArray(), FunctionBody(data)) fun write(result: ArraySlice) { result.writeInt(symbol) - result.writeInt(numberOfParameters) + result.writeIntArray(parameterTypes) body.write(result) } } @@ -816,7 +816,7 @@ internal object DFGSerializer { .toTypedArray() Function( functionSymbolMap[function.symbol]!!, - function.numberOfParameters, + function.parameterTypes.map { typeMap[it]!! }.toIntArray(), FunctionBody(nodes, nodeMap[body.returns]!!, nodeMap[body.throws]!!) ) } @@ -1100,7 +1100,12 @@ internal object DFGSerializer { moduleDataFlowGraph.functions.forEach { val symbol = functionSymbols[it.symbol] - functions.put(symbol, DataFlowIR.Function(symbol, it.numberOfParameters, deserializeBody(it.body))) + val function = DataFlowIR.Function( + symbol = symbol, + parameterTypes = it.parameterTypes.map { types[it] }.toTypedArray(), + body = deserializeBody(it.body) + ) + functions.put(symbol, function) } } } diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/DataFlowIR.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/DataFlowIR.kt index 4a468bf7b26..6e149ebed56 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/DataFlowIR.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/DataFlowIR.kt @@ -234,12 +234,12 @@ internal object DataFlowIR { class FunctionBody(val nodes: List, val returns: Node.Variable, val throws: Node.Variable) class Function(val symbol: FunctionSymbol, - val numberOfParameters: Int, + val parameterTypes: Array, val body: FunctionBody) { fun debugOutput() { println("FUNCTION $symbol") - println("Params: $numberOfParameters") + println("Params: ${parameterTypes.contentToString()}") val ids = body.nodes.withIndex().associateBy({ it.value }, { it.index }) body.nodes.forEach { println(" NODE #${ids[it]!!}") @@ -489,8 +489,7 @@ internal object DataFlowIR { return type } - fun mapType(type: KotlinType) = - mapClass(type.erasure().single().constructor.declarationDescriptor as ClassDescriptor) + fun mapType(type: KotlinType) = mapClass(type.erasure().single()) // TODO: use from LlvmDeclarations. private fun getFqName(descriptor: DeclarationDescriptor): FqName { diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/EscapeAnalysis.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/EscapeAnalysis.kt index cc64eb69f2e..216339f634c 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/EscapeAnalysis.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/EscapeAnalysis.kt @@ -267,7 +267,7 @@ internal object EscapeAnalysis { } for (functionSymbol in callGraph.directEdges.keys) { - val numberOfParameters = intraproceduralAnalysisResult[functionSymbol]!!.function.numberOfParameters + val numberOfParameters = intraproceduralAnalysisResult[functionSymbol]!!.function.parameterTypes.size escapeAnalysisResults[functionSymbol] = FunctionEscapeAnalysisResult( // Assume no edges at the beginning. // Then iteratively add needed.