diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/CallGraphBuilder.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/CallGraphBuilder.kt index 98d4bd72fc4..b7fd2645bcd 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/CallGraphBuilder.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/CallGraphBuilder.kt @@ -28,7 +28,7 @@ internal class CallGraphNode(val graph: CallGraph, val symbol: DataFlowIR.Functi graph.reversedEdges[symbol]!! } - class CallSite(val call: DataFlowIR.Node.Call, val isVirtual: Boolean, val actualCallee: DataFlowIR.FunctionSymbol) + class CallSite(val call: DataFlowIR.Node.Call, val node: DataFlowIR.Node, val isVirtual: Boolean, val actualCallee: DataFlowIR.FunctionSymbol) val callSites = mutableListOf() } @@ -105,20 +105,21 @@ internal class CallGraphBuilder( reversedEdges[symbol] = mutableListOf() } - private inline fun DataFlowIR.FunctionBody.forEachCallSite(block: (DataFlowIR.Node.Call) -> Unit): Unit = + private inline fun DataFlowIR.FunctionBody.forEachCallSite(block: (DataFlowIR.Node.Call, DataFlowIR.Node) -> Unit): Unit = forEachNonScopeNode { node -> when (node) { - is DataFlowIR.Node.Call -> block(node) + is DataFlowIR.Node.Call -> block(node, node) is DataFlowIR.Node.Singleton -> - node.constructor?.let { block(DataFlowIR.Node.Call(it, node.arguments ?: emptyList(), node.type, null)) } + node.constructor?.let { block(DataFlowIR.Node.Call(it, node.arguments ?: emptyList(), node.type, null), node) } is DataFlowIR.Node.ArrayRead -> block(DataFlowIR.Node.Call( callee = node.callee, arguments = listOf(node.array, node.index), returnType = node.type, - irCallSite = null) + irCallSite = null), + node ) is DataFlowIR.Node.ArrayWrite -> @@ -126,7 +127,8 @@ internal class CallGraphBuilder( callee = node.callee, arguments = listOf(node.array, node.index, node.value), returnType = moduleDFG.symbolTable.mapType(context.irBuiltIns.unitType), - irCallSite = null) + irCallSite = null), + node ) is DataFlowIR.Node.FunctionReference -> @@ -134,16 +136,17 @@ internal class CallGraphBuilder( callee = node.symbol, arguments = emptyList(), returnType = node.symbol.returnParameter.type, - irCallSite = null - )) + irCallSite = null), + node + ) else -> { } } } - private fun staticCall(caller: DataFlowIR.FunctionSymbol.Declared, call: DataFlowIR.Node.Call, callee: DataFlowIR.FunctionSymbol) { + private fun staticCall(caller: DataFlowIR.FunctionSymbol.Declared, call: DataFlowIR.Node.Call, node: DataFlowIR.Node, callee: DataFlowIR.FunctionSymbol) { val resolvedCallee = callee.resolved() - val callSite = CallGraphNode.CallSite(call, false, resolvedCallee) + val callSite = CallGraphNode.CallSite(call, node, false, resolvedCallee) val function = moduleDFG.functions[resolvedCallee] callGraph.addEdge(caller, callSite) if (function != null) @@ -152,14 +155,14 @@ internal class CallGraphBuilder( private fun handleFunction(symbol: DataFlowIR.FunctionSymbol.Declared, function: DataFlowIR.Function) { val body = function.body - body.forEachCallSite { call -> + body.forEachCallSite { call, node -> val devirtualizedCallSite = (call as? DataFlowIR.Node.VirtualCall)?.let { devirtualizedCallSites[it] } when { - call !is DataFlowIR.Node.VirtualCall -> staticCall(symbol, call, call.callee) + call !is DataFlowIR.Node.VirtualCall -> staticCall(symbol, call, node, call.callee) devirtualizedCallSite != null -> { devirtualizedCallSite.possibleCallees.forEach { - staticCall(symbol, call, it.callee) + staticCall(symbol, call, node, it.callee) } } @@ -189,9 +192,9 @@ internal class CallGraphBuilder( allPossibleCallees.add(actualCallee) } if (allPossibleCallees.size <= nonDevirtualizedCallSitesUnfoldFactor) - allPossibleCallees.forEach { staticCall(symbol, call, it) } + allPossibleCallees.forEach { staticCall(symbol, call, node, it) } else { - val callSite = CallGraphNode.CallSite(call, true, call.callee) + val callSite = CallGraphNode.CallSite(call, node, true, call.callee) callGraph.addEdge(symbol, callSite) allPossibleCallees.forEach { diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/EscapeAnalysis.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/EscapeAnalysis.kt index d47c2168810..720d69bf6bc 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/EscapeAnalysis.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/EscapeAnalysis.kt @@ -29,6 +29,19 @@ private val DataFlowIR.Node.ir else -> null } +private val CallGraphNode.CallSite.arguments: List + get() { + return if (call is DataFlowIR.Node.NewObject) { + (0..call.arguments.size).map { + if (it == 0) node else call.arguments[it - 1].node + } + } else { + (0..call.arguments.size).map { + if (it < call.arguments.size) call.arguments[it].node else node + } + } + } + internal object EscapeAnalysis { /* @@ -991,15 +1004,7 @@ internal object EscapeAnalysis { +calleeEscapeAnalysisResult.toString() } - val arguments = if (call is DataFlowIR.Node.NewObject) { - (0..call.arguments.size).map { - if (it == 0) call else call.arguments[it - 1].node - } - } else { - (0..call.arguments.size).map { - if (it < call.arguments.size) call.arguments[it].node else call - } - } + val arguments = callSite.arguments val calleeDrains = Array(calleeEscapeAnalysisResult.numberOfDrains) { newNode() }