[K/N] Refactor devirtualization graph build to avoid too deep recursion
^KT-52386
This commit is contained in:
+21
-14
@@ -644,7 +644,7 @@ internal object DevirtualizationAnalysis {
|
|||||||
|
|
||||||
context.logMultiple {
|
context.logMultiple {
|
||||||
+"Devirtualized from current module:"
|
+"Devirtualized from current module:"
|
||||||
result.forEach { virtualCall, devirtualizedCallSite ->
|
result.forEach { (virtualCall, devirtualizedCallSite) ->
|
||||||
if (virtualCall.irCallSite != null) {
|
if (virtualCall.irCallSite != null) {
|
||||||
+"DEVIRTUALIZED"
|
+"DEVIRTUALIZED"
|
||||||
+"FUNCTION: ${devirtualizedCallSite.second}"
|
+"FUNCTION: ${devirtualizedCallSite.second}"
|
||||||
@@ -656,7 +656,7 @@ internal object DevirtualizationAnalysis {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
+"Devirtualized from external modules:"
|
+"Devirtualized from external modules:"
|
||||||
result.forEach { virtualCall, devirtualizedCallSite ->
|
result.forEach { (virtualCall, devirtualizedCallSite) ->
|
||||||
if (virtualCall.irCallSite == null) {
|
if (virtualCall.irCallSite == null) {
|
||||||
+"DEVIRTUALIZED"
|
+"DEVIRTUALIZED"
|
||||||
+"FUNCTION: ${devirtualizedCallSite.second}"
|
+"FUNCTION: ${devirtualizedCallSite.second}"
|
||||||
@@ -896,7 +896,12 @@ internal object DevirtualizationAnalysis {
|
|||||||
val body = function.body
|
val body = function.body
|
||||||
val functionConstraintGraph = constraintGraph.functions[symbol]!!
|
val functionConstraintGraph = constraintGraph.functions[symbol]!!
|
||||||
|
|
||||||
body.forEachNonScopeNode { dfgNodeToConstraintNode(functionConstraintGraph, it) }
|
body.forEachNonScopeNode {
|
||||||
|
val node = dfgNodeToConstraintNode(functionConstraintGraph, it)
|
||||||
|
if (it is DataFlowIR.Node.Variable) {
|
||||||
|
generateVariableEdges(functionConstraintGraph, it, node)
|
||||||
|
}
|
||||||
|
}
|
||||||
addEdge(functionNodesMap[body.returns]!!, functionConstraintGraph.returns)
|
addEdge(functionNodesMap[body.returns]!!, functionConstraintGraph.returns)
|
||||||
addEdge(functionNodesMap[body.throws]!!, functionConstraintGraph.throws)
|
addEdge(functionNodesMap[body.throws]!!, functionConstraintGraph.throws)
|
||||||
|
|
||||||
@@ -1077,9 +1082,19 @@ internal object DevirtualizationAnalysis {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun generateVariableEdges(function: Function, node: DataFlowIR.Node.Variable, variableNode: Node) {
|
||||||
|
for (value in node.values) {
|
||||||
|
addEdge(edgeToConstraintNode(function, value), variableNode)
|
||||||
|
}
|
||||||
|
if (node.kind == DataFlowIR.VariableKind.CatchParameter)
|
||||||
|
function.throws.addCastEdge(createCastEdge(variableNode, node.type.resolved()))
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Takes a function DFG's node and creates a constraint graph node corresponding to it.
|
* Takes a function DFG's node and creates a constraint graph node corresponding to it.
|
||||||
* Also creates all necessary edges.
|
* Also creates all necessary edges, except for variable nodes.
|
||||||
|
* For variable nodes edges must be created separately, otherwise recursion can be too deep.
|
||||||
*/
|
*/
|
||||||
private fun dfgNodeToConstraintNode(function: Function, node: DataFlowIR.Node): Node {
|
private fun dfgNodeToConstraintNode(function: Function, node: DataFlowIR.Node): Node {
|
||||||
|
|
||||||
@@ -1102,17 +1117,9 @@ internal object DevirtualizationAnalysis {
|
|||||||
fun writeField(field: DataFlowIR.Field, value: Node) = addEdge(value, fieldNode(field))
|
fun writeField(field: DataFlowIR.Field, value: Node) = addEdge(value, fieldNode(field))
|
||||||
|
|
||||||
if (node is DataFlowIR.Node.Variable && node.kind != DataFlowIR.VariableKind.Temporary) {
|
if (node is DataFlowIR.Node.Variable && node.kind != DataFlowIR.VariableKind.Temporary) {
|
||||||
var variableNode = variables[node]
|
return variables.getOrPut(node) {
|
||||||
if (variableNode == null) {
|
ordinaryNode { "Variable\$${function.symbol}" }
|
||||||
variableNode = ordinaryNode { "Variable\$${function.symbol}" }
|
|
||||||
variables[node] = variableNode
|
|
||||||
for (value in node.values) {
|
|
||||||
addEdge(edgeToConstraintNode(value), variableNode)
|
|
||||||
}
|
|
||||||
if (node.kind == DataFlowIR.VariableKind.CatchParameter)
|
|
||||||
function.throws.addCastEdge(createCastEdge(variableNode, node.type.resolved()))
|
|
||||||
}
|
}
|
||||||
return variableNode
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return functionNodesMap.getOrPut(node) {
|
return functionNodesMap.getOrPut(node) {
|
||||||
|
|||||||
Reference in New Issue
Block a user