From 41f241f6087df719a96fb315683e493745b03394 Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Tue, 12 May 2020 19:11:29 +0300 Subject: [PATCH] FIR CFG: merge DFA + CFA edge in Simple edge --- .../resolve/cfg/flowFromInplaceLambda.dot | 6 +++--- .../resolve/cfg/lambdaAsReturnOfLambda.dot | 2 +- .../resolve/cfg/lambdaReturningObject.dot | 2 +- .../cfg/postponedLambdaInConstructor.dot | 2 +- .../smartcasts/controlStructures/returns.dot | 2 +- .../resolve/smartcasts/safeCalls/safeCalls.dot | 2 +- .../contracts/fromLibrary/callsInPlace.dot | 2 +- .../delegates/delegateWithAnonymousObject.dot | 4 ++-- .../smartcasts/tryWithLambdaInside.dot | 2 +- .../fir/resolve/dfa/cfg/ControlFlowGraph.kt | 17 +++++++++++++++-- 10 files changed, 27 insertions(+), 14 deletions(-) diff --git a/compiler/fir/analysis-tests/testData/resolve/cfg/flowFromInplaceLambda.dot b/compiler/fir/analysis-tests/testData/resolve/cfg/flowFromInplaceLambda.dot index 83b3f5d8d4c..dcc0022e39c 100644 --- a/compiler/fir/analysis-tests/testData/resolve/cfg/flowFromInplaceLambda.dot +++ b/compiler/fir/analysis-tests/testData/resolve/cfg/flowFromInplaceLambda.dot @@ -310,14 +310,14 @@ digraph flowFromInplaceLambda_kt { 106 [label="Exit function test_4" style="filled" fillcolor=red]; } 105 -> {107}; - 107 -> {108} [color=green]; + 107 -> {108}; 107 -> {126} [color=red]; 108 -> {109}; 109 -> {110}; 110 -> {111}; 111 -> {112}; 112 -> {113}; - 113 -> {114} [color=green]; + 113 -> {114}; 113 -> {132} [color=red]; 114 -> {115}; 115 -> {116}; @@ -419,7 +419,7 @@ digraph flowFromInplaceLambda_kt { 159 [label="Exit function test_6" style="filled" fillcolor=red]; } 158 -> {160}; - 160 -> {161} [color=green]; + 160 -> {161}; 160 -> {165} [color=red]; 161 -> {162}; 162 -> {163}; diff --git a/compiler/fir/analysis-tests/testData/resolve/cfg/lambdaAsReturnOfLambda.dot b/compiler/fir/analysis-tests/testData/resolve/cfg/lambdaAsReturnOfLambda.dot index 36e64fd6475..a71167b4cd1 100644 --- a/compiler/fir/analysis-tests/testData/resolve/cfg/lambdaAsReturnOfLambda.dot +++ b/compiler/fir/analysis-tests/testData/resolve/cfg/lambdaAsReturnOfLambda.dot @@ -39,7 +39,7 @@ digraph lambdaAsReturnOfLambda_kt { 11 [label="Exit property" style="filled" fillcolor=red]; } 10 -> {12}; - 12 -> {13} [color=green]; + 12 -> {13}; 12 -> {0} [color=red]; 13 -> {14}; 14 -> {15}; diff --git a/compiler/fir/analysis-tests/testData/resolve/cfg/lambdaReturningObject.dot b/compiler/fir/analysis-tests/testData/resolve/cfg/lambdaReturningObject.dot index f0ad9384f47..55520d65a8e 100644 --- a/compiler/fir/analysis-tests/testData/resolve/cfg/lambdaReturningObject.dot +++ b/compiler/fir/analysis-tests/testData/resolve/cfg/lambdaReturningObject.dot @@ -72,7 +72,7 @@ digraph lambdaReturningObject_kt { 18 [label="Exit function foo" style="filled" fillcolor=red]; } 17 -> {19}; - 19 -> {20} [color=green]; + 19 -> {20}; 19 -> {23} [color=red]; 20 -> {21}; 21 -> {22}; diff --git a/compiler/fir/analysis-tests/testData/resolve/cfg/postponedLambdaInConstructor.dot b/compiler/fir/analysis-tests/testData/resolve/cfg/postponedLambdaInConstructor.dot index 544bad0a291..c9230fcef5a 100644 --- a/compiler/fir/analysis-tests/testData/resolve/cfg/postponedLambdaInConstructor.dot +++ b/compiler/fir/analysis-tests/testData/resolve/cfg/postponedLambdaInConstructor.dot @@ -54,7 +54,7 @@ digraph postponedLambdaInConstructor_kt { 13 -> {15}; 14 -> {9} [color=green]; 14 -> {12} [color=red]; - 15 -> {16} [color=green]; + 15 -> {16}; 15 -> {17} [color=red]; 16 -> {14}; 17 -> {19}; diff --git a/compiler/fir/analysis-tests/testData/resolve/smartcasts/controlStructures/returns.dot b/compiler/fir/analysis-tests/testData/resolve/smartcasts/controlStructures/returns.dot index 401ed014921..4f3aaf03265 100644 --- a/compiler/fir/analysis-tests/testData/resolve/smartcasts/controlStructures/returns.dot +++ b/compiler/fir/analysis-tests/testData/resolve/smartcasts/controlStructures/returns.dot @@ -477,7 +477,7 @@ digraph returns_kt { 166 -> {167}; 167 -> {145}; 168 -> {169}; - 169 -> {170} [color=green]; + 169 -> {170}; 169 -> {172} [color=red]; 170 -> {171}; 171 -> {140}; diff --git a/compiler/fir/analysis-tests/testData/resolve/smartcasts/safeCalls/safeCalls.dot b/compiler/fir/analysis-tests/testData/resolve/smartcasts/safeCalls/safeCalls.dot index 9a8d35dfd78..8a3a1e6a8bd 100644 --- a/compiler/fir/analysis-tests/testData/resolve/smartcasts/safeCalls/safeCalls.dot +++ b/compiler/fir/analysis-tests/testData/resolve/smartcasts/safeCalls/safeCalls.dot @@ -142,7 +142,7 @@ digraph safeCalls_kt { 47 -> {44}; 48 -> {50}; 49 -> {53}; - 50 -> {51} [color=green]; + 50 -> {51}; 50 -> {55} [color=red]; 51 -> {52}; 52 -> {49}; diff --git a/compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromLibrary/callsInPlace.dot b/compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromLibrary/callsInPlace.dot index ba0d4462ca9..7ca780fcfd7 100644 --- a/compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromLibrary/callsInPlace.dot +++ b/compiler/fir/analysis-tests/testData/resolveWithStdlib/contracts/fromLibrary/callsInPlace.dot @@ -274,7 +274,7 @@ digraph callsInPlace_kt { 93 [label="Exit function test_8" style="filled" fillcolor=red]; } 92 -> {94}; - 94 -> {95} [color=green]; + 94 -> {95}; 94 -> {97} [color=red]; 95 -> {96}; 96 -> {93}; diff --git a/compiler/fir/analysis-tests/testData/resolveWithStdlib/delegates/delegateWithAnonymousObject.dot b/compiler/fir/analysis-tests/testData/resolveWithStdlib/delegates/delegateWithAnonymousObject.dot index 45194163c95..79d5c503af9 100644 --- a/compiler/fir/analysis-tests/testData/resolveWithStdlib/delegates/delegateWithAnonymousObject.dot +++ b/compiler/fir/analysis-tests/testData/resolveWithStdlib/delegates/delegateWithAnonymousObject.dot @@ -163,14 +163,14 @@ digraph delegateWithAnonymousObject_kt { 66 -> {54} [color=green]; 54 -> {56}; 55 -> {67} [color=green]; - 56 -> {57} [color=green]; + 56 -> {57}; 57 -> {58}; 58 -> {59}; 59 -> {60}; 60 -> {61}; 61 -> {62}; 62 -> {63}; - 63 -> {64} [color=green]; + 63 -> {64}; 63 -> {21} [color=red]; 64 -> {65}; 65 -> {55}; diff --git a/compiler/fir/analysis-tests/testData/resolveWithStdlib/smartcasts/tryWithLambdaInside.dot b/compiler/fir/analysis-tests/testData/resolveWithStdlib/smartcasts/tryWithLambdaInside.dot index a9cac38b413..2b8b9d11c4b 100644 --- a/compiler/fir/analysis-tests/testData/resolveWithStdlib/smartcasts/tryWithLambdaInside.dot +++ b/compiler/fir/analysis-tests/testData/resolveWithStdlib/smartcasts/tryWithLambdaInside.dot @@ -155,7 +155,7 @@ finally { 33 -> {41}; 34 -> {35}; 35 -> {36}; - 36 -> {37} [color=green]; + 36 -> {37}; 36 -> {46} [color=red]; 37 -> {38}; 38 -> {39}; diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraph.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraph.kt index 6f80ad405fd..0cc07821694 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraph.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraph.kt @@ -71,10 +71,23 @@ sealed class CFGNode(val owner: ControlFlowGraph, val level: addJustKindEdge(from, to, kind, propagateDeadness) } + private fun merge(first: EdgeKind, second: EdgeKind?): EdgeKind? { + return when (first) { + second -> first + EdgeKind.Cfg -> if (second == EdgeKind.Dfg) null else first + EdgeKind.Dfg -> if (second == EdgeKind.Cfg) null else first + else -> first + } + } + internal fun addJustKindEdge(from: CFGNode<*>, to: CFGNode<*>, kind: EdgeKind, propagateDeadness: Boolean) { if (kind != EdgeKind.Simple) { - from._outgoingEdges[to] = kind - to._incomingEdges[from] = kind + merge(kind, from._outgoingEdges[to])?.let { + from._outgoingEdges[to] = it + } ?: from._outgoingEdges.remove(to) + merge(kind, to._incomingEdges[from])?.let { + to._incomingEdges[from] = it + } ?: to._incomingEdges.remove(from) } if (propagateDeadness && kind == EdgeKind.Dead) { to.isDead = true