1 //===- LazyCallGraphTest.cpp - Unit tests for the lazy CG analysis --------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
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"
25 std::unique_ptr
<Module
> parseAssembly(LLVMContext
&Context
,
26 const char *Assembly
) {
28 std::unique_ptr
<Module
> M
= parseAssemblyString(Assembly
, Error
, Context
);
31 raw_string_ostream
OS(ErrMsg
);
34 // A failure here means that the test itself is buggy.
36 report_fatal_error(OS
.str().c_str());
42 IR forming a call graph with a diamond of triangle-shaped SCCs:
56 All call edges go up between SCCs, and clockwise around the SCC.
58 static const char DiamondOfTriangles
[] =
59 "define void @a1() {\n"
66 "define void @a2() {\n"
71 "define void @a3() {\n"
76 "define void @b1() {\n"
82 "define void @b2() {\n"
87 "define void @b3() {\n"
92 "define void @c1() {\n"
98 "define void @c2() {\n"
103 "define void @c3() {\n"
108 "define void @d1() {\n"
113 "define void @d2() {\n"
118 "define void @d3() {\n"
125 IR forming a reference graph with a diamond of triangle-shaped RefSCCs
139 All call edges go up between RefSCCs, and clockwise around the RefSCC.
141 static const char DiamondOfTrianglesRefGraph
[] =
142 "define void @a1() {\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"
150 "define void @a2() {\n"
152 " %a = alloca void ()*\n"
153 " store void ()* @a3, void ()** %a\n"
156 "define void @a3() {\n"
158 " %a = alloca void ()*\n"
159 " store void ()* @a1, void ()** %a\n"
162 "define void @b1() {\n"
164 " %a = alloca void ()*\n"
165 " store void ()* @b2, void ()** %a\n"
166 " store void ()* @d3, void ()** %a\n"
169 "define void @b2() {\n"
171 " %a = alloca void ()*\n"
172 " store void ()* @b3, void ()** %a\n"
175 "define void @b3() {\n"
177 " %a = alloca void ()*\n"
178 " store void ()* @b1, void ()** %a\n"
181 "define void @c1() {\n"
183 " %a = alloca void ()*\n"
184 " store void ()* @c2, void ()** %a\n"
185 " store void ()* @d2, void ()** %a\n"
188 "define void @c2() {\n"
190 " %a = alloca void ()*\n"
191 " store void ()* @c3, void ()** %a\n"
194 "define void @c3() {\n"
196 " %a = alloca void ()*\n"
197 " store void ()* @c1, void ()** %a\n"
200 "define void @d1() {\n"
202 " %a = alloca void ()*\n"
203 " store void ()* @d2, void ()** %a\n"
206 "define void @d2() {\n"
208 " %a = alloca void ()*\n"
209 " store void ()* @d3, void ()** %a\n"
212 "define void @d3() {\n"
214 " %a = alloca void ()*\n"
215 " store void ()* @d1, void ()** %a\n"
219 static LazyCallGraph
buildCG(Module
&M
) {
220 TargetLibraryInfoImpl
TLII(Triple(M
.getTargetTriple()));
221 TargetLibraryInfo
TLI(TLII
);
222 LazyCallGraph
CG(M
, TLI
);
226 TEST(LazyCallGraphTest
, BasicGraphFormation
) {
228 std::unique_ptr
<Module
> M
= parseAssembly(Context
, DiamondOfTriangles
);
229 LazyCallGraph CG
= buildCG(*M
);
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.
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
);
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
;
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]);
274 EXPECT_EQ(A2
->end(), std::next(A2
->begin()));
275 EXPECT_EQ("a3", A2
->begin()->getFunction().getName());
277 EXPECT_EQ(A3
->end(), std::next(A3
->begin()));
278 EXPECT_EQ("a1", A3
->begin()->getFunction().getName());
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]);
288 EXPECT_EQ(B2
->end(), std::next(B2
->begin()));
289 EXPECT_EQ("b3", B2
->begin()->getFunction().getName());
291 EXPECT_EQ(B3
->end(), std::next(B3
->begin()));
292 EXPECT_EQ("b1", B3
->begin()->getFunction().getName());
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]);
302 EXPECT_EQ(C2
->end(), std::next(C2
->begin()));
303 EXPECT_EQ("c3", C2
->begin()->getFunction().getName());
305 EXPECT_EQ(C3
->end(), std::next(C3
->begin()));
306 EXPECT_EQ("c1", C3
->begin()->getFunction().getName());
309 EXPECT_EQ(D1
->end(), std::next(D1
->begin()));
310 EXPECT_EQ("d2", D1
->begin()->getFunction().getName());
312 EXPECT_EQ(D2
->end(), std::next(D2
->begin()));
313 EXPECT_EQ("d3", D2
->begin()->getFunction().getName());
315 EXPECT_EQ(D3
->end(), std::next(D3
->begin()));
316 EXPECT_EQ("d1", D3
->begin()->getFunction().getName());
318 // Now lets look at the RefSCCs and SCCs.
320 auto J
= CG
.postorder_ref_scc_begin();
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]);
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());
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]);
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()));
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]);
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));
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]);
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));
390 EXPECT_EQ(CG
.postorder_ref_scc_end(), J
);
391 EXPECT_EQ(J
, std::next(CG
.postorder_ref_scc_begin(), 4));
394 static Function
&lookupFunction(Module
&M
, StringRef Name
) {
395 for (Function
&F
: M
)
396 if (F
.getName() == Name
)
398 report_fatal_error("Couldn't find function!");
401 TEST(LazyCallGraphTest
, BasicGraphMutation
) {
403 std::unique_ptr
<Module
> M
= parseAssembly(Context
, "define void @a() {\n"
409 "define void @b() {\n"
413 "define void @c() {\n"
417 LazyCallGraph CG
= buildCG(*M
);
419 LazyCallGraph::Node
&A
= CG
.get(lookupFunction(*M
, "a"));
420 LazyCallGraph::Node
&B
= CG
.get(lookupFunction(*M
, "b"));
422 EXPECT_EQ(2, std::distance(A
->begin(), A
->end()));
424 EXPECT_EQ(0, std::distance(B
->begin(), B
->end()));
426 LazyCallGraph::Node
&C
= CG
.get(lookupFunction(*M
, "c"));
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()));
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());
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());
442 EXPECT_EQ(1, std::distance(C
->begin(), C
->end()));
443 EXPECT_EQ(&C
, &C
->begin()->getNode());
446 EXPECT_EQ(0, std::distance(C
->begin(), C
->end()));
449 EXPECT_EQ(0, std::distance(B
->begin(), B
->end()));
452 TEST(LazyCallGraphTest
, InnerSCCFormation
) {
454 std::unique_ptr
<Module
> M
= parseAssembly(Context
, DiamondOfTriangles
);
455 LazyCallGraph CG
= buildCG(*M
);
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"));
463 CG
.insertEdge(D1
, A1
, LazyCallGraph::Edge::Ref
);
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
;
469 // We should build a single RefSCC for the entire graph.
471 auto I
= CG
.postorder_ref_scc_begin();
472 LazyCallGraph::RefSCC
&RC
= *I
++;
473 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
475 // Now walk the four SCCs which should be in post-order.
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]);
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]);
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]);
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]);
517 EXPECT_EQ(RC
.end(), J
);
520 TEST(LazyCallGraphTest
, MultiArmSCC
) {
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"
532 "define void @f2() {\n"
537 "define void @f3() {\n"
542 "define void @f4() {\n"
547 "define void @f5() {\n"
552 LazyCallGraph CG
= buildCG(*M
);
554 // Force the graph to be fully expanded.
556 auto I
= CG
.postorder_ref_scc_begin();
557 LazyCallGraph::RefSCC
&RC
= *I
++;
558 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
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
));
571 ASSERT_EQ(1, RC
.size());
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
));
581 TEST(LazyCallGraphTest
, OutgoingEdgeMutation
) {
583 std::unique_ptr
<Module
> M
= parseAssembly(Context
, "define void @a() {\n"
589 "define void @b() {\n"
594 "define void @c() {\n"
599 "define void @d() {\n"
603 LazyCallGraph CG
= buildCG(*M
);
605 // Force the graph to be fully expanded.
607 for (LazyCallGraph::RefSCC
&RC
: CG
.postorder_ref_sccs())
608 dbgs() << "Formed RefSCC: " << RC
<< "\n";
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
));
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
];
644 EXPECT_TRUE(NewE
.isCall());
645 EXPECT_EQ(&D
, &NewE
.getNode());
647 // Only the parent and child tests sholud have changed. The rest of the graph
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
));
666 ARC
.switchOutgoingEdgeToRef(A
, D
);
667 EXPECT_FALSE(NewE
.isCall());
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
));
687 ARC
.switchOutgoingEdgeToCall(A
, D
);
688 EXPECT_TRUE(NewE
.isCall());
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
));
708 ARC
.removeOutgoingEdge(A
, D
);
709 EXPECT_EQ(2, std::distance(A
->begin(), A
->end()));
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
));
730 TEST(LazyCallGraphTest
, IncomingEdgeInsertion
) {
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.
748 std::unique_ptr
<Module
> M
= parseAssembly(Context
, DiamondOfTriangles
);
749 LazyCallGraph CG
= buildCG(*M
);
751 // Force the graph to be fully expanded.
753 for (LazyCallGraph::RefSCC
&RC
: CG
.postorder_ref_sccs())
754 dbgs() << "Formed RefSCC: " << RC
<< "\n";
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()));
782 // Add an edge to make the graph:
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
)
800 EXPECT_EQ(&C2
, &E
.getNode());
802 // And marked the D ref-SCC as no longer valid.
803 EXPECT_EQ(1u, MergedRCs
.size());
804 EXPECT_EQ(&DRC
, MergedRCs
[0]);
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
));
820 // And that ancestry tests have been updated.
821 EXPECT_TRUE(ARC
.isParentOf(CRC
));
822 EXPECT_TRUE(BRC
.isParentOf(CRC
));
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();
827 EXPECT_EQ(&CRC
, &*I
) << "Actual RefSCC: " << *I
;
829 EXPECT_EQ(&BRC
, &*I
) << "Actual RefSCC: " << *I
;
831 EXPECT_EQ(&ARC
, &*I
) << "Actual RefSCC: " << *I
;
835 TEST(LazyCallGraphTest
, IncomingEdgeInsertionRefGraph
) {
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
);
843 // Force the graph to be fully expanded.
845 for (LazyCallGraph::RefSCC
&RC
: CG
.postorder_ref_sccs())
846 dbgs() << "Formed RefSCC: " << RC
<< "\n";
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()));
874 // Add an edge to make the graph:
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
)
892 EXPECT_EQ(&C2
, &E
.getNode());
894 // And marked the D ref-SCC as no longer valid.
895 EXPECT_EQ(1u, MergedRCs
.size());
896 EXPECT_EQ(&DRC
, MergedRCs
[0]);
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
));
912 // And that ancestry tests have been updated.
913 EXPECT_TRUE(ARC
.isParentOf(CRC
));
914 EXPECT_TRUE(BRC
.isParentOf(CRC
));
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();
919 EXPECT_EQ(&CRC
, &*I
) << "Actual RefSCC: " << *I
;
921 EXPECT_EQ(&BRC
, &*I
) << "Actual RefSCC: " << *I
;
923 EXPECT_EQ(&ARC
, &*I
) << "Actual RefSCC: " << *I
;
927 TEST(LazyCallGraphTest
, IncomingEdgeInsertionLargeCallCycle
) {
929 std::unique_ptr
<Module
> M
= parseAssembly(Context
, "define void @a() {\n"
934 "define void @b() {\n"
939 "define void @c() {\n"
944 "define void @d() {\n"
948 LazyCallGraph CG
= buildCG(*M
);
950 // Force the graph to be fully expanded.
952 for (LazyCallGraph::RefSCC
&RC
: CG
.postorder_ref_sccs())
953 dbgs() << "Formed RefSCC: " << RC
<< "\n";
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
);
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());
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());
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
));
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]);
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();
996 EXPECT_EQ(&ARC
, &*I
) << "Actual RefSCC: " << *I
;
1000 TEST(LazyCallGraphTest
, IncomingEdgeInsertionLargeRefCycle
) {
1001 LLVMContext Context
;
1002 std::unique_ptr
<Module
> M
=
1003 parseAssembly(Context
, "define void @a() {\n"
1005 " %p = alloca void ()*\n"
1006 " store void ()* @b, void ()** %p\n"
1009 "define void @b() {\n"
1011 " %p = alloca void ()*\n"
1012 " store void ()* @c, void ()** %p\n"
1015 "define void @c() {\n"
1017 " %p = alloca void ()*\n"
1018 " store void ()* @d, void ()** %p\n"
1021 "define void @d() {\n"
1025 LazyCallGraph CG
= buildCG(*M
);
1027 // Force the graph to be fully expanded.
1029 for (LazyCallGraph::RefSCC
&RC
: CG
.postorder_ref_sccs())
1030 dbgs() << "Formed RefSCC: " << RC
<< "\n";
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
);
1041 // Connect the top to the bottom forming a large RefSCC made up just of
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());
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());
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
));
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();
1063 EXPECT_EQ(&ARC
, &*I
) << "Actual RefSCC: " << *I
;
1064 EXPECT_EQ(++I
, End
);
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.
1072 // The ascii diagram is repeated here for easy reference.
1086 std::unique_ptr
<Module
> M
= parseAssembly(Context
, DiamondOfTriangles
);
1087 LazyCallGraph CG
= buildCG(*M
);
1089 // Force the graph to be fully expanded.
1091 for (LazyCallGraph::RefSCC
&RC
: CG
.postorder_ref_sccs())
1092 dbgs() << "Formed RefSCC: " << RC
<< "\n";
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()));
1120 // Delete d2 from the graph, as if it had been inlined.
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
;
1142 } else if (CI
->getParent()->getParent() == &D1
.getFunction()) {
1143 ASSERT_EQ(nullptr, D1Call
) << "Found too many D1 calls: " << *CI
;
1146 FAIL() << "Found an unexpected call instruction: " << *CI
;
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());
1157 // Insert new edges first.
1158 CRC
.insertTrivialCallEdge(C1
, D3
);
1159 DRC
.insertTrivialCallEdge(D1
, D3
);
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
));
1185 // Now that we've updated the call graph, D2 is dead, so remove it.
1186 CG
.removeDeadFunction(D2F
);
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
));
1202 // Verify the post-order walk hasn't changed.
1203 auto I
= CG
.postorder_ref_scc_begin(), E
= CG
.postorder_ref_scc_end();
1205 EXPECT_EQ(&NewDRC
, &*I
) << "Actual RefSCC: " << *I
;
1207 EXPECT_EQ(&CRC
, &*I
) << "Actual RefSCC: " << *I
;
1209 EXPECT_EQ(&BRC
, &*I
) << "Actual RefSCC: " << *I
;
1211 EXPECT_EQ(&ARC
, &*I
) << "Actual RefSCC: " << *I
;
1215 TEST(LazyCallGraphTest
, InternalEdgeMutation
) {
1216 LLVMContext Context
;
1217 std::unique_ptr
<Module
> M
= parseAssembly(Context
, "define void @a() {\n"
1222 "define void @b() {\n"
1227 "define void @c() {\n"
1232 LazyCallGraph CG
= buildCG(*M
);
1234 // Force the graph to be fully expanded.
1236 auto I
= CG
.postorder_ref_scc_begin();
1237 LazyCallGraph::RefSCC
&RC
= *I
++;
1238 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
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
));
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
));
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
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
1279 EXPECT_EQ(RC
.begin(), NewCs
.begin());
1280 EXPECT_EQ(std::prev(RC
.end()), NewCs
.end());
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
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]);
1292 EXPECT_EQ(2, CC
.size());
1293 EXPECT_EQ(&CC
, CG
.lookupSCC(A
));
1294 EXPECT_EQ(&CC
, CG
.lookupSCC(C
));
1296 EXPECT_EQ(&*J
++, CG
.lookupSCC(B
));
1297 EXPECT_EQ(&*J
++, CG
.lookupSCC(C
));
1298 EXPECT_EQ(RC
.end(), J
);
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"
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"
1312 "define void @b(i8** %ptr) {\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"
1319 "define void @c(i8** %ptr) {\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"
1326 LazyCallGraph CG
= buildCG(*M
);
1328 // Force the graph to be fully expanded.
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
));
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
));
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();
1351 EXPECT_EQ(&RC
, &*J
);
1352 EXPECT_EQ(E
, std::next(J
));
1354 // Increment I before we actually mutate the structure so that it remains
1355 // a valid iterator.
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();
1370 EXPECT_EQ(&BCRC
, &*J
);
1373 EXPECT_EQ(&ARC
, &*J
);
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"
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"
1390 "define void @b(i8** %ptr) {\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"
1397 "define void @c(i8** %ptr) {\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"
1404 LazyCallGraph CG
= buildCG(*M
);
1406 // Force the graph to be fully expanded.
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
));
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
));
1419 // Increment I before we actually mutate the structure so that it remains
1420 // a valid iterator.
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
});
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();
1436 EXPECT_EQ(&BRC
, &*J
);
1439 EXPECT_EQ(&ACRC
, &*J
);
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:
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"
1455 " call void @b(i8** %ptr)\n"
1456 " store i8* bitcast (void(i8**)* @c to i8*), i8** %ptr\n"
1459 "define void @b(i8** %ptr) {\n"
1461 " store i8* bitcast (void(i8**)* @a to i8*), i8** %ptr\n"
1462 " call void @c(i8** %ptr)\n"
1465 "define void @c(i8** %ptr) {\n"
1467 " call void @a(i8** %ptr)\n"
1468 " store i8* bitcast (void(i8**)* @b to i8*), i8** %ptr\n"
1471 LazyCallGraph CG
= buildCG(*M
);
1473 // Force the graph to be fully expanded.
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
));
1479 LazyCallGraph::SCC
&C
= *RC
.begin();
1480 EXPECT_EQ(RC
.end(), std::next(RC
.begin()));
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
));
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();
1504 EXPECT_EQ(&RC
, &*J
);
1505 EXPECT_EQ(E
, std::next(J
));
1507 // Remove the edge from b -> a and c -> b; again this doesn't change
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();
1520 EXPECT_EQ(&RC
, &*J
);
1521 EXPECT_EQ(E
, std::next(J
));
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"
1534 "define void @b() {\n"
1541 "define void @c() {\n"
1548 LazyCallGraph CG
= buildCG(*M
);
1550 // Force the graph to be fully expanded.
1552 auto I
= CG
.postorder_ref_scc_begin();
1553 LazyCallGraph::RefSCC
&RC
= *I
++;
1554 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
1556 EXPECT_EQ(1, RC
.size());
1557 LazyCallGraph::SCC
&AC
= *RC
.begin();
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
));
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 ->
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
));
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
);
1588 EXPECT_EQ(&BC
, &*J
);
1589 EXPECT_EQ(RC
.begin(), J
);
1590 EXPECT_EQ(J
, NewCs
.begin());
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
);
1603 EXPECT_EQ(&AC
, &*J
);
1605 EXPECT_EQ(&BC
, &*J
);
1607 EXPECT_EQ(&CC
, &*J
);
1608 EXPECT_EQ(RC
.begin(), J
);
1609 EXPECT_EQ(J
, NewCs
.begin());
1612 TEST(LazyCallGraphTest
, InternalRefEdgeToCall
) {
1613 LLVMContext Context
;
1614 // Basic tests for making a ref edge a call. This hits the basics of the
1616 std::unique_ptr
<Module
> M
=
1617 parseAssembly(Context
, "define void @a() {\n"
1621 " store void()* @d, void()** undef\n"
1624 "define void @b() {\n"
1626 " store void()* @c, void()** undef\n"
1630 "define void @c() {\n"
1632 " store void()* @b, void()** undef\n"
1636 "define void @d() {\n"
1638 " store void()* @a, void()** undef\n"
1641 LazyCallGraph CG
= buildCG(*M
);
1643 // Force the graph to be fully expanded.
1645 auto I
= CG
.postorder_ref_scc_begin();
1646 LazyCallGraph::RefSCC
&RC
= *I
++;
1647 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
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
);
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]);
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]);
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]);
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]);
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
));
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
1705 std::unique_ptr
<Module
> M
=
1706 parseAssembly(Context
, "define void @a() {\n"
1708 " call void @b1()\n"
1709 " call void @c1()\n"
1712 "define void @b1() {\n"
1714 " call void @c1()\n"
1715 " call void @b2()\n"
1718 "define void @c1() {\n"
1720 " call void @b2()\n"
1721 " call void @c2()\n"
1724 "define void @b2() {\n"
1726 " call void @c2()\n"
1727 " call void @b3()\n"
1730 "define void @c2() {\n"
1732 " call void @b3()\n"
1733 " call void @c3()\n"
1736 "define void @b3() {\n"
1738 " call void @c3()\n"
1742 "define void @c3() {\n"
1744 " store void()* @b1, void()** undef\n"
1748 "define void @d() {\n"
1750 " store void()* @a, void()** undef\n"
1753 LazyCallGraph CG
= buildCG(*M
);
1755 // Force the graph to be fully expanded.
1757 auto I
= CG
.postorder_ref_scc_begin();
1758 LazyCallGraph::RefSCC
&RC
= *I
++;
1759 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
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
);
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
);
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]);
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
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]);
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
1819 // 2) One connected to the source only that have to be shifted below the
1821 // 3) One connected to both source and target that has to remain and get
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
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.
1841 // And we form a cycle by connecting F to B.
1842 std::unique_ptr
<Module
> M
=
1843 parseAssembly(Context
, "define void @a() {\n"
1849 "define void @b() {\n"
1855 "define void @c() {\n"
1861 "define void @d() {\n"
1867 "define void @e() {\n"
1872 "define void @f() {\n"
1874 " store void()* @b, void()** undef\n"
1878 "define void @g() {\n"
1880 " store void()* @a, void()** undef\n"
1883 LazyCallGraph CG
= buildCG(*M
);
1885 // Force the graph to be fully expanded.
1887 auto I
= CG
.postorder_ref_scc_begin();
1888 LazyCallGraph::RefSCC
&RC
= *I
++;
1889 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
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
);
1906 // Remove the extra edges that were used to force a particular post-order.
1907 RC
.switchTrivialInternalEdgeToRef(C
, D
);
1908 RC
.switchTrivialInternalEdgeToRef(D
, E
);
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]);
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:
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]);
1938 EXPECT_EQ(3, BC
.size());
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]);
1949 // Test for IR containing constants using blockaddress constant expressions.
1950 // These are truly unique constructs: constant expressions with non-constant
1952 TEST(LazyCallGraphTest
, HandleBlockAddress
) {
1953 LLVMContext Context
;
1954 std::unique_ptr
<Module
> M
=
1955 parseAssembly(Context
, "define void @f() {\n"
1961 "define void @g(i8** %ptr) {\n"
1963 " store i8* blockaddress(@f, %bb), i8** %ptr\n"
1966 LazyCallGraph CG
= buildCG(*M
);
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
);
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
));
1981 TEST(LazyCallGraphTest
, ReplaceNodeFunction
) {
1982 LLVMContext Context
;
1983 // A graph with several different kinds of edges pointing at a particular
1985 std::unique_ptr
<Module
> M
=
1986 parseAssembly(Context
,
1987 "define void @a(i8** %ptr) {\n"
1989 " store i8* bitcast (void(i8**)* @d to i8*), i8** %ptr\n"
1992 "define void @b(i8** %ptr) {\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)"
1999 "define void @c(i8** %ptr) {\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"
2006 "define void @d(i8** %ptr) {\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"
2014 LazyCallGraph CG
= buildCG(*M
);
2016 // Force the graph to be fully expanded.
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
);
2023 ASSERT_EQ(2, RC1
.size());
2024 LazyCallGraph::SCC
&C1
= RC1
[0];
2025 LazyCallGraph::SCC
&C2
= RC1
[1];
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
));
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
);
2044 // Change each use of 'd' to use 'e'. This is particularly easy as they have
2046 D
.replaceAllUsesWith(&E
);
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());
2054 // Now replace the function in the graph.
2055 RC1
.replaceNodeFunction(DN
, E
);
2057 EXPECT_EQ(&E
, &DN
.getFunction());
2058 EXPECT_EQ(&DN
, &(*CN
)[DN
].getNode());
2059 EXPECT_EQ(&DN
, &(*BN
)[DN
].getNode());
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"
2069 " store i8* bitcast (void(i8**)* @d to i8*), i8** %ptr\n"
2072 "define void @b(i8** %ptr) {\n"
2074 " store i8* bitcast (void(i8**)* @c to i8*), i8** %ptr\n"
2077 "define void @c(i8** %ptr) {\n"
2079 " call void @d(i8** %ptr)"
2082 "define void @d(i8** %ptr) {\n"
2084 " call void @c(i8** %ptr)"
2085 " store i8* bitcast (void(i8**)* @b to i8*), i8** %ptr\n"
2088 "define void @dead() {\n"
2092 LazyCallGraph CG
= buildCG(*M
);
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"));
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
);
2110 // Force the graph to be fully expanded.
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
);
2118 ASSERT_EQ(2, RC1
.size());
2119 LazyCallGraph::SCC
&C1
= RC1
[0];
2120 LazyCallGraph::SCC
&C2
= RC1
[1];
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
));
2131 // Now delete 'dead'. There are no uses of this function but there are
2132 // spurious references.
2133 CG
.removeDeadFunction(DeadN
.getFunction());
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
);