[FIR] Add kind for back edges in CFG

This commit is contained in:
Dmitriy Novozhilov
2020-06-04 17:46:12 +03:00
parent 34be9e3569
commit 950bbfe3a5
20 changed files with 84 additions and 63 deletions
@@ -260,7 +260,7 @@ digraph complex_kt {
79 -> {68} [style=dotted]; 79 -> {68} [style=dotted];
80 -> {68}; 80 -> {68};
81 -> {82}; 81 -> {82};
82 -> {58}; 82 -> {58} [color=green style=dashed];
83 -> {84}; 83 -> {84};
84 -> {52}; 84 -> {52};
84 -> {85} [style=dotted]; 84 -> {85} [style=dotted];
+6 -5
View File
@@ -191,7 +191,7 @@ digraph jumps_kt {
63 -> {64} [style=dotted]; 63 -> {64} [style=dotted];
64 -> {65} [style=dotted]; 64 -> {65} [style=dotted];
65 -> {66} [style=dotted]; 65 -> {66} [style=dotted];
66 -> {56} [style=dotted]; 66 -> {56} [color=green style=dotted];
67 -> {68}; 67 -> {68};
68 -> {53}; 68 -> {53};
@@ -241,7 +241,8 @@ digraph jumps_kt {
80 -> {81} [style=dotted]; 80 -> {81} [style=dotted];
81 -> {82} [style=dotted]; 81 -> {82} [style=dotted];
82 -> {83} [style=dotted]; 82 -> {83} [style=dotted];
83 -> {73 72} [style=dotted]; 83 -> {72} [style=dotted];
83 -> {73} [color=green style=dotted];
84 -> {85}; 84 -> {85};
85 -> {70}; 85 -> {70};
@@ -307,14 +308,14 @@ digraph jumps_kt {
99 -> {100 106}; 99 -> {100 106};
100 -> {101}; 100 -> {101};
101 -> {102}; 101 -> {102};
102 -> {88};
102 -> {103} [style=dotted]; 102 -> {103} [style=dotted];
102 -> {88} [color=green style=dashed];
103 -> {104} [style=dotted]; 103 -> {104} [style=dotted];
104 -> {105} [style=dotted]; 104 -> {105} [style=dotted];
105 -> {96} [style=dotted]; 105 -> {96} [style=dotted];
106 -> {96}; 106 -> {96};
107 -> {108}; 107 -> {108};
108 -> {90}; 108 -> {90} [color=green style=dashed];
subgraph cluster_30 { subgraph cluster_30 {
color=red color=red
@@ -346,8 +347,8 @@ digraph jumps_kt {
115 -> {116}; 115 -> {116};
116 -> {113}; 116 -> {113};
117 -> {118 119}; 117 -> {118 119};
118 -> {117};
118 -> {115} [color=green]; 118 -> {115} [color=green];
118 -> {117} [color=green style=dashed];
119 -> {118}; 119 -> {118};
119 -> {120} [style=dotted]; 119 -> {120} [style=dotted];
120 -> {118} [style=dotted]; 120 -> {118} [style=dotted];
@@ -64,8 +64,8 @@ digraph lambdas_kt {
17 -> {6}; 17 -> {6};
18 -> {6}; 18 -> {6};
19 -> {20 21}; 19 -> {20 21};
20 -> {19};
20 -> {14} [color=green]; 20 -> {14} [color=green];
20 -> {19} [color=green style=dashed];
21 -> {22}; 21 -> {22};
22 -> {20}; 22 -> {20};
@@ -166,8 +166,8 @@ digraph lambdas_kt {
52 -> {53} [style=dotted]; 52 -> {53} [style=dotted];
53 -> {48} [style=dotted]; 53 -> {48} [style=dotted];
54 -> {55 56}; 54 -> {55 56};
55 -> {54};
55 -> {50} [color=green]; 55 -> {50} [color=green];
55 -> {54} [color=green style=dashed];
56 -> {57}; 56 -> {57};
57 -> {48}; 57 -> {48};
57 -> {58} [style=dotted]; 57 -> {58} [style=dotted];
@@ -203,8 +203,8 @@ digraph lambdas_kt {
64 -> {65} [style=dotted]; 64 -> {65} [style=dotted];
65 -> {60} [style=dotted]; 65 -> {60} [style=dotted];
66 -> {67 68}; 66 -> {67 68};
67 -> {66};
67 -> {62} [color=green]; 67 -> {62} [color=green];
67 -> {66} [color=green style=dashed];
68 -> {69}; 68 -> {69};
69 -> {60}; 69 -> {60};
69 -> {70} [style=dotted]; 69 -> {70} [style=dotted];
@@ -184,8 +184,8 @@ digraph localClassesWithImplicit_kt {
31 -> {32} [style=dotted]; 31 -> {32} [style=dotted];
32 -> {27} [style=dotted]; 32 -> {27} [style=dotted];
33 -> {34 35}; 33 -> {34 35};
34 -> {33};
34 -> {29} [color=green]; 34 -> {29} [color=green];
34 -> {33} [color=green style=dashed];
35 -> {36}; 35 -> {36};
36 -> {37}; 36 -> {37};
37 -> {39}; 37 -> {39};
@@ -217,8 +217,8 @@ digraph localClassesWithImplicit_kt {
62 -> {63} [style=dotted]; 62 -> {63} [style=dotted];
63 -> {58} [style=dotted]; 63 -> {58} [style=dotted];
64 -> {65 66}; 64 -> {65 66};
65 -> {64};
65 -> {60} [color=green]; 65 -> {60} [color=green];
65 -> {64} [color=green style=dashed];
66 -> {67}; 66 -> {67};
67 -> {68}; 67 -> {68};
68 -> {69}; 68 -> {69};
@@ -320,8 +320,8 @@ digraph localClassesWithImplicit_kt {
86 -> {87} [style=dotted]; 86 -> {87} [style=dotted];
87 -> {82} [style=dotted]; 87 -> {82} [style=dotted];
88 -> {89 90}; 88 -> {89 90};
89 -> {88};
89 -> {84} [color=green]; 89 -> {84} [color=green];
89 -> {88} [color=green style=dashed];
90 -> {91}; 90 -> {91};
91 -> {92}; 91 -> {92};
92 -> {94}; 92 -> {94};
@@ -379,8 +379,8 @@ digraph localClassesWithImplicit_kt {
117 -> {118} [style=dotted]; 117 -> {118} [style=dotted];
118 -> {113} [style=dotted]; 118 -> {113} [style=dotted];
119 -> {120 121}; 119 -> {120 121};
120 -> {119};
120 -> {115} [color=green]; 120 -> {115} [color=green];
120 -> {119} [color=green style=dashed];
121 -> {122}; 121 -> {122};
122 -> {123}; 122 -> {123};
123 -> {124}; 123 -> {124};
+10 -9
View File
@@ -46,7 +46,7 @@ digraph loops_kt {
10 -> {11}; 10 -> {11};
11 -> {12}; 11 -> {12};
12 -> {13}; 12 -> {13};
13 -> {4}; 13 -> {4} [color=green style=dashed];
14 -> {15}; 14 -> {15};
15 -> {1}; 15 -> {1};
@@ -93,7 +93,8 @@ digraph loops_kt {
26 -> {27}; 26 -> {27};
27 -> {28}; 27 -> {28};
28 -> {29}; 28 -> {29};
29 -> {20 19}; 29 -> {19};
29 -> {20} [color=green style=dashed];
30 -> {31}; 30 -> {31};
31 -> {17}; 31 -> {17};
@@ -158,7 +159,7 @@ digraph loops_kt {
51 -> {52}; 51 -> {52};
52 -> {53}; 52 -> {53};
53 -> {54}; 53 -> {54};
54 -> {41}; 54 -> {41} [color=green style=dashed];
55 -> {56}; 55 -> {56};
56 -> {33}; 56 -> {33};
@@ -201,7 +202,7 @@ digraph loops_kt {
65 -> {66}; 65 -> {66};
66 -> {67}; 66 -> {67};
67 -> {68}; 67 -> {68};
68 -> {61}; 68 -> {61} [color=green style=dashed];
69 -> {58} [style=dotted]; 69 -> {58} [style=dotted];
subgraph cluster_20 { subgraph cluster_20 {
@@ -275,7 +276,7 @@ digraph loops_kt {
89 -> {80} [style=dotted]; 89 -> {80} [style=dotted];
90 -> {80}; 90 -> {80};
91 -> {92}; 91 -> {92};
92 -> {74}; 92 -> {74} [color=green style=dashed];
93 -> {71}; 93 -> {71};
subgraph cluster_28 { subgraph cluster_28 {
@@ -317,7 +318,7 @@ digraph loops_kt {
102 -> {103} [style=dotted]; 102 -> {103} [style=dotted];
103 -> {104} [style=dotted]; 103 -> {104} [style=dotted];
104 -> {105} [style=dotted]; 104 -> {105} [style=dotted];
105 -> {98} [style=dotted]; 105 -> {98} [color=green style=dotted];
106 -> {95}; 106 -> {95};
subgraph cluster_33 { subgraph cluster_33 {
@@ -358,8 +359,8 @@ digraph loops_kt {
115 -> {116}; 115 -> {116};
116 -> {117}; 116 -> {117};
117 -> {118}; 117 -> {118};
118 -> {111};
118 -> {110} [style=dotted]; 118 -> {110} [style=dotted];
118 -> {111} [color=green style=dashed];
119 -> {108} [style=dotted]; 119 -> {108} [style=dotted];
subgraph cluster_38 { subgraph cluster_38 {
@@ -432,8 +433,8 @@ digraph loops_kt {
139 -> {140}; 139 -> {140};
140 -> {141}; 140 -> {141};
141 -> {142}; 141 -> {142};
142 -> {124};
142 -> {123} [style=dotted]; 142 -> {123} [style=dotted];
142 -> {124} [color=green style=dashed];
143 -> {121}; 143 -> {121};
subgraph cluster_46 { subgraph cluster_46 {
@@ -475,7 +476,7 @@ digraph loops_kt {
153 -> {154}; 153 -> {154};
154 -> {155}; 154 -> {155};
155 -> {147}; 155 -> {147};
155 -> {148} [style=dotted]; 155 -> {148} [color=green style=dotted];
156 -> {145}; 156 -> {145};
} }
@@ -34,8 +34,8 @@ digraph postponedLambdas_kt {
7 -> {8}; 7 -> {8};
8 -> {3}; 8 -> {3};
9 -> {10 11}; 9 -> {10 11};
10 -> {9};
10 -> {6} [color=green]; 10 -> {6} [color=green];
10 -> {9} [color=green style=dashed];
11 -> {10}; 11 -> {10};
} }
@@ -177,8 +177,8 @@ digraph propertiesAndInitBlocks_kt {
67 -> {64}; 67 -> {64};
20 -> {21 22}; 20 -> {21 22};
20 -> {26 35 38} [color=red]; 20 -> {26 35 38} [color=red];
21 -> {20};
21 -> {66} [color=green]; 21 -> {66} [color=green];
21 -> {20} [color=green style=dashed];
22 -> {23}; 22 -> {23};
23 -> {24}; 23 -> {24};
24 -> {64}; 24 -> {64};
@@ -280,8 +280,8 @@ digraph tryCatch_kt {
79 -> {80}; 79 -> {80};
80 -> {47}; 80 -> {47};
81 -> {82}; 81 -> {82};
82 -> {39};
82 -> {83} [style=dotted]; 82 -> {83} [style=dotted];
82 -> {39} [color=green style=dashed];
83 -> {84} [style=dotted]; 83 -> {84} [style=dotted];
84 -> {85} [style=dotted]; 84 -> {85} [style=dotted];
85 -> {47} [style=dotted]; 85 -> {47} [style=dotted];
@@ -294,7 +294,7 @@ digraph tryCatch_kt {
91 -> {92}; 91 -> {92};
92 -> {93}; 92 -> {93};
93 -> {94}; 93 -> {94};
94 -> {41}; 94 -> {41} [color=green style=dashed];
95 -> {96}; 95 -> {96};
96 -> {38}; 96 -> {38};
@@ -124,8 +124,8 @@ digraph boundSmartcastsInBranches_kt {
36 -> {37}; 36 -> {37};
37 -> {38}; 37 -> {38};
38 -> {39}; 38 -> {39};
39 -> {17};
39 -> {40} [style=dotted]; 39 -> {40} [style=dotted];
39 -> {17} [color=green style=dashed];
40 -> {41} [style=dotted]; 40 -> {41} [style=dotted];
41 -> {42} [style=dotted]; 41 -> {42} [style=dotted];
42 -> {29} [style=dotted]; 42 -> {29} [style=dotted];
@@ -133,7 +133,7 @@ digraph boundSmartcastsInBranches_kt {
44 -> {45}; 44 -> {45};
45 -> {46}; 45 -> {46};
46 -> {47}; 46 -> {47};
47 -> {19}; 47 -> {19} [color=green style=dashed];
subgraph cluster_12 { subgraph cluster_12 {
color=red color=red
@@ -91,6 +91,6 @@ digraph dataFlowInfoFromWhileCondition_kt {
26 -> {27}; 26 -> {27};
27 -> {28}; 27 -> {28};
28 -> {29}; 28 -> {29};
29 -> {14}; 29 -> {14} [color=green style=dashed];
} }
@@ -93,7 +93,7 @@ digraph endlessLoops_kt {
25 -> {16} [style=dotted]; 25 -> {16} [style=dotted];
26 -> {16}; 26 -> {16};
27 -> {28}; 27 -> {28};
28 -> {8}; 28 -> {8} [color=green style=dashed];
29 -> {30}; 29 -> {30};
30 -> {5}; 30 -> {5};
@@ -173,7 +173,7 @@ digraph endlessLoops_kt {
52 -> {41} [style=dotted]; 52 -> {41} [style=dotted];
53 -> {41}; 53 -> {41};
54 -> {55}; 54 -> {55};
55 -> {35}; 55 -> {35} [color=green style=dashed];
56 -> {57}; 56 -> {57};
57 -> {32}; 57 -> {32};
@@ -287,7 +287,7 @@ digraph endlessLoops_kt {
91 -> {82} [style=dotted]; 91 -> {82} [style=dotted];
92 -> {82}; 92 -> {82};
93 -> {94}; 93 -> {94};
94 -> {62}; 94 -> {62} [color=green style=dashed];
95 -> {96}; 95 -> {96};
96 -> {59}; 96 -> {59};
@@ -372,7 +372,7 @@ digraph endlessLoops_kt {
120 -> {121} [style=dotted]; 120 -> {121} [style=dotted];
121 -> {122} [style=dotted]; 121 -> {122} [style=dotted];
122 -> {123} [style=dotted]; 122 -> {123} [style=dotted];
123 -> {101} [style=dotted]; 123 -> {101} [color=green style=dotted];
124 -> {125}; 124 -> {125};
125 -> {98}; 125 -> {98};
@@ -451,8 +451,8 @@ digraph endlessLoops_kt {
147 -> {148}; 147 -> {148};
148 -> {149}; 148 -> {149};
149 -> {150}; 149 -> {150};
150 -> {130};
150 -> {129} [style=dotted]; 150 -> {129} [style=dotted];
150 -> {130} [color=green style=dashed];
151 -> {152}; 151 -> {152};
152 -> {127}; 152 -> {127};
@@ -531,8 +531,8 @@ digraph endlessLoops_kt {
174 -> {175}; 174 -> {175};
175 -> {176}; 175 -> {176};
176 -> {177}; 176 -> {177};
177 -> {157};
177 -> {156} [style=dotted]; 177 -> {156} [style=dotted];
177 -> {157} [color=green style=dashed];
178 -> {179}; 178 -> {179};
179 -> {154}; 179 -> {154};
@@ -577,8 +577,8 @@ digraph endlessLoops_kt {
189 -> {190}; 189 -> {190};
190 -> {191}; 190 -> {191};
191 -> {192}; 191 -> {192};
192 -> {184};
192 -> {183} [style=dotted]; 192 -> {183} [style=dotted];
192 -> {184} [color=green style=dashed];
193 -> {194} [style=dotted]; 193 -> {194} [style=dotted];
194 -> {181} [style=dotted]; 194 -> {181} [style=dotted];
@@ -250,7 +250,7 @@ digraph smartcastToNothing_kt {
81 -> {70} [style=dotted]; 81 -> {70} [style=dotted];
82 -> {70} [style=dotted]; 82 -> {70} [style=dotted];
83 -> {84} [style=dotted]; 83 -> {84} [style=dotted];
84 -> {56} [style=dotted]; 84 -> {56} [color=green style=dotted];
85 -> {86 87}; 85 -> {86 87};
86 -> {88}; 86 -> {88};
87 -> {48} [style=dotted]; 87 -> {48} [style=dotted];
@@ -59,8 +59,8 @@ digraph callsInPlace_kt {
17 -> {18}; 17 -> {18};
18 -> {14}; 18 -> {14};
19 -> {20 21}; 19 -> {20 21};
20 -> {19};
20 -> {17} [color=green]; 20 -> {17} [color=green];
20 -> {19} [color=green style=dashed];
21 -> {20}; 21 -> {20};
subgraph cluster_4 { subgraph cluster_4 {
@@ -85,8 +85,8 @@ digraph callsInPlace_kt {
26 -> {27}; 26 -> {27};
27 -> {23}; 27 -> {23};
28 -> {29 30}; 28 -> {29 30};
29 -> {28};
29 -> {25} [color=green]; 29 -> {25} [color=green];
29 -> {28} [color=green style=dashed];
30 -> {29}; 30 -> {29};
subgraph cluster_6 { subgraph cluster_6 {
@@ -203,12 +203,12 @@ digraph callsInPlace_kt {
68 -> {69}; 68 -> {69};
69 -> {64}; 69 -> {64};
70 -> {71 72}; 70 -> {71 72};
71 -> {70};
71 -> {66} [color=green]; 71 -> {66} [color=green];
71 -> {70} [color=green style=dashed];
72 -> {71}; 72 -> {71};
73 -> {74 75}; 73 -> {74 75};
74 -> {73};
74 -> {68} [color=green]; 74 -> {68} [color=green];
74 -> {73} [color=green style=dashed];
75 -> {74}; 75 -> {74};
subgraph cluster_14 { subgraph cluster_14 {
@@ -242,12 +242,12 @@ digraph callsInPlace_kt {
81 -> {82}; 81 -> {82};
82 -> {77}; 82 -> {77};
83 -> {84 85}; 83 -> {84 85};
84 -> {83};
84 -> {79} [color=green]; 84 -> {79} [color=green];
84 -> {83} [color=green style=dashed];
85 -> {84}; 85 -> {84};
86 -> {87 88}; 86 -> {87 88};
87 -> {86};
87 -> {81} [color=green]; 87 -> {81} [color=green];
87 -> {86} [color=green style=dashed];
88 -> {87}; 88 -> {87};
subgraph cluster_17 { subgraph cluster_17 {
@@ -48,8 +48,8 @@ digraph atLeastOnce_kt {
12 -> {13}; 12 -> {13};
13 -> {7}; 13 -> {7};
14 -> {16}; 14 -> {16};
15 -> {14};
15 -> {10} [color=green]; 15 -> {10} [color=green];
15 -> {14} [color=green style=dashed];
16 -> {17}; 16 -> {17};
17 -> {15}; 17 -> {15};
@@ -80,8 +80,8 @@ digraph atLeastOnce_kt {
24 -> {25}; 24 -> {25};
25 -> {19}; 25 -> {19};
26 -> {28}; 26 -> {28};
27 -> {26};
27 -> {22} [color=green]; 27 -> {22} [color=green];
27 -> {26} [color=green style=dashed];
28 -> {29}; 28 -> {29};
29 -> {27}; 29 -> {27};
@@ -48,8 +48,8 @@ digraph unknown_kt {
12 -> {13}; 12 -> {13};
13 -> {7}; 13 -> {7};
14 -> {15 16}; 14 -> {15 16};
15 -> {14};
15 -> {10} [color=green]; 15 -> {10} [color=green];
15 -> {14} [color=green style=dashed];
16 -> {17}; 16 -> {17};
17 -> {15}; 17 -> {15};
@@ -80,8 +80,8 @@ digraph unknown_kt {
24 -> {25}; 24 -> {25};
25 -> {19}; 25 -> {19};
26 -> {27 28}; 26 -> {27 28};
27 -> {26};
27 -> {22} [color=green]; 27 -> {22} [color=green];
27 -> {26} [color=green style=dashed];
28 -> {29}; 28 -> {29};
29 -> {27}; 29 -> {27};
@@ -94,8 +94,8 @@ finally {
23 -> {24} [style=dotted]; 23 -> {24} [style=dotted];
24 -> {8} [style=dotted]; 24 -> {8} [style=dotted];
25 -> {26 27}; 25 -> {26 27};
26 -> {25};
26 -> {16} [color=green]; 26 -> {16} [color=green];
26 -> {25} [color=green style=dashed];
27 -> {26}; 27 -> {26};
subgraph cluster_9 { subgraph cluster_9 {
@@ -69,9 +69,11 @@ class ControlFlowGraph(val declaration: FirDeclaration?, val name: String, val k
} }
} }
enum class EdgeKind(val usedInDfa: Boolean) { enum class EdgeKind(val usedInDfa: Boolean, val isBack: Boolean) {
Simple(usedInDfa = true), Simple(usedInDfa = true, isBack = false),
Dead(usedInDfa = false), Dead(usedInDfa = false, isBack = false),
Cfg(usedInDfa = false), Cfg(usedInDfa = false, isBack = false),
Dfg(usedInDfa = true) Dfg(usedInDfa = true, isBack = false),
Back(usedInDfa = false, isBack = true),
DeadBack(usedInDfa = false, isBack = true)
} }
@@ -151,7 +151,7 @@ class ControlFlowGraphBuilder {
val enterNode = functionEnterNodes.pop() val enterNode = functionEnterNodes.pop()
@Suppress("NON_EXHAUSTIVE_WHEN") @Suppress("NON_EXHAUSTIVE_WHEN")
when (invocationKind) { when (invocationKind) {
InvocationKind.AT_LEAST_ONCE, InvocationKind.UNKNOWN -> addEdge(exitNode, enterNode, propagateDeadness = false) InvocationKind.AT_LEAST_ONCE, InvocationKind.UNKNOWN -> addBackEdge(exitNode, enterNode)
} }
if (postponedExitNode != null) { if (postponedExitNode != null) {
CFGNode.addEdge(lastNodes.pop(), postponedExitNode, propagateDeadness = true, kind = EdgeKind.Cfg) CFGNode.addEdge(lastNodes.pop(), postponedExitNode, propagateDeadness = true, kind = EdgeKind.Cfg)
@@ -399,7 +399,7 @@ class ControlFlowGraphBuilder {
is FirBreakExpression -> loopExitNodes[jump.target.labeledElement] is FirBreakExpression -> loopExitNodes[jump.target.labeledElement]
else -> throw IllegalArgumentException("Unknown jump type: ${jump.render()}") else -> throw IllegalArgumentException("Unknown jump type: ${jump.render()}")
} }
addNodeWithJump(node, nextNode) addNodeWithJump(node, nextNode, isBack = jump is FirContinueExpression)
return node return node
} }
@@ -502,7 +502,7 @@ class ControlFlowGraphBuilder {
if (lastNodes.isNotEmpty) { if (lastNodes.isNotEmpty) {
val conditionEnterNode = lastNodes.pop() val conditionEnterNode = lastNodes.pop()
require(conditionEnterNode is LoopConditionEnterNode) { loop.render() } require(conditionEnterNode is LoopConditionEnterNode) { loop.render() }
addEdge(loopBlockExitNode, conditionEnterNode, propagateDeadness = false) addBackEdge(loopBlockExitNode, conditionEnterNode)
} }
val loopExitNode = loopExitNodes.pop() val loopExitNode = loopExitNodes.pop()
loopExitNode.updateDeadStatus() loopExitNode.updateDeadStatus()
@@ -543,7 +543,7 @@ class ControlFlowGraphBuilder {
addEdge(lastNodes.pop(), conditionExitNode) addEdge(lastNodes.pop(), conditionExitNode)
val blockEnterNode = lastNodes.pop() val blockEnterNode = lastNodes.pop()
require(blockEnterNode is LoopBlockEnterNode) require(blockEnterNode is LoopBlockEnterNode)
addEdge(conditionExitNode, blockEnterNode, propagateDeadness = false, isDead = conditionBooleanValue == false) addBackEdge(conditionExitNode, blockEnterNode, isDead = conditionBooleanValue == false)
val loopExit = loopExitNodes.pop() val loopExit = loopExitNodes.pop()
addEdge(conditionExitNode, loopExit, propagateDeadness = false, isDead = conditionBooleanValue == true) addEdge(conditionExitNode, loopExit, propagateDeadness = false, isDead = conditionBooleanValue == true)
loopExit.updateDeadStatus() loopExit.updateDeadStatus()
@@ -903,13 +903,17 @@ class ControlFlowGraphBuilder {
* it will be replaced after correct implementation of CFG for class initialization * it will be replaced after correct implementation of CFG for class initialization
*/ */
val exitNode: CFGNode<*> = exitNodes.top() val exitNode: CFGNode<*> = exitNodes.top()
addNodeWithJump(node, exitNode, preferredKind) addNodeWithJump(node, exitNode)
} }
private fun addNodeWithJump(node: CFGNode<*>, targetNode: CFGNode<*>?, preferredKind: EdgeKind = EdgeKind.Simple) { private fun addNodeWithJump(node: CFGNode<*>, targetNode: CFGNode<*>?, isBack: Boolean = false) {
addEdge(lastNodes.pop(), node) addEdge(lastNodes.pop(), node)
if (targetNode != null) { if (targetNode != null) {
addEdge(node, targetNode) if (isBack) {
addBackEdge(node, targetNode)
} else {
addEdge(node, targetNode)
}
} }
val stub = createStubNode() val stub = createStubNode()
addEdge(node, stub) addEdge(node, stub)
@@ -933,12 +937,23 @@ class ControlFlowGraphBuilder {
to: CFGNode<*>, to: CFGNode<*>,
propagateDeadness: Boolean = true, propagateDeadness: Boolean = true,
isDead: Boolean = false, isDead: Boolean = false,
preferredKind: EdgeKind = EdgeKind.Simple isBack: Boolean = false,
preferredKind: EdgeKind = EdgeKind.Simple,
) { ) {
val kind = if (isDead || from.isDead || to.isDead) EdgeKind.Dead else preferredKind val kind = if (isDead || from.isDead || to.isDead) {
if (isBack) EdgeKind.DeadBack else EdgeKind.Dead
} else preferredKind
CFGNode.addEdge(from, to, kind, propagateDeadness) CFGNode.addEdge(from, to, kind, propagateDeadness)
} }
private fun addBackEdge(
from: CFGNode<*>,
to: CFGNode<*>,
isDead: Boolean = false
) {
addEdge(from, to, propagateDeadness = false, isDead = isDead, isBack = true, preferredKind = EdgeKind.Back)
}
private val FirFunction<*>.invocationKind: InvocationKind? private val FirFunction<*>.invocationKind: InvocationKind?
get() = (this as? FirAnonymousFunction)?.invocationKind get() = (this as? FirAnonymousFunction)?.invocationKind
@@ -30,6 +30,8 @@ class FirControlFlowGraphRenderVisitor(
EdgeKind.Dead to "[style=dotted]", EdgeKind.Dead to "[style=dotted]",
EdgeKind.Cfg to "[color=green]", EdgeKind.Cfg to "[color=green]",
EdgeKind.Dfg to "[color=red]", EdgeKind.Dfg to "[color=red]",
EdgeKind.Back to "[color=green style=dashed]",
EdgeKind.DeadBack to "[color=green style=dotted]"
) )
) )
} }
@@ -308,7 +308,7 @@ abstract class AbstractFirDiagnosticsTest : AbstractFirBaseDiagnosticsTest() {
val toKind = to.incomingEdges.getValue(from) val toKind = to.incomingEdges.getValue(from)
TestCase.assertEquals(fromKind, toKind) TestCase.assertEquals(fromKind, toKind)
if (from.isDead || to.isDead) { if (from.isDead || to.isDead) {
KtUsefulTestCase.assertContainsElements(listOf(EdgeKind.Dead, EdgeKind.Cfg), toKind) KtUsefulTestCase.assertContainsElements(listOf(EdgeKind.Dead, EdgeKind.Cfg, EdgeKind.DeadBack, EdgeKind.Back), toKind)
} }
} }
} }