DFG: added parameter types to Function
This commit is contained in:
+17
-8
@@ -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)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
+10
-5
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-4
@@ -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 {
|
||||
|
||||
+1
-1
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user