• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===- 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"
13 #include "llvm/IR/Instructions.h"
14 #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 
21 using namespace llvm;
22 
23 namespace {
24 
parseAssembly(LLVMContext & Context,const char * Assembly)25 std::unique_ptr<Module> parseAssembly(LLVMContext &Context,
26                                       const char *Assembly) {
27   SMDiagnostic Error;
28   std::unique_ptr<Module> M = parseAssemblyString(Assembly, Error, Context);
29 
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.
35   if (!M)
36     report_fatal_error(OS.str().c_str());
37 
38   return M;
39 }
40 
41 /*
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  */
58 static 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 
124 /*
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  */
141 static 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 
buildCG(Module & M)219 static LazyCallGraph buildCG(Module &M) {
220   TargetLibraryInfoImpl TLII(Triple(M.getTargetTriple()));
221   TargetLibraryInfo TLI(TLII);
222   LazyCallGraph CG(M, TLI);
223   return CG;
224 }
225 
TEST(LazyCallGraphTest,BasicGraphFormation)226 TEST(LazyCallGraphTest, BasicGraphFormation) {
227   LLVMContext Context;
228   std::unique_ptr<Module> M = parseAssembly(Context, DiamondOfTriangles);
229   LazyCallGraph CG = buildCG(*M);
230 
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();
235   LazyCallGraph::Node &A1 = (I++)->getNode();
236   EXPECT_EQ("a1", A1.getFunction().getName());
237   LazyCallGraph::Node &A2 = (I++)->getNode();
238   EXPECT_EQ("a2", A2.getFunction().getName());
239   LazyCallGraph::Node &A3 = (I++)->getNode();
240   EXPECT_EQ("a3", A3.getFunction().getName());
241   LazyCallGraph::Node &B1 = (I++)->getNode();
242   EXPECT_EQ("b1", B1.getFunction().getName());
243   LazyCallGraph::Node &B2 = (I++)->getNode();
244   EXPECT_EQ("b2", B2.getFunction().getName());
245   LazyCallGraph::Node &B3 = (I++)->getNode();
246   EXPECT_EQ("b3", B3.getFunction().getName());
247   LazyCallGraph::Node &C1 = (I++)->getNode();
248   EXPECT_EQ("c1", C1.getFunction().getName());
249   LazyCallGraph::Node &C2 = (I++)->getNode();
250   EXPECT_EQ("c2", C2.getFunction().getName());
251   LazyCallGraph::Node &C3 = (I++)->getNode();
252   EXPECT_EQ("c3", C3.getFunction().getName());
253   LazyCallGraph::Node &D1 = (I++)->getNode();
254   EXPECT_EQ("d1", D1.getFunction().getName());
255   LazyCallGraph::Node &D2 = (I++)->getNode();
256   EXPECT_EQ("d2", D2.getFunction().getName());
257   LazyCallGraph::Node &D3 = (I++)->getNode();
258   EXPECT_EQ("d3", D3.getFunction().getName());
259   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 
265   for (LazyCallGraph::Edge &E : A1.populate())
266     Nodes.push_back(E.getFunction().getName());
267   llvm::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 
273   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());
279 
280   for (LazyCallGraph::Edge &E : B1.populate())
281     Nodes.push_back(E.getFunction().getName());
282   llvm::sort(Nodes.begin(), Nodes.end());
283   EXPECT_EQ("b2", Nodes[0]);
284   EXPECT_EQ("d3", Nodes[1]);
285   Nodes.clear();
286 
287   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());
293 
294   for (LazyCallGraph::Edge &E : C1.populate())
295     Nodes.push_back(E.getFunction().getName());
296   llvm::sort(Nodes.begin(), Nodes.end());
297   EXPECT_EQ("c2", Nodes[0]);
298   EXPECT_EQ("d2", Nodes[1]);
299   Nodes.clear();
300 
301   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());
307 
308   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());
317 
318   // Now lets look at the RefSCCs and SCCs.
319   CG.buildRefSCCs();
320   auto J = CG.postorder_ref_scc_begin();
321 
322   LazyCallGraph::RefSCC &D = *J++;
323   ASSERT_EQ(1, D.size());
324   for (LazyCallGraph::Node &N : *D.begin())
325     Nodes.push_back(N.getFunction().getName());
326   llvm::sort(Nodes.begin(), Nodes.end());
327   EXPECT_EQ(3u, Nodes.size());
328   EXPECT_EQ("d1", Nodes[0]);
329   EXPECT_EQ("d2", Nodes[1]);
330   EXPECT_EQ("d3", Nodes[2]);
331   Nodes.clear();
332   EXPECT_FALSE(D.isParentOf(D));
333   EXPECT_FALSE(D.isChildOf(D));
334   EXPECT_FALSE(D.isAncestorOf(D));
335   EXPECT_FALSE(D.isDescendantOf(D));
336   EXPECT_EQ(&D, &*CG.postorder_ref_scc_begin());
337 
338   LazyCallGraph::RefSCC &C = *J++;
339   ASSERT_EQ(1, C.size());
340   for (LazyCallGraph::Node &N : *C.begin())
341     Nodes.push_back(N.getFunction().getName());
342   llvm::sort(Nodes.begin(), Nodes.end());
343   EXPECT_EQ(3u, Nodes.size());
344   EXPECT_EQ("c1", Nodes[0]);
345   EXPECT_EQ("c2", Nodes[1]);
346   EXPECT_EQ("c3", Nodes[2]);
347   Nodes.clear();
348   EXPECT_TRUE(C.isParentOf(D));
349   EXPECT_FALSE(C.isChildOf(D));
350   EXPECT_TRUE(C.isAncestorOf(D));
351   EXPECT_FALSE(C.isDescendantOf(D));
352   EXPECT_EQ(&C, &*std::next(CG.postorder_ref_scc_begin()));
353 
354   LazyCallGraph::RefSCC &B = *J++;
355   ASSERT_EQ(1, B.size());
356   for (LazyCallGraph::Node &N : *B.begin())
357     Nodes.push_back(N.getFunction().getName());
358   llvm::sort(Nodes.begin(), Nodes.end());
359   EXPECT_EQ(3u, Nodes.size());
360   EXPECT_EQ("b1", Nodes[0]);
361   EXPECT_EQ("b2", Nodes[1]);
362   EXPECT_EQ("b3", Nodes[2]);
363   Nodes.clear();
364   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));
370   EXPECT_EQ(&B, &*std::next(CG.postorder_ref_scc_begin(), 2));
371 
372   LazyCallGraph::RefSCC &A = *J++;
373   ASSERT_EQ(1, A.size());
374   for (LazyCallGraph::Node &N : *A.begin())
375     Nodes.push_back(N.getFunction().getName());
376   llvm::sort(Nodes.begin(), Nodes.end());
377   EXPECT_EQ(3u, Nodes.size());
378   EXPECT_EQ("a1", Nodes[0]);
379   EXPECT_EQ("a2", Nodes[1]);
380   EXPECT_EQ("a3", Nodes[2]);
381   Nodes.clear();
382   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));
388   EXPECT_EQ(&A, &*std::next(CG.postorder_ref_scc_begin(), 3));
389 
390   EXPECT_EQ(CG.postorder_ref_scc_end(), J);
391   EXPECT_EQ(J, std::next(CG.postorder_ref_scc_begin(), 4));
392 }
393 
lookupFunction(Module & M,StringRef Name)394 static 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 
TEST(LazyCallGraphTest,BasicGraphMutation)401 TEST(LazyCallGraphTest, BasicGraphMutation) {
402   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");
417   LazyCallGraph CG = buildCG(*M);
418 
419   LazyCallGraph::Node &A = CG.get(lookupFunction(*M, "a"));
420   LazyCallGraph::Node &B = CG.get(lookupFunction(*M, "b"));
421   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()));
425 
426   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()));
431 
432   CG.insertEdge(C, B, LazyCallGraph::Edge::Call);
433   EXPECT_EQ(1, std::distance(C->begin(), C->end()));
434   EXPECT_EQ(&B, &C->begin()->getNode());
435 
436   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());
440 
441   CG.removeEdge(C, B);
442   EXPECT_EQ(1, std::distance(C->begin(), C->end()));
443   EXPECT_EQ(&C, &C->begin()->getNode());
444 
445   CG.removeEdge(C, C);
446   EXPECT_EQ(0, std::distance(C->begin(), C->end()));
447 
448   CG.removeEdge(B, C);
449   EXPECT_EQ(0, std::distance(B->begin(), B->end()));
450 }
451 
TEST(LazyCallGraphTest,InnerSCCFormation)452 TEST(LazyCallGraphTest, InnerSCCFormation) {
453   LLVMContext Context;
454   std::unique_ptr<Module> M = parseAssembly(Context, DiamondOfTriangles);
455   LazyCallGraph CG = buildCG(*M);
456 
457   // Now mutate the graph to connect every node into a single RefSCC to ensure
458   // that our inner SCC formation handles the rest.
459   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);
464 
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.
470   CG.buildRefSCCs();
471   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   llvm::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   llvm::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   llvm::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   llvm::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 
TEST(LazyCallGraphTest,MultiArmSCC)520 TEST(LazyCallGraphTest, MultiArmSCC) {
521   LLVMContext Context;
522   // 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
524   // children of each node in the SCC. Since this involves call edges, both
525   // Tarjan implementations will have to successfully navigate the structure.
526   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");
552   LazyCallGraph CG = buildCG(*M);
553 
554   // Force the graph to be fully expanded.
555   CG.buildRefSCCs();
556   auto I = CG.postorder_ref_scc_begin();
557   LazyCallGraph::RefSCC &RC = *I++;
558   EXPECT_EQ(CG.postorder_ref_scc_end(), I);
559 
560   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));
579 }
580 
TEST(LazyCallGraphTest,OutgoingEdgeMutation)581 TEST(LazyCallGraphTest, OutgoingEdgeMutation) {
582   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");
603   LazyCallGraph CG = buildCG(*M);
604 
605   // Force the graph to be fully expanded.
606   CG.buildRefSCCs();
607   for (LazyCallGraph::RefSCC &RC : CG.postorder_ref_sccs())
608     dbgs() << "Formed RefSCC: " << RC << "\n";
609 
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);
618   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));
623   EXPECT_TRUE(AC.isParentOf(BC));
624   EXPECT_TRUE(ARC.isParentOf(CRC));
625   EXPECT_TRUE(AC.isParentOf(CC));
626   EXPECT_FALSE(ARC.isParentOf(DRC));
627   EXPECT_FALSE(AC.isParentOf(DC));
628   EXPECT_TRUE(ARC.isAncestorOf(DRC));
629   EXPECT_TRUE(AC.isAncestorOf(DC));
630   EXPECT_FALSE(DRC.isChildOf(ARC));
631   EXPECT_FALSE(DC.isChildOf(AC));
632   EXPECT_TRUE(DRC.isDescendantOf(ARC));
633   EXPECT_TRUE(DC.isDescendantOf(AC));
634   EXPECT_TRUE(DRC.isChildOf(BRC));
635   EXPECT_TRUE(DC.isChildOf(BC));
636   EXPECT_TRUE(DRC.isChildOf(CRC));
637   EXPECT_TRUE(DC.isChildOf(CC));
638 
639   EXPECT_EQ(2, std::distance(A->begin(), A->end()));
640   ARC.insertOutgoingEdge(A, D, LazyCallGraph::Edge::Call);
641   EXPECT_EQ(3, std::distance(A->begin(), A->end()));
642   const LazyCallGraph::Edge &NewE = (*A)[D];
643   EXPECT_TRUE(NewE);
644   EXPECT_TRUE(NewE.isCall());
645   EXPECT_EQ(&D, &NewE.getNode());
646 
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));
650   EXPECT_TRUE(AC.isParentOf(DC));
651   EXPECT_TRUE(ARC.isAncestorOf(DRC));
652   EXPECT_TRUE(AC.isAncestorOf(DC));
653   EXPECT_TRUE(DRC.isChildOf(ARC));
654   EXPECT_TRUE(DC.isChildOf(AC));
655   EXPECT_TRUE(DRC.isDescendantOf(ARC));
656   EXPECT_TRUE(DC.isDescendantOf(AC));
657   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));
661   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 
669   // Verify the reference graph remains the same but the SCC graph is updated.
670   EXPECT_TRUE(ARC.isParentOf(DRC));
671   EXPECT_FALSE(AC.isParentOf(DC));
672   EXPECT_TRUE(ARC.isAncestorOf(DRC));
673   EXPECT_TRUE(AC.isAncestorOf(DC));
674   EXPECT_TRUE(DRC.isChildOf(ARC));
675   EXPECT_FALSE(DC.isChildOf(AC));
676   EXPECT_TRUE(DRC.isDescendantOf(ARC));
677   EXPECT_TRUE(DC.isDescendantOf(AC));
678   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 
690   // Verify the reference graph remains the same but the SCC graph is updated.
691   EXPECT_TRUE(ARC.isParentOf(DRC));
692   EXPECT_TRUE(AC.isParentOf(DC));
693   EXPECT_TRUE(ARC.isAncestorOf(DRC));
694   EXPECT_TRUE(AC.isAncestorOf(DC));
695   EXPECT_TRUE(DRC.isChildOf(ARC));
696   EXPECT_TRUE(DC.isChildOf(AC));
697   EXPECT_TRUE(DRC.isDescendantOf(ARC));
698   EXPECT_TRUE(DC.isDescendantOf(AC));
699   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);
709   EXPECT_EQ(2, std::distance(A->begin(), A->end()));
710 
711   // Now the parent and child tests fail again but the rest remains the same.
712   EXPECT_FALSE(ARC.isParentOf(DRC));
713   EXPECT_FALSE(AC.isParentOf(DC));
714   EXPECT_TRUE(ARC.isAncestorOf(DRC));
715   EXPECT_TRUE(AC.isAncestorOf(DC));
716   EXPECT_FALSE(DRC.isChildOf(ARC));
717   EXPECT_FALSE(DC.isChildOf(AC));
718   EXPECT_TRUE(DRC.isDescendantOf(ARC));
719   EXPECT_TRUE(DC.isDescendantOf(AC));
720   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));
728 }
729 
TEST(LazyCallGraphTest,IncomingEdgeInsertion)730 TEST(LazyCallGraphTest, IncomingEdgeInsertion) {
731   LLVMContext Context;
732   // 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   //
748   std::unique_ptr<Module> M = parseAssembly(Context, DiamondOfTriangles);
749   LazyCallGraph CG = buildCG(*M);
750 
751   // Force the graph to be fully expanded.
752   CG.buildRefSCCs();
753   for (LazyCallGraph::RefSCC &RC : CG.postorder_ref_sccs())
754     dbgs() << "Formed RefSCC: " << RC << "\n";
755 
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"));
768   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));
780   ASSERT_EQ(1, std::distance(D2->begin(), D2->end()));
781 
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        |
795   auto MergedRCs = CRC.insertIncomingRefEdge(D2, C2);
796   // Make sure we connected the nodes.
797   for (LazyCallGraph::Edge E : *D2) {
798     if (&E.getNode() == &D3)
799       continue;
800     EXPECT_EQ(&C2, &E.getNode());
801   }
802   // And marked the D ref-SCC as no longer valid.
803   EXPECT_EQ(1u, MergedRCs.size());
804   EXPECT_EQ(&DRC, MergedRCs[0]);
805 
806   // Make sure we have the correct nodes in the SCC sets.
807   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));
819 
820   // And that ancestry tests have been updated.
821   EXPECT_TRUE(ARC.isParentOf(CRC));
822   EXPECT_TRUE(BRC.isParentOf(CRC));
823 
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);
833 }
834 
TEST(LazyCallGraphTest,IncomingEdgeInsertionRefGraph)835 TEST(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);
841   LazyCallGraph CG = buildCG(*M);
842 
843   // Force the graph to be fully expanded.
844   CG.buildRefSCCs();
845   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));
872   ASSERT_EQ(1, std::distance(D2->begin(), D2->end()));
873 
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.
889   for (LazyCallGraph::Edge E : *D2) {
890     if (&E.getNode() == &D3)
891       continue;
892     EXPECT_EQ(&C2, &E.getNode());
893   }
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 
TEST(LazyCallGraphTest,IncomingEdgeInsertionLargeCallCycle)927 TEST(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");
948   LazyCallGraph CG = buildCG(*M);
949 
950   // Force the graph to be fully expanded.
951   CG.buildRefSCCs();
952   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.
971   EXPECT_NE(D->begin(), D->end());
972   EXPECT_EQ(&A, &D->begin()->getNode());
973 
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 
TEST(LazyCallGraphTest,IncomingEdgeInsertionLargeRefCycle)1000 TEST(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");
1025   LazyCallGraph CG = buildCG(*M);
1026 
1027   // Force the graph to be fully expanded.
1028   CG.buildRefSCCs();
1029   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.
1045   EXPECT_NE(D->begin(), D->end());
1046   EXPECT_EQ(&A, &D->begin()->getNode());
1047 
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);
1065 }
1066 
TEST(LazyCallGraphTest,InlineAndDeleteFunction)1067 TEST(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);
1087   LazyCallGraph CG = buildCG(*M);
1088 
1089   // Force the graph to be fully expanded.
1090   CG.buildRefSCCs();
1091   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));
1118   ASSERT_EQ(1, std::distance(D2->begin(), D2->end()));
1119 
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   ASSERT_EQ(2u, NewRCs.size());
1171   LazyCallGraph::RefSCC &NewDRC = *NewRCs[0];
1172   EXPECT_EQ(&NewDRC, CG.lookupRefSCC(D1));
1173   EXPECT_EQ(&NewDRC, CG.lookupRefSCC(D3));
1174   LazyCallGraph::RefSCC &D2RC = *NewRCs[1];
1175   EXPECT_EQ(&D2RC, CG.lookupRefSCC(D2));
1176   EXPECT_FALSE(NewDRC.isParentOf(D2RC));
1177   EXPECT_TRUE(CRC.isParentOf(D2RC));
1178   EXPECT_TRUE(CRC.isParentOf(NewDRC));
1179   EXPECT_TRUE(D2RC.isParentOf(NewDRC));
1180   CRC.removeOutgoingEdge(C1, D2);
1181   EXPECT_FALSE(CRC.isParentOf(D2RC));
1182   EXPECT_TRUE(CRC.isParentOf(NewDRC));
1183   EXPECT_TRUE(D2RC.isParentOf(NewDRC));
1184 
1185   // Now that we've updated the call graph, D2 is dead, so remove it.
1186   CG.removeDeadFunction(D2F);
1187 
1188   // Check that the graph still looks the same.
1189   EXPECT_EQ(&ARC, CG.lookupRefSCC(A1));
1190   EXPECT_EQ(&ARC, CG.lookupRefSCC(A2));
1191   EXPECT_EQ(&ARC, CG.lookupRefSCC(A3));
1192   EXPECT_EQ(&BRC, CG.lookupRefSCC(B1));
1193   EXPECT_EQ(&BRC, CG.lookupRefSCC(B2));
1194   EXPECT_EQ(&BRC, CG.lookupRefSCC(B3));
1195   EXPECT_EQ(&CRC, CG.lookupRefSCC(C1));
1196   EXPECT_EQ(&CRC, CG.lookupRefSCC(C2));
1197   EXPECT_EQ(&CRC, CG.lookupRefSCC(C3));
1198   EXPECT_EQ(&NewDRC, CG.lookupRefSCC(D1));
1199   EXPECT_EQ(&NewDRC, CG.lookupRefSCC(D3));
1200   EXPECT_TRUE(CRC.isParentOf(NewDRC));
1201 
1202   // Verify the post-order walk hasn't changed.
1203   auto I = CG.postorder_ref_scc_begin(), E = CG.postorder_ref_scc_end();
1204   ASSERT_NE(I, E);
1205   EXPECT_EQ(&NewDRC, &*I) << "Actual RefSCC: " << *I;
1206   ASSERT_NE(++I, E);
1207   EXPECT_EQ(&CRC, &*I) << "Actual RefSCC: " << *I;
1208   ASSERT_NE(++I, E);
1209   EXPECT_EQ(&BRC, &*I) << "Actual RefSCC: " << *I;
1210   ASSERT_NE(++I, E);
1211   EXPECT_EQ(&ARC, &*I) << "Actual RefSCC: " << *I;
1212   EXPECT_EQ(++I, E);
1213 }
1214 
TEST(LazyCallGraphTest,InternalEdgeMutation)1215 TEST(LazyCallGraphTest, InternalEdgeMutation) {
1216   LLVMContext Context;
1217   std::unique_ptr<Module> M = parseAssembly(Context, "define void @a() {\n"
1218                                                      "entry:\n"
1219                                                      "  call void @b()\n"
1220                                                      "  ret void\n"
1221                                                      "}\n"
1222                                                      "define void @b() {\n"
1223                                                      "entry:\n"
1224                                                      "  call void @c()\n"
1225                                                      "  ret void\n"
1226                                                      "}\n"
1227                                                      "define void @c() {\n"
1228                                                      "entry:\n"
1229                                                      "  call void @a()\n"
1230                                                      "  ret void\n"
1231                                                      "}\n");
1232   LazyCallGraph CG = buildCG(*M);
1233 
1234   // Force the graph to be fully expanded.
1235   CG.buildRefSCCs();
1236   auto I = CG.postorder_ref_scc_begin();
1237   LazyCallGraph::RefSCC &RC = *I++;
1238   EXPECT_EQ(CG.postorder_ref_scc_end(), I);
1239 
1240   LazyCallGraph::Node &A = *CG.lookup(lookupFunction(*M, "a"));
1241   LazyCallGraph::Node &B = *CG.lookup(lookupFunction(*M, "b"));
1242   LazyCallGraph::Node &C = *CG.lookup(lookupFunction(*M, "c"));
1243   EXPECT_EQ(&RC, CG.lookupRefSCC(A));
1244   EXPECT_EQ(&RC, CG.lookupRefSCC(B));
1245   EXPECT_EQ(&RC, CG.lookupRefSCC(C));
1246   EXPECT_EQ(1, RC.size());
1247   EXPECT_EQ(&*RC.begin(), CG.lookupSCC(A));
1248   EXPECT_EQ(&*RC.begin(), CG.lookupSCC(B));
1249   EXPECT_EQ(&*RC.begin(), CG.lookupSCC(C));
1250 
1251   // Insert an edge from 'a' to 'c'. Nothing changes about the graph.
1252   RC.insertInternalRefEdge(A, C);
1253   EXPECT_EQ(2, std::distance(A->begin(), A->end()));
1254   EXPECT_EQ(&RC, CG.lookupRefSCC(A));
1255   EXPECT_EQ(&RC, CG.lookupRefSCC(B));
1256   EXPECT_EQ(&RC, CG.lookupRefSCC(C));
1257   EXPECT_EQ(1, RC.size());
1258   EXPECT_EQ(&*RC.begin(), CG.lookupSCC(A));
1259   EXPECT_EQ(&*RC.begin(), CG.lookupSCC(B));
1260   EXPECT_EQ(&*RC.begin(), CG.lookupSCC(C));
1261 
1262   // Switch the call edge from 'b' to 'c' to a ref edge. This will break the
1263   // call cycle and cause us to form more SCCs. The RefSCC will remain the same
1264   // though.
1265   auto NewCs = RC.switchInternalEdgeToRef(B, C);
1266   EXPECT_EQ(&RC, CG.lookupRefSCC(A));
1267   EXPECT_EQ(&RC, CG.lookupRefSCC(B));
1268   EXPECT_EQ(&RC, CG.lookupRefSCC(C));
1269   auto J = RC.begin();
1270   // The SCCs must be in *post-order* which means successors before
1271   // predecessors. At this point we have call edges from C to A and from A to
1272   // B. The only valid postorder is B, A, C.
1273   EXPECT_EQ(&*J++, CG.lookupSCC(B));
1274   EXPECT_EQ(&*J++, CG.lookupSCC(A));
1275   EXPECT_EQ(&*J++, CG.lookupSCC(C));
1276   EXPECT_EQ(RC.end(), J);
1277   // And the returned range must be the slice of this sequence containing new
1278   // SCCs.
1279   EXPECT_EQ(RC.begin(), NewCs.begin());
1280   EXPECT_EQ(std::prev(RC.end()), NewCs.end());
1281 
1282   // Test turning the ref edge from A to C into a call edge. This will form an
1283   // SCC out of A and C. Since we previously had a call edge from C to A, the
1284   // C SCC should be preserved and have A merged into it while the A SCC should
1285   // be invalidated.
1286   LazyCallGraph::SCC &AC = *CG.lookupSCC(A);
1287   LazyCallGraph::SCC &CC = *CG.lookupSCC(C);
1288   EXPECT_TRUE(RC.switchInternalEdgeToCall(A, C, [&](ArrayRef<LazyCallGraph::SCC *> MergedCs) {
1289     ASSERT_EQ(1u, MergedCs.size());
1290     EXPECT_EQ(&AC, MergedCs[0]);
1291   }));
1292   EXPECT_EQ(2, CC.size());
1293   EXPECT_EQ(&CC, CG.lookupSCC(A));
1294   EXPECT_EQ(&CC, CG.lookupSCC(C));
1295   J = RC.begin();
1296   EXPECT_EQ(&*J++, CG.lookupSCC(B));
1297   EXPECT_EQ(&*J++, CG.lookupSCC(C));
1298   EXPECT_EQ(RC.end(), J);
1299 }
1300 
TEST(LazyCallGraphTest,InternalEdgeRemoval)1301 TEST(LazyCallGraphTest, InternalEdgeRemoval) {
1302   LLVMContext Context;
1303   // A nice fully connected (including self-edges) RefSCC.
1304   std::unique_ptr<Module> M = parseAssembly(
1305       Context, "define void @a(i8** %ptr) {\n"
1306                "entry:\n"
1307                "  store i8* bitcast (void(i8**)* @a to i8*), i8** %ptr\n"
1308                "  store i8* bitcast (void(i8**)* @b to i8*), i8** %ptr\n"
1309                "  store i8* bitcast (void(i8**)* @c to i8*), i8** %ptr\n"
1310                "  ret void\n"
1311                "}\n"
1312                "define void @b(i8** %ptr) {\n"
1313                "entry:\n"
1314                "  store i8* bitcast (void(i8**)* @a to i8*), i8** %ptr\n"
1315                "  store i8* bitcast (void(i8**)* @b to i8*), i8** %ptr\n"
1316                "  store i8* bitcast (void(i8**)* @c to i8*), i8** %ptr\n"
1317                "  ret void\n"
1318                "}\n"
1319                "define void @c(i8** %ptr) {\n"
1320                "entry:\n"
1321                "  store i8* bitcast (void(i8**)* @a to i8*), i8** %ptr\n"
1322                "  store i8* bitcast (void(i8**)* @b to i8*), i8** %ptr\n"
1323                "  store i8* bitcast (void(i8**)* @c to i8*), i8** %ptr\n"
1324                "  ret void\n"
1325                "}\n");
1326   LazyCallGraph CG = buildCG(*M);
1327 
1328   // Force the graph to be fully expanded.
1329   CG.buildRefSCCs();
1330   auto I = CG.postorder_ref_scc_begin(), E = CG.postorder_ref_scc_end();
1331   LazyCallGraph::RefSCC &RC = *I;
1332   EXPECT_EQ(E, std::next(I));
1333 
1334   LazyCallGraph::Node &A = *CG.lookup(lookupFunction(*M, "a"));
1335   LazyCallGraph::Node &B = *CG.lookup(lookupFunction(*M, "b"));
1336   LazyCallGraph::Node &C = *CG.lookup(lookupFunction(*M, "c"));
1337   EXPECT_EQ(&RC, CG.lookupRefSCC(A));
1338   EXPECT_EQ(&RC, CG.lookupRefSCC(B));
1339   EXPECT_EQ(&RC, CG.lookupRefSCC(C));
1340 
1341   // Remove the edge from b -> a, which should leave the 3 functions still in
1342   // a single connected component because of a -> b -> c -> a.
1343   SmallVector<LazyCallGraph::RefSCC *, 1> NewRCs =
1344       RC.removeInternalRefEdge(B, {&A});
1345   EXPECT_EQ(0u, NewRCs.size());
1346   EXPECT_EQ(&RC, CG.lookupRefSCC(A));
1347   EXPECT_EQ(&RC, CG.lookupRefSCC(B));
1348   EXPECT_EQ(&RC, CG.lookupRefSCC(C));
1349   auto J = CG.postorder_ref_scc_begin();
1350   EXPECT_EQ(I, J);
1351   EXPECT_EQ(&RC, &*J);
1352   EXPECT_EQ(E, std::next(J));
1353 
1354   // Increment I before we actually mutate the structure so that it remains
1355   // a valid iterator.
1356   ++I;
1357 
1358   // Remove the edge from c -> a, which should leave 'a' in the original RefSCC
1359   // and form a new RefSCC for 'b' and 'c'.
1360   NewRCs = RC.removeInternalRefEdge(C, {&A});
1361   ASSERT_EQ(2u, NewRCs.size());
1362   LazyCallGraph::RefSCC &BCRC = *NewRCs[0];
1363   LazyCallGraph::RefSCC &ARC = *NewRCs[1];
1364   EXPECT_EQ(&ARC, CG.lookupRefSCC(A));
1365   EXPECT_EQ(1, std::distance(ARC.begin(), ARC.end()));
1366   EXPECT_EQ(&BCRC, CG.lookupRefSCC(B));
1367   EXPECT_EQ(&BCRC, CG.lookupRefSCC(C));
1368   J = CG.postorder_ref_scc_begin();
1369   EXPECT_NE(I, J);
1370   EXPECT_EQ(&BCRC, &*J);
1371   ++J;
1372   EXPECT_NE(I, J);
1373   EXPECT_EQ(&ARC, &*J);
1374   ++J;
1375   EXPECT_EQ(I, J);
1376   EXPECT_EQ(E, J);
1377 }
1378 
TEST(LazyCallGraphTest,InternalMultiEdgeRemoval)1379 TEST(LazyCallGraphTest, InternalMultiEdgeRemoval) {
1380   LLVMContext Context;
1381   // A nice fully connected (including self-edges) RefSCC.
1382   std::unique_ptr<Module> M = parseAssembly(
1383       Context, "define void @a(i8** %ptr) {\n"
1384                "entry:\n"
1385                "  store i8* bitcast (void(i8**)* @a to i8*), i8** %ptr\n"
1386                "  store i8* bitcast (void(i8**)* @b to i8*), i8** %ptr\n"
1387                "  store i8* bitcast (void(i8**)* @c to i8*), i8** %ptr\n"
1388                "  ret void\n"
1389                "}\n"
1390                "define void @b(i8** %ptr) {\n"
1391                "entry:\n"
1392                "  store i8* bitcast (void(i8**)* @a to i8*), i8** %ptr\n"
1393                "  store i8* bitcast (void(i8**)* @b to i8*), i8** %ptr\n"
1394                "  store i8* bitcast (void(i8**)* @c to i8*), i8** %ptr\n"
1395                "  ret void\n"
1396                "}\n"
1397                "define void @c(i8** %ptr) {\n"
1398                "entry:\n"
1399                "  store i8* bitcast (void(i8**)* @a to i8*), i8** %ptr\n"
1400                "  store i8* bitcast (void(i8**)* @b to i8*), i8** %ptr\n"
1401                "  store i8* bitcast (void(i8**)* @c to i8*), i8** %ptr\n"
1402                "  ret void\n"
1403                "}\n");
1404   LazyCallGraph CG = buildCG(*M);
1405 
1406   // Force the graph to be fully expanded.
1407   CG.buildRefSCCs();
1408   auto I = CG.postorder_ref_scc_begin(), E = CG.postorder_ref_scc_end();
1409   LazyCallGraph::RefSCC &RC = *I;
1410   EXPECT_EQ(E, std::next(I));
1411 
1412   LazyCallGraph::Node &A = *CG.lookup(lookupFunction(*M, "a"));
1413   LazyCallGraph::Node &B = *CG.lookup(lookupFunction(*M, "b"));
1414   LazyCallGraph::Node &C = *CG.lookup(lookupFunction(*M, "c"));
1415   EXPECT_EQ(&RC, CG.lookupRefSCC(A));
1416   EXPECT_EQ(&RC, CG.lookupRefSCC(B));
1417   EXPECT_EQ(&RC, CG.lookupRefSCC(C));
1418 
1419   // Increment I before we actually mutate the structure so that it remains
1420   // a valid iterator.
1421   ++I;
1422 
1423   // Remove the edges from b -> a and b -> c, leaving b in its own RefSCC.
1424   SmallVector<LazyCallGraph::RefSCC *, 1> NewRCs =
1425       RC.removeInternalRefEdge(B, {&A, &C});
1426 
1427   ASSERT_EQ(2u, NewRCs.size());
1428   LazyCallGraph::RefSCC &BRC = *NewRCs[0];
1429   LazyCallGraph::RefSCC &ACRC = *NewRCs[1];
1430   EXPECT_EQ(&BRC, CG.lookupRefSCC(B));
1431   EXPECT_EQ(1, std::distance(BRC.begin(), BRC.end()));
1432   EXPECT_EQ(&ACRC, CG.lookupRefSCC(A));
1433   EXPECT_EQ(&ACRC, CG.lookupRefSCC(C));
1434   auto J = CG.postorder_ref_scc_begin();
1435   EXPECT_NE(I, J);
1436   EXPECT_EQ(&BRC, &*J);
1437   ++J;
1438   EXPECT_NE(I, J);
1439   EXPECT_EQ(&ACRC, &*J);
1440   ++J;
1441   EXPECT_EQ(I, J);
1442   EXPECT_EQ(E, J);
1443 }
1444 
TEST(LazyCallGraphTest,InternalNoOpEdgeRemoval)1445 TEST(LazyCallGraphTest, InternalNoOpEdgeRemoval) {
1446   LLVMContext Context;
1447   // A graph with a single cycle formed both from call and reference edges
1448   // which makes the reference edges trivial to delete. The graph looks like:
1449   //
1450   // Reference edges: a -> b -> c -> a
1451   //      Call edges: a -> c -> b -> a
1452   std::unique_ptr<Module> M = parseAssembly(
1453       Context, "define void @a(i8** %ptr) {\n"
1454                "entry:\n"
1455                "  call void @b(i8** %ptr)\n"
1456                "  store i8* bitcast (void(i8**)* @c to i8*), i8** %ptr\n"
1457                "  ret void\n"
1458                "}\n"
1459                "define void @b(i8** %ptr) {\n"
1460                "entry:\n"
1461                "  store i8* bitcast (void(i8**)* @a to i8*), i8** %ptr\n"
1462                "  call void @c(i8** %ptr)\n"
1463                "  ret void\n"
1464                "}\n"
1465                "define void @c(i8** %ptr) {\n"
1466                "entry:\n"
1467                "  call void @a(i8** %ptr)\n"
1468                "  store i8* bitcast (void(i8**)* @b to i8*), i8** %ptr\n"
1469                "  ret void\n"
1470                "}\n");
1471   LazyCallGraph CG = buildCG(*M);
1472 
1473   // Force the graph to be fully expanded.
1474   CG.buildRefSCCs();
1475   auto I = CG.postorder_ref_scc_begin(), E = CG.postorder_ref_scc_end();
1476   LazyCallGraph::RefSCC &RC = *I;
1477   EXPECT_EQ(E, std::next(I));
1478 
1479   LazyCallGraph::SCC &C = *RC.begin();
1480   EXPECT_EQ(RC.end(), std::next(RC.begin()));
1481 
1482   LazyCallGraph::Node &AN = *CG.lookup(lookupFunction(*M, "a"));
1483   LazyCallGraph::Node &BN = *CG.lookup(lookupFunction(*M, "b"));
1484   LazyCallGraph::Node &CN = *CG.lookup(lookupFunction(*M, "c"));
1485   EXPECT_EQ(&RC, CG.lookupRefSCC(AN));
1486   EXPECT_EQ(&RC, CG.lookupRefSCC(BN));
1487   EXPECT_EQ(&RC, CG.lookupRefSCC(CN));
1488   EXPECT_EQ(&C, CG.lookupSCC(AN));
1489   EXPECT_EQ(&C, CG.lookupSCC(BN));
1490   EXPECT_EQ(&C, CG.lookupSCC(CN));
1491 
1492   // Remove the edge from a -> c which doesn't change anything.
1493   SmallVector<LazyCallGraph::RefSCC *, 1> NewRCs =
1494       RC.removeInternalRefEdge(AN, {&CN});
1495   EXPECT_EQ(0u, NewRCs.size());
1496   EXPECT_EQ(&RC, CG.lookupRefSCC(AN));
1497   EXPECT_EQ(&RC, CG.lookupRefSCC(BN));
1498   EXPECT_EQ(&RC, CG.lookupRefSCC(CN));
1499   EXPECT_EQ(&C, CG.lookupSCC(AN));
1500   EXPECT_EQ(&C, CG.lookupSCC(BN));
1501   EXPECT_EQ(&C, CG.lookupSCC(CN));
1502   auto J = CG.postorder_ref_scc_begin();
1503   EXPECT_EQ(I, J);
1504   EXPECT_EQ(&RC, &*J);
1505   EXPECT_EQ(E, std::next(J));
1506 
1507   // Remove the edge from b -> a and c -> b; again this doesn't change
1508   // anything.
1509   NewRCs = RC.removeInternalRefEdge(BN, {&AN});
1510   NewRCs = RC.removeInternalRefEdge(CN, {&BN});
1511   EXPECT_EQ(0u, NewRCs.size());
1512   EXPECT_EQ(&RC, CG.lookupRefSCC(AN));
1513   EXPECT_EQ(&RC, CG.lookupRefSCC(BN));
1514   EXPECT_EQ(&RC, CG.lookupRefSCC(CN));
1515   EXPECT_EQ(&C, CG.lookupSCC(AN));
1516   EXPECT_EQ(&C, CG.lookupSCC(BN));
1517   EXPECT_EQ(&C, CG.lookupSCC(CN));
1518   J = CG.postorder_ref_scc_begin();
1519   EXPECT_EQ(I, J);
1520   EXPECT_EQ(&RC, &*J);
1521   EXPECT_EQ(E, std::next(J));
1522 }
1523 
TEST(LazyCallGraphTest,InternalCallEdgeToRef)1524 TEST(LazyCallGraphTest, InternalCallEdgeToRef) {
1525   LLVMContext Context;
1526   // A nice fully connected (including self-edges) SCC (and RefSCC)
1527   std::unique_ptr<Module> M = parseAssembly(Context, "define void @a() {\n"
1528                                                      "entry:\n"
1529                                                      "  call void @a()\n"
1530                                                      "  call void @b()\n"
1531                                                      "  call void @c()\n"
1532                                                      "  ret void\n"
1533                                                      "}\n"
1534                                                      "define void @b() {\n"
1535                                                      "entry:\n"
1536                                                      "  call void @a()\n"
1537                                                      "  call void @b()\n"
1538                                                      "  call void @c()\n"
1539                                                      "  ret void\n"
1540                                                      "}\n"
1541                                                      "define void @c() {\n"
1542                                                      "entry:\n"
1543                                                      "  call void @a()\n"
1544                                                      "  call void @b()\n"
1545                                                      "  call void @c()\n"
1546                                                      "  ret void\n"
1547                                                      "}\n");
1548   LazyCallGraph CG = buildCG(*M);
1549 
1550   // Force the graph to be fully expanded.
1551   CG.buildRefSCCs();
1552   auto I = CG.postorder_ref_scc_begin();
1553   LazyCallGraph::RefSCC &RC = *I++;
1554   EXPECT_EQ(CG.postorder_ref_scc_end(), I);
1555 
1556   EXPECT_EQ(1, RC.size());
1557   LazyCallGraph::SCC &AC = *RC.begin();
1558 
1559   LazyCallGraph::Node &AN = *CG.lookup(lookupFunction(*M, "a"));
1560   LazyCallGraph::Node &BN = *CG.lookup(lookupFunction(*M, "b"));
1561   LazyCallGraph::Node &CN = *CG.lookup(lookupFunction(*M, "c"));
1562   EXPECT_EQ(&AC, CG.lookupSCC(AN));
1563   EXPECT_EQ(&AC, CG.lookupSCC(BN));
1564   EXPECT_EQ(&AC, CG.lookupSCC(CN));
1565 
1566   // Remove the call edge from b -> a to a ref edge, which should leave the
1567   // 3 functions still in a single connected component because of a -> b ->
1568   // c -> a.
1569   auto NewCs = RC.switchInternalEdgeToRef(BN, AN);
1570   EXPECT_EQ(NewCs.begin(), NewCs.end());
1571   EXPECT_EQ(1, RC.size());
1572   EXPECT_EQ(&AC, CG.lookupSCC(AN));
1573   EXPECT_EQ(&AC, CG.lookupSCC(BN));
1574   EXPECT_EQ(&AC, CG.lookupSCC(CN));
1575 
1576   // Remove the edge from c -> a, which should leave 'a' in the original SCC
1577   // and form a new SCC for 'b' and 'c'.
1578   NewCs = RC.switchInternalEdgeToRef(CN, AN);
1579   EXPECT_EQ(1, std::distance(NewCs.begin(), NewCs.end()));
1580   EXPECT_EQ(2, RC.size());
1581   EXPECT_EQ(&AC, CG.lookupSCC(AN));
1582   LazyCallGraph::SCC &BC = *CG.lookupSCC(BN);
1583   EXPECT_NE(&BC, &AC);
1584   EXPECT_EQ(&BC, CG.lookupSCC(CN));
1585   auto J = RC.find(AC);
1586   EXPECT_EQ(&AC, &*J);
1587   --J;
1588   EXPECT_EQ(&BC, &*J);
1589   EXPECT_EQ(RC.begin(), J);
1590   EXPECT_EQ(J, NewCs.begin());
1591 
1592   // Remove the edge from c -> b, which should leave 'b' in the original SCC
1593   // and form a new SCC for 'c'. It shouldn't change 'a's SCC.
1594   NewCs = RC.switchInternalEdgeToRef(CN, BN);
1595   EXPECT_EQ(1, std::distance(NewCs.begin(), NewCs.end()));
1596   EXPECT_EQ(3, RC.size());
1597   EXPECT_EQ(&AC, CG.lookupSCC(AN));
1598   EXPECT_EQ(&BC, CG.lookupSCC(BN));
1599   LazyCallGraph::SCC &CC = *CG.lookupSCC(CN);
1600   EXPECT_NE(&CC, &AC);
1601   EXPECT_NE(&CC, &BC);
1602   J = RC.find(AC);
1603   EXPECT_EQ(&AC, &*J);
1604   --J;
1605   EXPECT_EQ(&BC, &*J);
1606   --J;
1607   EXPECT_EQ(&CC, &*J);
1608   EXPECT_EQ(RC.begin(), J);
1609   EXPECT_EQ(J, NewCs.begin());
1610 }
1611 
TEST(LazyCallGraphTest,InternalRefEdgeToCall)1612 TEST(LazyCallGraphTest, InternalRefEdgeToCall) {
1613   LLVMContext Context;
1614   // Basic tests for making a ref edge a call. This hits the basics of the
1615   // process only.
1616   std::unique_ptr<Module> M =
1617       parseAssembly(Context, "define void @a() {\n"
1618                              "entry:\n"
1619                              "  call void @b()\n"
1620                              "  call void @c()\n"
1621                              "  store void()* @d, void()** undef\n"
1622                              "  ret void\n"
1623                              "}\n"
1624                              "define void @b() {\n"
1625                              "entry:\n"
1626                              "  store void()* @c, void()** undef\n"
1627                              "  call void @d()\n"
1628                              "  ret void\n"
1629                              "}\n"
1630                              "define void @c() {\n"
1631                              "entry:\n"
1632                              "  store void()* @b, void()** undef\n"
1633                              "  call void @d()\n"
1634                              "  ret void\n"
1635                              "}\n"
1636                              "define void @d() {\n"
1637                              "entry:\n"
1638                              "  store void()* @a, void()** undef\n"
1639                              "  ret void\n"
1640                              "}\n");
1641   LazyCallGraph CG = buildCG(*M);
1642 
1643   // Force the graph to be fully expanded.
1644   CG.buildRefSCCs();
1645   auto I = CG.postorder_ref_scc_begin();
1646   LazyCallGraph::RefSCC &RC = *I++;
1647   EXPECT_EQ(CG.postorder_ref_scc_end(), I);
1648 
1649   LazyCallGraph::Node &A = *CG.lookup(lookupFunction(*M, "a"));
1650   LazyCallGraph::Node &B = *CG.lookup(lookupFunction(*M, "b"));
1651   LazyCallGraph::Node &C = *CG.lookup(lookupFunction(*M, "c"));
1652   LazyCallGraph::Node &D = *CG.lookup(lookupFunction(*M, "d"));
1653   LazyCallGraph::SCC &AC = *CG.lookupSCC(A);
1654   LazyCallGraph::SCC &BC = *CG.lookupSCC(B);
1655   LazyCallGraph::SCC &CC = *CG.lookupSCC(C);
1656   LazyCallGraph::SCC &DC = *CG.lookupSCC(D);
1657 
1658   // Check the initial post-order. Note that B and C could be flipped here (and
1659   // in our mutation) without changing the nature of this test.
1660   ASSERT_EQ(4, RC.size());
1661   EXPECT_EQ(&DC, &RC[0]);
1662   EXPECT_EQ(&BC, &RC[1]);
1663   EXPECT_EQ(&CC, &RC[2]);
1664   EXPECT_EQ(&AC, &RC[3]);
1665 
1666   // Switch the ref edge from A -> D to a call edge. This should have no
1667   // effect as it is already in postorder and no new cycles are formed.
1668   EXPECT_FALSE(RC.switchInternalEdgeToCall(A, D));
1669   ASSERT_EQ(4, RC.size());
1670   EXPECT_EQ(&DC, &RC[0]);
1671   EXPECT_EQ(&BC, &RC[1]);
1672   EXPECT_EQ(&CC, &RC[2]);
1673   EXPECT_EQ(&AC, &RC[3]);
1674 
1675   // Switch B -> C to a call edge. This doesn't form any new cycles but does
1676   // require reordering the SCCs.
1677   EXPECT_FALSE(RC.switchInternalEdgeToCall(B, C));
1678   ASSERT_EQ(4, RC.size());
1679   EXPECT_EQ(&DC, &RC[0]);
1680   EXPECT_EQ(&CC, &RC[1]);
1681   EXPECT_EQ(&BC, &RC[2]);
1682   EXPECT_EQ(&AC, &RC[3]);
1683 
1684   // Switch C -> B to a call edge. This forms a cycle and forces merging SCCs.
1685   EXPECT_TRUE(RC.switchInternalEdgeToCall(C, B, [&](ArrayRef<LazyCallGraph::SCC *> MergedCs) {
1686     ASSERT_EQ(1u, MergedCs.size());
1687     EXPECT_EQ(&CC, MergedCs[0]);
1688   }));
1689   ASSERT_EQ(3, RC.size());
1690   EXPECT_EQ(&DC, &RC[0]);
1691   EXPECT_EQ(&BC, &RC[1]);
1692   EXPECT_EQ(&AC, &RC[2]);
1693   EXPECT_EQ(2, BC.size());
1694   EXPECT_EQ(&BC, CG.lookupSCC(B));
1695   EXPECT_EQ(&BC, CG.lookupSCC(C));
1696 }
1697 
TEST(LazyCallGraphTest,InternalRefEdgeToCallNoCycleInterleaved)1698 TEST(LazyCallGraphTest, InternalRefEdgeToCallNoCycleInterleaved) {
1699   LLVMContext Context;
1700   // Test for having a post-order prior to changing a ref edge to a call edge
1701   // with SCCs connecting to the source and connecting to the target, but not
1702   // connecting to both, interleaved between the source and target. This
1703   // ensures we correctly partition the range rather than simply moving one or
1704   // the other.
1705   std::unique_ptr<Module> M =
1706       parseAssembly(Context, "define void @a() {\n"
1707                              "entry:\n"
1708                              "  call void @b1()\n"
1709                              "  call void @c1()\n"
1710                              "  ret void\n"
1711                              "}\n"
1712                              "define void @b1() {\n"
1713                              "entry:\n"
1714                              "  call void @c1()\n"
1715                              "  call void @b2()\n"
1716                              "  ret void\n"
1717                              "}\n"
1718                              "define void @c1() {\n"
1719                              "entry:\n"
1720                              "  call void @b2()\n"
1721                              "  call void @c2()\n"
1722                              "  ret void\n"
1723                              "}\n"
1724                              "define void @b2() {\n"
1725                              "entry:\n"
1726                              "  call void @c2()\n"
1727                              "  call void @b3()\n"
1728                              "  ret void\n"
1729                              "}\n"
1730                              "define void @c2() {\n"
1731                              "entry:\n"
1732                              "  call void @b3()\n"
1733                              "  call void @c3()\n"
1734                              "  ret void\n"
1735                              "}\n"
1736                              "define void @b3() {\n"
1737                              "entry:\n"
1738                              "  call void @c3()\n"
1739                              "  call void @d()\n"
1740                              "  ret void\n"
1741                              "}\n"
1742                              "define void @c3() {\n"
1743                              "entry:\n"
1744                              "  store void()* @b1, void()** undef\n"
1745                              "  call void @d()\n"
1746                              "  ret void\n"
1747                              "}\n"
1748                              "define void @d() {\n"
1749                              "entry:\n"
1750                              "  store void()* @a, void()** undef\n"
1751                              "  ret void\n"
1752                              "}\n");
1753   LazyCallGraph CG = buildCG(*M);
1754 
1755   // Force the graph to be fully expanded.
1756   CG.buildRefSCCs();
1757   auto I = CG.postorder_ref_scc_begin();
1758   LazyCallGraph::RefSCC &RC = *I++;
1759   EXPECT_EQ(CG.postorder_ref_scc_end(), I);
1760 
1761   LazyCallGraph::Node &A = *CG.lookup(lookupFunction(*M, "a"));
1762   LazyCallGraph::Node &B1 = *CG.lookup(lookupFunction(*M, "b1"));
1763   LazyCallGraph::Node &B2 = *CG.lookup(lookupFunction(*M, "b2"));
1764   LazyCallGraph::Node &B3 = *CG.lookup(lookupFunction(*M, "b3"));
1765   LazyCallGraph::Node &C1 = *CG.lookup(lookupFunction(*M, "c1"));
1766   LazyCallGraph::Node &C2 = *CG.lookup(lookupFunction(*M, "c2"));
1767   LazyCallGraph::Node &C3 = *CG.lookup(lookupFunction(*M, "c3"));
1768   LazyCallGraph::Node &D = *CG.lookup(lookupFunction(*M, "d"));
1769   LazyCallGraph::SCC &AC = *CG.lookupSCC(A);
1770   LazyCallGraph::SCC &B1C = *CG.lookupSCC(B1);
1771   LazyCallGraph::SCC &B2C = *CG.lookupSCC(B2);
1772   LazyCallGraph::SCC &B3C = *CG.lookupSCC(B3);
1773   LazyCallGraph::SCC &C1C = *CG.lookupSCC(C1);
1774   LazyCallGraph::SCC &C2C = *CG.lookupSCC(C2);
1775   LazyCallGraph::SCC &C3C = *CG.lookupSCC(C3);
1776   LazyCallGraph::SCC &DC = *CG.lookupSCC(D);
1777 
1778   // Several call edges are initially present to force a particual post-order.
1779   // Remove them now, leaving an interleaved post-order pattern.
1780   RC.switchTrivialInternalEdgeToRef(B3, C3);
1781   RC.switchTrivialInternalEdgeToRef(C2, B3);
1782   RC.switchTrivialInternalEdgeToRef(B2, C2);
1783   RC.switchTrivialInternalEdgeToRef(C1, B2);
1784   RC.switchTrivialInternalEdgeToRef(B1, C1);
1785 
1786   // Check the initial post-order. We ensure this order with the extra edges
1787   // that are nuked above.
1788   ASSERT_EQ(8, RC.size());
1789   EXPECT_EQ(&DC, &RC[0]);
1790   EXPECT_EQ(&C3C, &RC[1]);
1791   EXPECT_EQ(&B3C, &RC[2]);
1792   EXPECT_EQ(&C2C, &RC[3]);
1793   EXPECT_EQ(&B2C, &RC[4]);
1794   EXPECT_EQ(&C1C, &RC[5]);
1795   EXPECT_EQ(&B1C, &RC[6]);
1796   EXPECT_EQ(&AC, &RC[7]);
1797 
1798   // Switch C3 -> B1 to a call edge. This doesn't form any new cycles but does
1799   // require reordering the SCCs in the face of tricky internal node
1800   // structures.
1801   EXPECT_FALSE(RC.switchInternalEdgeToCall(C3, B1));
1802   ASSERT_EQ(8, RC.size());
1803   EXPECT_EQ(&DC, &RC[0]);
1804   EXPECT_EQ(&B3C, &RC[1]);
1805   EXPECT_EQ(&B2C, &RC[2]);
1806   EXPECT_EQ(&B1C, &RC[3]);
1807   EXPECT_EQ(&C3C, &RC[4]);
1808   EXPECT_EQ(&C2C, &RC[5]);
1809   EXPECT_EQ(&C1C, &RC[6]);
1810   EXPECT_EQ(&AC, &RC[7]);
1811 }
1812 
TEST(LazyCallGraphTest,InternalRefEdgeToCallBothPartitionAndMerge)1813 TEST(LazyCallGraphTest, InternalRefEdgeToCallBothPartitionAndMerge) {
1814   LLVMContext Context;
1815   // Test for having a postorder where between the source and target are all
1816   // three kinds of other SCCs:
1817   // 1) One connected to the target only that have to be shifted below the
1818   //    source.
1819   // 2) One connected to the source only that have to be shifted below the
1820   //    target.
1821   // 3) One connected to both source and target that has to remain and get
1822   //    merged away.
1823   //
1824   // To achieve this we construct a heavily connected graph to force
1825   // a particular post-order. Then we remove the forcing edges and connect
1826   // a cycle.
1827   //
1828   // Diagram for the graph we want on the left and the graph we use to force
1829   // the ordering on the right. Edges ponit down or right.
1830   //
1831   //   A    |    A    |
1832   //  / \   |   / \   |
1833   // B   E  |  B   \  |
1834   // |\  |  |  |\  |  |
1835   // | D |  |  C-D-E  |
1836   // |  \|  |  |  \|  |
1837   // C   F  |  \   F  |
1838   //  \ /   |   \ /   |
1839   //   G    |    G    |
1840   //
1841   // And we form a cycle by connecting F to B.
1842   std::unique_ptr<Module> M =
1843       parseAssembly(Context, "define void @a() {\n"
1844                              "entry:\n"
1845                              "  call void @b()\n"
1846                              "  call void @e()\n"
1847                              "  ret void\n"
1848                              "}\n"
1849                              "define void @b() {\n"
1850                              "entry:\n"
1851                              "  call void @c()\n"
1852                              "  call void @d()\n"
1853                              "  ret void\n"
1854                              "}\n"
1855                              "define void @c() {\n"
1856                              "entry:\n"
1857                              "  call void @d()\n"
1858                              "  call void @g()\n"
1859                              "  ret void\n"
1860                              "}\n"
1861                              "define void @d() {\n"
1862                              "entry:\n"
1863                              "  call void @e()\n"
1864                              "  call void @f()\n"
1865                              "  ret void\n"
1866                              "}\n"
1867                              "define void @e() {\n"
1868                              "entry:\n"
1869                              "  call void @f()\n"
1870                              "  ret void\n"
1871                              "}\n"
1872                              "define void @f() {\n"
1873                              "entry:\n"
1874                              "  store void()* @b, void()** undef\n"
1875                              "  call void @g()\n"
1876                              "  ret void\n"
1877                              "}\n"
1878                              "define void @g() {\n"
1879                              "entry:\n"
1880                              "  store void()* @a, void()** undef\n"
1881                              "  ret void\n"
1882                              "}\n");
1883   LazyCallGraph CG = buildCG(*M);
1884 
1885   // Force the graph to be fully expanded.
1886   CG.buildRefSCCs();
1887   auto I = CG.postorder_ref_scc_begin();
1888   LazyCallGraph::RefSCC &RC = *I++;
1889   EXPECT_EQ(CG.postorder_ref_scc_end(), I);
1890 
1891   LazyCallGraph::Node &A = *CG.lookup(lookupFunction(*M, "a"));
1892   LazyCallGraph::Node &B = *CG.lookup(lookupFunction(*M, "b"));
1893   LazyCallGraph::Node &C = *CG.lookup(lookupFunction(*M, "c"));
1894   LazyCallGraph::Node &D = *CG.lookup(lookupFunction(*M, "d"));
1895   LazyCallGraph::Node &E = *CG.lookup(lookupFunction(*M, "e"));
1896   LazyCallGraph::Node &F = *CG.lookup(lookupFunction(*M, "f"));
1897   LazyCallGraph::Node &G = *CG.lookup(lookupFunction(*M, "g"));
1898   LazyCallGraph::SCC &AC = *CG.lookupSCC(A);
1899   LazyCallGraph::SCC &BC = *CG.lookupSCC(B);
1900   LazyCallGraph::SCC &CC = *CG.lookupSCC(C);
1901   LazyCallGraph::SCC &DC = *CG.lookupSCC(D);
1902   LazyCallGraph::SCC &EC = *CG.lookupSCC(E);
1903   LazyCallGraph::SCC &FC = *CG.lookupSCC(F);
1904   LazyCallGraph::SCC &GC = *CG.lookupSCC(G);
1905 
1906   // Remove the extra edges that were used to force a particular post-order.
1907   RC.switchTrivialInternalEdgeToRef(C, D);
1908   RC.switchTrivialInternalEdgeToRef(D, E);
1909 
1910   // Check the initial post-order. We ensure this order with the extra edges
1911   // that are nuked above.
1912   ASSERT_EQ(7, RC.size());
1913   EXPECT_EQ(&GC, &RC[0]);
1914   EXPECT_EQ(&FC, &RC[1]);
1915   EXPECT_EQ(&EC, &RC[2]);
1916   EXPECT_EQ(&DC, &RC[3]);
1917   EXPECT_EQ(&CC, &RC[4]);
1918   EXPECT_EQ(&BC, &RC[5]);
1919   EXPECT_EQ(&AC, &RC[6]);
1920 
1921   // Switch F -> B to a call edge. This merges B, D, and F into a single SCC,
1922   // and has to place the C and E SCCs on either side of it:
1923   //   A          A    |
1924   //  / \        / \   |
1925   // B   E      |   E  |
1926   // |\  |       \ /   |
1927   // | D |  ->    B    |
1928   // |  \|       / \   |
1929   // C   F      C   |  |
1930   //  \ /        \ /   |
1931   //   G          G    |
1932   EXPECT_TRUE(RC.switchInternalEdgeToCall(
1933       F, B, [&](ArrayRef<LazyCallGraph::SCC *> MergedCs) {
1934         ASSERT_EQ(2u, MergedCs.size());
1935         EXPECT_EQ(&FC, MergedCs[0]);
1936         EXPECT_EQ(&DC, MergedCs[1]);
1937       }));
1938   EXPECT_EQ(3, BC.size());
1939 
1940   // And make sure the postorder was updated.
1941   ASSERT_EQ(5, RC.size());
1942   EXPECT_EQ(&GC, &RC[0]);
1943   EXPECT_EQ(&CC, &RC[1]);
1944   EXPECT_EQ(&BC, &RC[2]);
1945   EXPECT_EQ(&EC, &RC[3]);
1946   EXPECT_EQ(&AC, &RC[4]);
1947 }
1948 
1949 // Test for IR containing constants using blockaddress constant expressions.
1950 // These are truly unique constructs: constant expressions with non-constant
1951 // operands.
TEST(LazyCallGraphTest,HandleBlockAddress)1952 TEST(LazyCallGraphTest, HandleBlockAddress) {
1953   LLVMContext Context;
1954   std::unique_ptr<Module> M =
1955       parseAssembly(Context, "define void @f() {\n"
1956                              "entry:\n"
1957                              "  ret void\n"
1958                              "bb:\n"
1959                              "  unreachable\n"
1960                              "}\n"
1961                              "define void @g(i8** %ptr) {\n"
1962                              "entry:\n"
1963                              "  store i8* blockaddress(@f, %bb), i8** %ptr\n"
1964                              "  ret void\n"
1965                              "}\n");
1966   LazyCallGraph CG = buildCG(*M);
1967 
1968   CG.buildRefSCCs();
1969   auto I = CG.postorder_ref_scc_begin();
1970   LazyCallGraph::RefSCC &FRC = *I++;
1971   LazyCallGraph::RefSCC &GRC = *I++;
1972   EXPECT_EQ(CG.postorder_ref_scc_end(), I);
1973 
1974   LazyCallGraph::Node &F = *CG.lookup(lookupFunction(*M, "f"));
1975   LazyCallGraph::Node &G = *CG.lookup(lookupFunction(*M, "g"));
1976   EXPECT_EQ(&FRC, CG.lookupRefSCC(F));
1977   EXPECT_EQ(&GRC, CG.lookupRefSCC(G));
1978   EXPECT_TRUE(GRC.isParentOf(FRC));
1979 }
1980 
TEST(LazyCallGraphTest,ReplaceNodeFunction)1981 TEST(LazyCallGraphTest, ReplaceNodeFunction) {
1982   LLVMContext Context;
1983   // A graph with several different kinds of edges pointing at a particular
1984   // function.
1985   std::unique_ptr<Module> M =
1986       parseAssembly(Context,
1987                     "define void @a(i8** %ptr) {\n"
1988                     "entry:\n"
1989                     "  store i8* bitcast (void(i8**)* @d to i8*), i8** %ptr\n"
1990                     "  ret void\n"
1991                     "}\n"
1992                     "define void @b(i8** %ptr) {\n"
1993                     "entry:\n"
1994                     "  store i8* bitcast (void(i8**)* @d to i8*), i8** %ptr\n"
1995                     "  store i8* bitcast (void(i8**)* @d to i8*), i8** %ptr\n"
1996                     "  call void @d(i8** %ptr)"
1997                     "  ret void\n"
1998                     "}\n"
1999                     "define void @c(i8** %ptr) {\n"
2000                     "entry:\n"
2001                     "  call void @d(i8** %ptr)"
2002                     "  call void @d(i8** %ptr)"
2003                     "  store i8* bitcast (void(i8**)* @d to i8*), i8** %ptr\n"
2004                     "  ret void\n"
2005                     "}\n"
2006                     "define void @d(i8** %ptr) {\n"
2007                     "entry:\n"
2008                     "  store i8* bitcast (void(i8**)* @b to i8*), i8** %ptr\n"
2009                     "  call void @c(i8** %ptr)"
2010                     "  call void @d(i8** %ptr)"
2011                     "  store i8* bitcast (void(i8**)* @d to i8*), i8** %ptr\n"
2012                     "  ret void\n"
2013                     "}\n");
2014   LazyCallGraph CG = buildCG(*M);
2015 
2016   // Force the graph to be fully expanded.
2017   CG.buildRefSCCs();
2018   auto I = CG.postorder_ref_scc_begin();
2019   LazyCallGraph::RefSCC &RC1 = *I++;
2020   LazyCallGraph::RefSCC &RC2 = *I++;
2021   EXPECT_EQ(CG.postorder_ref_scc_end(), I);
2022 
2023   ASSERT_EQ(2, RC1.size());
2024   LazyCallGraph::SCC &C1 = RC1[0];
2025   LazyCallGraph::SCC &C2 = RC1[1];
2026 
2027   LazyCallGraph::Node &AN = *CG.lookup(lookupFunction(*M, "a"));
2028   LazyCallGraph::Node &BN = *CG.lookup(lookupFunction(*M, "b"));
2029   LazyCallGraph::Node &CN = *CG.lookup(lookupFunction(*M, "c"));
2030   LazyCallGraph::Node &DN = *CG.lookup(lookupFunction(*M, "d"));
2031   EXPECT_EQ(&C1, CG.lookupSCC(DN));
2032   EXPECT_EQ(&C1, CG.lookupSCC(CN));
2033   EXPECT_EQ(&C2, CG.lookupSCC(BN));
2034   EXPECT_EQ(&RC1, CG.lookupRefSCC(DN));
2035   EXPECT_EQ(&RC1, CG.lookupRefSCC(CN));
2036   EXPECT_EQ(&RC1, CG.lookupRefSCC(BN));
2037   EXPECT_EQ(&RC2, CG.lookupRefSCC(AN));
2038 
2039   // Now we need to build a new function 'e' with the same signature as 'd'.
2040   Function &D = DN.getFunction();
2041   Function &E = *Function::Create(D.getFunctionType(), D.getLinkage(), "e");
2042   D.getParent()->getFunctionList().insert(D.getIterator(), &E);
2043 
2044   // Change each use of 'd' to use 'e'. This is particularly easy as they have
2045   // the same type.
2046   D.replaceAllUsesWith(&E);
2047 
2048   // Splice the body of the old function into the new one.
2049   E.getBasicBlockList().splice(E.begin(), D.getBasicBlockList());
2050   // And fix up the one argument.
2051   D.arg_begin()->replaceAllUsesWith(&*E.arg_begin());
2052   E.arg_begin()->takeName(&*D.arg_begin());
2053 
2054   // Now replace the function in the graph.
2055   RC1.replaceNodeFunction(DN, E);
2056 
2057   EXPECT_EQ(&E, &DN.getFunction());
2058   EXPECT_EQ(&DN, &(*CN)[DN].getNode());
2059   EXPECT_EQ(&DN, &(*BN)[DN].getNode());
2060 }
2061 
TEST(LazyCallGraphTest,RemoveFunctionWithSpurriousRef)2062 TEST(LazyCallGraphTest, RemoveFunctionWithSpurriousRef) {
2063   LLVMContext Context;
2064   // A graph with a couple of RefSCCs.
2065   std::unique_ptr<Module> M =
2066       parseAssembly(Context,
2067                     "define void @a(i8** %ptr) {\n"
2068                     "entry:\n"
2069                     "  store i8* bitcast (void(i8**)* @d to i8*), i8** %ptr\n"
2070                     "  ret void\n"
2071                     "}\n"
2072                     "define void @b(i8** %ptr) {\n"
2073                     "entry:\n"
2074                     "  store i8* bitcast (void(i8**)* @c to i8*), i8** %ptr\n"
2075                     "  ret void\n"
2076                     "}\n"
2077                     "define void @c(i8** %ptr) {\n"
2078                     "entry:\n"
2079                     "  call void @d(i8** %ptr)"
2080                     "  ret void\n"
2081                     "}\n"
2082                     "define void @d(i8** %ptr) {\n"
2083                     "entry:\n"
2084                     "  call void @c(i8** %ptr)"
2085                     "  store i8* bitcast (void(i8**)* @b to i8*), i8** %ptr\n"
2086                     "  ret void\n"
2087                     "}\n"
2088                     "define void @dead() {\n"
2089                     "entry:\n"
2090                     "  ret void\n"
2091                     "}\n");
2092   LazyCallGraph CG = buildCG(*M);
2093 
2094   // Insert spurious ref edges.
2095   LazyCallGraph::Node &AN = CG.get(lookupFunction(*M, "a"));
2096   LazyCallGraph::Node &BN = CG.get(lookupFunction(*M, "b"));
2097   LazyCallGraph::Node &CN = CG.get(lookupFunction(*M, "c"));
2098   LazyCallGraph::Node &DN = CG.get(lookupFunction(*M, "d"));
2099   LazyCallGraph::Node &DeadN = CG.get(lookupFunction(*M, "dead"));
2100   AN.populate();
2101   BN.populate();
2102   CN.populate();
2103   DN.populate();
2104   DeadN.populate();
2105   CG.insertEdge(AN, DeadN, LazyCallGraph::Edge::Ref);
2106   CG.insertEdge(BN, DeadN, LazyCallGraph::Edge::Ref);
2107   CG.insertEdge(CN, DeadN, LazyCallGraph::Edge::Ref);
2108   CG.insertEdge(DN, DeadN, LazyCallGraph::Edge::Ref);
2109 
2110   // Force the graph to be fully expanded.
2111   CG.buildRefSCCs();
2112   auto I = CG.postorder_ref_scc_begin();
2113   LazyCallGraph::RefSCC &DeadRC = *I++;
2114   LazyCallGraph::RefSCC &RC1 = *I++;
2115   LazyCallGraph::RefSCC &RC2 = *I++;
2116   EXPECT_EQ(CG.postorder_ref_scc_end(), I);
2117 
2118   ASSERT_EQ(2, RC1.size());
2119   LazyCallGraph::SCC &C1 = RC1[0];
2120   LazyCallGraph::SCC &C2 = RC1[1];
2121 
2122   EXPECT_EQ(&DeadRC, CG.lookupRefSCC(DeadN));
2123   EXPECT_EQ(&C1, CG.lookupSCC(DN));
2124   EXPECT_EQ(&C1, CG.lookupSCC(CN));
2125   EXPECT_EQ(&C2, CG.lookupSCC(BN));
2126   EXPECT_EQ(&RC1, CG.lookupRefSCC(DN));
2127   EXPECT_EQ(&RC1, CG.lookupRefSCC(CN));
2128   EXPECT_EQ(&RC1, CG.lookupRefSCC(BN));
2129   EXPECT_EQ(&RC2, CG.lookupRefSCC(AN));
2130 
2131   // Now delete 'dead'. There are no uses of this function but there are
2132   // spurious references.
2133   CG.removeDeadFunction(DeadN.getFunction());
2134 
2135   // The only observable change should be that the RefSCC is gone from the
2136   // postorder sequence.
2137   I = CG.postorder_ref_scc_begin();
2138   EXPECT_EQ(&RC1, &*I++);
2139   EXPECT_EQ(&RC2, &*I++);
2140   EXPECT_EQ(CG.postorder_ref_scc_end(), I);
2141 }
2142 }
2143