[FIR] Rename edge kinds of control flow graph

This commit is contained in:
Dmitriy Novozhilov
2020-06-19 13:14:11 +03:00
parent f0cc3a32d9
commit 1dfccf1416
5 changed files with 46 additions and 46 deletions
@@ -29,17 +29,17 @@ sealed class CFGNode<out E : FirElement>(val owner: ControlFlowGraph, val level:
} }
private fun addJustKindEdge(from: CFGNode<*>, to: CFGNode<*>, kind: EdgeKind, propagateDeadness: Boolean, edgeExists: Boolean) { private fun addJustKindEdge(from: CFGNode<*>, to: CFGNode<*>, kind: EdgeKind, propagateDeadness: Boolean, edgeExists: Boolean) {
if (kind != EdgeKind.Simple) { if (kind != EdgeKind.Forward) {
val fromToKind = from._outgoingEdges[to] ?: runIf(edgeExists) { EdgeKind.Simple } val fromToKind = from._outgoingEdges[to] ?: runIf(edgeExists) { EdgeKind.Forward }
merge(kind, fromToKind)?.let { merge(kind, fromToKind)?.let {
from._outgoingEdges[to] = it from._outgoingEdges[to] = it
} ?: from._outgoingEdges.remove(to) } ?: from._outgoingEdges.remove(to)
val toFromKind = to._incomingEdges[from] ?: runIf(edgeExists) { EdgeKind.Simple } val toFromKind = to._incomingEdges[from] ?: runIf(edgeExists) { EdgeKind.Forward }
merge(kind, toFromKind)?.let { merge(kind, toFromKind)?.let {
to._incomingEdges[from] = it to._incomingEdges[from] = it
} ?: to._incomingEdges.remove(from) } ?: to._incomingEdges.remove(from)
} }
if (propagateDeadness && kind == EdgeKind.Dead) { if (propagateDeadness && kind == EdgeKind.DeadForward) {
to.isDead = true to.isDead = true
} }
} }
@@ -48,9 +48,9 @@ sealed class CFGNode<out E : FirElement>(val owner: ControlFlowGraph, val level:
return when { return when {
second == null -> first second == null -> first
first == second -> first first == second -> first
first == EdgeKind.Dead || second == EdgeKind.Dead -> EdgeKind.Dead first == EdgeKind.DeadForward || second == EdgeKind.DeadForward -> EdgeKind.DeadForward
first == EdgeKind.DeadBack || second == EdgeKind.DeadBack -> EdgeKind.DeadBack first == EdgeKind.DeadBackward || second == EdgeKind.DeadBackward -> EdgeKind.DeadBackward
first == EdgeKind.Simple || second == EdgeKind.Simple -> null first == EdgeKind.Forward || second == EdgeKind.Forward -> null
first.usedInDfa xor second.usedInDfa -> null first.usedInDfa xor second.usedInDfa -> null
else -> throw IllegalStateException() else -> throw IllegalStateException()
} }
@@ -86,8 +86,8 @@ sealed class CFGNode<out E : FirElement>(val owner: ControlFlowGraph, val level:
val previousNodes: List<CFGNode<*>> get() = _previousNodes val previousNodes: List<CFGNode<*>> get() = _previousNodes
val followingNodes: List<CFGNode<*>> get() = _followingNodes val followingNodes: List<CFGNode<*>> get() = _followingNodes
private val _incomingEdges = mutableMapOf<CFGNode<*>, EdgeKind>().withDefault { EdgeKind.Simple } private val _incomingEdges = mutableMapOf<CFGNode<*>, EdgeKind>().withDefault { EdgeKind.Forward }
private val _outgoingEdges = mutableMapOf<CFGNode<*>, EdgeKind>().withDefault { EdgeKind.Simple } private val _outgoingEdges = mutableMapOf<CFGNode<*>, EdgeKind>().withDefault { EdgeKind.Forward }
val incomingEdges: Map<CFGNode<*>, EdgeKind> get() = _incomingEdges val incomingEdges: Map<CFGNode<*>, EdgeKind> get() = _incomingEdges
val outgoingEdges: Map<CFGNode<*>, EdgeKind> get() = _outgoingEdges val outgoingEdges: Map<CFGNode<*>, EdgeKind> get() = _outgoingEdges
@@ -97,7 +97,7 @@ sealed class CFGNode<out E : FirElement>(val owner: ControlFlowGraph, val level:
protected set protected set
internal fun updateDeadStatus() { internal fun updateDeadStatus() {
isDead = incomingEdges.size == previousNodes.size && incomingEdges.values.all { it == EdgeKind.Dead } isDead = incomingEdges.size == previousNodes.size && incomingEdges.values.all { it == EdgeKind.DeadForward }
} }
abstract fun <R, D> accept(visitor: ControlFlowGraphVisitor<R, D>, data: D): R abstract fun <R, D> accept(visitor: ControlFlowGraphVisitor<R, D>, data: D): R
@@ -91,12 +91,12 @@ enum class EdgeKind(
val isBack: Boolean, val isBack: Boolean,
val isDead: Boolean val isDead: Boolean
) { ) {
Simple(usedInDfa = true, usedInCfa = true, isBack = false, isDead = false), Forward(usedInDfa = true, usedInCfa = true, isBack = false, isDead = false),
Dead(usedInDfa = false, usedInCfa = true, isBack = false, isDead = true), DeadForward(usedInDfa = false, usedInCfa = true, isBack = false, isDead = true),
Cfg(usedInDfa = false, usedInCfa = true, isBack = false, isDead = false), DfgForward(usedInDfa = true, usedInCfa = false, isBack = false, isDead = false),
Dfg(usedInDfa = true, usedInCfa = false, isBack = false, isDead = false), CfgForward(usedInDfa = false, usedInCfa = true, isBack = false, isDead = false),
Back(usedInDfa = false, usedInCfa = true, isBack = true, isDead = false), CfgBackward(usedInDfa = false, usedInCfa = true, isBack = true, isDead = false),
DeadBack(usedInDfa = false, usedInCfa = true, isBack = true, isDead = true) DeadBackward(usedInDfa = false, usedInCfa = true, isBack = true, isDead = true)
} }
@OptIn(ExperimentalStdlibApi::class) @OptIn(ExperimentalStdlibApi::class)
@@ -166,7 +166,7 @@ class ControlFlowGraphBuilder {
} }
if (previousNode != null) { if (previousNode != null) {
addEdge(previousNode, enterNode, preferredKind = EdgeKind.Dfg) addEdge(previousNode, enterNode, preferredKind = EdgeKind.DfgForward)
} }
createFunctionExitNode(function).also { createFunctionExitNode(function).also {
@@ -200,8 +200,8 @@ class ControlFlowGraphBuilder {
entersToPostponedAnonymousFunctions[symbol] = enterNode entersToPostponedAnonymousFunctions[symbol] = enterNode
exitsFromPostponedAnonymousFunctions[symbol] = exitNode exitsFromPostponedAnonymousFunctions[symbol] = exitNode
parentGraphForAnonymousFunctions[symbol] = currentGraph parentGraphForAnonymousFunctions[symbol] = currentGraph
popAndAddEdge(enterNode, preferredKind = EdgeKind.Simple) popAndAddEdge(enterNode, preferredKind = EdgeKind.Forward)
addEdge(enterNode, exitNode, preferredKind = EdgeKind.Dfg) addEdge(enterNode, exitNode, preferredKind = EdgeKind.DfgForward)
lastNodes.push(exitNode) lastNodes.push(exitNode)
return enterNode to exitNode return enterNode to exitNode
} }
@@ -295,9 +295,9 @@ class ControlFlowGraphBuilder {
val invocationKind = anonymousFunction.invocationKind val invocationKind = anonymousFunction.invocationKind
if (invocationKind != null) { if (invocationKind != null) {
addEdge(exitNode, postponedExitNode, preferredKind = EdgeKind.Cfg) addEdge(exitNode, postponedExitNode, preferredKind = EdgeKind.CfgForward)
} else { } else {
val kind = if (postponedExitNode.isDead) EdgeKind.Dead else EdgeKind.Cfg val kind = if (postponedExitNode.isDead) EdgeKind.DeadForward else EdgeKind.CfgForward
CFGNode.addJustKindEdge(postponedEnterNode, postponedExitNode, kind, propagateDeadness = true) CFGNode.addJustKindEdge(postponedEnterNode, postponedExitNode, kind, propagateDeadness = true)
} }
@@ -345,11 +345,11 @@ class ControlFlowGraphBuilder {
is FirAnonymousInitializer -> declaration.controlFlowGraphReference.controlFlowGraph is FirAnonymousInitializer -> declaration.controlFlowGraphReference.controlFlowGraph
else -> null else -> null
} ?: continue } ?: continue
addEdge(node, graph.enterNode, preferredKind = EdgeKind.Cfg) addEdge(node, graph.enterNode, preferredKind = EdgeKind.CfgForward)
node = graph.exitNode node = graph.exitNode
classGraph.addSubGraph(graph) classGraph.addSubGraph(graph)
} }
addEdge(node, exitNode, preferredKind = EdgeKind.Cfg) addEdge(node, exitNode, preferredKind = EdgeKind.CfgForward)
return popGraph() return popGraph()
} }
@@ -442,7 +442,7 @@ class ControlFlowGraphBuilder {
exitTargetsForTry.push(exitNode) exitTargetsForTry.push(exitNode)
enterToLocalClassesMembers[property.symbol]?.let { enterToLocalClassesMembers[property.symbol]?.let {
addEdge(it, enterNode, preferredKind = EdgeKind.Dfg) addEdge(it, enterNode, preferredKind = EdgeKind.DfgForward)
} }
lastNodes.push(enterNode) lastNodes.push(enterNode)
@@ -873,10 +873,10 @@ class ControlFlowGraphBuilder {
node: CFGNode<*>, node: CFGNode<*>,
callCompleted: Boolean callCompleted: Boolean
): Pair<EdgeKind, UnionFunctionCallArgumentsNode?> { ): Pair<EdgeKind, UnionFunctionCallArgumentsNode?> {
if (!shouldPassFlowFromInplaceLambda.top()) return EdgeKind.Simple to null if (!shouldPassFlowFromInplaceLambda.top()) return EdgeKind.Forward to null
var kind = EdgeKind.Simple var kind = EdgeKind.Forward
if (!callCompleted || exitsFromCompletedPostponedAnonymousFunctions.isEmpty()) { if (!callCompleted || exitsFromCompletedPostponedAnonymousFunctions.isEmpty()) {
return EdgeKind.Simple to null return EdgeKind.Forward to null
} }
val unionNode by lazy { createUnionFunctionCallArgumentsNode(node.fir) } val unionNode by lazy { createUnionFunctionCallArgumentsNode(node.fir) }
var hasDirectPreviousNode = false var hasDirectPreviousNode = false
@@ -889,11 +889,11 @@ class ControlFlowGraphBuilder {
if (node.level >= exitNode.level) continue if (node.level >= exitNode.level) continue
hasPostponedLambdas = true hasPostponedLambdas = true
if (exitNode == lastPostponedLambdaExitNode) { if (exitNode == lastPostponedLambdaExitNode) {
popAndAddEdge(node, preferredKind = EdgeKind.Cfg) popAndAddEdge(node, preferredKind = EdgeKind.CfgForward)
kind = EdgeKind.Dfg kind = EdgeKind.DfgForward
hasDirectPreviousNode = true hasDirectPreviousNode = true
} }
addEdge(exitNode.lastPreviousNode, unionNode, preferredKind = EdgeKind.Dfg) addEdge(exitNode.lastPreviousNode, unionNode, preferredKind = EdgeKind.DfgForward)
iterator.remove() iterator.remove()
} }
if (hasPostponedLambdas) { if (hasPostponedLambdas) {
@@ -903,7 +903,7 @@ class ControlFlowGraphBuilder {
addNewSimpleNode(unionNode) addNewSimpleNode(unionNode)
} }
} else { } else {
return EdgeKind.Simple to null return EdgeKind.Forward to null
} }
return Pair(kind, unionNode) return Pair(kind, unionNode)
} }
@@ -937,7 +937,7 @@ class ControlFlowGraphBuilder {
lastNodes.push(it) lastNodes.push(it)
} }
val lastNode = runIf(lastNode is InitBlockExitNode) { lastNodes.pop() } ?: enterToLocalClassesMembers[initBlock.symbol] val lastNode = runIf(lastNode is InitBlockExitNode) { lastNodes.pop() } ?: enterToLocalClassesMembers[initBlock.symbol]
lastNode?.let { addEdge(it, enterNode, preferredKind = EdgeKind.Dfg) } lastNode?.let { addEdge(it, enterNode, preferredKind = EdgeKind.DfgForward) }
createInitBlockExitNode(initBlock).also { createInitBlockExitNode(initBlock).also {
initBlockExitNodes.push(it) initBlockExitNodes.push(it)
@@ -1042,7 +1042,7 @@ class ControlFlowGraphBuilder {
private fun addNewSimpleNode( private fun addNewSimpleNode(
node: CFGNode<*>, node: CFGNode<*>,
isDead: Boolean = false, isDead: Boolean = false,
preferredKind: EdgeKind = EdgeKind.Simple preferredKind: EdgeKind = EdgeKind.Forward
): CFGNode<*> { ): CFGNode<*> {
val lastNode = lastNodes.pop() val lastNode = lastNodes.pop()
addEdge(lastNode, node, isDead = isDead, preferredKind = preferredKind) addEdge(lastNode, node, isDead = isDead, preferredKind = preferredKind)
@@ -1050,7 +1050,7 @@ class ControlFlowGraphBuilder {
return lastNode return lastNode
} }
private fun addNodeThatReturnsNothing(node: CFGNode<*>, preferredKind: EdgeKind = EdgeKind.Simple) { private fun addNodeThatReturnsNothing(node: CFGNode<*>, preferredKind: EdgeKind = EdgeKind.Forward) {
val exitNode: CFGNode<*> = exitTargetsForTry.top() val exitNode: CFGNode<*> = exitTargetsForTry.top()
addNodeWithJump(node, exitNode, preferredKind) addNodeWithJump(node, exitNode, preferredKind)
} }
@@ -1058,7 +1058,7 @@ class ControlFlowGraphBuilder {
private fun addNodeWithJump( private fun addNodeWithJump(
node: CFGNode<*>, node: CFGNode<*>,
targetNode: CFGNode<*>?, targetNode: CFGNode<*>?,
preferredKind: EdgeKind = EdgeKind.Simple, preferredKind: EdgeKind = EdgeKind.Forward,
isBack: Boolean = false isBack: Boolean = false
) { ) {
popAndAddEdge(node, preferredKind) popAndAddEdge(node, preferredKind)
@@ -1074,7 +1074,7 @@ class ControlFlowGraphBuilder {
lastNodes.push(stub) lastNodes.push(stub)
} }
private fun popAndAddEdge(to: CFGNode<*>, preferredKind: EdgeKind = EdgeKind.Simple) { private fun popAndAddEdge(to: CFGNode<*>, preferredKind: EdgeKind = EdgeKind.Forward) {
addEdge(lastNodes.pop(), to, preferredKind = preferredKind) addEdge(lastNodes.pop(), to, preferredKind = preferredKind)
} }
@@ -1084,10 +1084,10 @@ class ControlFlowGraphBuilder {
propagateDeadness: Boolean = true, propagateDeadness: Boolean = true,
isDead: Boolean = false, isDead: Boolean = false,
isBack: Boolean = false, isBack: Boolean = false,
preferredKind: EdgeKind = EdgeKind.Simple preferredKind: EdgeKind = EdgeKind.Forward
) { ) {
val kind = if (isDead || from.isDead || to.isDead) { val kind = if (isDead || from.isDead || to.isDead) {
if (isBack) EdgeKind.DeadBack else EdgeKind.Dead if (isBack) EdgeKind.DeadBackward else EdgeKind.DeadForward
} else preferredKind } else preferredKind
CFGNode.addEdge(from, to, kind, propagateDeadness) CFGNode.addEdge(from, to, kind, propagateDeadness)
} }
@@ -1097,7 +1097,7 @@ class ControlFlowGraphBuilder {
to: CFGNode<*>, to: CFGNode<*>,
isDead: Boolean = false isDead: Boolean = false
) { ) {
addEdge(from, to, propagateDeadness = false, isDead = isDead, isBack = true, preferredKind = EdgeKind.Back) addEdge(from, to, propagateDeadness = false, isDead = isDead, isBack = true, preferredKind = EdgeKind.CfgBackward)
} }
// ----------------------------------- Utils ----------------------------------- // ----------------------------------- Utils -----------------------------------
@@ -26,12 +26,12 @@ class FirControlFlowGraphRenderVisitor(
private val EDGE_STYLE = EnumMap( private val EDGE_STYLE = EnumMap(
mapOf( mapOf(
EdgeKind.Simple to "", EdgeKind.Forward to "",
EdgeKind.Dead to "[style=dotted]", EdgeKind.DeadForward to "[style=dotted]",
EdgeKind.Cfg to "[color=green]", EdgeKind.CfgForward to "[color=green]",
EdgeKind.Dfg to "[color=red]", EdgeKind.DfgForward to "[color=red]",
EdgeKind.Back to "[color=green style=dashed]", EdgeKind.CfgBackward to "[color=green style=dashed]",
EdgeKind.DeadBack to "[color=green style=dotted]" EdgeKind.DeadBackward to "[color=green style=dotted]"
) )
) )
} }
@@ -310,7 +310,7 @@ abstract class AbstractFirDiagnosticsTest : AbstractFirBaseDiagnosticsTest() {
} }
} }
private val cfgKinds = listOf(EdgeKind.Dead, EdgeKind.Cfg, EdgeKind.DeadBack, EdgeKind.Back) private val cfgKinds = listOf(EdgeKind.DeadForward, EdgeKind.CfgForward, EdgeKind.DeadBackward, EdgeKind.CfgBackward)
private fun checkEdge(from: CFGNode<*>, to: CFGNode<*>) { private fun checkEdge(from: CFGNode<*>, to: CFGNode<*>) {
KtUsefulTestCase.assertContainsElements(from.followingNodes, to) KtUsefulTestCase.assertContainsElements(from.followingNodes, to)