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.KotlinType
|
||||||
import org.jetbrains.kotlin.types.typeUtil.isNothing
|
import org.jetbrains.kotlin.types.typeUtil.isNothing
|
||||||
import org.jetbrains.kotlin.types.typeUtil.isUnit
|
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
|
val descriptor = type.constructor.declarationDescriptor
|
||||||
when (descriptor) {
|
when (descriptor) {
|
||||||
is ClassDescriptor -> erasure += type.makeNotNullable()
|
is ClassDescriptor -> erasure += descriptor
|
||||||
is TypeParameterDescriptor -> {
|
is TypeParameterDescriptor -> {
|
||||||
descriptor.upperBounds.forEach {
|
descriptor.upperBounds.forEach {
|
||||||
computeErasure(it, erasure)
|
computeErasure(it, erasure)
|
||||||
@@ -70,8 +69,8 @@ private fun computeErasure(type: KotlinType, erasure: MutableList<KotlinType>) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun KotlinType.erasure(): List<KotlinType> {
|
internal fun KotlinType.erasure(): List<ClassDescriptor> {
|
||||||
val result = mutableListOf<KotlinType>()
|
val result = mutableListOf<ClassDescriptor>()
|
||||||
computeErasure(this, result)
|
computeErasure(this, result)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
@@ -409,6 +408,7 @@ internal class ModuleDFGBuilder(val context: Context, val irModule: IrModuleFrag
|
|||||||
private val doResumeFunctionDescriptor = context.getInternalClass("CoroutineImpl").unsubstitutedMemberScope
|
private val doResumeFunctionDescriptor = context.getInternalClass("CoroutineImpl").unsubstitutedMemberScope
|
||||||
.getContributedFunctions(Name.identifier("doResume"), NoLookupLocation.FROM_BACKEND).single()
|
.getContributedFunctions(Name.identifier("doResume"), NoLookupLocation.FROM_BACKEND).single()
|
||||||
private val getContinuationSymbol = context.ir.symbols.getContinuation
|
private val getContinuationSymbol = context.ir.symbols.getContinuation
|
||||||
|
private val continuationType = getContinuationSymbol.descriptor.returnType!!
|
||||||
|
|
||||||
private val arrayGetSymbol = context.ir.symbols.arrayGet
|
private val arrayGetSymbol = context.ir.symbols.arrayGet
|
||||||
private val arraySetSymbol = context.ir.symbols.arraySet
|
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) }
|
{ 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 {
|
fun build(): DataFlowIR.Function {
|
||||||
expressions.forEach { getNode(it) }
|
expressions.forEach { getNode(it) }
|
||||||
val returnsNode = DataFlowIR.Node.Variable(returnValues.map { expressionToEdge(it) }, true)
|
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 +
|
val allNodes = nodes.values + variables.values + templateParameters.values + returnsNode + throwsNode +
|
||||||
(if (descriptor.isSuspend) listOf(continuationParameter!!) else emptyList())
|
(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(
|
return DataFlowIR.Function(
|
||||||
symbol = symbolTable.mapFunction(descriptor),
|
symbol = symbolTable.mapFunction(descriptor),
|
||||||
numberOfParameters = templateParameters.size + if (descriptor.isSuspend) 1 else 0,
|
parameterTypes = parameterTypes,
|
||||||
body = DataFlowIR.FunctionBody(allNodes.distinct().toList(), returnsNode, throwsNode)
|
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) {
|
fun write(result: ArraySlice) {
|
||||||
result.writeInt(symbol)
|
result.writeInt(symbol)
|
||||||
result.writeInt(numberOfParameters)
|
result.writeIntArray(parameterTypes)
|
||||||
body.write(result)
|
body.write(result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -816,7 +816,7 @@ internal object DFGSerializer {
|
|||||||
.toTypedArray()
|
.toTypedArray()
|
||||||
Function(
|
Function(
|
||||||
functionSymbolMap[function.symbol]!!,
|
functionSymbolMap[function.symbol]!!,
|
||||||
function.numberOfParameters,
|
function.parameterTypes.map { typeMap[it]!! }.toIntArray(),
|
||||||
FunctionBody(nodes, nodeMap[body.returns]!!, nodeMap[body.throws]!!)
|
FunctionBody(nodes, nodeMap[body.returns]!!, nodeMap[body.throws]!!)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -1100,7 +1100,12 @@ internal object DFGSerializer {
|
|||||||
|
|
||||||
moduleDataFlowGraph.functions.forEach {
|
moduleDataFlowGraph.functions.forEach {
|
||||||
val symbol = functionSymbols[it.symbol]
|
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 FunctionBody(val nodes: List<Node>, val returns: Node.Variable, val throws: Node.Variable)
|
||||||
|
|
||||||
class Function(val symbol: FunctionSymbol,
|
class Function(val symbol: FunctionSymbol,
|
||||||
val numberOfParameters: Int,
|
val parameterTypes: Array<Type>,
|
||||||
val body: FunctionBody) {
|
val body: FunctionBody) {
|
||||||
|
|
||||||
fun debugOutput() {
|
fun debugOutput() {
|
||||||
println("FUNCTION $symbol")
|
println("FUNCTION $symbol")
|
||||||
println("Params: $numberOfParameters")
|
println("Params: ${parameterTypes.contentToString()}")
|
||||||
val ids = body.nodes.withIndex().associateBy({ it.value }, { it.index })
|
val ids = body.nodes.withIndex().associateBy({ it.value }, { it.index })
|
||||||
body.nodes.forEach {
|
body.nodes.forEach {
|
||||||
println(" NODE #${ids[it]!!}")
|
println(" NODE #${ids[it]!!}")
|
||||||
@@ -489,8 +489,7 @@ internal object DataFlowIR {
|
|||||||
return type
|
return type
|
||||||
}
|
}
|
||||||
|
|
||||||
fun mapType(type: KotlinType) =
|
fun mapType(type: KotlinType) = mapClass(type.erasure().single())
|
||||||
mapClass(type.erasure().single().constructor.declarationDescriptor as ClassDescriptor)
|
|
||||||
|
|
||||||
// TODO: use from LlvmDeclarations.
|
// TODO: use from LlvmDeclarations.
|
||||||
private fun getFqName(descriptor: DeclarationDescriptor): FqName {
|
private fun getFqName(descriptor: DeclarationDescriptor): FqName {
|
||||||
|
|||||||
+1
-1
@@ -267,7 +267,7 @@ internal object EscapeAnalysis {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (functionSymbol in callGraph.directEdges.keys) {
|
for (functionSymbol in callGraph.directEdges.keys) {
|
||||||
val numberOfParameters = intraproceduralAnalysisResult[functionSymbol]!!.function.numberOfParameters
|
val numberOfParameters = intraproceduralAnalysisResult[functionSymbol]!!.function.parameterTypes.size
|
||||||
escapeAnalysisResults[functionSymbol] = FunctionEscapeAnalysisResult(
|
escapeAnalysisResults[functionSymbol] = FunctionEscapeAnalysisResult(
|
||||||
// Assume no edges at the beginning.
|
// Assume no edges at the beginning.
|
||||||
// Then iteratively add needed.
|
// Then iteratively add needed.
|
||||||
|
|||||||
Reference in New Issue
Block a user