[K/N] Fixed a bug in escape analysis
#KT-59693 Fixed
This commit is contained in:
+36
-26
@@ -1175,11 +1175,11 @@ 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,30 +1768,40 @@ internal object EscapeAnalysis {
|
|||||||
nodeIds[drain] = drainFactory()
|
nodeIds[drain] = drainFactory()
|
||||||
}
|
}
|
||||||
|
|
||||||
var front = nodeIds.keys.toList()
|
var front = nodeIds.keys.toMutableList()
|
||||||
while (front.isNotEmpty()) {
|
do {
|
||||||
val nextFront = mutableListOf<PointsToGraphNode>()
|
while (front.isNotEmpty()) {
|
||||||
for (node in front) {
|
val nextFront = mutableListOf<PointsToGraphNode>()
|
||||||
val nodeId = nodeIds[node]!!
|
for (node in front) {
|
||||||
node.edges.filterIsInstance<PointsToGraphEdge.Field>().forEach { edge ->
|
val nodeId = nodeIds[node]!!
|
||||||
val field = edge.field
|
node.edges.filterIsInstance<PointsToGraphEdge.Field>().forEach { edge ->
|
||||||
val nextNode = edge.node
|
val field = edge.field
|
||||||
if (nextNode.drain in interestingDrains && nextNode != node /* Skip loops */) {
|
val nextNode = edge.node
|
||||||
val nextNodeId = nodeId.goto(field)
|
if (nextNode.drain in interestingDrains && nextNode != node /* Skip loops */) {
|
||||||
if (nodeIds[nextNode] != null)
|
val nextNodeId = nodeId.goto(field)
|
||||||
error("Expected only one incoming field edge. ${nodeIds[nextNode]} != $nextNodeId")
|
if (nodeIds[nextNode] == null) {
|
||||||
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
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user