blob: 9e7e128bcfb3736da0e0a6eef7a7c2fa456d02ea [file] [log] [blame]
Chandler Carruthc7bad9a2014-04-23 08:08:49 +00001//===- LazyCallGraphTest.cpp - Unit tests for the lazy CG analysis --------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "llvm/Analysis/LazyCallGraph.h"
11#include "llvm/AsmParser/Parser.h"
12#include "llvm/IR/Function.h"
Chandler Carruth9a67b072017-06-06 11:06:56 +000013#include "llvm/IR/Instructions.h"
Chandler Carruthc7bad9a2014-04-23 08:08:49 +000014#include "llvm/IR/LLVMContext.h"
15#include "llvm/IR/Module.h"
16#include "llvm/Support/ErrorHandling.h"
17#include "llvm/Support/SourceMgr.h"
18#include "gtest/gtest.h"
19#include <memory>
20
21using namespace llvm;
22
23namespace {
24
Mehdi Amini03b42e42016-04-14 21:59:01 +000025std::unique_ptr<Module> parseAssembly(LLVMContext &Context,
26 const char *Assembly) {
Chandler Carruthc7bad9a2014-04-23 08:08:49 +000027 SMDiagnostic Error;
Mehdi Amini03b42e42016-04-14 21:59:01 +000028 std::unique_ptr<Module> M = parseAssemblyString(Assembly, Error, Context);
Chandler Carruthc7bad9a2014-04-23 08:08:49 +000029
30 std::string ErrMsg;
31 raw_string_ostream OS(ErrMsg);
32 Error.print("", OS);
33
34 // A failure here means that the test itself is buggy.
Rafael Espindola11c07d72014-08-19 16:58:54 +000035 if (!M)
Chandler Carruthc7bad9a2014-04-23 08:08:49 +000036 report_fatal_error(OS.str().c_str());
37
38 return M;
39}
40
Filipe Cabecinhas39545662014-10-22 02:16:06 +000041/*
42 IR forming a call graph with a diamond of triangle-shaped SCCs:
43
44 d1
45 / \
46 d3--d2
47 / \
48 b1 c1
49 / \ / \
50 b3--b2 c3--c2
51 \ /
52 a1
53 / \
54 a3--a2
55
56 All call edges go up between SCCs, and clockwise around the SCC.
57 */
Chandler Carruthc7bad9a2014-04-23 08:08:49 +000058static const char DiamondOfTriangles[] =
59 "define void @a1() {\n"
60 "entry:\n"
61 " call void @a2()\n"
62 " call void @b2()\n"
63 " call void @c3()\n"
64 " ret void\n"
65 "}\n"
66 "define void @a2() {\n"
67 "entry:\n"
68 " call void @a3()\n"
69 " ret void\n"
70 "}\n"
71 "define void @a3() {\n"
72 "entry:\n"
73 " call void @a1()\n"
74 " ret void\n"
75 "}\n"
76 "define void @b1() {\n"
77 "entry:\n"
78 " call void @b2()\n"
79 " call void @d3()\n"
80 " ret void\n"
81 "}\n"
82 "define void @b2() {\n"
83 "entry:\n"
84 " call void @b3()\n"
85 " ret void\n"
86 "}\n"
87 "define void @b3() {\n"
88 "entry:\n"
89 " call void @b1()\n"
90 " ret void\n"
91 "}\n"
92 "define void @c1() {\n"
93 "entry:\n"
94 " call void @c2()\n"
95 " call void @d2()\n"
96 " ret void\n"
97 "}\n"
98 "define void @c2() {\n"
99 "entry:\n"
100 " call void @c3()\n"
101 " ret void\n"
102 "}\n"
103 "define void @c3() {\n"
104 "entry:\n"
105 " call void @c1()\n"
106 " ret void\n"
107 "}\n"
108 "define void @d1() {\n"
109 "entry:\n"
110 " call void @d2()\n"
111 " ret void\n"
112 "}\n"
113 "define void @d2() {\n"
114 "entry:\n"
115 " call void @d3()\n"
116 " ret void\n"
117 "}\n"
118 "define void @d3() {\n"
119 "entry:\n"
120 " call void @d1()\n"
121 " ret void\n"
122 "}\n";
123
Chandler Carruth49d728a2016-09-16 10:20:17 +0000124/*
125 IR forming a reference graph with a diamond of triangle-shaped RefSCCs
126
127 d1
128 / \
129 d3--d2
130 / \
131 b1 c1
132 / \ / \
133 b3--b2 c3--c2
134 \ /
135 a1
136 / \
137 a3--a2
138
139 All call edges go up between RefSCCs, and clockwise around the RefSCC.
140 */
141static const char DiamondOfTrianglesRefGraph[] =
142 "define void @a1() {\n"
143 "entry:\n"
144 " %a = alloca void ()*\n"
145 " store void ()* @a2, void ()** %a\n"
146 " store void ()* @b2, void ()** %a\n"
147 " store void ()* @c3, void ()** %a\n"
148 " ret void\n"
149 "}\n"
150 "define void @a2() {\n"
151 "entry:\n"
152 " %a = alloca void ()*\n"
153 " store void ()* @a3, void ()** %a\n"
154 " ret void\n"
155 "}\n"
156 "define void @a3() {\n"
157 "entry:\n"
158 " %a = alloca void ()*\n"
159 " store void ()* @a1, void ()** %a\n"
160 " ret void\n"
161 "}\n"
162 "define void @b1() {\n"
163 "entry:\n"
164 " %a = alloca void ()*\n"
165 " store void ()* @b2, void ()** %a\n"
166 " store void ()* @d3, void ()** %a\n"
167 " ret void\n"
168 "}\n"
169 "define void @b2() {\n"
170 "entry:\n"
171 " %a = alloca void ()*\n"
172 " store void ()* @b3, void ()** %a\n"
173 " ret void\n"
174 "}\n"
175 "define void @b3() {\n"
176 "entry:\n"
177 " %a = alloca void ()*\n"
178 " store void ()* @b1, void ()** %a\n"
179 " ret void\n"
180 "}\n"
181 "define void @c1() {\n"
182 "entry:\n"
183 " %a = alloca void ()*\n"
184 " store void ()* @c2, void ()** %a\n"
185 " store void ()* @d2, void ()** %a\n"
186 " ret void\n"
187 "}\n"
188 "define void @c2() {\n"
189 "entry:\n"
190 " %a = alloca void ()*\n"
191 " store void ()* @c3, void ()** %a\n"
192 " ret void\n"
193 "}\n"
194 "define void @c3() {\n"
195 "entry:\n"
196 " %a = alloca void ()*\n"
197 " store void ()* @c1, void ()** %a\n"
198 " ret void\n"
199 "}\n"
200 "define void @d1() {\n"
201 "entry:\n"
202 " %a = alloca void ()*\n"
203 " store void ()* @d2, void ()** %a\n"
204 " ret void\n"
205 "}\n"
206 "define void @d2() {\n"
207 "entry:\n"
208 " %a = alloca void ()*\n"
209 " store void ()* @d3, void ()** %a\n"
210 " ret void\n"
211 "}\n"
212 "define void @d3() {\n"
213 "entry:\n"
214 " %a = alloca void ()*\n"
215 " store void ()* @d1, void ()** %a\n"
216 " ret void\n"
217 "}\n";
218
Chandler Carruthf59a8382017-07-15 08:08:19 +0000219static LazyCallGraph buildCG(Module &M) {
220 TargetLibraryInfoImpl TLII(Triple(M.getTargetTriple()));
221 TargetLibraryInfo TLI(TLII);
222 LazyCallGraph CG(M, TLI);
223 return CG;
224}
225
Chandler Carruthc7bad9a2014-04-23 08:08:49 +0000226TEST(LazyCallGraphTest, BasicGraphFormation) {
Mehdi Amini03b42e42016-04-14 21:59:01 +0000227 LLVMContext Context;
228 std::unique_ptr<Module> M = parseAssembly(Context, DiamondOfTriangles);
Chandler Carruthf59a8382017-07-15 08:08:19 +0000229 LazyCallGraph CG = buildCG(*M);
Chandler Carruthc7bad9a2014-04-23 08:08:49 +0000230
231 // The order of the entry nodes should be stable w.r.t. the source order of
232 // the IR, and everything in our module is an entry node, so just directly
233 // build variables for each node.
234 auto I = CG.begin();
Chandler Carruthaaad9f82017-02-09 23:24:13 +0000235 LazyCallGraph::Node &A1 = (I++)->getNode();
Chandler Carruthbd5d3082014-04-23 23:34:48 +0000236 EXPECT_EQ("a1", A1.getFunction().getName());
Chandler Carruthaaad9f82017-02-09 23:24:13 +0000237 LazyCallGraph::Node &A2 = (I++)->getNode();
Chandler Carruthbd5d3082014-04-23 23:34:48 +0000238 EXPECT_EQ("a2", A2.getFunction().getName());
Chandler Carruthaaad9f82017-02-09 23:24:13 +0000239 LazyCallGraph::Node &A3 = (I++)->getNode();
Chandler Carruthbd5d3082014-04-23 23:34:48 +0000240 EXPECT_EQ("a3", A3.getFunction().getName());
Chandler Carruthaaad9f82017-02-09 23:24:13 +0000241 LazyCallGraph::Node &B1 = (I++)->getNode();
Chandler Carruthbd5d3082014-04-23 23:34:48 +0000242 EXPECT_EQ("b1", B1.getFunction().getName());
Chandler Carruthaaad9f82017-02-09 23:24:13 +0000243 LazyCallGraph::Node &B2 = (I++)->getNode();
Chandler Carruthbd5d3082014-04-23 23:34:48 +0000244 EXPECT_EQ("b2", B2.getFunction().getName());
Chandler Carruthaaad9f82017-02-09 23:24:13 +0000245 LazyCallGraph::Node &B3 = (I++)->getNode();
Chandler Carruthbd5d3082014-04-23 23:34:48 +0000246 EXPECT_EQ("b3", B3.getFunction().getName());
Chandler Carruthaaad9f82017-02-09 23:24:13 +0000247 LazyCallGraph::Node &C1 = (I++)->getNode();
Chandler Carruthbd5d3082014-04-23 23:34:48 +0000248 EXPECT_EQ("c1", C1.getFunction().getName());
Chandler Carruthaaad9f82017-02-09 23:24:13 +0000249 LazyCallGraph::Node &C2 = (I++)->getNode();
Chandler Carruthbd5d3082014-04-23 23:34:48 +0000250 EXPECT_EQ("c2", C2.getFunction().getName());
Chandler Carruthaaad9f82017-02-09 23:24:13 +0000251 LazyCallGraph::Node &C3 = (I++)->getNode();
Chandler Carruthbd5d3082014-04-23 23:34:48 +0000252 EXPECT_EQ("c3", C3.getFunction().getName());
Chandler Carruthaaad9f82017-02-09 23:24:13 +0000253 LazyCallGraph::Node &D1 = (I++)->getNode();
Chandler Carruthbd5d3082014-04-23 23:34:48 +0000254 EXPECT_EQ("d1", D1.getFunction().getName());
Chandler Carruthaaad9f82017-02-09 23:24:13 +0000255 LazyCallGraph::Node &D2 = (I++)->getNode();
Chandler Carruthbd5d3082014-04-23 23:34:48 +0000256 EXPECT_EQ("d2", D2.getFunction().getName());
Chandler Carruthaaad9f82017-02-09 23:24:13 +0000257 LazyCallGraph::Node &D3 = (I++)->getNode();
Chandler Carruthbd5d3082014-04-23 23:34:48 +0000258 EXPECT_EQ("d3", D3.getFunction().getName());
Chandler Carruthc7bad9a2014-04-23 08:08:49 +0000259 EXPECT_EQ(CG.end(), I);
260
261 // Build vectors and sort them for the rest of the assertions to make them
262 // independent of order.
263 std::vector<std::string> Nodes;
264
Chandler Carruthaaad9f82017-02-09 23:24:13 +0000265 for (LazyCallGraph::Edge &E : A1.populate())
Chandler Carrutha4499e92016-02-02 03:57:13 +0000266 Nodes.push_back(E.getFunction().getName());
Chandler Carruthc7bad9a2014-04-23 08:08:49 +0000267 std::sort(Nodes.begin(), Nodes.end());
268 EXPECT_EQ("a2", Nodes[0]);
269 EXPECT_EQ("b2", Nodes[1]);
270 EXPECT_EQ("c3", Nodes[2]);
271 Nodes.clear();
272
Chandler Carruthaaad9f82017-02-09 23:24:13 +0000273 A2.populate();
274 EXPECT_EQ(A2->end(), std::next(A2->begin()));
275 EXPECT_EQ("a3", A2->begin()->getFunction().getName());
276 A3.populate();
277 EXPECT_EQ(A3->end(), std::next(A3->begin()));
278 EXPECT_EQ("a1", A3->begin()->getFunction().getName());
Chandler Carruthc7bad9a2014-04-23 08:08:49 +0000279
Chandler Carruthaaad9f82017-02-09 23:24:13 +0000280 for (LazyCallGraph::Edge &E : B1.populate())
Chandler Carrutha4499e92016-02-02 03:57:13 +0000281 Nodes.push_back(E.getFunction().getName());
Chandler Carruthc7bad9a2014-04-23 08:08:49 +0000282 std::sort(Nodes.begin(), Nodes.end());
283 EXPECT_EQ("b2", Nodes[0]);
284 EXPECT_EQ("d3", Nodes[1]);
285 Nodes.clear();
286
Chandler Carruthaaad9f82017-02-09 23:24:13 +0000287 B2.populate();
288 EXPECT_EQ(B2->end(), std::next(B2->begin()));
289 EXPECT_EQ("b3", B2->begin()->getFunction().getName());
290 B3.populate();
291 EXPECT_EQ(B3->end(), std::next(B3->begin()));
292 EXPECT_EQ("b1", B3->begin()->getFunction().getName());
Chandler Carruthc7bad9a2014-04-23 08:08:49 +0000293
Chandler Carruthaaad9f82017-02-09 23:24:13 +0000294 for (LazyCallGraph::Edge &E : C1.populate())
Chandler Carrutha4499e92016-02-02 03:57:13 +0000295 Nodes.push_back(E.getFunction().getName());
Chandler Carruthc7bad9a2014-04-23 08:08:49 +0000296 std::sort(Nodes.begin(), Nodes.end());
297 EXPECT_EQ("c2", Nodes[0]);
298 EXPECT_EQ("d2", Nodes[1]);
299 Nodes.clear();
300
Chandler Carruthaaad9f82017-02-09 23:24:13 +0000301 C2.populate();
302 EXPECT_EQ(C2->end(), std::next(C2->begin()));
303 EXPECT_EQ("c3", C2->begin()->getFunction().getName());
304 C3.populate();
305 EXPECT_EQ(C3->end(), std::next(C3->begin()));
306 EXPECT_EQ("c1", C3->begin()->getFunction().getName());
Chandler Carruthc7bad9a2014-04-23 08:08:49 +0000307
Chandler Carruthaaad9f82017-02-09 23:24:13 +0000308 D1.populate();
309 EXPECT_EQ(D1->end(), std::next(D1->begin()));
310 EXPECT_EQ("d2", D1->begin()->getFunction().getName());
311 D2.populate();
312 EXPECT_EQ(D2->end(), std::next(D2->begin()));
313 EXPECT_EQ("d3", D2->begin()->getFunction().getName());
314 D3.populate();
315 EXPECT_EQ(D3->end(), std::next(D3->begin()));
316 EXPECT_EQ("d1", D3->begin()->getFunction().getName());
Chandler Carruthc7bad9a2014-04-23 08:08:49 +0000317
Chandler Carruthe5944d92016-02-17 00:18:16 +0000318 // Now lets look at the RefSCCs and SCCs.
Chandler Carruth2e0fe3e2017-02-06 19:38:06 +0000319 CG.buildRefSCCs();
Chandler Carruthe5944d92016-02-17 00:18:16 +0000320 auto J = CG.postorder_ref_scc_begin();
Chandler Carruthc7bad9a2014-04-23 08:08:49 +0000321
Chandler Carruthe5944d92016-02-17 00:18:16 +0000322 LazyCallGraph::RefSCC &D = *J++;
323 ASSERT_EQ(1, D.size());
324 for (LazyCallGraph::Node &N : *D.begin())
325 Nodes.push_back(N.getFunction().getName());
Chandler Carruthc7bad9a2014-04-23 08:08:49 +0000326 std::sort(Nodes.begin(), Nodes.end());
Chandler Carruthead50d32014-04-24 09:59:56 +0000327 EXPECT_EQ(3u, Nodes.size());
Chandler Carruthc7bad9a2014-04-23 08:08:49 +0000328 EXPECT_EQ("d1", Nodes[0]);
329 EXPECT_EQ("d2", Nodes[1]);
330 EXPECT_EQ("d3", Nodes[2]);
Chandler Carruthc7bad9a2014-04-23 08:08:49 +0000331 Nodes.clear();
Chandler Carruth4b096742014-05-01 12:12:42 +0000332 EXPECT_FALSE(D.isParentOf(D));
333 EXPECT_FALSE(D.isChildOf(D));
334 EXPECT_FALSE(D.isAncestorOf(D));
335 EXPECT_FALSE(D.isDescendantOf(D));
Chandler Carruth49d728a2016-09-16 10:20:17 +0000336 EXPECT_EQ(&D, &*CG.postorder_ref_scc_begin());
Chandler Carruthc7bad9a2014-04-23 08:08:49 +0000337
Chandler Carruthe5944d92016-02-17 00:18:16 +0000338 LazyCallGraph::RefSCC &C = *J++;
339 ASSERT_EQ(1, C.size());
340 for (LazyCallGraph::Node &N : *C.begin())
341 Nodes.push_back(N.getFunction().getName());
Chandler Carruthc7bad9a2014-04-23 08:08:49 +0000342 std::sort(Nodes.begin(), Nodes.end());
Chandler Carruthead50d32014-04-24 09:59:56 +0000343 EXPECT_EQ(3u, Nodes.size());
Chandler Carruthc7bad9a2014-04-23 08:08:49 +0000344 EXPECT_EQ("c1", Nodes[0]);
345 EXPECT_EQ("c2", Nodes[1]);
346 EXPECT_EQ("c3", Nodes[2]);
Chandler Carruthc7bad9a2014-04-23 08:08:49 +0000347 Nodes.clear();
Chandler Carruth4b096742014-05-01 12:12:42 +0000348 EXPECT_TRUE(C.isParentOf(D));
349 EXPECT_FALSE(C.isChildOf(D));
350 EXPECT_TRUE(C.isAncestorOf(D));
351 EXPECT_FALSE(C.isDescendantOf(D));
Chandler Carruth49d728a2016-09-16 10:20:17 +0000352 EXPECT_EQ(&C, &*std::next(CG.postorder_ref_scc_begin()));
Chandler Carruthc7bad9a2014-04-23 08:08:49 +0000353
Chandler Carruthe5944d92016-02-17 00:18:16 +0000354 LazyCallGraph::RefSCC &B = *J++;
355 ASSERT_EQ(1, B.size());
356 for (LazyCallGraph::Node &N : *B.begin())
357 Nodes.push_back(N.getFunction().getName());
Chandler Carruthc7bad9a2014-04-23 08:08:49 +0000358 std::sort(Nodes.begin(), Nodes.end());
Chandler Carruthead50d32014-04-24 09:59:56 +0000359 EXPECT_EQ(3u, Nodes.size());
Chandler Carruthc7bad9a2014-04-23 08:08:49 +0000360 EXPECT_EQ("b1", Nodes[0]);
361 EXPECT_EQ("b2", Nodes[1]);
362 EXPECT_EQ("b3", Nodes[2]);
Chandler Carruthc7bad9a2014-04-23 08:08:49 +0000363 Nodes.clear();
Chandler Carruth4b096742014-05-01 12:12:42 +0000364 EXPECT_TRUE(B.isParentOf(D));
365 EXPECT_FALSE(B.isChildOf(D));
366 EXPECT_TRUE(B.isAncestorOf(D));
367 EXPECT_FALSE(B.isDescendantOf(D));
368 EXPECT_FALSE(B.isAncestorOf(C));
369 EXPECT_FALSE(C.isAncestorOf(B));
Chandler Carruth49d728a2016-09-16 10:20:17 +0000370 EXPECT_EQ(&B, &*std::next(CG.postorder_ref_scc_begin(), 2));
Chandler Carruthc7bad9a2014-04-23 08:08:49 +0000371
Chandler Carruthe5944d92016-02-17 00:18:16 +0000372 LazyCallGraph::RefSCC &A = *J++;
373 ASSERT_EQ(1, A.size());
374 for (LazyCallGraph::Node &N : *A.begin())
375 Nodes.push_back(N.getFunction().getName());
Chandler Carruthc7bad9a2014-04-23 08:08:49 +0000376 std::sort(Nodes.begin(), Nodes.end());
Chandler Carruthead50d32014-04-24 09:59:56 +0000377 EXPECT_EQ(3u, Nodes.size());
Chandler Carruthc7bad9a2014-04-23 08:08:49 +0000378 EXPECT_EQ("a1", Nodes[0]);
379 EXPECT_EQ("a2", Nodes[1]);
380 EXPECT_EQ("a3", Nodes[2]);
Chandler Carruthc7bad9a2014-04-23 08:08:49 +0000381 Nodes.clear();
Chandler Carruth4b096742014-05-01 12:12:42 +0000382 EXPECT_TRUE(A.isParentOf(B));
383 EXPECT_TRUE(A.isParentOf(C));
384 EXPECT_FALSE(A.isParentOf(D));
385 EXPECT_TRUE(A.isAncestorOf(B));
386 EXPECT_TRUE(A.isAncestorOf(C));
387 EXPECT_TRUE(A.isAncestorOf(D));
Chandler Carruth49d728a2016-09-16 10:20:17 +0000388 EXPECT_EQ(&A, &*std::next(CG.postorder_ref_scc_begin(), 3));
Chandler Carruthc7bad9a2014-04-23 08:08:49 +0000389
Chandler Carruthe5944d92016-02-17 00:18:16 +0000390 EXPECT_EQ(CG.postorder_ref_scc_end(), J);
Chandler Carruth49d728a2016-09-16 10:20:17 +0000391 EXPECT_EQ(J, std::next(CG.postorder_ref_scc_begin(), 4));
Chandler Carruthc7bad9a2014-04-23 08:08:49 +0000392}
393
Chandler Carruthcace6622014-04-23 10:31:17 +0000394static Function &lookupFunction(Module &M, StringRef Name) {
395 for (Function &F : M)
396 if (F.getName() == Name)
397 return F;
398 report_fatal_error("Couldn't find function!");
399}
400
Chandler Carruthc00a7ff2014-04-28 11:10:23 +0000401TEST(LazyCallGraphTest, BasicGraphMutation) {
Mehdi Amini03b42e42016-04-14 21:59:01 +0000402 LLVMContext Context;
403 std::unique_ptr<Module> M = parseAssembly(Context, "define void @a() {\n"
404 "entry:\n"
405 " call void @b()\n"
406 " call void @c()\n"
407 " ret void\n"
408 "}\n"
409 "define void @b() {\n"
410 "entry:\n"
411 " ret void\n"
412 "}\n"
413 "define void @c() {\n"
414 "entry:\n"
415 " ret void\n"
416 "}\n");
Chandler Carruthf59a8382017-07-15 08:08:19 +0000417 LazyCallGraph CG = buildCG(*M);
Chandler Carruthc00a7ff2014-04-28 11:10:23 +0000418
419 LazyCallGraph::Node &A = CG.get(lookupFunction(*M, "a"));
420 LazyCallGraph::Node &B = CG.get(lookupFunction(*M, "b"));
Chandler Carruthaaad9f82017-02-09 23:24:13 +0000421 A.populate();
422 EXPECT_EQ(2, std::distance(A->begin(), A->end()));
423 B.populate();
424 EXPECT_EQ(0, std::distance(B->begin(), B->end()));
Chandler Carruthc00a7ff2014-04-28 11:10:23 +0000425
Chandler Carruthaaad9f82017-02-09 23:24:13 +0000426 LazyCallGraph::Node &C = CG.get(lookupFunction(*M, "c"));
427 C.populate();
428 CG.insertEdge(B, C, LazyCallGraph::Edge::Call);
429 EXPECT_EQ(1, std::distance(B->begin(), B->end()));
430 EXPECT_EQ(0, std::distance(C->begin(), C->end()));
Chandler Carruthc00a7ff2014-04-28 11:10:23 +0000431
Chandler Carruthaaad9f82017-02-09 23:24:13 +0000432 CG.insertEdge(C, B, LazyCallGraph::Edge::Call);
433 EXPECT_EQ(1, std::distance(C->begin(), C->end()));
434 EXPECT_EQ(&B, &C->begin()->getNode());
Chandler Carruthc00a7ff2014-04-28 11:10:23 +0000435
Chandler Carruthaaad9f82017-02-09 23:24:13 +0000436 CG.insertEdge(C, C, LazyCallGraph::Edge::Call);
437 EXPECT_EQ(2, std::distance(C->begin(), C->end()));
438 EXPECT_EQ(&B, &C->begin()->getNode());
439 EXPECT_EQ(&C, &std::next(C->begin())->getNode());
Chandler Carruthc5026b62014-04-30 07:45:27 +0000440
Chandler Carruthaaad9f82017-02-09 23:24:13 +0000441 CG.removeEdge(C, B);
442 EXPECT_EQ(1, std::distance(C->begin(), C->end()));
443 EXPECT_EQ(&C, &C->begin()->getNode());
Chandler Carruthc5026b62014-04-30 07:45:27 +0000444
Chandler Carruthaaad9f82017-02-09 23:24:13 +0000445 CG.removeEdge(C, C);
446 EXPECT_EQ(0, std::distance(C->begin(), C->end()));
Chandler Carruthc5026b62014-04-30 07:45:27 +0000447
Chandler Carruthaaad9f82017-02-09 23:24:13 +0000448 CG.removeEdge(B, C);
449 EXPECT_EQ(0, std::distance(B->begin(), B->end()));
Chandler Carruthc00a7ff2014-04-28 11:10:23 +0000450}
451
Chandler Carruthe5944d92016-02-17 00:18:16 +0000452TEST(LazyCallGraphTest, InnerSCCFormation) {
Mehdi Amini03b42e42016-04-14 21:59:01 +0000453 LLVMContext Context;
454 std::unique_ptr<Module> M = parseAssembly(Context, DiamondOfTriangles);
Chandler Carruthf59a8382017-07-15 08:08:19 +0000455 LazyCallGraph CG = buildCG(*M);
Chandler Carruthe5944d92016-02-17 00:18:16 +0000456
457 // Now mutate the graph to connect every node into a single RefSCC to ensure
458 // that our inner SCC formation handles the rest.
Chandler Carruthaaad9f82017-02-09 23:24:13 +0000459 LazyCallGraph::Node &D1 = CG.get(lookupFunction(*M, "d1"));
460 LazyCallGraph::Node &A1 = CG.get(lookupFunction(*M, "a1"));
461 A1.populate();
462 D1.populate();
463 CG.insertEdge(D1, A1, LazyCallGraph::Edge::Ref);
Chandler Carruthe5944d92016-02-17 00:18:16 +0000464
465 // Build vectors and sort them for the rest of the assertions to make them
466 // independent of order.
467 std::vector<std::string> Nodes;
468
469 // We should build a single RefSCC for the entire graph.
Chandler Carruth2e0fe3e2017-02-06 19:38:06 +0000470 CG.buildRefSCCs();
Chandler Carruthe5944d92016-02-17 00:18:16 +0000471 auto I = CG.postorder_ref_scc_begin();
472 LazyCallGraph::RefSCC &RC = *I++;
473 EXPECT_EQ(CG.postorder_ref_scc_end(), I);
474
475 // Now walk the four SCCs which should be in post-order.
476 auto J = RC.begin();
477 LazyCallGraph::SCC &D = *J++;
478 for (LazyCallGraph::Node &N : D)
479 Nodes.push_back(N.getFunction().getName());
480 std::sort(Nodes.begin(), Nodes.end());
481 EXPECT_EQ(3u, Nodes.size());
482 EXPECT_EQ("d1", Nodes[0]);
483 EXPECT_EQ("d2", Nodes[1]);
484 EXPECT_EQ("d3", Nodes[2]);
485 Nodes.clear();
486
487 LazyCallGraph::SCC &B = *J++;
488 for (LazyCallGraph::Node &N : B)
489 Nodes.push_back(N.getFunction().getName());
490 std::sort(Nodes.begin(), Nodes.end());
491 EXPECT_EQ(3u, Nodes.size());
492 EXPECT_EQ("b1", Nodes[0]);
493 EXPECT_EQ("b2", Nodes[1]);
494 EXPECT_EQ("b3", Nodes[2]);
495 Nodes.clear();
496
497 LazyCallGraph::SCC &C = *J++;
498 for (LazyCallGraph::Node &N : C)
499 Nodes.push_back(N.getFunction().getName());
500 std::sort(Nodes.begin(), Nodes.end());
501 EXPECT_EQ(3u, Nodes.size());
502 EXPECT_EQ("c1", Nodes[0]);
503 EXPECT_EQ("c2", Nodes[1]);
504 EXPECT_EQ("c3", Nodes[2]);
505 Nodes.clear();
506
507 LazyCallGraph::SCC &A = *J++;
508 for (LazyCallGraph::Node &N : A)
509 Nodes.push_back(N.getFunction().getName());
510 std::sort(Nodes.begin(), Nodes.end());
511 EXPECT_EQ(3u, Nodes.size());
512 EXPECT_EQ("a1", Nodes[0]);
513 EXPECT_EQ("a2", Nodes[1]);
514 EXPECT_EQ("a3", Nodes[2]);
515 Nodes.clear();
516
517 EXPECT_EQ(RC.end(), J);
518}
519
Chandler Carruthcace6622014-04-23 10:31:17 +0000520TEST(LazyCallGraphTest, MultiArmSCC) {
Mehdi Amini03b42e42016-04-14 21:59:01 +0000521 LLVMContext Context;
Chandler Carruthcace6622014-04-23 10:31:17 +0000522 // Two interlocking cycles. The really useful thing about this SCC is that it
523 // will require Tarjan's DFS to backtrack and finish processing all of the
Chandler Carruthe5944d92016-02-17 00:18:16 +0000524 // children of each node in the SCC. Since this involves call edges, both
525 // Tarjan implementations will have to successfully navigate the structure.
Mehdi Amini03b42e42016-04-14 21:59:01 +0000526 std::unique_ptr<Module> M = parseAssembly(Context, "define void @f1() {\n"
527 "entry:\n"
528 " call void @f2()\n"
529 " call void @f4()\n"
530 " ret void\n"
531 "}\n"
532 "define void @f2() {\n"
533 "entry:\n"
534 " call void @f3()\n"
535 " ret void\n"
536 "}\n"
537 "define void @f3() {\n"
538 "entry:\n"
539 " call void @f1()\n"
540 " ret void\n"
541 "}\n"
542 "define void @f4() {\n"
543 "entry:\n"
544 " call void @f5()\n"
545 " ret void\n"
546 "}\n"
547 "define void @f5() {\n"
548 "entry:\n"
549 " call void @f1()\n"
550 " ret void\n"
551 "}\n");
Chandler Carruthf59a8382017-07-15 08:08:19 +0000552 LazyCallGraph CG = buildCG(*M);
Chandler Carruthcace6622014-04-23 10:31:17 +0000553
554 // Force the graph to be fully expanded.
Chandler Carruth2e0fe3e2017-02-06 19:38:06 +0000555 CG.buildRefSCCs();
Chandler Carruthe5944d92016-02-17 00:18:16 +0000556 auto I = CG.postorder_ref_scc_begin();
557 LazyCallGraph::RefSCC &RC = *I++;
558 EXPECT_EQ(CG.postorder_ref_scc_end(), I);
Chandler Carruthcace6622014-04-23 10:31:17 +0000559
Chandler Carruthe5944d92016-02-17 00:18:16 +0000560 LazyCallGraph::Node &N1 = *CG.lookup(lookupFunction(*M, "f1"));
561 LazyCallGraph::Node &N2 = *CG.lookup(lookupFunction(*M, "f2"));
562 LazyCallGraph::Node &N3 = *CG.lookup(lookupFunction(*M, "f3"));
563 LazyCallGraph::Node &N4 = *CG.lookup(lookupFunction(*M, "f4"));
564 LazyCallGraph::Node &N5 = *CG.lookup(lookupFunction(*M, "f4"));
565 EXPECT_EQ(&RC, CG.lookupRefSCC(N1));
566 EXPECT_EQ(&RC, CG.lookupRefSCC(N2));
567 EXPECT_EQ(&RC, CG.lookupRefSCC(N3));
568 EXPECT_EQ(&RC, CG.lookupRefSCC(N4));
569 EXPECT_EQ(&RC, CG.lookupRefSCC(N5));
570
571 ASSERT_EQ(1, RC.size());
572
573 LazyCallGraph::SCC &C = *RC.begin();
574 EXPECT_EQ(&C, CG.lookupSCC(N1));
575 EXPECT_EQ(&C, CG.lookupSCC(N2));
576 EXPECT_EQ(&C, CG.lookupSCC(N3));
577 EXPECT_EQ(&C, CG.lookupSCC(N4));
578 EXPECT_EQ(&C, CG.lookupSCC(N5));
Chandler Carruthcace6622014-04-23 10:31:17 +0000579}
580
Chandler Carruthe5944d92016-02-17 00:18:16 +0000581TEST(LazyCallGraphTest, OutgoingEdgeMutation) {
Mehdi Amini03b42e42016-04-14 21:59:01 +0000582 LLVMContext Context;
583 std::unique_ptr<Module> M = parseAssembly(Context, "define void @a() {\n"
584 "entry:\n"
585 " call void @b()\n"
586 " call void @c()\n"
587 " ret void\n"
588 "}\n"
589 "define void @b() {\n"
590 "entry:\n"
591 " call void @d()\n"
592 " ret void\n"
593 "}\n"
594 "define void @c() {\n"
595 "entry:\n"
596 " call void @d()\n"
597 " ret void\n"
598 "}\n"
599 "define void @d() {\n"
600 "entry:\n"
601 " ret void\n"
602 "}\n");
Chandler Carruthf59a8382017-07-15 08:08:19 +0000603 LazyCallGraph CG = buildCG(*M);
Chandler Carruthcc6e1872014-05-04 09:38:23 +0000604
605 // Force the graph to be fully expanded.
Chandler Carruth2e0fe3e2017-02-06 19:38:06 +0000606 CG.buildRefSCCs();
Chandler Carruthe5944d92016-02-17 00:18:16 +0000607 for (LazyCallGraph::RefSCC &RC : CG.postorder_ref_sccs())
Chandler Carruth49d728a2016-09-16 10:20:17 +0000608 dbgs() << "Formed RefSCC: " << RC << "\n";
Chandler Carruthcc6e1872014-05-04 09:38:23 +0000609
610 LazyCallGraph::Node &A = *CG.lookup(lookupFunction(*M, "a"));
611 LazyCallGraph::Node &B = *CG.lookup(lookupFunction(*M, "b"));
612 LazyCallGraph::Node &C = *CG.lookup(lookupFunction(*M, "c"));
613 LazyCallGraph::Node &D = *CG.lookup(lookupFunction(*M, "d"));
614 LazyCallGraph::SCC &AC = *CG.lookupSCC(A);
615 LazyCallGraph::SCC &BC = *CG.lookupSCC(B);
616 LazyCallGraph::SCC &CC = *CG.lookupSCC(C);
617 LazyCallGraph::SCC &DC = *CG.lookupSCC(D);
Chandler Carruthe5944d92016-02-17 00:18:16 +0000618 LazyCallGraph::RefSCC &ARC = *CG.lookupRefSCC(A);
619 LazyCallGraph::RefSCC &BRC = *CG.lookupRefSCC(B);
620 LazyCallGraph::RefSCC &CRC = *CG.lookupRefSCC(C);
621 LazyCallGraph::RefSCC &DRC = *CG.lookupRefSCC(D);
622 EXPECT_TRUE(ARC.isParentOf(BRC));
Chandler Carruthf8c09d62016-11-22 20:35:32 +0000623 EXPECT_TRUE(AC.isParentOf(BC));
Chandler Carruthe5944d92016-02-17 00:18:16 +0000624 EXPECT_TRUE(ARC.isParentOf(CRC));
Chandler Carruthf8c09d62016-11-22 20:35:32 +0000625 EXPECT_TRUE(AC.isParentOf(CC));
Chandler Carruthe5944d92016-02-17 00:18:16 +0000626 EXPECT_FALSE(ARC.isParentOf(DRC));
Chandler Carruthf8c09d62016-11-22 20:35:32 +0000627 EXPECT_FALSE(AC.isParentOf(DC));
Chandler Carruthe5944d92016-02-17 00:18:16 +0000628 EXPECT_TRUE(ARC.isAncestorOf(DRC));
Chandler Carruthf8c09d62016-11-22 20:35:32 +0000629 EXPECT_TRUE(AC.isAncestorOf(DC));
Chandler Carruthe5944d92016-02-17 00:18:16 +0000630 EXPECT_FALSE(DRC.isChildOf(ARC));
Chandler Carruthf8c09d62016-11-22 20:35:32 +0000631 EXPECT_FALSE(DC.isChildOf(AC));
Chandler Carruthe5944d92016-02-17 00:18:16 +0000632 EXPECT_TRUE(DRC.isDescendantOf(ARC));
Chandler Carruthf8c09d62016-11-22 20:35:32 +0000633 EXPECT_TRUE(DC.isDescendantOf(AC));
Chandler Carruthe5944d92016-02-17 00:18:16 +0000634 EXPECT_TRUE(DRC.isChildOf(BRC));
Chandler Carruthf8c09d62016-11-22 20:35:32 +0000635 EXPECT_TRUE(DC.isChildOf(BC));
Chandler Carruthe5944d92016-02-17 00:18:16 +0000636 EXPECT_TRUE(DRC.isChildOf(CRC));
Chandler Carruthf8c09d62016-11-22 20:35:32 +0000637 EXPECT_TRUE(DC.isChildOf(CC));
Chandler Carruthcc6e1872014-05-04 09:38:23 +0000638
Chandler Carruthaaad9f82017-02-09 23:24:13 +0000639 EXPECT_EQ(2, std::distance(A->begin(), A->end()));
Chandler Carruthe5944d92016-02-17 00:18:16 +0000640 ARC.insertOutgoingEdge(A, D, LazyCallGraph::Edge::Call);
Chandler Carruthaaad9f82017-02-09 23:24:13 +0000641 EXPECT_EQ(3, std::distance(A->begin(), A->end()));
642 const LazyCallGraph::Edge &NewE = (*A)[D];
Chandler Carruthe5944d92016-02-17 00:18:16 +0000643 EXPECT_TRUE(NewE);
644 EXPECT_TRUE(NewE.isCall());
Chandler Carruthaaad9f82017-02-09 23:24:13 +0000645 EXPECT_EQ(&D, &NewE.getNode());
Chandler Carruthe5944d92016-02-17 00:18:16 +0000646
647 // Only the parent and child tests sholud have changed. The rest of the graph
648 // remains the same.
649 EXPECT_TRUE(ARC.isParentOf(DRC));
Chandler Carruthf8c09d62016-11-22 20:35:32 +0000650 EXPECT_TRUE(AC.isParentOf(DC));
Chandler Carruthe5944d92016-02-17 00:18:16 +0000651 EXPECT_TRUE(ARC.isAncestorOf(DRC));
Chandler Carruthf8c09d62016-11-22 20:35:32 +0000652 EXPECT_TRUE(AC.isAncestorOf(DC));
Chandler Carruthe5944d92016-02-17 00:18:16 +0000653 EXPECT_TRUE(DRC.isChildOf(ARC));
Chandler Carruthf8c09d62016-11-22 20:35:32 +0000654 EXPECT_TRUE(DC.isChildOf(AC));
Chandler Carruthe5944d92016-02-17 00:18:16 +0000655 EXPECT_TRUE(DRC.isDescendantOf(ARC));
Chandler Carruthf8c09d62016-11-22 20:35:32 +0000656 EXPECT_TRUE(DC.isDescendantOf(AC));
Chandler Carruthcc6e1872014-05-04 09:38:23 +0000657 EXPECT_EQ(&AC, CG.lookupSCC(A));
658 EXPECT_EQ(&BC, CG.lookupSCC(B));
659 EXPECT_EQ(&CC, CG.lookupSCC(C));
660 EXPECT_EQ(&DC, CG.lookupSCC(D));
Chandler Carruthe5944d92016-02-17 00:18:16 +0000661 EXPECT_EQ(&ARC, CG.lookupRefSCC(A));
662 EXPECT_EQ(&BRC, CG.lookupRefSCC(B));
663 EXPECT_EQ(&CRC, CG.lookupRefSCC(C));
664 EXPECT_EQ(&DRC, CG.lookupRefSCC(D));
665
666 ARC.switchOutgoingEdgeToRef(A, D);
667 EXPECT_FALSE(NewE.isCall());
668
Chandler Carruthf8c09d62016-11-22 20:35:32 +0000669 // Verify the reference graph remains the same but the SCC graph is updated.
Chandler Carruthe5944d92016-02-17 00:18:16 +0000670 EXPECT_TRUE(ARC.isParentOf(DRC));
Chandler Carruthf8c09d62016-11-22 20:35:32 +0000671 EXPECT_FALSE(AC.isParentOf(DC));
Chandler Carruthe5944d92016-02-17 00:18:16 +0000672 EXPECT_TRUE(ARC.isAncestorOf(DRC));
Chandler Carruthf8c09d62016-11-22 20:35:32 +0000673 EXPECT_TRUE(AC.isAncestorOf(DC));
Chandler Carruthe5944d92016-02-17 00:18:16 +0000674 EXPECT_TRUE(DRC.isChildOf(ARC));
Chandler Carruthf8c09d62016-11-22 20:35:32 +0000675 EXPECT_FALSE(DC.isChildOf(AC));
Chandler Carruthe5944d92016-02-17 00:18:16 +0000676 EXPECT_TRUE(DRC.isDescendantOf(ARC));
Chandler Carruthf8c09d62016-11-22 20:35:32 +0000677 EXPECT_TRUE(DC.isDescendantOf(AC));
Chandler Carruthe5944d92016-02-17 00:18:16 +0000678 EXPECT_EQ(&AC, CG.lookupSCC(A));
679 EXPECT_EQ(&BC, CG.lookupSCC(B));
680 EXPECT_EQ(&CC, CG.lookupSCC(C));
681 EXPECT_EQ(&DC, CG.lookupSCC(D));
682 EXPECT_EQ(&ARC, CG.lookupRefSCC(A));
683 EXPECT_EQ(&BRC, CG.lookupRefSCC(B));
684 EXPECT_EQ(&CRC, CG.lookupRefSCC(C));
685 EXPECT_EQ(&DRC, CG.lookupRefSCC(D));
686
687 ARC.switchOutgoingEdgeToCall(A, D);
688 EXPECT_TRUE(NewE.isCall());
689
Chandler Carruthf8c09d62016-11-22 20:35:32 +0000690 // Verify the reference graph remains the same but the SCC graph is updated.
Chandler Carruthe5944d92016-02-17 00:18:16 +0000691 EXPECT_TRUE(ARC.isParentOf(DRC));
Chandler Carruthf8c09d62016-11-22 20:35:32 +0000692 EXPECT_TRUE(AC.isParentOf(DC));
Chandler Carruthe5944d92016-02-17 00:18:16 +0000693 EXPECT_TRUE(ARC.isAncestorOf(DRC));
Chandler Carruthf8c09d62016-11-22 20:35:32 +0000694 EXPECT_TRUE(AC.isAncestorOf(DC));
Chandler Carruthe5944d92016-02-17 00:18:16 +0000695 EXPECT_TRUE(DRC.isChildOf(ARC));
Chandler Carruthf8c09d62016-11-22 20:35:32 +0000696 EXPECT_TRUE(DC.isChildOf(AC));
Chandler Carruthe5944d92016-02-17 00:18:16 +0000697 EXPECT_TRUE(DRC.isDescendantOf(ARC));
Chandler Carruthf8c09d62016-11-22 20:35:32 +0000698 EXPECT_TRUE(DC.isDescendantOf(AC));
Chandler Carruthe5944d92016-02-17 00:18:16 +0000699 EXPECT_EQ(&AC, CG.lookupSCC(A));
700 EXPECT_EQ(&BC, CG.lookupSCC(B));
701 EXPECT_EQ(&CC, CG.lookupSCC(C));
702 EXPECT_EQ(&DC, CG.lookupSCC(D));
703 EXPECT_EQ(&ARC, CG.lookupRefSCC(A));
704 EXPECT_EQ(&BRC, CG.lookupRefSCC(B));
705 EXPECT_EQ(&CRC, CG.lookupRefSCC(C));
706 EXPECT_EQ(&DRC, CG.lookupRefSCC(D));
707
708 ARC.removeOutgoingEdge(A, D);
Chandler Carruthaaad9f82017-02-09 23:24:13 +0000709 EXPECT_EQ(2, std::distance(A->begin(), A->end()));
Chandler Carruthe5944d92016-02-17 00:18:16 +0000710
711 // Now the parent and child tests fail again but the rest remains the same.
712 EXPECT_FALSE(ARC.isParentOf(DRC));
Chandler Carruthf8c09d62016-11-22 20:35:32 +0000713 EXPECT_FALSE(AC.isParentOf(DC));
Chandler Carruthe5944d92016-02-17 00:18:16 +0000714 EXPECT_TRUE(ARC.isAncestorOf(DRC));
Chandler Carruthf8c09d62016-11-22 20:35:32 +0000715 EXPECT_TRUE(AC.isAncestorOf(DC));
Chandler Carruthe5944d92016-02-17 00:18:16 +0000716 EXPECT_FALSE(DRC.isChildOf(ARC));
Chandler Carruthf8c09d62016-11-22 20:35:32 +0000717 EXPECT_FALSE(DC.isChildOf(AC));
Chandler Carruthe5944d92016-02-17 00:18:16 +0000718 EXPECT_TRUE(DRC.isDescendantOf(ARC));
Chandler Carruthf8c09d62016-11-22 20:35:32 +0000719 EXPECT_TRUE(DC.isDescendantOf(AC));
Chandler Carruthe5944d92016-02-17 00:18:16 +0000720 EXPECT_EQ(&AC, CG.lookupSCC(A));
721 EXPECT_EQ(&BC, CG.lookupSCC(B));
722 EXPECT_EQ(&CC, CG.lookupSCC(C));
723 EXPECT_EQ(&DC, CG.lookupSCC(D));
724 EXPECT_EQ(&ARC, CG.lookupRefSCC(A));
725 EXPECT_EQ(&BRC, CG.lookupRefSCC(B));
726 EXPECT_EQ(&CRC, CG.lookupRefSCC(C));
727 EXPECT_EQ(&DRC, CG.lookupRefSCC(D));
Chandler Carruthcc6e1872014-05-04 09:38:23 +0000728}
729
Chandler Carruthe5944d92016-02-17 00:18:16 +0000730TEST(LazyCallGraphTest, IncomingEdgeInsertion) {
Mehdi Amini03b42e42016-04-14 21:59:01 +0000731 LLVMContext Context;
Chandler Carruth312dddf2014-05-04 09:38:32 +0000732 // We want to ensure we can add edges even across complex diamond graphs, so
733 // we use the diamond of triangles graph defined above. The ascii diagram is
734 // repeated here for easy reference.
735 //
736 // d1 |
737 // / \ |
738 // d3--d2 |
739 // / \ |
740 // b1 c1 |
741 // / \ / \ |
742 // b3--b2 c3--c2 |
743 // \ / |
744 // a1 |
745 // / \ |
746 // a3--a2 |
747 //
Mehdi Amini03b42e42016-04-14 21:59:01 +0000748 std::unique_ptr<Module> M = parseAssembly(Context, DiamondOfTriangles);
Chandler Carruthf59a8382017-07-15 08:08:19 +0000749 LazyCallGraph CG = buildCG(*M);
Chandler Carruth312dddf2014-05-04 09:38:32 +0000750
751 // Force the graph to be fully expanded.
Chandler Carruth2e0fe3e2017-02-06 19:38:06 +0000752 CG.buildRefSCCs();
Chandler Carruthe5944d92016-02-17 00:18:16 +0000753 for (LazyCallGraph::RefSCC &RC : CG.postorder_ref_sccs())
Chandler Carruth49d728a2016-09-16 10:20:17 +0000754 dbgs() << "Formed RefSCC: " << RC << "\n";
Chandler Carruth312dddf2014-05-04 09:38:32 +0000755
756 LazyCallGraph::Node &A1 = *CG.lookup(lookupFunction(*M, "a1"));
757 LazyCallGraph::Node &A2 = *CG.lookup(lookupFunction(*M, "a2"));
758 LazyCallGraph::Node &A3 = *CG.lookup(lookupFunction(*M, "a3"));
759 LazyCallGraph::Node &B1 = *CG.lookup(lookupFunction(*M, "b1"));
760 LazyCallGraph::Node &B2 = *CG.lookup(lookupFunction(*M, "b2"));
761 LazyCallGraph::Node &B3 = *CG.lookup(lookupFunction(*M, "b3"));
762 LazyCallGraph::Node &C1 = *CG.lookup(lookupFunction(*M, "c1"));
763 LazyCallGraph::Node &C2 = *CG.lookup(lookupFunction(*M, "c2"));
764 LazyCallGraph::Node &C3 = *CG.lookup(lookupFunction(*M, "c3"));
765 LazyCallGraph::Node &D1 = *CG.lookup(lookupFunction(*M, "d1"));
766 LazyCallGraph::Node &D2 = *CG.lookup(lookupFunction(*M, "d2"));
767 LazyCallGraph::Node &D3 = *CG.lookup(lookupFunction(*M, "d3"));
Chandler Carruthe5944d92016-02-17 00:18:16 +0000768 LazyCallGraph::RefSCC &ARC = *CG.lookupRefSCC(A1);
769 LazyCallGraph::RefSCC &BRC = *CG.lookupRefSCC(B1);
770 LazyCallGraph::RefSCC &CRC = *CG.lookupRefSCC(C1);
771 LazyCallGraph::RefSCC &DRC = *CG.lookupRefSCC(D1);
772 ASSERT_EQ(&ARC, CG.lookupRefSCC(A2));
773 ASSERT_EQ(&ARC, CG.lookupRefSCC(A3));
774 ASSERT_EQ(&BRC, CG.lookupRefSCC(B2));
775 ASSERT_EQ(&BRC, CG.lookupRefSCC(B3));
776 ASSERT_EQ(&CRC, CG.lookupRefSCC(C2));
777 ASSERT_EQ(&CRC, CG.lookupRefSCC(C3));
778 ASSERT_EQ(&DRC, CG.lookupRefSCC(D2));
779 ASSERT_EQ(&DRC, CG.lookupRefSCC(D3));
Chandler Carruthaaad9f82017-02-09 23:24:13 +0000780 ASSERT_EQ(1, std::distance(D2->begin(), D2->end()));
Chandler Carruth312dddf2014-05-04 09:38:32 +0000781
782 // Add an edge to make the graph:
783 //
784 // d1 |
785 // / \ |
786 // d3--d2---. |
787 // / \ | |
788 // b1 c1 | |
789 // / \ / \ / |
790 // b3--b2 c3--c2 |
791 // \ / |
792 // a1 |
793 // / \ |
794 // a3--a2 |
Chandler Carruthe5944d92016-02-17 00:18:16 +0000795 auto MergedRCs = CRC.insertIncomingRefEdge(D2, C2);
Chandler Carruth312dddf2014-05-04 09:38:32 +0000796 // Make sure we connected the nodes.
Chandler Carruthaaad9f82017-02-09 23:24:13 +0000797 for (LazyCallGraph::Edge E : *D2) {
798 if (&E.getNode() == &D3)
Chandler Carruthe5944d92016-02-17 00:18:16 +0000799 continue;
Chandler Carruthaaad9f82017-02-09 23:24:13 +0000800 EXPECT_EQ(&C2, &E.getNode());
Chandler Carruthe5944d92016-02-17 00:18:16 +0000801 }
802 // And marked the D ref-SCC as no longer valid.
803 EXPECT_EQ(1u, MergedRCs.size());
804 EXPECT_EQ(&DRC, MergedRCs[0]);
Chandler Carruth312dddf2014-05-04 09:38:32 +0000805
806 // Make sure we have the correct nodes in the SCC sets.
Chandler Carruthe5944d92016-02-17 00:18:16 +0000807 EXPECT_EQ(&ARC, CG.lookupRefSCC(A1));
808 EXPECT_EQ(&ARC, CG.lookupRefSCC(A2));
809 EXPECT_EQ(&ARC, CG.lookupRefSCC(A3));
810 EXPECT_EQ(&BRC, CG.lookupRefSCC(B1));
811 EXPECT_EQ(&BRC, CG.lookupRefSCC(B2));
812 EXPECT_EQ(&BRC, CG.lookupRefSCC(B3));
813 EXPECT_EQ(&CRC, CG.lookupRefSCC(C1));
814 EXPECT_EQ(&CRC, CG.lookupRefSCC(C2));
815 EXPECT_EQ(&CRC, CG.lookupRefSCC(C3));
816 EXPECT_EQ(&CRC, CG.lookupRefSCC(D1));
817 EXPECT_EQ(&CRC, CG.lookupRefSCC(D2));
818 EXPECT_EQ(&CRC, CG.lookupRefSCC(D3));
Chandler Carruth312dddf2014-05-04 09:38:32 +0000819
820 // And that ancestry tests have been updated.
Chandler Carruthe5944d92016-02-17 00:18:16 +0000821 EXPECT_TRUE(ARC.isParentOf(CRC));
822 EXPECT_TRUE(BRC.isParentOf(CRC));
Chandler Carruth49d728a2016-09-16 10:20:17 +0000823
824 // And verify the post-order walk reflects the updated structure.
825 auto I = CG.postorder_ref_scc_begin(), E = CG.postorder_ref_scc_end();
826 ASSERT_NE(I, E);
827 EXPECT_EQ(&CRC, &*I) << "Actual RefSCC: " << *I;
828 ASSERT_NE(++I, E);
829 EXPECT_EQ(&BRC, &*I) << "Actual RefSCC: " << *I;
830 ASSERT_NE(++I, E);
831 EXPECT_EQ(&ARC, &*I) << "Actual RefSCC: " << *I;
832 EXPECT_EQ(++I, E);
Chandler Carruth312dddf2014-05-04 09:38:32 +0000833}
834
Chandler Carruth49d728a2016-09-16 10:20:17 +0000835TEST(LazyCallGraphTest, IncomingEdgeInsertionRefGraph) {
836 LLVMContext Context;
837 // Another variation of the above test but with all the edges switched to
838 // references rather than calls.
839 std::unique_ptr<Module> M =
840 parseAssembly(Context, DiamondOfTrianglesRefGraph);
Chandler Carruthf59a8382017-07-15 08:08:19 +0000841 LazyCallGraph CG = buildCG(*M);
Chandler Carruth49d728a2016-09-16 10:20:17 +0000842
843 // Force the graph to be fully expanded.
Chandler Carruth2e0fe3e2017-02-06 19:38:06 +0000844 CG.buildRefSCCs();
Chandler Carruth49d728a2016-09-16 10:20:17 +0000845 for (LazyCallGraph::RefSCC &RC : CG.postorder_ref_sccs())
846 dbgs() << "Formed RefSCC: " << RC << "\n";
847
848 LazyCallGraph::Node &A1 = *CG.lookup(lookupFunction(*M, "a1"));
849 LazyCallGraph::Node &A2 = *CG.lookup(lookupFunction(*M, "a2"));
850 LazyCallGraph::Node &A3 = *CG.lookup(lookupFunction(*M, "a3"));
851 LazyCallGraph::Node &B1 = *CG.lookup(lookupFunction(*M, "b1"));
852 LazyCallGraph::Node &B2 = *CG.lookup(lookupFunction(*M, "b2"));
853 LazyCallGraph::Node &B3 = *CG.lookup(lookupFunction(*M, "b3"));
854 LazyCallGraph::Node &C1 = *CG.lookup(lookupFunction(*M, "c1"));
855 LazyCallGraph::Node &C2 = *CG.lookup(lookupFunction(*M, "c2"));
856 LazyCallGraph::Node &C3 = *CG.lookup(lookupFunction(*M, "c3"));
857 LazyCallGraph::Node &D1 = *CG.lookup(lookupFunction(*M, "d1"));
858 LazyCallGraph::Node &D2 = *CG.lookup(lookupFunction(*M, "d2"));
859 LazyCallGraph::Node &D3 = *CG.lookup(lookupFunction(*M, "d3"));
860 LazyCallGraph::RefSCC &ARC = *CG.lookupRefSCC(A1);
861 LazyCallGraph::RefSCC &BRC = *CG.lookupRefSCC(B1);
862 LazyCallGraph::RefSCC &CRC = *CG.lookupRefSCC(C1);
863 LazyCallGraph::RefSCC &DRC = *CG.lookupRefSCC(D1);
864 ASSERT_EQ(&ARC, CG.lookupRefSCC(A2));
865 ASSERT_EQ(&ARC, CG.lookupRefSCC(A3));
866 ASSERT_EQ(&BRC, CG.lookupRefSCC(B2));
867 ASSERT_EQ(&BRC, CG.lookupRefSCC(B3));
868 ASSERT_EQ(&CRC, CG.lookupRefSCC(C2));
869 ASSERT_EQ(&CRC, CG.lookupRefSCC(C3));
870 ASSERT_EQ(&DRC, CG.lookupRefSCC(D2));
871 ASSERT_EQ(&DRC, CG.lookupRefSCC(D3));
Chandler Carruthaaad9f82017-02-09 23:24:13 +0000872 ASSERT_EQ(1, std::distance(D2->begin(), D2->end()));
Chandler Carruth49d728a2016-09-16 10:20:17 +0000873
874 // Add an edge to make the graph:
875 //
876 // d1 |
877 // / \ |
878 // d3--d2---. |
879 // / \ | |
880 // b1 c1 | |
881 // / \ / \ / |
882 // b3--b2 c3--c2 |
883 // \ / |
884 // a1 |
885 // / \ |
886 // a3--a2 |
887 auto MergedRCs = CRC.insertIncomingRefEdge(D2, C2);
888 // Make sure we connected the nodes.
Chandler Carruthaaad9f82017-02-09 23:24:13 +0000889 for (LazyCallGraph::Edge E : *D2) {
890 if (&E.getNode() == &D3)
Chandler Carruth49d728a2016-09-16 10:20:17 +0000891 continue;
Chandler Carruthaaad9f82017-02-09 23:24:13 +0000892 EXPECT_EQ(&C2, &E.getNode());
Chandler Carruth49d728a2016-09-16 10:20:17 +0000893 }
894 // And marked the D ref-SCC as no longer valid.
895 EXPECT_EQ(1u, MergedRCs.size());
896 EXPECT_EQ(&DRC, MergedRCs[0]);
897
898 // Make sure we have the correct nodes in the SCC sets.
899 EXPECT_EQ(&ARC, CG.lookupRefSCC(A1));
900 EXPECT_EQ(&ARC, CG.lookupRefSCC(A2));
901 EXPECT_EQ(&ARC, CG.lookupRefSCC(A3));
902 EXPECT_EQ(&BRC, CG.lookupRefSCC(B1));
903 EXPECT_EQ(&BRC, CG.lookupRefSCC(B2));
904 EXPECT_EQ(&BRC, CG.lookupRefSCC(B3));
905 EXPECT_EQ(&CRC, CG.lookupRefSCC(C1));
906 EXPECT_EQ(&CRC, CG.lookupRefSCC(C2));
907 EXPECT_EQ(&CRC, CG.lookupRefSCC(C3));
908 EXPECT_EQ(&CRC, CG.lookupRefSCC(D1));
909 EXPECT_EQ(&CRC, CG.lookupRefSCC(D2));
910 EXPECT_EQ(&CRC, CG.lookupRefSCC(D3));
911
912 // And that ancestry tests have been updated.
913 EXPECT_TRUE(ARC.isParentOf(CRC));
914 EXPECT_TRUE(BRC.isParentOf(CRC));
915
916 // And verify the post-order walk reflects the updated structure.
917 auto I = CG.postorder_ref_scc_begin(), E = CG.postorder_ref_scc_end();
918 ASSERT_NE(I, E);
919 EXPECT_EQ(&CRC, &*I) << "Actual RefSCC: " << *I;
920 ASSERT_NE(++I, E);
921 EXPECT_EQ(&BRC, &*I) << "Actual RefSCC: " << *I;
922 ASSERT_NE(++I, E);
923 EXPECT_EQ(&ARC, &*I) << "Actual RefSCC: " << *I;
924 EXPECT_EQ(++I, E);
925}
926
927TEST(LazyCallGraphTest, IncomingEdgeInsertionLargeCallCycle) {
928 LLVMContext Context;
929 std::unique_ptr<Module> M = parseAssembly(Context, "define void @a() {\n"
930 "entry:\n"
931 " call void @b()\n"
932 " ret void\n"
933 "}\n"
934 "define void @b() {\n"
935 "entry:\n"
936 " call void @c()\n"
937 " ret void\n"
938 "}\n"
939 "define void @c() {\n"
940 "entry:\n"
941 " call void @d()\n"
942 " ret void\n"
943 "}\n"
944 "define void @d() {\n"
945 "entry:\n"
946 " ret void\n"
947 "}\n");
Chandler Carruthf59a8382017-07-15 08:08:19 +0000948 LazyCallGraph CG = buildCG(*M);
Chandler Carruth49d728a2016-09-16 10:20:17 +0000949
950 // Force the graph to be fully expanded.
Chandler Carruth2e0fe3e2017-02-06 19:38:06 +0000951 CG.buildRefSCCs();
Chandler Carruth49d728a2016-09-16 10:20:17 +0000952 for (LazyCallGraph::RefSCC &RC : CG.postorder_ref_sccs())
953 dbgs() << "Formed RefSCC: " << RC << "\n";
954
955 LazyCallGraph::Node &A = *CG.lookup(lookupFunction(*M, "a"));
956 LazyCallGraph::Node &B = *CG.lookup(lookupFunction(*M, "b"));
957 LazyCallGraph::Node &C = *CG.lookup(lookupFunction(*M, "c"));
958 LazyCallGraph::Node &D = *CG.lookup(lookupFunction(*M, "d"));
959 LazyCallGraph::SCC &AC = *CG.lookupSCC(A);
960 LazyCallGraph::SCC &BC = *CG.lookupSCC(B);
961 LazyCallGraph::SCC &CC = *CG.lookupSCC(C);
962 LazyCallGraph::SCC &DC = *CG.lookupSCC(D);
963 LazyCallGraph::RefSCC &ARC = *CG.lookupRefSCC(A);
964 LazyCallGraph::RefSCC &BRC = *CG.lookupRefSCC(B);
965 LazyCallGraph::RefSCC &CRC = *CG.lookupRefSCC(C);
966 LazyCallGraph::RefSCC &DRC = *CG.lookupRefSCC(D);
967
968 // Connect the top to the bottom forming a large RefSCC made up mostly of calls.
969 auto MergedRCs = ARC.insertIncomingRefEdge(D, A);
970 // Make sure we connected the nodes.
Chandler Carruthaaad9f82017-02-09 23:24:13 +0000971 EXPECT_NE(D->begin(), D->end());
972 EXPECT_EQ(&A, &D->begin()->getNode());
Chandler Carruth49d728a2016-09-16 10:20:17 +0000973
974 // Check that we have the dead RCs, but ignore the order.
975 EXPECT_EQ(3u, MergedRCs.size());
976 EXPECT_NE(find(MergedRCs, &BRC), MergedRCs.end());
977 EXPECT_NE(find(MergedRCs, &CRC), MergedRCs.end());
978 EXPECT_NE(find(MergedRCs, &DRC), MergedRCs.end());
979
980 // Make sure the nodes point to the right place now.
981 EXPECT_EQ(&ARC, CG.lookupRefSCC(A));
982 EXPECT_EQ(&ARC, CG.lookupRefSCC(B));
983 EXPECT_EQ(&ARC, CG.lookupRefSCC(C));
984 EXPECT_EQ(&ARC, CG.lookupRefSCC(D));
985
986 // Check that the SCCs are in postorder.
987 EXPECT_EQ(4, ARC.size());
988 EXPECT_EQ(&DC, &ARC[0]);
989 EXPECT_EQ(&CC, &ARC[1]);
990 EXPECT_EQ(&BC, &ARC[2]);
991 EXPECT_EQ(&AC, &ARC[3]);
992
993 // And verify the post-order walk reflects the updated structure.
994 auto I = CG.postorder_ref_scc_begin(), E = CG.postorder_ref_scc_end();
995 ASSERT_NE(I, E);
996 EXPECT_EQ(&ARC, &*I) << "Actual RefSCC: " << *I;
997 EXPECT_EQ(++I, E);
998}
999
1000TEST(LazyCallGraphTest, IncomingEdgeInsertionLargeRefCycle) {
1001 LLVMContext Context;
1002 std::unique_ptr<Module> M =
1003 parseAssembly(Context, "define void @a() {\n"
1004 "entry:\n"
1005 " %p = alloca void ()*\n"
1006 " store void ()* @b, void ()** %p\n"
1007 " ret void\n"
1008 "}\n"
1009 "define void @b() {\n"
1010 "entry:\n"
1011 " %p = alloca void ()*\n"
1012 " store void ()* @c, void ()** %p\n"
1013 " ret void\n"
1014 "}\n"
1015 "define void @c() {\n"
1016 "entry:\n"
1017 " %p = alloca void ()*\n"
1018 " store void ()* @d, void ()** %p\n"
1019 " ret void\n"
1020 "}\n"
1021 "define void @d() {\n"
1022 "entry:\n"
1023 " ret void\n"
1024 "}\n");
Chandler Carruthf59a8382017-07-15 08:08:19 +00001025 LazyCallGraph CG = buildCG(*M);
Chandler Carruth49d728a2016-09-16 10:20:17 +00001026
1027 // Force the graph to be fully expanded.
Chandler Carruth2e0fe3e2017-02-06 19:38:06 +00001028 CG.buildRefSCCs();
Chandler Carruth49d728a2016-09-16 10:20:17 +00001029 for (LazyCallGraph::RefSCC &RC : CG.postorder_ref_sccs())
1030 dbgs() << "Formed RefSCC: " << RC << "\n";
1031
1032 LazyCallGraph::Node &A = *CG.lookup(lookupFunction(*M, "a"));
1033 LazyCallGraph::Node &B = *CG.lookup(lookupFunction(*M, "b"));
1034 LazyCallGraph::Node &C = *CG.lookup(lookupFunction(*M, "c"));
1035 LazyCallGraph::Node &D = *CG.lookup(lookupFunction(*M, "d"));
1036 LazyCallGraph::RefSCC &ARC = *CG.lookupRefSCC(A);
1037 LazyCallGraph::RefSCC &BRC = *CG.lookupRefSCC(B);
1038 LazyCallGraph::RefSCC &CRC = *CG.lookupRefSCC(C);
1039 LazyCallGraph::RefSCC &DRC = *CG.lookupRefSCC(D);
1040
1041 // Connect the top to the bottom forming a large RefSCC made up just of
1042 // references.
1043 auto MergedRCs = ARC.insertIncomingRefEdge(D, A);
1044 // Make sure we connected the nodes.
Chandler Carruthaaad9f82017-02-09 23:24:13 +00001045 EXPECT_NE(D->begin(), D->end());
1046 EXPECT_EQ(&A, &D->begin()->getNode());
Chandler Carruth49d728a2016-09-16 10:20:17 +00001047
1048 // Check that we have the dead RCs, but ignore the order.
1049 EXPECT_EQ(3u, MergedRCs.size());
1050 EXPECT_NE(find(MergedRCs, &BRC), MergedRCs.end());
1051 EXPECT_NE(find(MergedRCs, &CRC), MergedRCs.end());
1052 EXPECT_NE(find(MergedRCs, &DRC), MergedRCs.end());
1053
1054 // Make sure the nodes point to the right place now.
1055 EXPECT_EQ(&ARC, CG.lookupRefSCC(A));
1056 EXPECT_EQ(&ARC, CG.lookupRefSCC(B));
1057 EXPECT_EQ(&ARC, CG.lookupRefSCC(C));
1058 EXPECT_EQ(&ARC, CG.lookupRefSCC(D));
1059
1060 // And verify the post-order walk reflects the updated structure.
1061 auto I = CG.postorder_ref_scc_begin(), End = CG.postorder_ref_scc_end();
1062 ASSERT_NE(I, End);
1063 EXPECT_EQ(&ARC, &*I) << "Actual RefSCC: " << *I;
1064 EXPECT_EQ(++I, End);
Chandler Carruth312dddf2014-05-04 09:38:32 +00001065}
1066
Chandler Carruth5dbc1642016-10-12 07:59:56 +00001067TEST(LazyCallGraphTest, InlineAndDeleteFunction) {
1068 LLVMContext Context;
1069 // We want to ensure we can delete nodes from relatively complex graphs and
1070 // so use the diamond of triangles graph defined above.
1071 //
1072 // The ascii diagram is repeated here for easy reference.
1073 //
1074 // d1 |
1075 // / \ |
1076 // d3--d2 |
1077 // / \ |
1078 // b1 c1 |
1079 // / \ / \ |
1080 // b3--b2 c3--c2 |
1081 // \ / |
1082 // a1 |
1083 // / \ |
1084 // a3--a2 |
1085 //
1086 std::unique_ptr<Module> M = parseAssembly(Context, DiamondOfTriangles);
Chandler Carruthf59a8382017-07-15 08:08:19 +00001087 LazyCallGraph CG = buildCG(*M);
Chandler Carruth5dbc1642016-10-12 07:59:56 +00001088
1089 // Force the graph to be fully expanded.
Chandler Carruth2e0fe3e2017-02-06 19:38:06 +00001090 CG.buildRefSCCs();
Chandler Carruth5dbc1642016-10-12 07:59:56 +00001091 for (LazyCallGraph::RefSCC &RC : CG.postorder_ref_sccs())
1092 dbgs() << "Formed RefSCC: " << RC << "\n";
1093
1094 LazyCallGraph::Node &A1 = *CG.lookup(lookupFunction(*M, "a1"));
1095 LazyCallGraph::Node &A2 = *CG.lookup(lookupFunction(*M, "a2"));
1096 LazyCallGraph::Node &A3 = *CG.lookup(lookupFunction(*M, "a3"));
1097 LazyCallGraph::Node &B1 = *CG.lookup(lookupFunction(*M, "b1"));
1098 LazyCallGraph::Node &B2 = *CG.lookup(lookupFunction(*M, "b2"));
1099 LazyCallGraph::Node &B3 = *CG.lookup(lookupFunction(*M, "b3"));
1100 LazyCallGraph::Node &C1 = *CG.lookup(lookupFunction(*M, "c1"));
1101 LazyCallGraph::Node &C2 = *CG.lookup(lookupFunction(*M, "c2"));
1102 LazyCallGraph::Node &C3 = *CG.lookup(lookupFunction(*M, "c3"));
1103 LazyCallGraph::Node &D1 = *CG.lookup(lookupFunction(*M, "d1"));
1104 LazyCallGraph::Node &D2 = *CG.lookup(lookupFunction(*M, "d2"));
1105 LazyCallGraph::Node &D3 = *CG.lookup(lookupFunction(*M, "d3"));
1106 LazyCallGraph::RefSCC &ARC = *CG.lookupRefSCC(A1);
1107 LazyCallGraph::RefSCC &BRC = *CG.lookupRefSCC(B1);
1108 LazyCallGraph::RefSCC &CRC = *CG.lookupRefSCC(C1);
1109 LazyCallGraph::RefSCC &DRC = *CG.lookupRefSCC(D1);
1110 ASSERT_EQ(&ARC, CG.lookupRefSCC(A2));
1111 ASSERT_EQ(&ARC, CG.lookupRefSCC(A3));
1112 ASSERT_EQ(&BRC, CG.lookupRefSCC(B2));
1113 ASSERT_EQ(&BRC, CG.lookupRefSCC(B3));
1114 ASSERT_EQ(&CRC, CG.lookupRefSCC(C2));
1115 ASSERT_EQ(&CRC, CG.lookupRefSCC(C3));
1116 ASSERT_EQ(&DRC, CG.lookupRefSCC(D2));
1117 ASSERT_EQ(&DRC, CG.lookupRefSCC(D3));
Chandler Carruthaaad9f82017-02-09 23:24:13 +00001118 ASSERT_EQ(1, std::distance(D2->begin(), D2->end()));
Chandler Carruth5dbc1642016-10-12 07:59:56 +00001119
1120 // Delete d2 from the graph, as if it had been inlined.
1121 //
1122 // d1 |
1123 // / / |
1124 // d3--. |
1125 // / \ |
1126 // b1 c1 |
1127 // / \ / \ |
1128 // b3--b2 c3--c2 |
1129 // \ / |
1130 // a1 |
1131 // / \ |
1132 // a3--a2 |
1133
1134 Function &D2F = D2.getFunction();
1135 CallInst *C1Call = nullptr, *D1Call = nullptr;
1136 for (User *U : D2F.users()) {
1137 CallInst *CI = dyn_cast<CallInst>(U);
1138 ASSERT_TRUE(CI) << "Expected a call: " << *U;
1139 if (CI->getParent()->getParent() == &C1.getFunction()) {
1140 ASSERT_EQ(nullptr, C1Call) << "Found too many C1 calls: " << *CI;
1141 C1Call = CI;
1142 } else if (CI->getParent()->getParent() == &D1.getFunction()) {
1143 ASSERT_EQ(nullptr, D1Call) << "Found too many D1 calls: " << *CI;
1144 D1Call = CI;
1145 } else {
1146 FAIL() << "Found an unexpected call instruction: " << *CI;
1147 }
1148 }
1149 ASSERT_NE(C1Call, nullptr);
1150 ASSERT_NE(D1Call, nullptr);
1151 ASSERT_EQ(&D2F, C1Call->getCalledFunction());
1152 ASSERT_EQ(&D2F, D1Call->getCalledFunction());
1153 C1Call->setCalledFunction(&D3.getFunction());
1154 D1Call->setCalledFunction(&D3.getFunction());
1155 ASSERT_EQ(0u, D2F.getNumUses());
1156
1157 // Insert new edges first.
1158 CRC.insertTrivialCallEdge(C1, D3);
1159 DRC.insertTrivialCallEdge(D1, D3);
1160
1161 // Then remove the old ones.
1162 LazyCallGraph::SCC &DC = *CG.lookupSCC(D2);
1163 auto NewCs = DRC.switchInternalEdgeToRef(D1, D2);
1164 EXPECT_EQ(&DC, CG.lookupSCC(D2));
1165 EXPECT_EQ(NewCs.end(), std::next(NewCs.begin()));
1166 LazyCallGraph::SCC &NewDC = *NewCs.begin();
1167 EXPECT_EQ(&NewDC, CG.lookupSCC(D1));
1168 EXPECT_EQ(&NewDC, CG.lookupSCC(D3));
1169 auto NewRCs = DRC.removeInternalRefEdge(D1, D2);
1170 EXPECT_EQ(&DRC, CG.lookupRefSCC(D2));
1171 EXPECT_EQ(NewRCs.end(), std::next(NewRCs.begin()));
1172 LazyCallGraph::RefSCC &NewDRC = **NewRCs.begin();
1173 EXPECT_EQ(&NewDRC, CG.lookupRefSCC(D1));
1174 EXPECT_EQ(&NewDRC, CG.lookupRefSCC(D3));
1175 EXPECT_FALSE(NewDRC.isParentOf(DRC));
1176 EXPECT_TRUE(CRC.isParentOf(DRC));
1177 EXPECT_TRUE(CRC.isParentOf(NewDRC));
1178 EXPECT_TRUE(DRC.isParentOf(NewDRC));
1179 CRC.removeOutgoingEdge(C1, D2);
1180 EXPECT_FALSE(CRC.isParentOf(DRC));
1181 EXPECT_TRUE(CRC.isParentOf(NewDRC));
1182 EXPECT_TRUE(DRC.isParentOf(NewDRC));
1183
1184 // Now that we've updated the call graph, D2 is dead, so remove it.
1185 CG.removeDeadFunction(D2F);
1186
1187 // Check that the graph still looks the same.
1188 EXPECT_EQ(&ARC, CG.lookupRefSCC(A1));
1189 EXPECT_EQ(&ARC, CG.lookupRefSCC(A2));
1190 EXPECT_EQ(&ARC, CG.lookupRefSCC(A3));
1191 EXPECT_EQ(&BRC, CG.lookupRefSCC(B1));
1192 EXPECT_EQ(&BRC, CG.lookupRefSCC(B2));
1193 EXPECT_EQ(&BRC, CG.lookupRefSCC(B3));
1194 EXPECT_EQ(&CRC, CG.lookupRefSCC(C1));
1195 EXPECT_EQ(&CRC, CG.lookupRefSCC(C2));
1196 EXPECT_EQ(&CRC, CG.lookupRefSCC(C3));
1197 EXPECT_EQ(&NewDRC, CG.lookupRefSCC(D1));
1198 EXPECT_EQ(&NewDRC, CG.lookupRefSCC(D3));
1199 EXPECT_TRUE(CRC.isParentOf(NewDRC));
1200
1201 // Verify the post-order walk hasn't changed.
1202 auto I = CG.postorder_ref_scc_begin(), E = CG.postorder_ref_scc_end();
1203 ASSERT_NE(I, E);
1204 EXPECT_EQ(&NewDRC, &*I) << "Actual RefSCC: " << *I;
1205 ASSERT_NE(++I, E);
1206 EXPECT_EQ(&CRC, &*I) << "Actual RefSCC: " << *I;
1207 ASSERT_NE(++I, E);
1208 EXPECT_EQ(&BRC, &*I) << "Actual RefSCC: " << *I;
1209 ASSERT_NE(++I, E);
1210 EXPECT_EQ(&ARC, &*I) << "Actual RefSCC: " << *I;
1211 EXPECT_EQ(++I, E);
1212}
1213
Chandler Carruthe5944d92016-02-17 00:18:16 +00001214TEST(LazyCallGraphTest, InternalEdgeMutation) {
Mehdi Amini03b42e42016-04-14 21:59:01 +00001215 LLVMContext Context;
1216 std::unique_ptr<Module> M = parseAssembly(Context, "define void @a() {\n"
1217 "entry:\n"
1218 " call void @b()\n"
1219 " ret void\n"
1220 "}\n"
1221 "define void @b() {\n"
1222 "entry:\n"
1223 " call void @c()\n"
1224 " ret void\n"
1225 "}\n"
1226 "define void @c() {\n"
1227 "entry:\n"
1228 " call void @a()\n"
1229 " ret void\n"
1230 "}\n");
Chandler Carruthf59a8382017-07-15 08:08:19 +00001231 LazyCallGraph CG = buildCG(*M);
Chandler Carruth9302fbf2014-04-23 11:03:03 +00001232
1233 // Force the graph to be fully expanded.
Chandler Carruth2e0fe3e2017-02-06 19:38:06 +00001234 CG.buildRefSCCs();
Chandler Carruthe5944d92016-02-17 00:18:16 +00001235 auto I = CG.postorder_ref_scc_begin();
1236 LazyCallGraph::RefSCC &RC = *I++;
1237 EXPECT_EQ(CG.postorder_ref_scc_end(), I);
Chandler Carruth9302fbf2014-04-23 11:03:03 +00001238
Chandler Carrutha10e2402014-04-23 23:12:06 +00001239 LazyCallGraph::Node &A = *CG.lookup(lookupFunction(*M, "a"));
1240 LazyCallGraph::Node &B = *CG.lookup(lookupFunction(*M, "b"));
Chandler Carruthe5944d92016-02-17 00:18:16 +00001241 LazyCallGraph::Node &C = *CG.lookup(lookupFunction(*M, "c"));
1242 EXPECT_EQ(&RC, CG.lookupRefSCC(A));
1243 EXPECT_EQ(&RC, CG.lookupRefSCC(B));
1244 EXPECT_EQ(&RC, CG.lookupRefSCC(C));
1245 EXPECT_EQ(1, RC.size());
1246 EXPECT_EQ(&*RC.begin(), CG.lookupSCC(A));
1247 EXPECT_EQ(&*RC.begin(), CG.lookupSCC(B));
1248 EXPECT_EQ(&*RC.begin(), CG.lookupSCC(C));
Chandler Carruth9302fbf2014-04-23 11:03:03 +00001249
Chandler Carruthe5944d92016-02-17 00:18:16 +00001250 // Insert an edge from 'a' to 'c'. Nothing changes about the graph.
1251 RC.insertInternalRefEdge(A, C);
Chandler Carruthaaad9f82017-02-09 23:24:13 +00001252 EXPECT_EQ(2, std::distance(A->begin(), A->end()));
Chandler Carruthe5944d92016-02-17 00:18:16 +00001253 EXPECT_EQ(&RC, CG.lookupRefSCC(A));
1254 EXPECT_EQ(&RC, CG.lookupRefSCC(B));
1255 EXPECT_EQ(&RC, CG.lookupRefSCC(C));
1256 EXPECT_EQ(1, RC.size());
1257 EXPECT_EQ(&*RC.begin(), CG.lookupSCC(A));
1258 EXPECT_EQ(&*RC.begin(), CG.lookupSCC(B));
1259 EXPECT_EQ(&*RC.begin(), CG.lookupSCC(C));
Chandler Carruth5217c942014-04-30 10:48:36 +00001260
Chandler Carruthe5944d92016-02-17 00:18:16 +00001261 // Switch the call edge from 'b' to 'c' to a ref edge. This will break the
1262 // call cycle and cause us to form more SCCs. The RefSCC will remain the same
1263 // though.
Chandler Carruth443e57e2016-12-28 10:34:50 +00001264 auto NewCs = RC.switchInternalEdgeToRef(B, C);
Chandler Carruthe5944d92016-02-17 00:18:16 +00001265 EXPECT_EQ(&RC, CG.lookupRefSCC(A));
1266 EXPECT_EQ(&RC, CG.lookupRefSCC(B));
1267 EXPECT_EQ(&RC, CG.lookupRefSCC(C));
1268 auto J = RC.begin();
1269 // The SCCs must be in *post-order* which means successors before
1270 // predecessors. At this point we have call edges from C to A and from A to
1271 // B. The only valid postorder is B, A, C.
1272 EXPECT_EQ(&*J++, CG.lookupSCC(B));
1273 EXPECT_EQ(&*J++, CG.lookupSCC(A));
1274 EXPECT_EQ(&*J++, CG.lookupSCC(C));
1275 EXPECT_EQ(RC.end(), J);
Chandler Carruth443e57e2016-12-28 10:34:50 +00001276 // And the returned range must be the slice of this sequence containing new
1277 // SCCs.
1278 EXPECT_EQ(RC.begin(), NewCs.begin());
1279 EXPECT_EQ(std::prev(RC.end()), NewCs.end());
Chandler Carruthe5944d92016-02-17 00:18:16 +00001280
1281 // Test turning the ref edge from A to C into a call edge. This will form an
1282 // SCC out of A and C. Since we previously had a call edge from C to A, the
1283 // C SCC should be preserved and have A merged into it while the A SCC should
1284 // be invalidated.
1285 LazyCallGraph::SCC &AC = *CG.lookupSCC(A);
1286 LazyCallGraph::SCC &CC = *CG.lookupSCC(C);
Chandler Carruthc213c672017-07-09 13:45:11 +00001287 EXPECT_TRUE(RC.switchInternalEdgeToCall(A, C, [&](ArrayRef<LazyCallGraph::SCC *> MergedCs) {
1288 ASSERT_EQ(1u, MergedCs.size());
1289 EXPECT_EQ(&AC, MergedCs[0]);
1290 }));
Chandler Carruthe5944d92016-02-17 00:18:16 +00001291 EXPECT_EQ(2, CC.size());
1292 EXPECT_EQ(&CC, CG.lookupSCC(A));
1293 EXPECT_EQ(&CC, CG.lookupSCC(C));
1294 J = RC.begin();
1295 EXPECT_EQ(&*J++, CG.lookupSCC(B));
1296 EXPECT_EQ(&*J++, CG.lookupSCC(C));
1297 EXPECT_EQ(RC.end(), J);
Chandler Carruth5217c942014-04-30 10:48:36 +00001298}
1299
Chandler Carruthe5944d92016-02-17 00:18:16 +00001300TEST(LazyCallGraphTest, InternalEdgeRemoval) {
Mehdi Amini03b42e42016-04-14 21:59:01 +00001301 LLVMContext Context;
Chandler Carruthe5944d92016-02-17 00:18:16 +00001302 // A nice fully connected (including self-edges) RefSCC.
1303 std::unique_ptr<Module> M = parseAssembly(
Mehdi Amini03b42e42016-04-14 21:59:01 +00001304 Context, "define void @a(i8** %ptr) {\n"
1305 "entry:\n"
1306 " store i8* bitcast (void(i8**)* @a to i8*), i8** %ptr\n"
1307 " store i8* bitcast (void(i8**)* @b to i8*), i8** %ptr\n"
1308 " store i8* bitcast (void(i8**)* @c to i8*), i8** %ptr\n"
1309 " ret void\n"
1310 "}\n"
1311 "define void @b(i8** %ptr) {\n"
1312 "entry:\n"
1313 " store i8* bitcast (void(i8**)* @a to i8*), i8** %ptr\n"
1314 " store i8* bitcast (void(i8**)* @b to i8*), i8** %ptr\n"
1315 " store i8* bitcast (void(i8**)* @c to i8*), i8** %ptr\n"
1316 " ret void\n"
1317 "}\n"
1318 "define void @c(i8** %ptr) {\n"
1319 "entry:\n"
1320 " store i8* bitcast (void(i8**)* @a to i8*), i8** %ptr\n"
1321 " store i8* bitcast (void(i8**)* @b to i8*), i8** %ptr\n"
1322 " store i8* bitcast (void(i8**)* @c to i8*), i8** %ptr\n"
1323 " ret void\n"
1324 "}\n");
Chandler Carruthf59a8382017-07-15 08:08:19 +00001325 LazyCallGraph CG = buildCG(*M);
Chandler Carruth9302fbf2014-04-23 11:03:03 +00001326
1327 // Force the graph to be fully expanded.
Chandler Carruth2e0fe3e2017-02-06 19:38:06 +00001328 CG.buildRefSCCs();
Chandler Carruth49d728a2016-09-16 10:20:17 +00001329 auto I = CG.postorder_ref_scc_begin(), E = CG.postorder_ref_scc_end();
1330 LazyCallGraph::RefSCC &RC = *I;
1331 EXPECT_EQ(E, std::next(I));
Chandler Carruth9302fbf2014-04-23 11:03:03 +00001332
Chandler Carruthe5944d92016-02-17 00:18:16 +00001333 LazyCallGraph::Node &A = *CG.lookup(lookupFunction(*M, "a"));
1334 LazyCallGraph::Node &B = *CG.lookup(lookupFunction(*M, "b"));
1335 LazyCallGraph::Node &C = *CG.lookup(lookupFunction(*M, "c"));
1336 EXPECT_EQ(&RC, CG.lookupRefSCC(A));
1337 EXPECT_EQ(&RC, CG.lookupRefSCC(B));
1338 EXPECT_EQ(&RC, CG.lookupRefSCC(C));
Chandler Carruth9302fbf2014-04-23 11:03:03 +00001339
1340 // Remove the edge from b -> a, which should leave the 3 functions still in
1341 // a single connected component because of a -> b -> c -> a.
Chandler Carruthe5944d92016-02-17 00:18:16 +00001342 SmallVector<LazyCallGraph::RefSCC *, 1> NewRCs =
1343 RC.removeInternalRefEdge(B, A);
1344 EXPECT_EQ(0u, NewRCs.size());
1345 EXPECT_EQ(&RC, CG.lookupRefSCC(A));
1346 EXPECT_EQ(&RC, CG.lookupRefSCC(B));
1347 EXPECT_EQ(&RC, CG.lookupRefSCC(C));
Chandler Carruth49d728a2016-09-16 10:20:17 +00001348 auto J = CG.postorder_ref_scc_begin();
1349 EXPECT_EQ(I, J);
1350 EXPECT_EQ(&RC, &*J);
1351 EXPECT_EQ(E, std::next(J));
Chandler Carruthe5944d92016-02-17 00:18:16 +00001352
1353 // Remove the edge from c -> a, which should leave 'a' in the original RefSCC
1354 // and form a new RefSCC for 'b' and 'c'.
1355 NewRCs = RC.removeInternalRefEdge(C, A);
1356 EXPECT_EQ(1u, NewRCs.size());
1357 EXPECT_EQ(&RC, CG.lookupRefSCC(A));
1358 EXPECT_EQ(1, std::distance(RC.begin(), RC.end()));
Chandler Carruth49d728a2016-09-16 10:20:17 +00001359 LazyCallGraph::RefSCC &RC2 = *CG.lookupRefSCC(B);
1360 EXPECT_EQ(&RC2, CG.lookupRefSCC(C));
1361 EXPECT_EQ(&RC2, NewRCs[0]);
1362 J = CG.postorder_ref_scc_begin();
1363 EXPECT_NE(I, J);
1364 EXPECT_EQ(&RC2, &*J);
1365 ++J;
1366 EXPECT_EQ(I, J);
1367 EXPECT_EQ(&RC, &*J);
1368 ++I;
1369 EXPECT_EQ(E, I);
1370 ++J;
1371 EXPECT_EQ(E, J);
Chandler Carruthe5944d92016-02-17 00:18:16 +00001372}
1373
Chandler Carruthc6334572016-12-28 02:24:58 +00001374TEST(LazyCallGraphTest, InternalNoOpEdgeRemoval) {
1375 LLVMContext Context;
1376 // A graph with a single cycle formed both from call and reference edges
1377 // which makes the reference edges trivial to delete. The graph looks like:
1378 //
1379 // Reference edges: a -> b -> c -> a
1380 // Call edges: a -> c -> b -> a
1381 std::unique_ptr<Module> M = parseAssembly(
1382 Context, "define void @a(i8** %ptr) {\n"
1383 "entry:\n"
1384 " call void @b(i8** %ptr)\n"
1385 " store i8* bitcast (void(i8**)* @c to i8*), i8** %ptr\n"
1386 " ret void\n"
1387 "}\n"
1388 "define void @b(i8** %ptr) {\n"
1389 "entry:\n"
1390 " store i8* bitcast (void(i8**)* @a to i8*), i8** %ptr\n"
1391 " call void @c(i8** %ptr)\n"
1392 " ret void\n"
1393 "}\n"
1394 "define void @c(i8** %ptr) {\n"
1395 "entry:\n"
1396 " call void @a(i8** %ptr)\n"
1397 " store i8* bitcast (void(i8**)* @b to i8*), i8** %ptr\n"
1398 " ret void\n"
1399 "}\n");
Chandler Carruthf59a8382017-07-15 08:08:19 +00001400 LazyCallGraph CG = buildCG(*M);
Chandler Carruthc6334572016-12-28 02:24:58 +00001401
1402 // Force the graph to be fully expanded.
Chandler Carruth2e0fe3e2017-02-06 19:38:06 +00001403 CG.buildRefSCCs();
Chandler Carruthc6334572016-12-28 02:24:58 +00001404 auto I = CG.postorder_ref_scc_begin(), E = CG.postorder_ref_scc_end();
1405 LazyCallGraph::RefSCC &RC = *I;
1406 EXPECT_EQ(E, std::next(I));
1407
1408 LazyCallGraph::SCC &C = *RC.begin();
1409 EXPECT_EQ(RC.end(), std::next(RC.begin()));
1410
1411 LazyCallGraph::Node &AN = *CG.lookup(lookupFunction(*M, "a"));
1412 LazyCallGraph::Node &BN = *CG.lookup(lookupFunction(*M, "b"));
1413 LazyCallGraph::Node &CN = *CG.lookup(lookupFunction(*M, "c"));
1414 EXPECT_EQ(&RC, CG.lookupRefSCC(AN));
1415 EXPECT_EQ(&RC, CG.lookupRefSCC(BN));
1416 EXPECT_EQ(&RC, CG.lookupRefSCC(CN));
1417 EXPECT_EQ(&C, CG.lookupSCC(AN));
1418 EXPECT_EQ(&C, CG.lookupSCC(BN));
1419 EXPECT_EQ(&C, CG.lookupSCC(CN));
1420
1421 // Remove the edge from a -> c which doesn't change anything.
1422 SmallVector<LazyCallGraph::RefSCC *, 1> NewRCs =
1423 RC.removeInternalRefEdge(AN, CN);
1424 EXPECT_EQ(0u, NewRCs.size());
1425 EXPECT_EQ(&RC, CG.lookupRefSCC(AN));
1426 EXPECT_EQ(&RC, CG.lookupRefSCC(BN));
1427 EXPECT_EQ(&RC, CG.lookupRefSCC(CN));
1428 EXPECT_EQ(&C, CG.lookupSCC(AN));
1429 EXPECT_EQ(&C, CG.lookupSCC(BN));
1430 EXPECT_EQ(&C, CG.lookupSCC(CN));
1431 auto J = CG.postorder_ref_scc_begin();
1432 EXPECT_EQ(I, J);
1433 EXPECT_EQ(&RC, &*J);
1434 EXPECT_EQ(E, std::next(J));
1435
1436 // Remove the edge from b -> a and c -> b; again this doesn't change
1437 // anything.
1438 NewRCs = RC.removeInternalRefEdge(BN, AN);
1439 NewRCs = RC.removeInternalRefEdge(CN, BN);
1440 EXPECT_EQ(0u, NewRCs.size());
1441 EXPECT_EQ(&RC, CG.lookupRefSCC(AN));
1442 EXPECT_EQ(&RC, CG.lookupRefSCC(BN));
1443 EXPECT_EQ(&RC, CG.lookupRefSCC(CN));
1444 EXPECT_EQ(&C, CG.lookupSCC(AN));
1445 EXPECT_EQ(&C, CG.lookupSCC(BN));
1446 EXPECT_EQ(&C, CG.lookupSCC(CN));
1447 J = CG.postorder_ref_scc_begin();
1448 EXPECT_EQ(I, J);
1449 EXPECT_EQ(&RC, &*J);
1450 EXPECT_EQ(E, std::next(J));
1451}
1452
Chandler Carruthe5944d92016-02-17 00:18:16 +00001453TEST(LazyCallGraphTest, InternalCallEdgeToRef) {
Mehdi Amini03b42e42016-04-14 21:59:01 +00001454 LLVMContext Context;
Chandler Carruthe5944d92016-02-17 00:18:16 +00001455 // A nice fully connected (including self-edges) SCC (and RefSCC)
Mehdi Amini03b42e42016-04-14 21:59:01 +00001456 std::unique_ptr<Module> M = parseAssembly(Context, "define void @a() {\n"
1457 "entry:\n"
1458 " call void @a()\n"
1459 " call void @b()\n"
1460 " call void @c()\n"
1461 " ret void\n"
1462 "}\n"
1463 "define void @b() {\n"
1464 "entry:\n"
1465 " call void @a()\n"
1466 " call void @b()\n"
1467 " call void @c()\n"
1468 " ret void\n"
1469 "}\n"
1470 "define void @c() {\n"
1471 "entry:\n"
1472 " call void @a()\n"
1473 " call void @b()\n"
1474 " call void @c()\n"
1475 " ret void\n"
1476 "}\n");
Chandler Carruthf59a8382017-07-15 08:08:19 +00001477 LazyCallGraph CG = buildCG(*M);
Chandler Carruthe5944d92016-02-17 00:18:16 +00001478
1479 // Force the graph to be fully expanded.
Chandler Carruth2e0fe3e2017-02-06 19:38:06 +00001480 CG.buildRefSCCs();
Chandler Carruthe5944d92016-02-17 00:18:16 +00001481 auto I = CG.postorder_ref_scc_begin();
1482 LazyCallGraph::RefSCC &RC = *I++;
1483 EXPECT_EQ(CG.postorder_ref_scc_end(), I);
1484
1485 EXPECT_EQ(1, RC.size());
Chandler Carruth443e57e2016-12-28 10:34:50 +00001486 LazyCallGraph::SCC &AC = *RC.begin();
Chandler Carruthe5944d92016-02-17 00:18:16 +00001487
Chandler Carruth443e57e2016-12-28 10:34:50 +00001488 LazyCallGraph::Node &AN = *CG.lookup(lookupFunction(*M, "a"));
1489 LazyCallGraph::Node &BN = *CG.lookup(lookupFunction(*M, "b"));
1490 LazyCallGraph::Node &CN = *CG.lookup(lookupFunction(*M, "c"));
1491 EXPECT_EQ(&AC, CG.lookupSCC(AN));
1492 EXPECT_EQ(&AC, CG.lookupSCC(BN));
1493 EXPECT_EQ(&AC, CG.lookupSCC(CN));
Chandler Carruthe5944d92016-02-17 00:18:16 +00001494
1495 // Remove the call edge from b -> a to a ref edge, which should leave the
1496 // 3 functions still in a single connected component because of a -> b ->
1497 // c -> a.
Chandler Carruth443e57e2016-12-28 10:34:50 +00001498 auto NewCs = RC.switchInternalEdgeToRef(BN, AN);
1499 EXPECT_EQ(NewCs.begin(), NewCs.end());
Chandler Carruthe5944d92016-02-17 00:18:16 +00001500 EXPECT_EQ(1, RC.size());
Chandler Carruth443e57e2016-12-28 10:34:50 +00001501 EXPECT_EQ(&AC, CG.lookupSCC(AN));
1502 EXPECT_EQ(&AC, CG.lookupSCC(BN));
1503 EXPECT_EQ(&AC, CG.lookupSCC(CN));
Chandler Carruth9302fbf2014-04-23 11:03:03 +00001504
1505 // Remove the edge from c -> a, which should leave 'a' in the original SCC
1506 // and form a new SCC for 'b' and 'c'.
Chandler Carruth443e57e2016-12-28 10:34:50 +00001507 NewCs = RC.switchInternalEdgeToRef(CN, AN);
1508 EXPECT_EQ(1, std::distance(NewCs.begin(), NewCs.end()));
Chandler Carruthe5944d92016-02-17 00:18:16 +00001509 EXPECT_EQ(2, RC.size());
Chandler Carruth443e57e2016-12-28 10:34:50 +00001510 EXPECT_EQ(&AC, CG.lookupSCC(AN));
1511 LazyCallGraph::SCC &BC = *CG.lookupSCC(BN);
1512 EXPECT_NE(&BC, &AC);
1513 EXPECT_EQ(&BC, CG.lookupSCC(CN));
1514 auto J = RC.find(AC);
1515 EXPECT_EQ(&AC, &*J);
Chandler Carruthe5944d92016-02-17 00:18:16 +00001516 --J;
Chandler Carruth443e57e2016-12-28 10:34:50 +00001517 EXPECT_EQ(&BC, &*J);
Chandler Carruthe5944d92016-02-17 00:18:16 +00001518 EXPECT_EQ(RC.begin(), J);
Chandler Carruth443e57e2016-12-28 10:34:50 +00001519 EXPECT_EQ(J, NewCs.begin());
Chandler Carruthe5944d92016-02-17 00:18:16 +00001520
1521 // Remove the edge from c -> b, which should leave 'b' in the original SCC
1522 // and form a new SCC for 'c'. It shouldn't change 'a's SCC.
Chandler Carruth443e57e2016-12-28 10:34:50 +00001523 NewCs = RC.switchInternalEdgeToRef(CN, BN);
1524 EXPECT_EQ(1, std::distance(NewCs.begin(), NewCs.end()));
Chandler Carruthe5944d92016-02-17 00:18:16 +00001525 EXPECT_EQ(3, RC.size());
Chandler Carruth443e57e2016-12-28 10:34:50 +00001526 EXPECT_EQ(&AC, CG.lookupSCC(AN));
1527 EXPECT_EQ(&BC, CG.lookupSCC(BN));
1528 LazyCallGraph::SCC &CC = *CG.lookupSCC(CN);
1529 EXPECT_NE(&CC, &AC);
1530 EXPECT_NE(&CC, &BC);
1531 J = RC.find(AC);
1532 EXPECT_EQ(&AC, &*J);
Chandler Carruthe5944d92016-02-17 00:18:16 +00001533 --J;
Chandler Carruth443e57e2016-12-28 10:34:50 +00001534 EXPECT_EQ(&BC, &*J);
Chandler Carruthe5944d92016-02-17 00:18:16 +00001535 --J;
Chandler Carruth443e57e2016-12-28 10:34:50 +00001536 EXPECT_EQ(&CC, &*J);
Chandler Carruthe5944d92016-02-17 00:18:16 +00001537 EXPECT_EQ(RC.begin(), J);
Chandler Carruth443e57e2016-12-28 10:34:50 +00001538 EXPECT_EQ(J, NewCs.begin());
Chandler Carruthe5944d92016-02-17 00:18:16 +00001539}
1540
1541TEST(LazyCallGraphTest, InternalRefEdgeToCall) {
Mehdi Amini03b42e42016-04-14 21:59:01 +00001542 LLVMContext Context;
Chandler Carruthe5944d92016-02-17 00:18:16 +00001543 // Basic tests for making a ref edge a call. This hits the basics of the
1544 // process only.
Mehdi Amini03b42e42016-04-14 21:59:01 +00001545 std::unique_ptr<Module> M =
1546 parseAssembly(Context, "define void @a() {\n"
1547 "entry:\n"
1548 " call void @b()\n"
1549 " call void @c()\n"
1550 " store void()* @d, void()** undef\n"
1551 " ret void\n"
1552 "}\n"
1553 "define void @b() {\n"
1554 "entry:\n"
1555 " store void()* @c, void()** undef\n"
1556 " call void @d()\n"
1557 " ret void\n"
1558 "}\n"
1559 "define void @c() {\n"
1560 "entry:\n"
1561 " store void()* @b, void()** undef\n"
1562 " call void @d()\n"
1563 " ret void\n"
1564 "}\n"
1565 "define void @d() {\n"
1566 "entry:\n"
1567 " store void()* @a, void()** undef\n"
1568 " ret void\n"
1569 "}\n");
Chandler Carruthf59a8382017-07-15 08:08:19 +00001570 LazyCallGraph CG = buildCG(*M);
Chandler Carruthe5944d92016-02-17 00:18:16 +00001571
1572 // Force the graph to be fully expanded.
Chandler Carruth2e0fe3e2017-02-06 19:38:06 +00001573 CG.buildRefSCCs();
Chandler Carruthe5944d92016-02-17 00:18:16 +00001574 auto I = CG.postorder_ref_scc_begin();
1575 LazyCallGraph::RefSCC &RC = *I++;
1576 EXPECT_EQ(CG.postorder_ref_scc_end(), I);
1577
1578 LazyCallGraph::Node &A = *CG.lookup(lookupFunction(*M, "a"));
1579 LazyCallGraph::Node &B = *CG.lookup(lookupFunction(*M, "b"));
1580 LazyCallGraph::Node &C = *CG.lookup(lookupFunction(*M, "c"));
1581 LazyCallGraph::Node &D = *CG.lookup(lookupFunction(*M, "d"));
1582 LazyCallGraph::SCC &AC = *CG.lookupSCC(A);
1583 LazyCallGraph::SCC &BC = *CG.lookupSCC(B);
1584 LazyCallGraph::SCC &CC = *CG.lookupSCC(C);
1585 LazyCallGraph::SCC &DC = *CG.lookupSCC(D);
1586
1587 // Check the initial post-order. Note that B and C could be flipped here (and
1588 // in our mutation) without changing the nature of this test.
1589 ASSERT_EQ(4, RC.size());
1590 EXPECT_EQ(&DC, &RC[0]);
1591 EXPECT_EQ(&BC, &RC[1]);
1592 EXPECT_EQ(&CC, &RC[2]);
1593 EXPECT_EQ(&AC, &RC[3]);
1594
1595 // Switch the ref edge from A -> D to a call edge. This should have no
1596 // effect as it is already in postorder and no new cycles are formed.
Chandler Carruthc213c672017-07-09 13:45:11 +00001597 EXPECT_FALSE(RC.switchInternalEdgeToCall(A, D));
Chandler Carruthe5944d92016-02-17 00:18:16 +00001598 ASSERT_EQ(4, RC.size());
1599 EXPECT_EQ(&DC, &RC[0]);
1600 EXPECT_EQ(&BC, &RC[1]);
1601 EXPECT_EQ(&CC, &RC[2]);
1602 EXPECT_EQ(&AC, &RC[3]);
1603
1604 // Switch B -> C to a call edge. This doesn't form any new cycles but does
1605 // require reordering the SCCs.
Chandler Carruthc213c672017-07-09 13:45:11 +00001606 EXPECT_FALSE(RC.switchInternalEdgeToCall(B, C));
Chandler Carruthe5944d92016-02-17 00:18:16 +00001607 ASSERT_EQ(4, RC.size());
1608 EXPECT_EQ(&DC, &RC[0]);
1609 EXPECT_EQ(&CC, &RC[1]);
1610 EXPECT_EQ(&BC, &RC[2]);
1611 EXPECT_EQ(&AC, &RC[3]);
1612
1613 // Switch C -> B to a call edge. This forms a cycle and forces merging SCCs.
Chandler Carruthc213c672017-07-09 13:45:11 +00001614 EXPECT_TRUE(RC.switchInternalEdgeToCall(C, B, [&](ArrayRef<LazyCallGraph::SCC *> MergedCs) {
1615 ASSERT_EQ(1u, MergedCs.size());
1616 EXPECT_EQ(&CC, MergedCs[0]);
1617 }));
Chandler Carruthe5944d92016-02-17 00:18:16 +00001618 ASSERT_EQ(3, RC.size());
1619 EXPECT_EQ(&DC, &RC[0]);
1620 EXPECT_EQ(&BC, &RC[1]);
1621 EXPECT_EQ(&AC, &RC[2]);
1622 EXPECT_EQ(2, BC.size());
1623 EXPECT_EQ(&BC, CG.lookupSCC(B));
1624 EXPECT_EQ(&BC, CG.lookupSCC(C));
1625}
1626
1627TEST(LazyCallGraphTest, InternalRefEdgeToCallNoCycleInterleaved) {
Mehdi Amini03b42e42016-04-14 21:59:01 +00001628 LLVMContext Context;
Chandler Carruthe5944d92016-02-17 00:18:16 +00001629 // Test for having a post-order prior to changing a ref edge to a call edge
1630 // with SCCs connecting to the source and connecting to the target, but not
1631 // connecting to both, interleaved between the source and target. This
1632 // ensures we correctly partition the range rather than simply moving one or
1633 // the other.
Mehdi Amini03b42e42016-04-14 21:59:01 +00001634 std::unique_ptr<Module> M =
1635 parseAssembly(Context, "define void @a() {\n"
1636 "entry:\n"
1637 " call void @b1()\n"
1638 " call void @c1()\n"
1639 " ret void\n"
1640 "}\n"
1641 "define void @b1() {\n"
1642 "entry:\n"
1643 " call void @c1()\n"
1644 " call void @b2()\n"
1645 " ret void\n"
1646 "}\n"
1647 "define void @c1() {\n"
1648 "entry:\n"
1649 " call void @b2()\n"
1650 " call void @c2()\n"
1651 " ret void\n"
1652 "}\n"
1653 "define void @b2() {\n"
1654 "entry:\n"
1655 " call void @c2()\n"
1656 " call void @b3()\n"
1657 " ret void\n"
1658 "}\n"
1659 "define void @c2() {\n"
1660 "entry:\n"
1661 " call void @b3()\n"
1662 " call void @c3()\n"
1663 " ret void\n"
1664 "}\n"
1665 "define void @b3() {\n"
1666 "entry:\n"
1667 " call void @c3()\n"
1668 " call void @d()\n"
1669 " ret void\n"
1670 "}\n"
1671 "define void @c3() {\n"
1672 "entry:\n"
1673 " store void()* @b1, void()** undef\n"
1674 " call void @d()\n"
1675 " ret void\n"
1676 "}\n"
1677 "define void @d() {\n"
1678 "entry:\n"
1679 " store void()* @a, void()** undef\n"
1680 " ret void\n"
1681 "}\n");
Chandler Carruthf59a8382017-07-15 08:08:19 +00001682 LazyCallGraph CG = buildCG(*M);
Chandler Carruthe5944d92016-02-17 00:18:16 +00001683
1684 // Force the graph to be fully expanded.
Chandler Carruth2e0fe3e2017-02-06 19:38:06 +00001685 CG.buildRefSCCs();
Chandler Carruthe5944d92016-02-17 00:18:16 +00001686 auto I = CG.postorder_ref_scc_begin();
1687 LazyCallGraph::RefSCC &RC = *I++;
1688 EXPECT_EQ(CG.postorder_ref_scc_end(), I);
1689
1690 LazyCallGraph::Node &A = *CG.lookup(lookupFunction(*M, "a"));
1691 LazyCallGraph::Node &B1 = *CG.lookup(lookupFunction(*M, "b1"));
1692 LazyCallGraph::Node &B2 = *CG.lookup(lookupFunction(*M, "b2"));
1693 LazyCallGraph::Node &B3 = *CG.lookup(lookupFunction(*M, "b3"));
1694 LazyCallGraph::Node &C1 = *CG.lookup(lookupFunction(*M, "c1"));
1695 LazyCallGraph::Node &C2 = *CG.lookup(lookupFunction(*M, "c2"));
1696 LazyCallGraph::Node &C3 = *CG.lookup(lookupFunction(*M, "c3"));
1697 LazyCallGraph::Node &D = *CG.lookup(lookupFunction(*M, "d"));
1698 LazyCallGraph::SCC &AC = *CG.lookupSCC(A);
1699 LazyCallGraph::SCC &B1C = *CG.lookupSCC(B1);
1700 LazyCallGraph::SCC &B2C = *CG.lookupSCC(B2);
1701 LazyCallGraph::SCC &B3C = *CG.lookupSCC(B3);
1702 LazyCallGraph::SCC &C1C = *CG.lookupSCC(C1);
1703 LazyCallGraph::SCC &C2C = *CG.lookupSCC(C2);
1704 LazyCallGraph::SCC &C3C = *CG.lookupSCC(C3);
1705 LazyCallGraph::SCC &DC = *CG.lookupSCC(D);
1706
1707 // Several call edges are initially present to force a particual post-order.
1708 // Remove them now, leaving an interleaved post-order pattern.
Chandler Carruth443e57e2016-12-28 10:34:50 +00001709 RC.switchTrivialInternalEdgeToRef(B3, C3);
1710 RC.switchTrivialInternalEdgeToRef(C2, B3);
1711 RC.switchTrivialInternalEdgeToRef(B2, C2);
1712 RC.switchTrivialInternalEdgeToRef(C1, B2);
1713 RC.switchTrivialInternalEdgeToRef(B1, C1);
Chandler Carruthe5944d92016-02-17 00:18:16 +00001714
1715 // Check the initial post-order. We ensure this order with the extra edges
1716 // that are nuked above.
1717 ASSERT_EQ(8, RC.size());
1718 EXPECT_EQ(&DC, &RC[0]);
1719 EXPECT_EQ(&C3C, &RC[1]);
1720 EXPECT_EQ(&B3C, &RC[2]);
1721 EXPECT_EQ(&C2C, &RC[3]);
1722 EXPECT_EQ(&B2C, &RC[4]);
1723 EXPECT_EQ(&C1C, &RC[5]);
1724 EXPECT_EQ(&B1C, &RC[6]);
1725 EXPECT_EQ(&AC, &RC[7]);
1726
1727 // Switch C3 -> B1 to a call edge. This doesn't form any new cycles but does
1728 // require reordering the SCCs in the face of tricky internal node
1729 // structures.
Chandler Carruthc213c672017-07-09 13:45:11 +00001730 EXPECT_FALSE(RC.switchInternalEdgeToCall(C3, B1));
Chandler Carruthe5944d92016-02-17 00:18:16 +00001731 ASSERT_EQ(8, RC.size());
1732 EXPECT_EQ(&DC, &RC[0]);
1733 EXPECT_EQ(&B3C, &RC[1]);
1734 EXPECT_EQ(&B2C, &RC[2]);
1735 EXPECT_EQ(&B1C, &RC[3]);
1736 EXPECT_EQ(&C3C, &RC[4]);
1737 EXPECT_EQ(&C2C, &RC[5]);
1738 EXPECT_EQ(&C1C, &RC[6]);
1739 EXPECT_EQ(&AC, &RC[7]);
1740}
1741
1742TEST(LazyCallGraphTest, InternalRefEdgeToCallBothPartitionAndMerge) {
Mehdi Amini03b42e42016-04-14 21:59:01 +00001743 LLVMContext Context;
Chandler Carruthe5944d92016-02-17 00:18:16 +00001744 // Test for having a postorder where between the source and target are all
1745 // three kinds of other SCCs:
1746 // 1) One connected to the target only that have to be shifted below the
1747 // source.
1748 // 2) One connected to the source only that have to be shifted below the
1749 // target.
1750 // 3) One connected to both source and target that has to remain and get
1751 // merged away.
1752 //
1753 // To achieve this we construct a heavily connected graph to force
1754 // a particular post-order. Then we remove the forcing edges and connect
1755 // a cycle.
1756 //
1757 // Diagram for the graph we want on the left and the graph we use to force
1758 // the ordering on the right. Edges ponit down or right.
1759 //
1760 // A | A |
1761 // / \ | / \ |
1762 // B E | B \ |
1763 // |\ | | |\ | |
1764 // | D | | C-D-E |
1765 // | \| | | \| |
1766 // C F | \ F |
1767 // \ / | \ / |
1768 // G | G |
1769 //
1770 // And we form a cycle by connecting F to B.
Mehdi Amini03b42e42016-04-14 21:59:01 +00001771 std::unique_ptr<Module> M =
1772 parseAssembly(Context, "define void @a() {\n"
1773 "entry:\n"
1774 " call void @b()\n"
1775 " call void @e()\n"
1776 " ret void\n"
1777 "}\n"
1778 "define void @b() {\n"
1779 "entry:\n"
1780 " call void @c()\n"
1781 " call void @d()\n"
1782 " ret void\n"
1783 "}\n"
1784 "define void @c() {\n"
1785 "entry:\n"
1786 " call void @d()\n"
1787 " call void @g()\n"
1788 " ret void\n"
1789 "}\n"
1790 "define void @d() {\n"
1791 "entry:\n"
1792 " call void @e()\n"
1793 " call void @f()\n"
1794 " ret void\n"
1795 "}\n"
1796 "define void @e() {\n"
1797 "entry:\n"
1798 " call void @f()\n"
1799 " ret void\n"
1800 "}\n"
1801 "define void @f() {\n"
1802 "entry:\n"
1803 " store void()* @b, void()** undef\n"
1804 " call void @g()\n"
1805 " ret void\n"
1806 "}\n"
1807 "define void @g() {\n"
1808 "entry:\n"
1809 " store void()* @a, void()** undef\n"
1810 " ret void\n"
1811 "}\n");
Chandler Carruthf59a8382017-07-15 08:08:19 +00001812 LazyCallGraph CG = buildCG(*M);
Chandler Carruthe5944d92016-02-17 00:18:16 +00001813
1814 // Force the graph to be fully expanded.
Chandler Carruth2e0fe3e2017-02-06 19:38:06 +00001815 CG.buildRefSCCs();
Chandler Carruthe5944d92016-02-17 00:18:16 +00001816 auto I = CG.postorder_ref_scc_begin();
1817 LazyCallGraph::RefSCC &RC = *I++;
1818 EXPECT_EQ(CG.postorder_ref_scc_end(), I);
1819
1820 LazyCallGraph::Node &A = *CG.lookup(lookupFunction(*M, "a"));
1821 LazyCallGraph::Node &B = *CG.lookup(lookupFunction(*M, "b"));
1822 LazyCallGraph::Node &C = *CG.lookup(lookupFunction(*M, "c"));
1823 LazyCallGraph::Node &D = *CG.lookup(lookupFunction(*M, "d"));
1824 LazyCallGraph::Node &E = *CG.lookup(lookupFunction(*M, "e"));
1825 LazyCallGraph::Node &F = *CG.lookup(lookupFunction(*M, "f"));
1826 LazyCallGraph::Node &G = *CG.lookup(lookupFunction(*M, "g"));
1827 LazyCallGraph::SCC &AC = *CG.lookupSCC(A);
1828 LazyCallGraph::SCC &BC = *CG.lookupSCC(B);
1829 LazyCallGraph::SCC &CC = *CG.lookupSCC(C);
1830 LazyCallGraph::SCC &DC = *CG.lookupSCC(D);
1831 LazyCallGraph::SCC &EC = *CG.lookupSCC(E);
1832 LazyCallGraph::SCC &FC = *CG.lookupSCC(F);
1833 LazyCallGraph::SCC &GC = *CG.lookupSCC(G);
1834
1835 // Remove the extra edges that were used to force a particular post-order.
Chandler Carruth443e57e2016-12-28 10:34:50 +00001836 RC.switchTrivialInternalEdgeToRef(C, D);
1837 RC.switchTrivialInternalEdgeToRef(D, E);
Chandler Carruthe5944d92016-02-17 00:18:16 +00001838
1839 // Check the initial post-order. We ensure this order with the extra edges
1840 // that are nuked above.
1841 ASSERT_EQ(7, RC.size());
1842 EXPECT_EQ(&GC, &RC[0]);
1843 EXPECT_EQ(&FC, &RC[1]);
1844 EXPECT_EQ(&EC, &RC[2]);
1845 EXPECT_EQ(&DC, &RC[3]);
1846 EXPECT_EQ(&CC, &RC[4]);
1847 EXPECT_EQ(&BC, &RC[5]);
1848 EXPECT_EQ(&AC, &RC[6]);
1849
1850 // Switch F -> B to a call edge. This merges B, D, and F into a single SCC,
1851 // and has to place the C and E SCCs on either side of it:
1852 // A A |
1853 // / \ / \ |
1854 // B E | E |
1855 // |\ | \ / |
1856 // | D | -> B |
1857 // | \| / \ |
1858 // C F C | |
1859 // \ / \ / |
1860 // G G |
Chandler Carruthc213c672017-07-09 13:45:11 +00001861 EXPECT_TRUE(RC.switchInternalEdgeToCall(
1862 F, B, [&](ArrayRef<LazyCallGraph::SCC *> MergedCs) {
1863 ASSERT_EQ(2u, MergedCs.size());
1864 EXPECT_EQ(&FC, MergedCs[0]);
1865 EXPECT_EQ(&DC, MergedCs[1]);
1866 }));
Chandler Carruthe5944d92016-02-17 00:18:16 +00001867 EXPECT_EQ(3, BC.size());
1868
1869 // And make sure the postorder was updated.
1870 ASSERT_EQ(5, RC.size());
1871 EXPECT_EQ(&GC, &RC[0]);
1872 EXPECT_EQ(&CC, &RC[1]);
1873 EXPECT_EQ(&BC, &RC[2]);
1874 EXPECT_EQ(&EC, &RC[3]);
1875 EXPECT_EQ(&AC, &RC[4]);
Chandler Carruth9302fbf2014-04-23 11:03:03 +00001876}
1877
Chandler Carruth16250452016-12-27 05:00:45 +00001878// Test for IR containing constants using blockaddress constant expressions.
1879// These are truly unique constructs: constant expressions with non-constant
1880// operands.
1881TEST(LazyCallGraphTest, HandleBlockAddress) {
1882 LLVMContext Context;
1883 std::unique_ptr<Module> M =
1884 parseAssembly(Context, "define void @f() {\n"
1885 "entry:\n"
1886 " ret void\n"
1887 "bb:\n"
1888 " unreachable\n"
1889 "}\n"
1890 "define void @g(i8** %ptr) {\n"
1891 "entry:\n"
1892 " store i8* blockaddress(@f, %bb), i8** %ptr\n"
1893 " ret void\n"
1894 "}\n");
Chandler Carruthf59a8382017-07-15 08:08:19 +00001895 LazyCallGraph CG = buildCG(*M);
Chandler Carruth16250452016-12-27 05:00:45 +00001896
Chandler Carruth2e0fe3e2017-02-06 19:38:06 +00001897 CG.buildRefSCCs();
Chandler Carruth16250452016-12-27 05:00:45 +00001898 auto I = CG.postorder_ref_scc_begin();
1899 LazyCallGraph::RefSCC &FRC = *I++;
1900 LazyCallGraph::RefSCC &GRC = *I++;
1901 EXPECT_EQ(CG.postorder_ref_scc_end(), I);
1902
1903 LazyCallGraph::Node &F = *CG.lookup(lookupFunction(*M, "f"));
1904 LazyCallGraph::Node &G = *CG.lookup(lookupFunction(*M, "g"));
1905 EXPECT_EQ(&FRC, CG.lookupRefSCC(F));
1906 EXPECT_EQ(&GRC, CG.lookupRefSCC(G));
1907 EXPECT_TRUE(GRC.isParentOf(FRC));
1908}
1909
Chandler Carruthaaad9f82017-02-09 23:24:13 +00001910TEST(LazyCallGraphTest, ReplaceNodeFunction) {
1911 LLVMContext Context;
1912 // A graph with several different kinds of edges pointing at a particular
1913 // function.
1914 std::unique_ptr<Module> M =
1915 parseAssembly(Context,
1916 "define void @a(i8** %ptr) {\n"
1917 "entry:\n"
1918 " store i8* bitcast (void(i8**)* @d to i8*), i8** %ptr\n"
1919 " ret void\n"
1920 "}\n"
1921 "define void @b(i8** %ptr) {\n"
1922 "entry:\n"
1923 " store i8* bitcast (void(i8**)* @d to i8*), i8** %ptr\n"
1924 " store i8* bitcast (void(i8**)* @d to i8*), i8** %ptr\n"
1925 " call void @d(i8** %ptr)"
1926 " ret void\n"
1927 "}\n"
1928 "define void @c(i8** %ptr) {\n"
1929 "entry:\n"
1930 " call void @d(i8** %ptr)"
1931 " call void @d(i8** %ptr)"
1932 " store i8* bitcast (void(i8**)* @d to i8*), i8** %ptr\n"
1933 " ret void\n"
1934 "}\n"
1935 "define void @d(i8** %ptr) {\n"
1936 "entry:\n"
1937 " store i8* bitcast (void(i8**)* @b to i8*), i8** %ptr\n"
1938 " call void @c(i8** %ptr)"
1939 " call void @d(i8** %ptr)"
1940 " store i8* bitcast (void(i8**)* @d to i8*), i8** %ptr\n"
1941 " ret void\n"
1942 "}\n");
Chandler Carruthf59a8382017-07-15 08:08:19 +00001943 LazyCallGraph CG = buildCG(*M);
Chandler Carruthaaad9f82017-02-09 23:24:13 +00001944
1945 // Force the graph to be fully expanded.
1946 CG.buildRefSCCs();
1947 auto I = CG.postorder_ref_scc_begin();
1948 LazyCallGraph::RefSCC &RC1 = *I++;
1949 LazyCallGraph::RefSCC &RC2 = *I++;
1950 EXPECT_EQ(CG.postorder_ref_scc_end(), I);
1951
Simon Pilgrimbd83f832017-03-11 13:02:31 +00001952 ASSERT_EQ(2, RC1.size());
Chandler Carruthaaad9f82017-02-09 23:24:13 +00001953 LazyCallGraph::SCC &C1 = RC1[0];
1954 LazyCallGraph::SCC &C2 = RC1[1];
1955
1956 LazyCallGraph::Node &AN = *CG.lookup(lookupFunction(*M, "a"));
1957 LazyCallGraph::Node &BN = *CG.lookup(lookupFunction(*M, "b"));
1958 LazyCallGraph::Node &CN = *CG.lookup(lookupFunction(*M, "c"));
1959 LazyCallGraph::Node &DN = *CG.lookup(lookupFunction(*M, "d"));
1960 EXPECT_EQ(&C1, CG.lookupSCC(DN));
1961 EXPECT_EQ(&C1, CG.lookupSCC(CN));
1962 EXPECT_EQ(&C2, CG.lookupSCC(BN));
1963 EXPECT_EQ(&RC1, CG.lookupRefSCC(DN));
1964 EXPECT_EQ(&RC1, CG.lookupRefSCC(CN));
1965 EXPECT_EQ(&RC1, CG.lookupRefSCC(BN));
1966 EXPECT_EQ(&RC2, CG.lookupRefSCC(AN));
1967
1968 // Now we need to build a new function 'e' with the same signature as 'd'.
1969 Function &D = DN.getFunction();
1970 Function &E = *Function::Create(D.getFunctionType(), D.getLinkage(), "e");
1971 D.getParent()->getFunctionList().insert(D.getIterator(), &E);
1972
1973 // Change each use of 'd' to use 'e'. This is particularly easy as they have
1974 // the same type.
1975 D.replaceAllUsesWith(&E);
1976
1977 // Splice the body of the old function into the new one.
1978 E.getBasicBlockList().splice(E.begin(), D.getBasicBlockList());
1979 // And fix up the one argument.
1980 D.arg_begin()->replaceAllUsesWith(&*E.arg_begin());
1981 E.arg_begin()->takeName(&*D.arg_begin());
1982
1983 // Now replace the function in the graph.
1984 RC1.replaceNodeFunction(DN, E);
1985
1986 EXPECT_EQ(&E, &DN.getFunction());
1987 EXPECT_EQ(&DN, &(*CN)[DN].getNode());
1988 EXPECT_EQ(&DN, &(*BN)[DN].getNode());
1989}
Chandler Carruth1f8fcfe2017-02-09 23:30:14 +00001990
1991TEST(LazyCallGraphTest, RemoveFunctionWithSpurriousRef) {
1992 LLVMContext Context;
1993 // A graph with a couple of RefSCCs.
1994 std::unique_ptr<Module> M =
1995 parseAssembly(Context,
1996 "define void @a(i8** %ptr) {\n"
1997 "entry:\n"
1998 " store i8* bitcast (void(i8**)* @d to i8*), i8** %ptr\n"
1999 " ret void\n"
2000 "}\n"
2001 "define void @b(i8** %ptr) {\n"
2002 "entry:\n"
2003 " store i8* bitcast (void(i8**)* @c to i8*), i8** %ptr\n"
2004 " ret void\n"
2005 "}\n"
2006 "define void @c(i8** %ptr) {\n"
2007 "entry:\n"
2008 " call void @d(i8** %ptr)"
2009 " ret void\n"
2010 "}\n"
2011 "define void @d(i8** %ptr) {\n"
2012 "entry:\n"
2013 " call void @c(i8** %ptr)"
2014 " store i8* bitcast (void(i8**)* @b to i8*), i8** %ptr\n"
2015 " ret void\n"
2016 "}\n"
2017 "define void @dead() {\n"
2018 "entry:\n"
2019 " ret void\n"
2020 "}\n");
Chandler Carruthf59a8382017-07-15 08:08:19 +00002021 LazyCallGraph CG = buildCG(*M);
Chandler Carruth1f8fcfe2017-02-09 23:30:14 +00002022
2023 // Insert spurious ref edges.
2024 LazyCallGraph::Node &AN = CG.get(lookupFunction(*M, "a"));
2025 LazyCallGraph::Node &BN = CG.get(lookupFunction(*M, "b"));
2026 LazyCallGraph::Node &CN = CG.get(lookupFunction(*M, "c"));
2027 LazyCallGraph::Node &DN = CG.get(lookupFunction(*M, "d"));
2028 LazyCallGraph::Node &DeadN = CG.get(lookupFunction(*M, "dead"));
2029 AN.populate();
2030 BN.populate();
2031 CN.populate();
2032 DN.populate();
2033 DeadN.populate();
2034 CG.insertEdge(AN, DeadN, LazyCallGraph::Edge::Ref);
2035 CG.insertEdge(BN, DeadN, LazyCallGraph::Edge::Ref);
2036 CG.insertEdge(CN, DeadN, LazyCallGraph::Edge::Ref);
2037 CG.insertEdge(DN, DeadN, LazyCallGraph::Edge::Ref);
2038
2039 // Force the graph to be fully expanded.
2040 CG.buildRefSCCs();
2041 auto I = CG.postorder_ref_scc_begin();
2042 LazyCallGraph::RefSCC &DeadRC = *I++;
2043 LazyCallGraph::RefSCC &RC1 = *I++;
2044 LazyCallGraph::RefSCC &RC2 = *I++;
2045 EXPECT_EQ(CG.postorder_ref_scc_end(), I);
2046
Simon Pilgrimbd83f832017-03-11 13:02:31 +00002047 ASSERT_EQ(2, RC1.size());
Chandler Carruth1f8fcfe2017-02-09 23:30:14 +00002048 LazyCallGraph::SCC &C1 = RC1[0];
2049 LazyCallGraph::SCC &C2 = RC1[1];
2050
2051 EXPECT_EQ(&DeadRC, CG.lookupRefSCC(DeadN));
2052 EXPECT_EQ(&C1, CG.lookupSCC(DN));
2053 EXPECT_EQ(&C1, CG.lookupSCC(CN));
2054 EXPECT_EQ(&C2, CG.lookupSCC(BN));
2055 EXPECT_EQ(&RC1, CG.lookupRefSCC(DN));
2056 EXPECT_EQ(&RC1, CG.lookupRefSCC(CN));
2057 EXPECT_EQ(&RC1, CG.lookupRefSCC(BN));
2058 EXPECT_EQ(&RC2, CG.lookupRefSCC(AN));
2059
2060 // Now delete 'dead'. There are no uses of this function but there are
2061 // spurious references.
2062 CG.removeDeadFunction(DeadN.getFunction());
2063
2064 // The only observable change should be that the RefSCC is gone from the
2065 // postorder sequence.
2066 I = CG.postorder_ref_scc_begin();
2067 EXPECT_EQ(&RC1, &*I++);
2068 EXPECT_EQ(&RC2, &*I++);
2069 EXPECT_EQ(CG.postorder_ref_scc_end(), I);
2070}
Chandler Carruthc7bad9a2014-04-23 08:08:49 +00002071}