[K/N] Fixed a bug in escape analysis

#KT-59693 Fixed
This commit is contained in:
Igor Chevdar
2023-06-30 12:07:09 +03:00
committed by Space Team
parent 0bbf16dff4
commit 4f859a634e
@@ -1175,10 +1175,10 @@ internal object EscapeAnalysis {
is PointsToGraphEdge.Assignment -> is PointsToGraphEdge.Assignment ->
compressedEdges += CompressedPointsToGraph.Edge(fromCompressedNode, toCompressedNode) compressedEdges += CompressedPointsToGraph.Edge(fromCompressedNode, toCompressedNode)
is PointsToGraphEdge.Field -> is PointsToGraphEdge.Field -> {
if (edge.node == from /* A loop */) { val next = fromCompressedNode.goto(edge.field)
compressedEdges += CompressedPointsToGraph.Edge( if (next != toCompressedNode) // Skip loops.
fromCompressedNode.goto(edge.field), toCompressedNode) compressedEdges += CompressedPointsToGraph.Edge(next, toCompressedNode)
} }
} }
} }
@@ -1768,7 +1768,8 @@ internal object EscapeAnalysis {
nodeIds[drain] = drainFactory() nodeIds[drain] = drainFactory()
} }
var front = nodeIds.keys.toList() var front = nodeIds.keys.toMutableList()
do {
while (front.isNotEmpty()) { while (front.isNotEmpty()) {
val nextFront = mutableListOf<PointsToGraphNode>() val nextFront = mutableListOf<PointsToGraphNode>()
for (node in front) { for (node in front) {
@@ -1778,20 +1779,29 @@ internal object EscapeAnalysis {
val nextNode = edge.node val nextNode = edge.node
if (nextNode.drain in interestingDrains && nextNode != node /* Skip loops */) { if (nextNode.drain in interestingDrains && nextNode != node /* Skip loops */) {
val nextNodeId = nodeId.goto(field) val nextNodeId = nodeId.goto(field)
if (nodeIds[nextNode] != null) if (nodeIds[nextNode] == null) {
error("Expected only one incoming field edge. ${nodeIds[nextNode]} != $nextNodeId")
nodeIds[nextNode] = nextNodeId nodeIds[nextNode] = nextNodeId
if (nextNode.isDrain) if (nextNode.isDrain)
nextFront += nextNode nextFront += nextNode
} }
} }
} }
}
front = nextFront front = nextFront
} }
// Find unpainted drain.
for (drain in interestingDrains) { for (drain in interestingDrains) {
if (nodeIds[drain] == null && drain.edges.any { it.node.drain in interestingDrains }) if (nodeIds[drain] == null
error("Drains have not been painted properly") // A little optimization - skip leaf drains.
&& drain.edges.any { it.node.drain in interestingDrains }
) {
nodeIds[drain] = drainFactory()
front += drain
break
} }
}
} while (front.isNotEmpty()) // Loop until all drains have been painted.
return nodeIds return nodeIds
} }