DFG: added parameter types to Function

This commit is contained in:
Igor Chevdar
2018-01-30 14:02:47 +03:00
parent 0629513fd9
commit 51801b9009
4 changed files with 31 additions and 18 deletions
@@ -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<KotlinType>) {
private fun computeErasure(type: KotlinType, erasure: MutableList<ClassDescriptor>) {
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<KotlinType>) {
}
}
internal fun KotlinType.erasure(): List<KotlinType> {
val result = mutableListOf<KotlinType>()
internal fun KotlinType.erasure(): List<ClassDescriptor> {
val result = mutableListOf<ClassDescriptor>()
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>): 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)
)
}
@@ -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)
}
}
}
@@ -234,12 +234,12 @@ internal object DataFlowIR {
class FunctionBody(val nodes: List<Node>, val returns: Node.Variable, val throws: Node.Variable)
class Function(val symbol: FunctionSymbol,
val numberOfParameters: Int,
val parameterTypes: Array<Type>,
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 {
@@ -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.