[K/N] Fixed a corner case in escape analysis
#KT-61409 Fixed
This commit is contained in:
+21
-16
@@ -1353,7 +1353,7 @@ internal object EscapeAnalysis {
|
|||||||
// (picking a leaf drain with only one incoming edge at a time).
|
// (picking a leaf drain with only one incoming edge at a time).
|
||||||
// They can be removed because they don't add any relations between the parameters.
|
// They can be removed because they don't add any relations between the parameters.
|
||||||
val reversedEdges = interestingDrains.associateWith {
|
val reversedEdges = interestingDrains.associateWith {
|
||||||
mutableListOf<Pair<PointsToGraphNode, PointsToGraphEdge>>()
|
mutableListOf<PointsToGraphNode>()
|
||||||
}
|
}
|
||||||
val edgesCount = mutableMapOf<PointsToGraphNode, Int>()
|
val edgesCount = mutableMapOf<PointsToGraphNode, Int>()
|
||||||
val leaves = mutableListOf<PointsToGraphNode>()
|
val leaves = mutableListOf<PointsToGraphNode>()
|
||||||
@@ -1361,7 +1361,7 @@ internal object EscapeAnalysis {
|
|||||||
var count = 0
|
var count = 0
|
||||||
for (edge in drain.edges) {
|
for (edge in drain.edges) {
|
||||||
val nextDrain = edge.node.drain
|
val nextDrain = edge.node.drain
|
||||||
reversedEdges[nextDrain]!! += drain to edge
|
reversedEdges[nextDrain]!! += drain
|
||||||
if (nextDrain in interestingDrains)
|
if (nextDrain in interestingDrains)
|
||||||
++count
|
++count
|
||||||
}
|
}
|
||||||
@@ -1383,10 +1383,10 @@ internal object EscapeAnalysis {
|
|||||||
if (drain in parameterDrains)
|
if (drain in parameterDrains)
|
||||||
continue
|
continue
|
||||||
if (incomingEdges.size == 1
|
if (incomingEdges.size == 1
|
||||||
&& incomingEdges[0].let { (node, edge) -> escapes(node) || !escapes(edge.node) }
|
&& (escapes(incomingEdges[0]) || !escapes(drain))
|
||||||
) {
|
) {
|
||||||
interestingDrains.remove(drain)
|
interestingDrains.remove(drain)
|
||||||
val prevDrain = incomingEdges[0].first
|
val prevDrain = incomingEdges[0]
|
||||||
val count = edgesCount[prevDrain]!! - 1
|
val count = edgesCount[prevDrain]!! - 1
|
||||||
edgesCount[prevDrain] = count
|
edgesCount[prevDrain] = count
|
||||||
if (count == 0)
|
if (count == 0)
|
||||||
@@ -1523,19 +1523,24 @@ internal object EscapeAnalysis {
|
|||||||
.filter { nodeIds[it] == null } // Was optimized away.
|
.filter { nodeIds[it] == null } // Was optimized away.
|
||||||
.forEach { drain ->
|
.forEach { drain ->
|
||||||
val referencingNodes = findReferencing(drain).filter { nodeIds[it] != null }
|
val referencingNodes = findReferencing(drain).filter { nodeIds[it] != null }
|
||||||
var needDrain = false
|
if (escapes(drain) && referencingNodes.all { !escapes(it) }) {
|
||||||
outerLoop@ for (i in referencingNodes.indices)
|
|
||||||
for (j in i + 1 until referencingNodes.size) {
|
|
||||||
val firstNode = referencingNodes[i]
|
|
||||||
val secondNode = referencingNodes[j]
|
|
||||||
val pair = Pair(firstNode, secondNode)
|
|
||||||
if (pair !in connectedNodes) {
|
|
||||||
needDrain = true
|
|
||||||
break@outerLoop
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (needDrain)
|
|
||||||
nodeIds[drain] = drainFactory()
|
nodeIds[drain] = drainFactory()
|
||||||
|
escapeOrigins += drain
|
||||||
|
} else {
|
||||||
|
var needDrain = false
|
||||||
|
outerLoop@ for (i in referencingNodes.indices)
|
||||||
|
for (j in i + 1 until referencingNodes.size) {
|
||||||
|
val firstNode = referencingNodes[i]
|
||||||
|
val secondNode = referencingNodes[j]
|
||||||
|
val pair = Pair(firstNode, secondNode)
|
||||||
|
if (pair !in connectedNodes) {
|
||||||
|
needDrain = true
|
||||||
|
break@outerLoop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (needDrain)
|
||||||
|
nodeIds[drain] = drainFactory()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user