1 //===- LazyCallGraphTest.cpp - Unit tests for the lazy CG analysis --------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "llvm/Analysis/LazyCallGraph.h"
10 #include "llvm/AsmParser/Parser.h"
11 #include "llvm/IR/Function.h"
12 #include "llvm/IR/Instructions.h"
13 #include "llvm/IR/LLVMContext.h"
14 #include "llvm/IR/Module.h"
15 #include "llvm/Support/ErrorHandling.h"
16 #include "llvm/Support/SourceMgr.h"
17 #include "gtest/gtest.h"
24 std::unique_ptr
<Module
> parseAssembly(LLVMContext
&Context
,
25 const char *Assembly
) {
27 std::unique_ptr
<Module
> M
= parseAssemblyString(Assembly
, Error
, Context
);
30 raw_string_ostream
OS(ErrMsg
);
33 // A failure here means that the test itself is buggy.
35 report_fatal_error(OS
.str().c_str());
41 IR forming a call graph with a diamond of triangle-shaped SCCs:
55 All call edges go up between SCCs, and clockwise around the SCC.
57 static const char DiamondOfTriangles
[] =
58 "define void @a1() {\n"
65 "define void @a2() {\n"
70 "define void @a3() {\n"
75 "define void @b1() {\n"
81 "define void @b2() {\n"
86 "define void @b3() {\n"
91 "define void @c1() {\n"
97 "define void @c2() {\n"
102 "define void @c3() {\n"
107 "define void @d1() {\n"
112 "define void @d2() {\n"
117 "define void @d3() {\n"
124 IR forming a reference graph with a diamond of triangle-shaped RefSCCs
138 All call edges go up between RefSCCs, and clockwise around the RefSCC.
140 static const char DiamondOfTrianglesRefGraph
[] =
141 "define void @a1() {\n"
143 " %a = alloca void ()*\n"
144 " store void ()* @a2, void ()** %a\n"
145 " store void ()* @b2, void ()** %a\n"
146 " store void ()* @c3, void ()** %a\n"
149 "define void @a2() {\n"
151 " %a = alloca void ()*\n"
152 " store void ()* @a3, void ()** %a\n"
155 "define void @a3() {\n"
157 " %a = alloca void ()*\n"
158 " store void ()* @a1, void ()** %a\n"
161 "define void @b1() {\n"
163 " %a = alloca void ()*\n"
164 " store void ()* @b2, void ()** %a\n"
165 " store void ()* @d3, void ()** %a\n"
168 "define void @b2() {\n"
170 " %a = alloca void ()*\n"
171 " store void ()* @b3, void ()** %a\n"
174 "define void @b3() {\n"
176 " %a = alloca void ()*\n"
177 " store void ()* @b1, void ()** %a\n"
180 "define void @c1() {\n"
182 " %a = alloca void ()*\n"
183 " store void ()* @c2, void ()** %a\n"
184 " store void ()* @d2, void ()** %a\n"
187 "define void @c2() {\n"
189 " %a = alloca void ()*\n"
190 " store void ()* @c3, void ()** %a\n"
193 "define void @c3() {\n"
195 " %a = alloca void ()*\n"
196 " store void ()* @c1, void ()** %a\n"
199 "define void @d1() {\n"
201 " %a = alloca void ()*\n"
202 " store void ()* @d2, void ()** %a\n"
205 "define void @d2() {\n"
207 " %a = alloca void ()*\n"
208 " store void ()* @d3, void ()** %a\n"
211 "define void @d3() {\n"
213 " %a = alloca void ()*\n"
214 " store void ()* @d1, void ()** %a\n"
218 static LazyCallGraph
buildCG(Module
&M
) {
219 TargetLibraryInfoImpl
TLII(Triple(M
.getTargetTriple()));
220 TargetLibraryInfo
TLI(TLII
);
221 auto GetTLI
= [&TLI
](Function
&F
) -> TargetLibraryInfo
& { return TLI
; };
223 LazyCallGraph
CG(M
, GetTLI
);
227 TEST(LazyCallGraphTest
, BasicGraphFormation
) {
229 std::unique_ptr
<Module
> M
= parseAssembly(Context
, DiamondOfTriangles
);
230 LazyCallGraph CG
= buildCG(*M
);
232 // The order of the entry nodes should be stable w.r.t. the source order of
233 // the IR, and everything in our module is an entry node, so just directly
234 // build variables for each node.
236 LazyCallGraph::Node
&A1
= (I
++)->getNode();
237 EXPECT_EQ("a1", A1
.getFunction().getName());
238 LazyCallGraph::Node
&A2
= (I
++)->getNode();
239 EXPECT_EQ("a2", A2
.getFunction().getName());
240 LazyCallGraph::Node
&A3
= (I
++)->getNode();
241 EXPECT_EQ("a3", A3
.getFunction().getName());
242 LazyCallGraph::Node
&B1
= (I
++)->getNode();
243 EXPECT_EQ("b1", B1
.getFunction().getName());
244 LazyCallGraph::Node
&B2
= (I
++)->getNode();
245 EXPECT_EQ("b2", B2
.getFunction().getName());
246 LazyCallGraph::Node
&B3
= (I
++)->getNode();
247 EXPECT_EQ("b3", B3
.getFunction().getName());
248 LazyCallGraph::Node
&C1
= (I
++)->getNode();
249 EXPECT_EQ("c1", C1
.getFunction().getName());
250 LazyCallGraph::Node
&C2
= (I
++)->getNode();
251 EXPECT_EQ("c2", C2
.getFunction().getName());
252 LazyCallGraph::Node
&C3
= (I
++)->getNode();
253 EXPECT_EQ("c3", C3
.getFunction().getName());
254 LazyCallGraph::Node
&D1
= (I
++)->getNode();
255 EXPECT_EQ("d1", D1
.getFunction().getName());
256 LazyCallGraph::Node
&D2
= (I
++)->getNode();
257 EXPECT_EQ("d2", D2
.getFunction().getName());
258 LazyCallGraph::Node
&D3
= (I
++)->getNode();
259 EXPECT_EQ("d3", D3
.getFunction().getName());
260 EXPECT_EQ(CG
.end(), I
);
262 // Build vectors and sort them for the rest of the assertions to make them
263 // independent of order.
264 std::vector
<std::string
> Nodes
;
266 for (LazyCallGraph::Edge
&E
: A1
.populate())
267 Nodes
.push_back(E
.getFunction().getName());
269 EXPECT_EQ("a2", Nodes
[0]);
270 EXPECT_EQ("b2", Nodes
[1]);
271 EXPECT_EQ("c3", Nodes
[2]);
275 EXPECT_EQ(A2
->end(), std::next(A2
->begin()));
276 EXPECT_EQ("a3", A2
->begin()->getFunction().getName());
278 EXPECT_EQ(A3
->end(), std::next(A3
->begin()));
279 EXPECT_EQ("a1", A3
->begin()->getFunction().getName());
281 for (LazyCallGraph::Edge
&E
: B1
.populate())
282 Nodes
.push_back(E
.getFunction().getName());
284 EXPECT_EQ("b2", Nodes
[0]);
285 EXPECT_EQ("d3", Nodes
[1]);
289 EXPECT_EQ(B2
->end(), std::next(B2
->begin()));
290 EXPECT_EQ("b3", B2
->begin()->getFunction().getName());
292 EXPECT_EQ(B3
->end(), std::next(B3
->begin()));
293 EXPECT_EQ("b1", B3
->begin()->getFunction().getName());
295 for (LazyCallGraph::Edge
&E
: C1
.populate())
296 Nodes
.push_back(E
.getFunction().getName());
298 EXPECT_EQ("c2", Nodes
[0]);
299 EXPECT_EQ("d2", Nodes
[1]);
303 EXPECT_EQ(C2
->end(), std::next(C2
->begin()));
304 EXPECT_EQ("c3", C2
->begin()->getFunction().getName());
306 EXPECT_EQ(C3
->end(), std::next(C3
->begin()));
307 EXPECT_EQ("c1", C3
->begin()->getFunction().getName());
310 EXPECT_EQ(D1
->end(), std::next(D1
->begin()));
311 EXPECT_EQ("d2", D1
->begin()->getFunction().getName());
313 EXPECT_EQ(D2
->end(), std::next(D2
->begin()));
314 EXPECT_EQ("d3", D2
->begin()->getFunction().getName());
316 EXPECT_EQ(D3
->end(), std::next(D3
->begin()));
317 EXPECT_EQ("d1", D3
->begin()->getFunction().getName());
319 // Now lets look at the RefSCCs and SCCs.
321 auto J
= CG
.postorder_ref_scc_begin();
323 LazyCallGraph::RefSCC
&D
= *J
++;
324 ASSERT_EQ(1, D
.size());
325 for (LazyCallGraph::Node
&N
: *D
.begin())
326 Nodes
.push_back(N
.getFunction().getName());
328 EXPECT_EQ(3u, Nodes
.size());
329 EXPECT_EQ("d1", Nodes
[0]);
330 EXPECT_EQ("d2", Nodes
[1]);
331 EXPECT_EQ("d3", Nodes
[2]);
333 EXPECT_FALSE(D
.isParentOf(D
));
334 EXPECT_FALSE(D
.isChildOf(D
));
335 EXPECT_FALSE(D
.isAncestorOf(D
));
336 EXPECT_FALSE(D
.isDescendantOf(D
));
337 EXPECT_EQ(&D
, &*CG
.postorder_ref_scc_begin());
339 LazyCallGraph::RefSCC
&C
= *J
++;
340 ASSERT_EQ(1, C
.size());
341 for (LazyCallGraph::Node
&N
: *C
.begin())
342 Nodes
.push_back(N
.getFunction().getName());
344 EXPECT_EQ(3u, Nodes
.size());
345 EXPECT_EQ("c1", Nodes
[0]);
346 EXPECT_EQ("c2", Nodes
[1]);
347 EXPECT_EQ("c3", Nodes
[2]);
349 EXPECT_TRUE(C
.isParentOf(D
));
350 EXPECT_FALSE(C
.isChildOf(D
));
351 EXPECT_TRUE(C
.isAncestorOf(D
));
352 EXPECT_FALSE(C
.isDescendantOf(D
));
353 EXPECT_EQ(&C
, &*std::next(CG
.postorder_ref_scc_begin()));
355 LazyCallGraph::RefSCC
&B
= *J
++;
356 ASSERT_EQ(1, B
.size());
357 for (LazyCallGraph::Node
&N
: *B
.begin())
358 Nodes
.push_back(N
.getFunction().getName());
360 EXPECT_EQ(3u, Nodes
.size());
361 EXPECT_EQ("b1", Nodes
[0]);
362 EXPECT_EQ("b2", Nodes
[1]);
363 EXPECT_EQ("b3", Nodes
[2]);
365 EXPECT_TRUE(B
.isParentOf(D
));
366 EXPECT_FALSE(B
.isChildOf(D
));
367 EXPECT_TRUE(B
.isAncestorOf(D
));
368 EXPECT_FALSE(B
.isDescendantOf(D
));
369 EXPECT_FALSE(B
.isAncestorOf(C
));
370 EXPECT_FALSE(C
.isAncestorOf(B
));
371 EXPECT_EQ(&B
, &*std::next(CG
.postorder_ref_scc_begin(), 2));
373 LazyCallGraph::RefSCC
&A
= *J
++;
374 ASSERT_EQ(1, A
.size());
375 for (LazyCallGraph::Node
&N
: *A
.begin())
376 Nodes
.push_back(N
.getFunction().getName());
378 EXPECT_EQ(3u, Nodes
.size());
379 EXPECT_EQ("a1", Nodes
[0]);
380 EXPECT_EQ("a2", Nodes
[1]);
381 EXPECT_EQ("a3", Nodes
[2]);
383 EXPECT_TRUE(A
.isParentOf(B
));
384 EXPECT_TRUE(A
.isParentOf(C
));
385 EXPECT_FALSE(A
.isParentOf(D
));
386 EXPECT_TRUE(A
.isAncestorOf(B
));
387 EXPECT_TRUE(A
.isAncestorOf(C
));
388 EXPECT_TRUE(A
.isAncestorOf(D
));
389 EXPECT_EQ(&A
, &*std::next(CG
.postorder_ref_scc_begin(), 3));
391 EXPECT_EQ(CG
.postorder_ref_scc_end(), J
);
392 EXPECT_EQ(J
, std::next(CG
.postorder_ref_scc_begin(), 4));
395 static Function
&lookupFunction(Module
&M
, StringRef Name
) {
396 for (Function
&F
: M
)
397 if (F
.getName() == Name
)
399 report_fatal_error("Couldn't find function!");
402 TEST(LazyCallGraphTest
, BasicGraphMutation
) {
404 std::unique_ptr
<Module
> M
= parseAssembly(Context
, "define void @a() {\n"
410 "define void @b() {\n"
414 "define void @c() {\n"
418 LazyCallGraph CG
= buildCG(*M
);
420 LazyCallGraph::Node
&A
= CG
.get(lookupFunction(*M
, "a"));
421 LazyCallGraph::Node
&B
= CG
.get(lookupFunction(*M
, "b"));
423 EXPECT_EQ(2, std::distance(A
->begin(), A
->end()));
425 EXPECT_EQ(0, std::distance(B
->begin(), B
->end()));
427 LazyCallGraph::Node
&C
= CG
.get(lookupFunction(*M
, "c"));
429 CG
.insertEdge(B
, C
, LazyCallGraph::Edge::Call
);
430 EXPECT_EQ(1, std::distance(B
->begin(), B
->end()));
431 EXPECT_EQ(0, std::distance(C
->begin(), C
->end()));
433 CG
.insertEdge(C
, B
, LazyCallGraph::Edge::Call
);
434 EXPECT_EQ(1, std::distance(C
->begin(), C
->end()));
435 EXPECT_EQ(&B
, &C
->begin()->getNode());
437 CG
.insertEdge(C
, C
, LazyCallGraph::Edge::Call
);
438 EXPECT_EQ(2, std::distance(C
->begin(), C
->end()));
439 EXPECT_EQ(&B
, &C
->begin()->getNode());
440 EXPECT_EQ(&C
, &std::next(C
->begin())->getNode());
443 EXPECT_EQ(1, std::distance(C
->begin(), C
->end()));
444 EXPECT_EQ(&C
, &C
->begin()->getNode());
447 EXPECT_EQ(0, std::distance(C
->begin(), C
->end()));
450 EXPECT_EQ(0, std::distance(B
->begin(), B
->end()));
453 TEST(LazyCallGraphTest
, InnerSCCFormation
) {
455 std::unique_ptr
<Module
> M
= parseAssembly(Context
, DiamondOfTriangles
);
456 LazyCallGraph CG
= buildCG(*M
);
458 // Now mutate the graph to connect every node into a single RefSCC to ensure
459 // that our inner SCC formation handles the rest.
460 LazyCallGraph::Node
&D1
= CG
.get(lookupFunction(*M
, "d1"));
461 LazyCallGraph::Node
&A1
= CG
.get(lookupFunction(*M
, "a1"));
464 CG
.insertEdge(D1
, A1
, LazyCallGraph::Edge::Ref
);
466 // Build vectors and sort them for the rest of the assertions to make them
467 // independent of order.
468 std::vector
<std::string
> Nodes
;
470 // We should build a single RefSCC for the entire graph.
472 auto I
= CG
.postorder_ref_scc_begin();
473 LazyCallGraph::RefSCC
&RC
= *I
++;
474 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
476 // Now walk the four SCCs which should be in post-order.
478 LazyCallGraph::SCC
&D
= *J
++;
479 for (LazyCallGraph::Node
&N
: D
)
480 Nodes
.push_back(N
.getFunction().getName());
482 EXPECT_EQ(3u, Nodes
.size());
483 EXPECT_EQ("d1", Nodes
[0]);
484 EXPECT_EQ("d2", Nodes
[1]);
485 EXPECT_EQ("d3", Nodes
[2]);
488 LazyCallGraph::SCC
&B
= *J
++;
489 for (LazyCallGraph::Node
&N
: B
)
490 Nodes
.push_back(N
.getFunction().getName());
492 EXPECT_EQ(3u, Nodes
.size());
493 EXPECT_EQ("b1", Nodes
[0]);
494 EXPECT_EQ("b2", Nodes
[1]);
495 EXPECT_EQ("b3", Nodes
[2]);
498 LazyCallGraph::SCC
&C
= *J
++;
499 for (LazyCallGraph::Node
&N
: C
)
500 Nodes
.push_back(N
.getFunction().getName());
502 EXPECT_EQ(3u, Nodes
.size());
503 EXPECT_EQ("c1", Nodes
[0]);
504 EXPECT_EQ("c2", Nodes
[1]);
505 EXPECT_EQ("c3", Nodes
[2]);
508 LazyCallGraph::SCC
&A
= *J
++;
509 for (LazyCallGraph::Node
&N
: A
)
510 Nodes
.push_back(N
.getFunction().getName());
512 EXPECT_EQ(3u, Nodes
.size());
513 EXPECT_EQ("a1", Nodes
[0]);
514 EXPECT_EQ("a2", Nodes
[1]);
515 EXPECT_EQ("a3", Nodes
[2]);
518 EXPECT_EQ(RC
.end(), J
);
521 TEST(LazyCallGraphTest
, MultiArmSCC
) {
523 // Two interlocking cycles. The really useful thing about this SCC is that it
524 // will require Tarjan's DFS to backtrack and finish processing all of the
525 // children of each node in the SCC. Since this involves call edges, both
526 // Tarjan implementations will have to successfully navigate the structure.
527 std::unique_ptr
<Module
> M
= parseAssembly(Context
, "define void @f1() {\n"
533 "define void @f2() {\n"
538 "define void @f3() {\n"
543 "define void @f4() {\n"
548 "define void @f5() {\n"
553 LazyCallGraph CG
= buildCG(*M
);
555 // Force the graph to be fully expanded.
557 auto I
= CG
.postorder_ref_scc_begin();
558 LazyCallGraph::RefSCC
&RC
= *I
++;
559 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
561 LazyCallGraph::Node
&N1
= *CG
.lookup(lookupFunction(*M
, "f1"));
562 LazyCallGraph::Node
&N2
= *CG
.lookup(lookupFunction(*M
, "f2"));
563 LazyCallGraph::Node
&N3
= *CG
.lookup(lookupFunction(*M
, "f3"));
564 LazyCallGraph::Node
&N4
= *CG
.lookup(lookupFunction(*M
, "f4"));
565 LazyCallGraph::Node
&N5
= *CG
.lookup(lookupFunction(*M
, "f4"));
566 EXPECT_EQ(&RC
, CG
.lookupRefSCC(N1
));
567 EXPECT_EQ(&RC
, CG
.lookupRefSCC(N2
));
568 EXPECT_EQ(&RC
, CG
.lookupRefSCC(N3
));
569 EXPECT_EQ(&RC
, CG
.lookupRefSCC(N4
));
570 EXPECT_EQ(&RC
, CG
.lookupRefSCC(N5
));
572 ASSERT_EQ(1, RC
.size());
574 LazyCallGraph::SCC
&C
= *RC
.begin();
575 EXPECT_EQ(&C
, CG
.lookupSCC(N1
));
576 EXPECT_EQ(&C
, CG
.lookupSCC(N2
));
577 EXPECT_EQ(&C
, CG
.lookupSCC(N3
));
578 EXPECT_EQ(&C
, CG
.lookupSCC(N4
));
579 EXPECT_EQ(&C
, CG
.lookupSCC(N5
));
582 TEST(LazyCallGraphTest
, OutgoingEdgeMutation
) {
584 std::unique_ptr
<Module
> M
= parseAssembly(Context
, "define void @a() {\n"
590 "define void @b() {\n"
595 "define void @c() {\n"
600 "define void @d() {\n"
604 LazyCallGraph CG
= buildCG(*M
);
606 // Force the graph to be fully expanded.
608 for (LazyCallGraph::RefSCC
&RC
: CG
.postorder_ref_sccs())
609 dbgs() << "Formed RefSCC: " << RC
<< "\n";
611 LazyCallGraph::Node
&A
= *CG
.lookup(lookupFunction(*M
, "a"));
612 LazyCallGraph::Node
&B
= *CG
.lookup(lookupFunction(*M
, "b"));
613 LazyCallGraph::Node
&C
= *CG
.lookup(lookupFunction(*M
, "c"));
614 LazyCallGraph::Node
&D
= *CG
.lookup(lookupFunction(*M
, "d"));
615 LazyCallGraph::SCC
&AC
= *CG
.lookupSCC(A
);
616 LazyCallGraph::SCC
&BC
= *CG
.lookupSCC(B
);
617 LazyCallGraph::SCC
&CC
= *CG
.lookupSCC(C
);
618 LazyCallGraph::SCC
&DC
= *CG
.lookupSCC(D
);
619 LazyCallGraph::RefSCC
&ARC
= *CG
.lookupRefSCC(A
);
620 LazyCallGraph::RefSCC
&BRC
= *CG
.lookupRefSCC(B
);
621 LazyCallGraph::RefSCC
&CRC
= *CG
.lookupRefSCC(C
);
622 LazyCallGraph::RefSCC
&DRC
= *CG
.lookupRefSCC(D
);
623 EXPECT_TRUE(ARC
.isParentOf(BRC
));
624 EXPECT_TRUE(AC
.isParentOf(BC
));
625 EXPECT_TRUE(ARC
.isParentOf(CRC
));
626 EXPECT_TRUE(AC
.isParentOf(CC
));
627 EXPECT_FALSE(ARC
.isParentOf(DRC
));
628 EXPECT_FALSE(AC
.isParentOf(DC
));
629 EXPECT_TRUE(ARC
.isAncestorOf(DRC
));
630 EXPECT_TRUE(AC
.isAncestorOf(DC
));
631 EXPECT_FALSE(DRC
.isChildOf(ARC
));
632 EXPECT_FALSE(DC
.isChildOf(AC
));
633 EXPECT_TRUE(DRC
.isDescendantOf(ARC
));
634 EXPECT_TRUE(DC
.isDescendantOf(AC
));
635 EXPECT_TRUE(DRC
.isChildOf(BRC
));
636 EXPECT_TRUE(DC
.isChildOf(BC
));
637 EXPECT_TRUE(DRC
.isChildOf(CRC
));
638 EXPECT_TRUE(DC
.isChildOf(CC
));
640 EXPECT_EQ(2, std::distance(A
->begin(), A
->end()));
641 ARC
.insertOutgoingEdge(A
, D
, LazyCallGraph::Edge::Call
);
642 EXPECT_EQ(3, std::distance(A
->begin(), A
->end()));
643 const LazyCallGraph::Edge
&NewE
= (*A
)[D
];
645 EXPECT_TRUE(NewE
.isCall());
646 EXPECT_EQ(&D
, &NewE
.getNode());
648 // Only the parent and child tests sholud have changed. The rest of the graph
650 EXPECT_TRUE(ARC
.isParentOf(DRC
));
651 EXPECT_TRUE(AC
.isParentOf(DC
));
652 EXPECT_TRUE(ARC
.isAncestorOf(DRC
));
653 EXPECT_TRUE(AC
.isAncestorOf(DC
));
654 EXPECT_TRUE(DRC
.isChildOf(ARC
));
655 EXPECT_TRUE(DC
.isChildOf(AC
));
656 EXPECT_TRUE(DRC
.isDescendantOf(ARC
));
657 EXPECT_TRUE(DC
.isDescendantOf(AC
));
658 EXPECT_EQ(&AC
, CG
.lookupSCC(A
));
659 EXPECT_EQ(&BC
, CG
.lookupSCC(B
));
660 EXPECT_EQ(&CC
, CG
.lookupSCC(C
));
661 EXPECT_EQ(&DC
, CG
.lookupSCC(D
));
662 EXPECT_EQ(&ARC
, CG
.lookupRefSCC(A
));
663 EXPECT_EQ(&BRC
, CG
.lookupRefSCC(B
));
664 EXPECT_EQ(&CRC
, CG
.lookupRefSCC(C
));
665 EXPECT_EQ(&DRC
, CG
.lookupRefSCC(D
));
667 ARC
.switchOutgoingEdgeToRef(A
, D
);
668 EXPECT_FALSE(NewE
.isCall());
670 // Verify the reference graph remains the same but the SCC graph is updated.
671 EXPECT_TRUE(ARC
.isParentOf(DRC
));
672 EXPECT_FALSE(AC
.isParentOf(DC
));
673 EXPECT_TRUE(ARC
.isAncestorOf(DRC
));
674 EXPECT_TRUE(AC
.isAncestorOf(DC
));
675 EXPECT_TRUE(DRC
.isChildOf(ARC
));
676 EXPECT_FALSE(DC
.isChildOf(AC
));
677 EXPECT_TRUE(DRC
.isDescendantOf(ARC
));
678 EXPECT_TRUE(DC
.isDescendantOf(AC
));
679 EXPECT_EQ(&AC
, CG
.lookupSCC(A
));
680 EXPECT_EQ(&BC
, CG
.lookupSCC(B
));
681 EXPECT_EQ(&CC
, CG
.lookupSCC(C
));
682 EXPECT_EQ(&DC
, CG
.lookupSCC(D
));
683 EXPECT_EQ(&ARC
, CG
.lookupRefSCC(A
));
684 EXPECT_EQ(&BRC
, CG
.lookupRefSCC(B
));
685 EXPECT_EQ(&CRC
, CG
.lookupRefSCC(C
));
686 EXPECT_EQ(&DRC
, CG
.lookupRefSCC(D
));
688 ARC
.switchOutgoingEdgeToCall(A
, D
);
689 EXPECT_TRUE(NewE
.isCall());
691 // Verify the reference graph remains the same but the SCC graph is updated.
692 EXPECT_TRUE(ARC
.isParentOf(DRC
));
693 EXPECT_TRUE(AC
.isParentOf(DC
));
694 EXPECT_TRUE(ARC
.isAncestorOf(DRC
));
695 EXPECT_TRUE(AC
.isAncestorOf(DC
));
696 EXPECT_TRUE(DRC
.isChildOf(ARC
));
697 EXPECT_TRUE(DC
.isChildOf(AC
));
698 EXPECT_TRUE(DRC
.isDescendantOf(ARC
));
699 EXPECT_TRUE(DC
.isDescendantOf(AC
));
700 EXPECT_EQ(&AC
, CG
.lookupSCC(A
));
701 EXPECT_EQ(&BC
, CG
.lookupSCC(B
));
702 EXPECT_EQ(&CC
, CG
.lookupSCC(C
));
703 EXPECT_EQ(&DC
, CG
.lookupSCC(D
));
704 EXPECT_EQ(&ARC
, CG
.lookupRefSCC(A
));
705 EXPECT_EQ(&BRC
, CG
.lookupRefSCC(B
));
706 EXPECT_EQ(&CRC
, CG
.lookupRefSCC(C
));
707 EXPECT_EQ(&DRC
, CG
.lookupRefSCC(D
));
709 ARC
.removeOutgoingEdge(A
, D
);
710 EXPECT_EQ(2, std::distance(A
->begin(), A
->end()));
712 // Now the parent and child tests fail again but the rest remains the same.
713 EXPECT_FALSE(ARC
.isParentOf(DRC
));
714 EXPECT_FALSE(AC
.isParentOf(DC
));
715 EXPECT_TRUE(ARC
.isAncestorOf(DRC
));
716 EXPECT_TRUE(AC
.isAncestorOf(DC
));
717 EXPECT_FALSE(DRC
.isChildOf(ARC
));
718 EXPECT_FALSE(DC
.isChildOf(AC
));
719 EXPECT_TRUE(DRC
.isDescendantOf(ARC
));
720 EXPECT_TRUE(DC
.isDescendantOf(AC
));
721 EXPECT_EQ(&AC
, CG
.lookupSCC(A
));
722 EXPECT_EQ(&BC
, CG
.lookupSCC(B
));
723 EXPECT_EQ(&CC
, CG
.lookupSCC(C
));
724 EXPECT_EQ(&DC
, CG
.lookupSCC(D
));
725 EXPECT_EQ(&ARC
, CG
.lookupRefSCC(A
));
726 EXPECT_EQ(&BRC
, CG
.lookupRefSCC(B
));
727 EXPECT_EQ(&CRC
, CG
.lookupRefSCC(C
));
728 EXPECT_EQ(&DRC
, CG
.lookupRefSCC(D
));
731 TEST(LazyCallGraphTest
, IncomingEdgeInsertion
) {
733 // We want to ensure we can add edges even across complex diamond graphs, so
734 // we use the diamond of triangles graph defined above. The ascii diagram is
735 // repeated here for easy reference.
749 std::unique_ptr
<Module
> M
= parseAssembly(Context
, DiamondOfTriangles
);
750 LazyCallGraph CG
= buildCG(*M
);
752 // Force the graph to be fully expanded.
754 for (LazyCallGraph::RefSCC
&RC
: CG
.postorder_ref_sccs())
755 dbgs() << "Formed RefSCC: " << RC
<< "\n";
757 LazyCallGraph::Node
&A1
= *CG
.lookup(lookupFunction(*M
, "a1"));
758 LazyCallGraph::Node
&A2
= *CG
.lookup(lookupFunction(*M
, "a2"));
759 LazyCallGraph::Node
&A3
= *CG
.lookup(lookupFunction(*M
, "a3"));
760 LazyCallGraph::Node
&B1
= *CG
.lookup(lookupFunction(*M
, "b1"));
761 LazyCallGraph::Node
&B2
= *CG
.lookup(lookupFunction(*M
, "b2"));
762 LazyCallGraph::Node
&B3
= *CG
.lookup(lookupFunction(*M
, "b3"));
763 LazyCallGraph::Node
&C1
= *CG
.lookup(lookupFunction(*M
, "c1"));
764 LazyCallGraph::Node
&C2
= *CG
.lookup(lookupFunction(*M
, "c2"));
765 LazyCallGraph::Node
&C3
= *CG
.lookup(lookupFunction(*M
, "c3"));
766 LazyCallGraph::Node
&D1
= *CG
.lookup(lookupFunction(*M
, "d1"));
767 LazyCallGraph::Node
&D2
= *CG
.lookup(lookupFunction(*M
, "d2"));
768 LazyCallGraph::Node
&D3
= *CG
.lookup(lookupFunction(*M
, "d3"));
769 LazyCallGraph::RefSCC
&ARC
= *CG
.lookupRefSCC(A1
);
770 LazyCallGraph::RefSCC
&BRC
= *CG
.lookupRefSCC(B1
);
771 LazyCallGraph::RefSCC
&CRC
= *CG
.lookupRefSCC(C1
);
772 LazyCallGraph::RefSCC
&DRC
= *CG
.lookupRefSCC(D1
);
773 ASSERT_EQ(&ARC
, CG
.lookupRefSCC(A2
));
774 ASSERT_EQ(&ARC
, CG
.lookupRefSCC(A3
));
775 ASSERT_EQ(&BRC
, CG
.lookupRefSCC(B2
));
776 ASSERT_EQ(&BRC
, CG
.lookupRefSCC(B3
));
777 ASSERT_EQ(&CRC
, CG
.lookupRefSCC(C2
));
778 ASSERT_EQ(&CRC
, CG
.lookupRefSCC(C3
));
779 ASSERT_EQ(&DRC
, CG
.lookupRefSCC(D2
));
780 ASSERT_EQ(&DRC
, CG
.lookupRefSCC(D3
));
781 ASSERT_EQ(1, std::distance(D2
->begin(), D2
->end()));
783 // Add an edge to make the graph:
796 auto MergedRCs
= CRC
.insertIncomingRefEdge(D2
, C2
);
797 // Make sure we connected the nodes.
798 for (LazyCallGraph::Edge E
: *D2
) {
799 if (&E
.getNode() == &D3
)
801 EXPECT_EQ(&C2
, &E
.getNode());
803 // And marked the D ref-SCC as no longer valid.
804 EXPECT_EQ(1u, MergedRCs
.size());
805 EXPECT_EQ(&DRC
, MergedRCs
[0]);
807 // Make sure we have the correct nodes in the SCC sets.
808 EXPECT_EQ(&ARC
, CG
.lookupRefSCC(A1
));
809 EXPECT_EQ(&ARC
, CG
.lookupRefSCC(A2
));
810 EXPECT_EQ(&ARC
, CG
.lookupRefSCC(A3
));
811 EXPECT_EQ(&BRC
, CG
.lookupRefSCC(B1
));
812 EXPECT_EQ(&BRC
, CG
.lookupRefSCC(B2
));
813 EXPECT_EQ(&BRC
, CG
.lookupRefSCC(B3
));
814 EXPECT_EQ(&CRC
, CG
.lookupRefSCC(C1
));
815 EXPECT_EQ(&CRC
, CG
.lookupRefSCC(C2
));
816 EXPECT_EQ(&CRC
, CG
.lookupRefSCC(C3
));
817 EXPECT_EQ(&CRC
, CG
.lookupRefSCC(D1
));
818 EXPECT_EQ(&CRC
, CG
.lookupRefSCC(D2
));
819 EXPECT_EQ(&CRC
, CG
.lookupRefSCC(D3
));
821 // And that ancestry tests have been updated.
822 EXPECT_TRUE(ARC
.isParentOf(CRC
));
823 EXPECT_TRUE(BRC
.isParentOf(CRC
));
825 // And verify the post-order walk reflects the updated structure.
826 auto I
= CG
.postorder_ref_scc_begin(), E
= CG
.postorder_ref_scc_end();
828 EXPECT_EQ(&CRC
, &*I
) << "Actual RefSCC: " << *I
;
830 EXPECT_EQ(&BRC
, &*I
) << "Actual RefSCC: " << *I
;
832 EXPECT_EQ(&ARC
, &*I
) << "Actual RefSCC: " << *I
;
836 TEST(LazyCallGraphTest
, IncomingEdgeInsertionRefGraph
) {
838 // Another variation of the above test but with all the edges switched to
839 // references rather than calls.
840 std::unique_ptr
<Module
> M
=
841 parseAssembly(Context
, DiamondOfTrianglesRefGraph
);
842 LazyCallGraph CG
= buildCG(*M
);
844 // Force the graph to be fully expanded.
846 for (LazyCallGraph::RefSCC
&RC
: CG
.postorder_ref_sccs())
847 dbgs() << "Formed RefSCC: " << RC
<< "\n";
849 LazyCallGraph::Node
&A1
= *CG
.lookup(lookupFunction(*M
, "a1"));
850 LazyCallGraph::Node
&A2
= *CG
.lookup(lookupFunction(*M
, "a2"));
851 LazyCallGraph::Node
&A3
= *CG
.lookup(lookupFunction(*M
, "a3"));
852 LazyCallGraph::Node
&B1
= *CG
.lookup(lookupFunction(*M
, "b1"));
853 LazyCallGraph::Node
&B2
= *CG
.lookup(lookupFunction(*M
, "b2"));
854 LazyCallGraph::Node
&B3
= *CG
.lookup(lookupFunction(*M
, "b3"));
855 LazyCallGraph::Node
&C1
= *CG
.lookup(lookupFunction(*M
, "c1"));
856 LazyCallGraph::Node
&C2
= *CG
.lookup(lookupFunction(*M
, "c2"));
857 LazyCallGraph::Node
&C3
= *CG
.lookup(lookupFunction(*M
, "c3"));
858 LazyCallGraph::Node
&D1
= *CG
.lookup(lookupFunction(*M
, "d1"));
859 LazyCallGraph::Node
&D2
= *CG
.lookup(lookupFunction(*M
, "d2"));
860 LazyCallGraph::Node
&D3
= *CG
.lookup(lookupFunction(*M
, "d3"));
861 LazyCallGraph::RefSCC
&ARC
= *CG
.lookupRefSCC(A1
);
862 LazyCallGraph::RefSCC
&BRC
= *CG
.lookupRefSCC(B1
);
863 LazyCallGraph::RefSCC
&CRC
= *CG
.lookupRefSCC(C1
);
864 LazyCallGraph::RefSCC
&DRC
= *CG
.lookupRefSCC(D1
);
865 ASSERT_EQ(&ARC
, CG
.lookupRefSCC(A2
));
866 ASSERT_EQ(&ARC
, CG
.lookupRefSCC(A3
));
867 ASSERT_EQ(&BRC
, CG
.lookupRefSCC(B2
));
868 ASSERT_EQ(&BRC
, CG
.lookupRefSCC(B3
));
869 ASSERT_EQ(&CRC
, CG
.lookupRefSCC(C2
));
870 ASSERT_EQ(&CRC
, CG
.lookupRefSCC(C3
));
871 ASSERT_EQ(&DRC
, CG
.lookupRefSCC(D2
));
872 ASSERT_EQ(&DRC
, CG
.lookupRefSCC(D3
));
873 ASSERT_EQ(1, std::distance(D2
->begin(), D2
->end()));
875 // Add an edge to make the graph:
888 auto MergedRCs
= CRC
.insertIncomingRefEdge(D2
, C2
);
889 // Make sure we connected the nodes.
890 for (LazyCallGraph::Edge E
: *D2
) {
891 if (&E
.getNode() == &D3
)
893 EXPECT_EQ(&C2
, &E
.getNode());
895 // And marked the D ref-SCC as no longer valid.
896 EXPECT_EQ(1u, MergedRCs
.size());
897 EXPECT_EQ(&DRC
, MergedRCs
[0]);
899 // Make sure we have the correct nodes in the SCC sets.
900 EXPECT_EQ(&ARC
, CG
.lookupRefSCC(A1
));
901 EXPECT_EQ(&ARC
, CG
.lookupRefSCC(A2
));
902 EXPECT_EQ(&ARC
, CG
.lookupRefSCC(A3
));
903 EXPECT_EQ(&BRC
, CG
.lookupRefSCC(B1
));
904 EXPECT_EQ(&BRC
, CG
.lookupRefSCC(B2
));
905 EXPECT_EQ(&BRC
, CG
.lookupRefSCC(B3
));
906 EXPECT_EQ(&CRC
, CG
.lookupRefSCC(C1
));
907 EXPECT_EQ(&CRC
, CG
.lookupRefSCC(C2
));
908 EXPECT_EQ(&CRC
, CG
.lookupRefSCC(C3
));
909 EXPECT_EQ(&CRC
, CG
.lookupRefSCC(D1
));
910 EXPECT_EQ(&CRC
, CG
.lookupRefSCC(D2
));
911 EXPECT_EQ(&CRC
, CG
.lookupRefSCC(D3
));
913 // And that ancestry tests have been updated.
914 EXPECT_TRUE(ARC
.isParentOf(CRC
));
915 EXPECT_TRUE(BRC
.isParentOf(CRC
));
917 // And verify the post-order walk reflects the updated structure.
918 auto I
= CG
.postorder_ref_scc_begin(), E
= CG
.postorder_ref_scc_end();
920 EXPECT_EQ(&CRC
, &*I
) << "Actual RefSCC: " << *I
;
922 EXPECT_EQ(&BRC
, &*I
) << "Actual RefSCC: " << *I
;
924 EXPECT_EQ(&ARC
, &*I
) << "Actual RefSCC: " << *I
;
928 TEST(LazyCallGraphTest
, IncomingEdgeInsertionLargeCallCycle
) {
930 std::unique_ptr
<Module
> M
= parseAssembly(Context
, "define void @a() {\n"
935 "define void @b() {\n"
940 "define void @c() {\n"
945 "define void @d() {\n"
949 LazyCallGraph CG
= buildCG(*M
);
951 // Force the graph to be fully expanded.
953 for (LazyCallGraph::RefSCC
&RC
: CG
.postorder_ref_sccs())
954 dbgs() << "Formed RefSCC: " << RC
<< "\n";
956 LazyCallGraph::Node
&A
= *CG
.lookup(lookupFunction(*M
, "a"));
957 LazyCallGraph::Node
&B
= *CG
.lookup(lookupFunction(*M
, "b"));
958 LazyCallGraph::Node
&C
= *CG
.lookup(lookupFunction(*M
, "c"));
959 LazyCallGraph::Node
&D
= *CG
.lookup(lookupFunction(*M
, "d"));
960 LazyCallGraph::SCC
&AC
= *CG
.lookupSCC(A
);
961 LazyCallGraph::SCC
&BC
= *CG
.lookupSCC(B
);
962 LazyCallGraph::SCC
&CC
= *CG
.lookupSCC(C
);
963 LazyCallGraph::SCC
&DC
= *CG
.lookupSCC(D
);
964 LazyCallGraph::RefSCC
&ARC
= *CG
.lookupRefSCC(A
);
965 LazyCallGraph::RefSCC
&BRC
= *CG
.lookupRefSCC(B
);
966 LazyCallGraph::RefSCC
&CRC
= *CG
.lookupRefSCC(C
);
967 LazyCallGraph::RefSCC
&DRC
= *CG
.lookupRefSCC(D
);
969 // Connect the top to the bottom forming a large RefSCC made up mostly of calls.
970 auto MergedRCs
= ARC
.insertIncomingRefEdge(D
, A
);
971 // Make sure we connected the nodes.
972 EXPECT_NE(D
->begin(), D
->end());
973 EXPECT_EQ(&A
, &D
->begin()->getNode());
975 // Check that we have the dead RCs, but ignore the order.
976 EXPECT_EQ(3u, MergedRCs
.size());
977 EXPECT_NE(find(MergedRCs
, &BRC
), MergedRCs
.end());
978 EXPECT_NE(find(MergedRCs
, &CRC
), MergedRCs
.end());
979 EXPECT_NE(find(MergedRCs
, &DRC
), MergedRCs
.end());
981 // Make sure the nodes point to the right place now.
982 EXPECT_EQ(&ARC
, CG
.lookupRefSCC(A
));
983 EXPECT_EQ(&ARC
, CG
.lookupRefSCC(B
));
984 EXPECT_EQ(&ARC
, CG
.lookupRefSCC(C
));
985 EXPECT_EQ(&ARC
, CG
.lookupRefSCC(D
));
987 // Check that the SCCs are in postorder.
988 EXPECT_EQ(4, ARC
.size());
989 EXPECT_EQ(&DC
, &ARC
[0]);
990 EXPECT_EQ(&CC
, &ARC
[1]);
991 EXPECT_EQ(&BC
, &ARC
[2]);
992 EXPECT_EQ(&AC
, &ARC
[3]);
994 // And verify the post-order walk reflects the updated structure.
995 auto I
= CG
.postorder_ref_scc_begin(), E
= CG
.postorder_ref_scc_end();
997 EXPECT_EQ(&ARC
, &*I
) << "Actual RefSCC: " << *I
;
1001 TEST(LazyCallGraphTest
, IncomingEdgeInsertionLargeRefCycle
) {
1002 LLVMContext Context
;
1003 std::unique_ptr
<Module
> M
=
1004 parseAssembly(Context
, "define void @a() {\n"
1006 " %p = alloca void ()*\n"
1007 " store void ()* @b, void ()** %p\n"
1010 "define void @b() {\n"
1012 " %p = alloca void ()*\n"
1013 " store void ()* @c, void ()** %p\n"
1016 "define void @c() {\n"
1018 " %p = alloca void ()*\n"
1019 " store void ()* @d, void ()** %p\n"
1022 "define void @d() {\n"
1026 LazyCallGraph CG
= buildCG(*M
);
1028 // Force the graph to be fully expanded.
1030 for (LazyCallGraph::RefSCC
&RC
: CG
.postorder_ref_sccs())
1031 dbgs() << "Formed RefSCC: " << RC
<< "\n";
1033 LazyCallGraph::Node
&A
= *CG
.lookup(lookupFunction(*M
, "a"));
1034 LazyCallGraph::Node
&B
= *CG
.lookup(lookupFunction(*M
, "b"));
1035 LazyCallGraph::Node
&C
= *CG
.lookup(lookupFunction(*M
, "c"));
1036 LazyCallGraph::Node
&D
= *CG
.lookup(lookupFunction(*M
, "d"));
1037 LazyCallGraph::RefSCC
&ARC
= *CG
.lookupRefSCC(A
);
1038 LazyCallGraph::RefSCC
&BRC
= *CG
.lookupRefSCC(B
);
1039 LazyCallGraph::RefSCC
&CRC
= *CG
.lookupRefSCC(C
);
1040 LazyCallGraph::RefSCC
&DRC
= *CG
.lookupRefSCC(D
);
1042 // Connect the top to the bottom forming a large RefSCC made up just of
1044 auto MergedRCs
= ARC
.insertIncomingRefEdge(D
, A
);
1045 // Make sure we connected the nodes.
1046 EXPECT_NE(D
->begin(), D
->end());
1047 EXPECT_EQ(&A
, &D
->begin()->getNode());
1049 // Check that we have the dead RCs, but ignore the order.
1050 EXPECT_EQ(3u, MergedRCs
.size());
1051 EXPECT_NE(find(MergedRCs
, &BRC
), MergedRCs
.end());
1052 EXPECT_NE(find(MergedRCs
, &CRC
), MergedRCs
.end());
1053 EXPECT_NE(find(MergedRCs
, &DRC
), MergedRCs
.end());
1055 // Make sure the nodes point to the right place now.
1056 EXPECT_EQ(&ARC
, CG
.lookupRefSCC(A
));
1057 EXPECT_EQ(&ARC
, CG
.lookupRefSCC(B
));
1058 EXPECT_EQ(&ARC
, CG
.lookupRefSCC(C
));
1059 EXPECT_EQ(&ARC
, CG
.lookupRefSCC(D
));
1061 // And verify the post-order walk reflects the updated structure.
1062 auto I
= CG
.postorder_ref_scc_begin(), End
= CG
.postorder_ref_scc_end();
1064 EXPECT_EQ(&ARC
, &*I
) << "Actual RefSCC: " << *I
;
1065 EXPECT_EQ(++I
, End
);
1068 TEST(LazyCallGraphTest
, InlineAndDeleteFunction
) {
1069 LLVMContext Context
;
1070 // We want to ensure we can delete nodes from relatively complex graphs and
1071 // so use the diamond of triangles graph defined above.
1073 // The ascii diagram is repeated here for easy reference.
1087 std::unique_ptr
<Module
> M
= parseAssembly(Context
, DiamondOfTriangles
);
1088 LazyCallGraph CG
= buildCG(*M
);
1090 // Force the graph to be fully expanded.
1092 for (LazyCallGraph::RefSCC
&RC
: CG
.postorder_ref_sccs())
1093 dbgs() << "Formed RefSCC: " << RC
<< "\n";
1095 LazyCallGraph::Node
&A1
= *CG
.lookup(lookupFunction(*M
, "a1"));
1096 LazyCallGraph::Node
&A2
= *CG
.lookup(lookupFunction(*M
, "a2"));
1097 LazyCallGraph::Node
&A3
= *CG
.lookup(lookupFunction(*M
, "a3"));
1098 LazyCallGraph::Node
&B1
= *CG
.lookup(lookupFunction(*M
, "b1"));
1099 LazyCallGraph::Node
&B2
= *CG
.lookup(lookupFunction(*M
, "b2"));
1100 LazyCallGraph::Node
&B3
= *CG
.lookup(lookupFunction(*M
, "b3"));
1101 LazyCallGraph::Node
&C1
= *CG
.lookup(lookupFunction(*M
, "c1"));
1102 LazyCallGraph::Node
&C2
= *CG
.lookup(lookupFunction(*M
, "c2"));
1103 LazyCallGraph::Node
&C3
= *CG
.lookup(lookupFunction(*M
, "c3"));
1104 LazyCallGraph::Node
&D1
= *CG
.lookup(lookupFunction(*M
, "d1"));
1105 LazyCallGraph::Node
&D2
= *CG
.lookup(lookupFunction(*M
, "d2"));
1106 LazyCallGraph::Node
&D3
= *CG
.lookup(lookupFunction(*M
, "d3"));
1107 LazyCallGraph::RefSCC
&ARC
= *CG
.lookupRefSCC(A1
);
1108 LazyCallGraph::RefSCC
&BRC
= *CG
.lookupRefSCC(B1
);
1109 LazyCallGraph::RefSCC
&CRC
= *CG
.lookupRefSCC(C1
);
1110 LazyCallGraph::RefSCC
&DRC
= *CG
.lookupRefSCC(D1
);
1111 ASSERT_EQ(&ARC
, CG
.lookupRefSCC(A2
));
1112 ASSERT_EQ(&ARC
, CG
.lookupRefSCC(A3
));
1113 ASSERT_EQ(&BRC
, CG
.lookupRefSCC(B2
));
1114 ASSERT_EQ(&BRC
, CG
.lookupRefSCC(B3
));
1115 ASSERT_EQ(&CRC
, CG
.lookupRefSCC(C2
));
1116 ASSERT_EQ(&CRC
, CG
.lookupRefSCC(C3
));
1117 ASSERT_EQ(&DRC
, CG
.lookupRefSCC(D2
));
1118 ASSERT_EQ(&DRC
, CG
.lookupRefSCC(D3
));
1119 ASSERT_EQ(1, std::distance(D2
->begin(), D2
->end()));
1121 // Delete d2 from the graph, as if it had been inlined.
1135 Function
&D2F
= D2
.getFunction();
1136 CallInst
*C1Call
= nullptr, *D1Call
= nullptr;
1137 for (User
*U
: D2F
.users()) {
1138 CallInst
*CI
= dyn_cast
<CallInst
>(U
);
1139 ASSERT_TRUE(CI
) << "Expected a call: " << *U
;
1140 if (CI
->getParent()->getParent() == &C1
.getFunction()) {
1141 ASSERT_EQ(nullptr, C1Call
) << "Found too many C1 calls: " << *CI
;
1143 } else if (CI
->getParent()->getParent() == &D1
.getFunction()) {
1144 ASSERT_EQ(nullptr, D1Call
) << "Found too many D1 calls: " << *CI
;
1147 FAIL() << "Found an unexpected call instruction: " << *CI
;
1150 ASSERT_NE(C1Call
, nullptr);
1151 ASSERT_NE(D1Call
, nullptr);
1152 ASSERT_EQ(&D2F
, C1Call
->getCalledFunction());
1153 ASSERT_EQ(&D2F
, D1Call
->getCalledFunction());
1154 C1Call
->setCalledFunction(&D3
.getFunction());
1155 D1Call
->setCalledFunction(&D3
.getFunction());
1156 ASSERT_EQ(0u, D2F
.getNumUses());
1158 // Insert new edges first.
1159 CRC
.insertTrivialCallEdge(C1
, D3
);
1160 DRC
.insertTrivialCallEdge(D1
, D3
);
1162 // Then remove the old ones.
1163 LazyCallGraph::SCC
&DC
= *CG
.lookupSCC(D2
);
1164 auto NewCs
= DRC
.switchInternalEdgeToRef(D1
, D2
);
1165 EXPECT_EQ(&DC
, CG
.lookupSCC(D2
));
1166 EXPECT_EQ(NewCs
.end(), std::next(NewCs
.begin()));
1167 LazyCallGraph::SCC
&NewDC
= *NewCs
.begin();
1168 EXPECT_EQ(&NewDC
, CG
.lookupSCC(D1
));
1169 EXPECT_EQ(&NewDC
, CG
.lookupSCC(D3
));
1170 auto NewRCs
= DRC
.removeInternalRefEdge(D1
, {&D2
});
1171 ASSERT_EQ(2u, NewRCs
.size());
1172 LazyCallGraph::RefSCC
&NewDRC
= *NewRCs
[0];
1173 EXPECT_EQ(&NewDRC
, CG
.lookupRefSCC(D1
));
1174 EXPECT_EQ(&NewDRC
, CG
.lookupRefSCC(D3
));
1175 LazyCallGraph::RefSCC
&D2RC
= *NewRCs
[1];
1176 EXPECT_EQ(&D2RC
, CG
.lookupRefSCC(D2
));
1177 EXPECT_FALSE(NewDRC
.isParentOf(D2RC
));
1178 EXPECT_TRUE(CRC
.isParentOf(D2RC
));
1179 EXPECT_TRUE(CRC
.isParentOf(NewDRC
));
1180 EXPECT_TRUE(D2RC
.isParentOf(NewDRC
));
1181 CRC
.removeOutgoingEdge(C1
, D2
);
1182 EXPECT_FALSE(CRC
.isParentOf(D2RC
));
1183 EXPECT_TRUE(CRC
.isParentOf(NewDRC
));
1184 EXPECT_TRUE(D2RC
.isParentOf(NewDRC
));
1186 // Now that we've updated the call graph, D2 is dead, so remove it.
1187 CG
.removeDeadFunction(D2F
);
1189 // Check that the graph still looks the same.
1190 EXPECT_EQ(&ARC
, CG
.lookupRefSCC(A1
));
1191 EXPECT_EQ(&ARC
, CG
.lookupRefSCC(A2
));
1192 EXPECT_EQ(&ARC
, CG
.lookupRefSCC(A3
));
1193 EXPECT_EQ(&BRC
, CG
.lookupRefSCC(B1
));
1194 EXPECT_EQ(&BRC
, CG
.lookupRefSCC(B2
));
1195 EXPECT_EQ(&BRC
, CG
.lookupRefSCC(B3
));
1196 EXPECT_EQ(&CRC
, CG
.lookupRefSCC(C1
));
1197 EXPECT_EQ(&CRC
, CG
.lookupRefSCC(C2
));
1198 EXPECT_EQ(&CRC
, CG
.lookupRefSCC(C3
));
1199 EXPECT_EQ(&NewDRC
, CG
.lookupRefSCC(D1
));
1200 EXPECT_EQ(&NewDRC
, CG
.lookupRefSCC(D3
));
1201 EXPECT_TRUE(CRC
.isParentOf(NewDRC
));
1203 // Verify the post-order walk hasn't changed.
1204 auto I
= CG
.postorder_ref_scc_begin(), E
= CG
.postorder_ref_scc_end();
1206 EXPECT_EQ(&NewDRC
, &*I
) << "Actual RefSCC: " << *I
;
1208 EXPECT_EQ(&CRC
, &*I
) << "Actual RefSCC: " << *I
;
1210 EXPECT_EQ(&BRC
, &*I
) << "Actual RefSCC: " << *I
;
1212 EXPECT_EQ(&ARC
, &*I
) << "Actual RefSCC: " << *I
;
1216 TEST(LazyCallGraphTest
, InternalEdgeMutation
) {
1217 LLVMContext Context
;
1218 std::unique_ptr
<Module
> M
= parseAssembly(Context
, "define void @a() {\n"
1223 "define void @b() {\n"
1228 "define void @c() {\n"
1233 LazyCallGraph CG
= buildCG(*M
);
1235 // Force the graph to be fully expanded.
1237 auto I
= CG
.postorder_ref_scc_begin();
1238 LazyCallGraph::RefSCC
&RC
= *I
++;
1239 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
1241 LazyCallGraph::Node
&A
= *CG
.lookup(lookupFunction(*M
, "a"));
1242 LazyCallGraph::Node
&B
= *CG
.lookup(lookupFunction(*M
, "b"));
1243 LazyCallGraph::Node
&C
= *CG
.lookup(lookupFunction(*M
, "c"));
1244 EXPECT_EQ(&RC
, CG
.lookupRefSCC(A
));
1245 EXPECT_EQ(&RC
, CG
.lookupRefSCC(B
));
1246 EXPECT_EQ(&RC
, CG
.lookupRefSCC(C
));
1247 EXPECT_EQ(1, RC
.size());
1248 EXPECT_EQ(&*RC
.begin(), CG
.lookupSCC(A
));
1249 EXPECT_EQ(&*RC
.begin(), CG
.lookupSCC(B
));
1250 EXPECT_EQ(&*RC
.begin(), CG
.lookupSCC(C
));
1252 // Insert an edge from 'a' to 'c'. Nothing changes about the graph.
1253 RC
.insertInternalRefEdge(A
, C
);
1254 EXPECT_EQ(2, std::distance(A
->begin(), A
->end()));
1255 EXPECT_EQ(&RC
, CG
.lookupRefSCC(A
));
1256 EXPECT_EQ(&RC
, CG
.lookupRefSCC(B
));
1257 EXPECT_EQ(&RC
, CG
.lookupRefSCC(C
));
1258 EXPECT_EQ(1, RC
.size());
1259 EXPECT_EQ(&*RC
.begin(), CG
.lookupSCC(A
));
1260 EXPECT_EQ(&*RC
.begin(), CG
.lookupSCC(B
));
1261 EXPECT_EQ(&*RC
.begin(), CG
.lookupSCC(C
));
1263 // Switch the call edge from 'b' to 'c' to a ref edge. This will break the
1264 // call cycle and cause us to form more SCCs. The RefSCC will remain the same
1266 auto NewCs
= RC
.switchInternalEdgeToRef(B
, C
);
1267 EXPECT_EQ(&RC
, CG
.lookupRefSCC(A
));
1268 EXPECT_EQ(&RC
, CG
.lookupRefSCC(B
));
1269 EXPECT_EQ(&RC
, CG
.lookupRefSCC(C
));
1270 auto J
= RC
.begin();
1271 // The SCCs must be in *post-order* which means successors before
1272 // predecessors. At this point we have call edges from C to A and from A to
1273 // B. The only valid postorder is B, A, C.
1274 EXPECT_EQ(&*J
++, CG
.lookupSCC(B
));
1275 EXPECT_EQ(&*J
++, CG
.lookupSCC(A
));
1276 EXPECT_EQ(&*J
++, CG
.lookupSCC(C
));
1277 EXPECT_EQ(RC
.end(), J
);
1278 // And the returned range must be the slice of this sequence containing new
1280 EXPECT_EQ(RC
.begin(), NewCs
.begin());
1281 EXPECT_EQ(std::prev(RC
.end()), NewCs
.end());
1283 // Test turning the ref edge from A to C into a call edge. This will form an
1284 // SCC out of A and C. Since we previously had a call edge from C to A, the
1285 // C SCC should be preserved and have A merged into it while the A SCC should
1287 LazyCallGraph::SCC
&AC
= *CG
.lookupSCC(A
);
1288 LazyCallGraph::SCC
&CC
= *CG
.lookupSCC(C
);
1289 EXPECT_TRUE(RC
.switchInternalEdgeToCall(A
, C
, [&](ArrayRef
<LazyCallGraph::SCC
*> MergedCs
) {
1290 ASSERT_EQ(1u, MergedCs
.size());
1291 EXPECT_EQ(&AC
, MergedCs
[0]);
1293 EXPECT_EQ(2, CC
.size());
1294 EXPECT_EQ(&CC
, CG
.lookupSCC(A
));
1295 EXPECT_EQ(&CC
, CG
.lookupSCC(C
));
1297 EXPECT_EQ(&*J
++, CG
.lookupSCC(B
));
1298 EXPECT_EQ(&*J
++, CG
.lookupSCC(C
));
1299 EXPECT_EQ(RC
.end(), J
);
1302 TEST(LazyCallGraphTest
, InternalEdgeRemoval
) {
1303 LLVMContext Context
;
1304 // A nice fully connected (including self-edges) RefSCC.
1305 std::unique_ptr
<Module
> M
= parseAssembly(
1306 Context
, "define void @a(i8** %ptr) {\n"
1308 " store i8* bitcast (void(i8**)* @a to i8*), i8** %ptr\n"
1309 " store i8* bitcast (void(i8**)* @b to i8*), i8** %ptr\n"
1310 " store i8* bitcast (void(i8**)* @c to i8*), i8** %ptr\n"
1313 "define void @b(i8** %ptr) {\n"
1315 " store i8* bitcast (void(i8**)* @a to i8*), i8** %ptr\n"
1316 " store i8* bitcast (void(i8**)* @b to i8*), i8** %ptr\n"
1317 " store i8* bitcast (void(i8**)* @c to i8*), i8** %ptr\n"
1320 "define void @c(i8** %ptr) {\n"
1322 " store i8* bitcast (void(i8**)* @a to i8*), i8** %ptr\n"
1323 " store i8* bitcast (void(i8**)* @b to i8*), i8** %ptr\n"
1324 " store i8* bitcast (void(i8**)* @c to i8*), i8** %ptr\n"
1327 LazyCallGraph CG
= buildCG(*M
);
1329 // Force the graph to be fully expanded.
1331 auto I
= CG
.postorder_ref_scc_begin(), E
= CG
.postorder_ref_scc_end();
1332 LazyCallGraph::RefSCC
&RC
= *I
;
1333 EXPECT_EQ(E
, std::next(I
));
1335 LazyCallGraph::Node
&A
= *CG
.lookup(lookupFunction(*M
, "a"));
1336 LazyCallGraph::Node
&B
= *CG
.lookup(lookupFunction(*M
, "b"));
1337 LazyCallGraph::Node
&C
= *CG
.lookup(lookupFunction(*M
, "c"));
1338 EXPECT_EQ(&RC
, CG
.lookupRefSCC(A
));
1339 EXPECT_EQ(&RC
, CG
.lookupRefSCC(B
));
1340 EXPECT_EQ(&RC
, CG
.lookupRefSCC(C
));
1342 // Remove the edge from b -> a, which should leave the 3 functions still in
1343 // a single connected component because of a -> b -> c -> a.
1344 SmallVector
<LazyCallGraph::RefSCC
*, 1> NewRCs
=
1345 RC
.removeInternalRefEdge(B
, {&A
});
1346 EXPECT_EQ(0u, NewRCs
.size());
1347 EXPECT_EQ(&RC
, CG
.lookupRefSCC(A
));
1348 EXPECT_EQ(&RC
, CG
.lookupRefSCC(B
));
1349 EXPECT_EQ(&RC
, CG
.lookupRefSCC(C
));
1350 auto J
= CG
.postorder_ref_scc_begin();
1352 EXPECT_EQ(&RC
, &*J
);
1353 EXPECT_EQ(E
, std::next(J
));
1355 // Increment I before we actually mutate the structure so that it remains
1356 // a valid iterator.
1359 // Remove the edge from c -> a, which should leave 'a' in the original RefSCC
1360 // and form a new RefSCC for 'b' and 'c'.
1361 NewRCs
= RC
.removeInternalRefEdge(C
, {&A
});
1362 ASSERT_EQ(2u, NewRCs
.size());
1363 LazyCallGraph::RefSCC
&BCRC
= *NewRCs
[0];
1364 LazyCallGraph::RefSCC
&ARC
= *NewRCs
[1];
1365 EXPECT_EQ(&ARC
, CG
.lookupRefSCC(A
));
1366 EXPECT_EQ(1, std::distance(ARC
.begin(), ARC
.end()));
1367 EXPECT_EQ(&BCRC
, CG
.lookupRefSCC(B
));
1368 EXPECT_EQ(&BCRC
, CG
.lookupRefSCC(C
));
1369 J
= CG
.postorder_ref_scc_begin();
1371 EXPECT_EQ(&BCRC
, &*J
);
1374 EXPECT_EQ(&ARC
, &*J
);
1380 TEST(LazyCallGraphTest
, InternalMultiEdgeRemoval
) {
1381 LLVMContext Context
;
1382 // A nice fully connected (including self-edges) RefSCC.
1383 std::unique_ptr
<Module
> M
= parseAssembly(
1384 Context
, "define void @a(i8** %ptr) {\n"
1386 " store i8* bitcast (void(i8**)* @a to i8*), i8** %ptr\n"
1387 " store i8* bitcast (void(i8**)* @b to i8*), i8** %ptr\n"
1388 " store i8* bitcast (void(i8**)* @c to i8*), i8** %ptr\n"
1391 "define void @b(i8** %ptr) {\n"
1393 " store i8* bitcast (void(i8**)* @a to i8*), i8** %ptr\n"
1394 " store i8* bitcast (void(i8**)* @b to i8*), i8** %ptr\n"
1395 " store i8* bitcast (void(i8**)* @c to i8*), i8** %ptr\n"
1398 "define void @c(i8** %ptr) {\n"
1400 " store i8* bitcast (void(i8**)* @a to i8*), i8** %ptr\n"
1401 " store i8* bitcast (void(i8**)* @b to i8*), i8** %ptr\n"
1402 " store i8* bitcast (void(i8**)* @c to i8*), i8** %ptr\n"
1405 LazyCallGraph CG
= buildCG(*M
);
1407 // Force the graph to be fully expanded.
1409 auto I
= CG
.postorder_ref_scc_begin(), E
= CG
.postorder_ref_scc_end();
1410 LazyCallGraph::RefSCC
&RC
= *I
;
1411 EXPECT_EQ(E
, std::next(I
));
1413 LazyCallGraph::Node
&A
= *CG
.lookup(lookupFunction(*M
, "a"));
1414 LazyCallGraph::Node
&B
= *CG
.lookup(lookupFunction(*M
, "b"));
1415 LazyCallGraph::Node
&C
= *CG
.lookup(lookupFunction(*M
, "c"));
1416 EXPECT_EQ(&RC
, CG
.lookupRefSCC(A
));
1417 EXPECT_EQ(&RC
, CG
.lookupRefSCC(B
));
1418 EXPECT_EQ(&RC
, CG
.lookupRefSCC(C
));
1420 // Increment I before we actually mutate the structure so that it remains
1421 // a valid iterator.
1424 // Remove the edges from b -> a and b -> c, leaving b in its own RefSCC.
1425 SmallVector
<LazyCallGraph::RefSCC
*, 1> NewRCs
=
1426 RC
.removeInternalRefEdge(B
, {&A
, &C
});
1428 ASSERT_EQ(2u, NewRCs
.size());
1429 LazyCallGraph::RefSCC
&BRC
= *NewRCs
[0];
1430 LazyCallGraph::RefSCC
&ACRC
= *NewRCs
[1];
1431 EXPECT_EQ(&BRC
, CG
.lookupRefSCC(B
));
1432 EXPECT_EQ(1, std::distance(BRC
.begin(), BRC
.end()));
1433 EXPECT_EQ(&ACRC
, CG
.lookupRefSCC(A
));
1434 EXPECT_EQ(&ACRC
, CG
.lookupRefSCC(C
));
1435 auto J
= CG
.postorder_ref_scc_begin();
1437 EXPECT_EQ(&BRC
, &*J
);
1440 EXPECT_EQ(&ACRC
, &*J
);
1446 TEST(LazyCallGraphTest
, InternalNoOpEdgeRemoval
) {
1447 LLVMContext Context
;
1448 // A graph with a single cycle formed both from call and reference edges
1449 // which makes the reference edges trivial to delete. The graph looks like:
1451 // Reference edges: a -> b -> c -> a
1452 // Call edges: a -> c -> b -> a
1453 std::unique_ptr
<Module
> M
= parseAssembly(
1454 Context
, "define void @a(i8** %ptr) {\n"
1456 " call void @b(i8** %ptr)\n"
1457 " store i8* bitcast (void(i8**)* @c to i8*), i8** %ptr\n"
1460 "define void @b(i8** %ptr) {\n"
1462 " store i8* bitcast (void(i8**)* @a to i8*), i8** %ptr\n"
1463 " call void @c(i8** %ptr)\n"
1466 "define void @c(i8** %ptr) {\n"
1468 " call void @a(i8** %ptr)\n"
1469 " store i8* bitcast (void(i8**)* @b to i8*), i8** %ptr\n"
1472 LazyCallGraph CG
= buildCG(*M
);
1474 // Force the graph to be fully expanded.
1476 auto I
= CG
.postorder_ref_scc_begin(), E
= CG
.postorder_ref_scc_end();
1477 LazyCallGraph::RefSCC
&RC
= *I
;
1478 EXPECT_EQ(E
, std::next(I
));
1480 LazyCallGraph::SCC
&C
= *RC
.begin();
1481 EXPECT_EQ(RC
.end(), std::next(RC
.begin()));
1483 LazyCallGraph::Node
&AN
= *CG
.lookup(lookupFunction(*M
, "a"));
1484 LazyCallGraph::Node
&BN
= *CG
.lookup(lookupFunction(*M
, "b"));
1485 LazyCallGraph::Node
&CN
= *CG
.lookup(lookupFunction(*M
, "c"));
1486 EXPECT_EQ(&RC
, CG
.lookupRefSCC(AN
));
1487 EXPECT_EQ(&RC
, CG
.lookupRefSCC(BN
));
1488 EXPECT_EQ(&RC
, CG
.lookupRefSCC(CN
));
1489 EXPECT_EQ(&C
, CG
.lookupSCC(AN
));
1490 EXPECT_EQ(&C
, CG
.lookupSCC(BN
));
1491 EXPECT_EQ(&C
, CG
.lookupSCC(CN
));
1493 // Remove the edge from a -> c which doesn't change anything.
1494 SmallVector
<LazyCallGraph::RefSCC
*, 1> NewRCs
=
1495 RC
.removeInternalRefEdge(AN
, {&CN
});
1496 EXPECT_EQ(0u, NewRCs
.size());
1497 EXPECT_EQ(&RC
, CG
.lookupRefSCC(AN
));
1498 EXPECT_EQ(&RC
, CG
.lookupRefSCC(BN
));
1499 EXPECT_EQ(&RC
, CG
.lookupRefSCC(CN
));
1500 EXPECT_EQ(&C
, CG
.lookupSCC(AN
));
1501 EXPECT_EQ(&C
, CG
.lookupSCC(BN
));
1502 EXPECT_EQ(&C
, CG
.lookupSCC(CN
));
1503 auto J
= CG
.postorder_ref_scc_begin();
1505 EXPECT_EQ(&RC
, &*J
);
1506 EXPECT_EQ(E
, std::next(J
));
1508 // Remove the edge from b -> a and c -> b; again this doesn't change
1510 NewRCs
= RC
.removeInternalRefEdge(BN
, {&AN
});
1511 NewRCs
= RC
.removeInternalRefEdge(CN
, {&BN
});
1512 EXPECT_EQ(0u, NewRCs
.size());
1513 EXPECT_EQ(&RC
, CG
.lookupRefSCC(AN
));
1514 EXPECT_EQ(&RC
, CG
.lookupRefSCC(BN
));
1515 EXPECT_EQ(&RC
, CG
.lookupRefSCC(CN
));
1516 EXPECT_EQ(&C
, CG
.lookupSCC(AN
));
1517 EXPECT_EQ(&C
, CG
.lookupSCC(BN
));
1518 EXPECT_EQ(&C
, CG
.lookupSCC(CN
));
1519 J
= CG
.postorder_ref_scc_begin();
1521 EXPECT_EQ(&RC
, &*J
);
1522 EXPECT_EQ(E
, std::next(J
));
1525 TEST(LazyCallGraphTest
, InternalCallEdgeToRef
) {
1526 LLVMContext Context
;
1527 // A nice fully connected (including self-edges) SCC (and RefSCC)
1528 std::unique_ptr
<Module
> M
= parseAssembly(Context
, "define void @a() {\n"
1535 "define void @b() {\n"
1542 "define void @c() {\n"
1549 LazyCallGraph CG
= buildCG(*M
);
1551 // Force the graph to be fully expanded.
1553 auto I
= CG
.postorder_ref_scc_begin();
1554 LazyCallGraph::RefSCC
&RC
= *I
++;
1555 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
1557 EXPECT_EQ(1, RC
.size());
1558 LazyCallGraph::SCC
&AC
= *RC
.begin();
1560 LazyCallGraph::Node
&AN
= *CG
.lookup(lookupFunction(*M
, "a"));
1561 LazyCallGraph::Node
&BN
= *CG
.lookup(lookupFunction(*M
, "b"));
1562 LazyCallGraph::Node
&CN
= *CG
.lookup(lookupFunction(*M
, "c"));
1563 EXPECT_EQ(&AC
, CG
.lookupSCC(AN
));
1564 EXPECT_EQ(&AC
, CG
.lookupSCC(BN
));
1565 EXPECT_EQ(&AC
, CG
.lookupSCC(CN
));
1567 // Remove the call edge from b -> a to a ref edge, which should leave the
1568 // 3 functions still in a single connected component because of a -> b ->
1570 auto NewCs
= RC
.switchInternalEdgeToRef(BN
, AN
);
1571 EXPECT_EQ(NewCs
.begin(), NewCs
.end());
1572 EXPECT_EQ(1, RC
.size());
1573 EXPECT_EQ(&AC
, CG
.lookupSCC(AN
));
1574 EXPECT_EQ(&AC
, CG
.lookupSCC(BN
));
1575 EXPECT_EQ(&AC
, CG
.lookupSCC(CN
));
1577 // Remove the edge from c -> a, which should leave 'a' in the original SCC
1578 // and form a new SCC for 'b' and 'c'.
1579 NewCs
= RC
.switchInternalEdgeToRef(CN
, AN
);
1580 EXPECT_EQ(1, std::distance(NewCs
.begin(), NewCs
.end()));
1581 EXPECT_EQ(2, RC
.size());
1582 EXPECT_EQ(&AC
, CG
.lookupSCC(AN
));
1583 LazyCallGraph::SCC
&BC
= *CG
.lookupSCC(BN
);
1584 EXPECT_NE(&BC
, &AC
);
1585 EXPECT_EQ(&BC
, CG
.lookupSCC(CN
));
1586 auto J
= RC
.find(AC
);
1587 EXPECT_EQ(&AC
, &*J
);
1589 EXPECT_EQ(&BC
, &*J
);
1590 EXPECT_EQ(RC
.begin(), J
);
1591 EXPECT_EQ(J
, NewCs
.begin());
1593 // Remove the edge from c -> b, which should leave 'b' in the original SCC
1594 // and form a new SCC for 'c'. It shouldn't change 'a's SCC.
1595 NewCs
= RC
.switchInternalEdgeToRef(CN
, BN
);
1596 EXPECT_EQ(1, std::distance(NewCs
.begin(), NewCs
.end()));
1597 EXPECT_EQ(3, RC
.size());
1598 EXPECT_EQ(&AC
, CG
.lookupSCC(AN
));
1599 EXPECT_EQ(&BC
, CG
.lookupSCC(BN
));
1600 LazyCallGraph::SCC
&CC
= *CG
.lookupSCC(CN
);
1601 EXPECT_NE(&CC
, &AC
);
1602 EXPECT_NE(&CC
, &BC
);
1604 EXPECT_EQ(&AC
, &*J
);
1606 EXPECT_EQ(&BC
, &*J
);
1608 EXPECT_EQ(&CC
, &*J
);
1609 EXPECT_EQ(RC
.begin(), J
);
1610 EXPECT_EQ(J
, NewCs
.begin());
1613 TEST(LazyCallGraphTest
, InternalRefEdgeToCall
) {
1614 LLVMContext Context
;
1615 // Basic tests for making a ref edge a call. This hits the basics of the
1617 std::unique_ptr
<Module
> M
=
1618 parseAssembly(Context
, "define void @a() {\n"
1622 " store void()* @d, void()** undef\n"
1625 "define void @b() {\n"
1627 " store void()* @c, void()** undef\n"
1631 "define void @c() {\n"
1633 " store void()* @b, void()** undef\n"
1637 "define void @d() {\n"
1639 " store void()* @a, void()** undef\n"
1642 LazyCallGraph CG
= buildCG(*M
);
1644 // Force the graph to be fully expanded.
1646 auto I
= CG
.postorder_ref_scc_begin();
1647 LazyCallGraph::RefSCC
&RC
= *I
++;
1648 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
1650 LazyCallGraph::Node
&A
= *CG
.lookup(lookupFunction(*M
, "a"));
1651 LazyCallGraph::Node
&B
= *CG
.lookup(lookupFunction(*M
, "b"));
1652 LazyCallGraph::Node
&C
= *CG
.lookup(lookupFunction(*M
, "c"));
1653 LazyCallGraph::Node
&D
= *CG
.lookup(lookupFunction(*M
, "d"));
1654 LazyCallGraph::SCC
&AC
= *CG
.lookupSCC(A
);
1655 LazyCallGraph::SCC
&BC
= *CG
.lookupSCC(B
);
1656 LazyCallGraph::SCC
&CC
= *CG
.lookupSCC(C
);
1657 LazyCallGraph::SCC
&DC
= *CG
.lookupSCC(D
);
1659 // Check the initial post-order. Note that B and C could be flipped here (and
1660 // in our mutation) without changing the nature of this test.
1661 ASSERT_EQ(4, RC
.size());
1662 EXPECT_EQ(&DC
, &RC
[0]);
1663 EXPECT_EQ(&BC
, &RC
[1]);
1664 EXPECT_EQ(&CC
, &RC
[2]);
1665 EXPECT_EQ(&AC
, &RC
[3]);
1667 // Switch the ref edge from A -> D to a call edge. This should have no
1668 // effect as it is already in postorder and no new cycles are formed.
1669 EXPECT_FALSE(RC
.switchInternalEdgeToCall(A
, D
));
1670 ASSERT_EQ(4, RC
.size());
1671 EXPECT_EQ(&DC
, &RC
[0]);
1672 EXPECT_EQ(&BC
, &RC
[1]);
1673 EXPECT_EQ(&CC
, &RC
[2]);
1674 EXPECT_EQ(&AC
, &RC
[3]);
1676 // Switch B -> C to a call edge. This doesn't form any new cycles but does
1677 // require reordering the SCCs.
1678 EXPECT_FALSE(RC
.switchInternalEdgeToCall(B
, C
));
1679 ASSERT_EQ(4, RC
.size());
1680 EXPECT_EQ(&DC
, &RC
[0]);
1681 EXPECT_EQ(&CC
, &RC
[1]);
1682 EXPECT_EQ(&BC
, &RC
[2]);
1683 EXPECT_EQ(&AC
, &RC
[3]);
1685 // Switch C -> B to a call edge. This forms a cycle and forces merging SCCs.
1686 EXPECT_TRUE(RC
.switchInternalEdgeToCall(C
, B
, [&](ArrayRef
<LazyCallGraph::SCC
*> MergedCs
) {
1687 ASSERT_EQ(1u, MergedCs
.size());
1688 EXPECT_EQ(&CC
, MergedCs
[0]);
1690 ASSERT_EQ(3, RC
.size());
1691 EXPECT_EQ(&DC
, &RC
[0]);
1692 EXPECT_EQ(&BC
, &RC
[1]);
1693 EXPECT_EQ(&AC
, &RC
[2]);
1694 EXPECT_EQ(2, BC
.size());
1695 EXPECT_EQ(&BC
, CG
.lookupSCC(B
));
1696 EXPECT_EQ(&BC
, CG
.lookupSCC(C
));
1699 TEST(LazyCallGraphTest
, InternalRefEdgeToCallNoCycleInterleaved
) {
1700 LLVMContext Context
;
1701 // Test for having a post-order prior to changing a ref edge to a call edge
1702 // with SCCs connecting to the source and connecting to the target, but not
1703 // connecting to both, interleaved between the source and target. This
1704 // ensures we correctly partition the range rather than simply moving one or
1706 std::unique_ptr
<Module
> M
=
1707 parseAssembly(Context
, "define void @a() {\n"
1709 " call void @b1()\n"
1710 " call void @c1()\n"
1713 "define void @b1() {\n"
1715 " call void @c1()\n"
1716 " call void @b2()\n"
1719 "define void @c1() {\n"
1721 " call void @b2()\n"
1722 " call void @c2()\n"
1725 "define void @b2() {\n"
1727 " call void @c2()\n"
1728 " call void @b3()\n"
1731 "define void @c2() {\n"
1733 " call void @b3()\n"
1734 " call void @c3()\n"
1737 "define void @b3() {\n"
1739 " call void @c3()\n"
1743 "define void @c3() {\n"
1745 " store void()* @b1, void()** undef\n"
1749 "define void @d() {\n"
1751 " store void()* @a, void()** undef\n"
1754 LazyCallGraph CG
= buildCG(*M
);
1756 // Force the graph to be fully expanded.
1758 auto I
= CG
.postorder_ref_scc_begin();
1759 LazyCallGraph::RefSCC
&RC
= *I
++;
1760 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
1762 LazyCallGraph::Node
&A
= *CG
.lookup(lookupFunction(*M
, "a"));
1763 LazyCallGraph::Node
&B1
= *CG
.lookup(lookupFunction(*M
, "b1"));
1764 LazyCallGraph::Node
&B2
= *CG
.lookup(lookupFunction(*M
, "b2"));
1765 LazyCallGraph::Node
&B3
= *CG
.lookup(lookupFunction(*M
, "b3"));
1766 LazyCallGraph::Node
&C1
= *CG
.lookup(lookupFunction(*M
, "c1"));
1767 LazyCallGraph::Node
&C2
= *CG
.lookup(lookupFunction(*M
, "c2"));
1768 LazyCallGraph::Node
&C3
= *CG
.lookup(lookupFunction(*M
, "c3"));
1769 LazyCallGraph::Node
&D
= *CG
.lookup(lookupFunction(*M
, "d"));
1770 LazyCallGraph::SCC
&AC
= *CG
.lookupSCC(A
);
1771 LazyCallGraph::SCC
&B1C
= *CG
.lookupSCC(B1
);
1772 LazyCallGraph::SCC
&B2C
= *CG
.lookupSCC(B2
);
1773 LazyCallGraph::SCC
&B3C
= *CG
.lookupSCC(B3
);
1774 LazyCallGraph::SCC
&C1C
= *CG
.lookupSCC(C1
);
1775 LazyCallGraph::SCC
&C2C
= *CG
.lookupSCC(C2
);
1776 LazyCallGraph::SCC
&C3C
= *CG
.lookupSCC(C3
);
1777 LazyCallGraph::SCC
&DC
= *CG
.lookupSCC(D
);
1779 // Several call edges are initially present to force a particual post-order.
1780 // Remove them now, leaving an interleaved post-order pattern.
1781 RC
.switchTrivialInternalEdgeToRef(B3
, C3
);
1782 RC
.switchTrivialInternalEdgeToRef(C2
, B3
);
1783 RC
.switchTrivialInternalEdgeToRef(B2
, C2
);
1784 RC
.switchTrivialInternalEdgeToRef(C1
, B2
);
1785 RC
.switchTrivialInternalEdgeToRef(B1
, C1
);
1787 // Check the initial post-order. We ensure this order with the extra edges
1788 // that are nuked above.
1789 ASSERT_EQ(8, RC
.size());
1790 EXPECT_EQ(&DC
, &RC
[0]);
1791 EXPECT_EQ(&C3C
, &RC
[1]);
1792 EXPECT_EQ(&B3C
, &RC
[2]);
1793 EXPECT_EQ(&C2C
, &RC
[3]);
1794 EXPECT_EQ(&B2C
, &RC
[4]);
1795 EXPECT_EQ(&C1C
, &RC
[5]);
1796 EXPECT_EQ(&B1C
, &RC
[6]);
1797 EXPECT_EQ(&AC
, &RC
[7]);
1799 // Switch C3 -> B1 to a call edge. This doesn't form any new cycles but does
1800 // require reordering the SCCs in the face of tricky internal node
1802 EXPECT_FALSE(RC
.switchInternalEdgeToCall(C3
, B1
));
1803 ASSERT_EQ(8, RC
.size());
1804 EXPECT_EQ(&DC
, &RC
[0]);
1805 EXPECT_EQ(&B3C
, &RC
[1]);
1806 EXPECT_EQ(&B2C
, &RC
[2]);
1807 EXPECT_EQ(&B1C
, &RC
[3]);
1808 EXPECT_EQ(&C3C
, &RC
[4]);
1809 EXPECT_EQ(&C2C
, &RC
[5]);
1810 EXPECT_EQ(&C1C
, &RC
[6]);
1811 EXPECT_EQ(&AC
, &RC
[7]);
1814 TEST(LazyCallGraphTest
, InternalRefEdgeToCallBothPartitionAndMerge
) {
1815 LLVMContext Context
;
1816 // Test for having a postorder where between the source and target are all
1817 // three kinds of other SCCs:
1818 // 1) One connected to the target only that have to be shifted below the
1820 // 2) One connected to the source only that have to be shifted below the
1822 // 3) One connected to both source and target that has to remain and get
1825 // To achieve this we construct a heavily connected graph to force
1826 // a particular post-order. Then we remove the forcing edges and connect
1829 // Diagram for the graph we want on the left and the graph we use to force
1830 // the ordering on the right. Edges ponit down or right.
1842 // And we form a cycle by connecting F to B.
1843 std::unique_ptr
<Module
> M
=
1844 parseAssembly(Context
, "define void @a() {\n"
1850 "define void @b() {\n"
1856 "define void @c() {\n"
1862 "define void @d() {\n"
1868 "define void @e() {\n"
1873 "define void @f() {\n"
1875 " store void()* @b, void()** undef\n"
1879 "define void @g() {\n"
1881 " store void()* @a, void()** undef\n"
1884 LazyCallGraph CG
= buildCG(*M
);
1886 // Force the graph to be fully expanded.
1888 auto I
= CG
.postorder_ref_scc_begin();
1889 LazyCallGraph::RefSCC
&RC
= *I
++;
1890 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
1892 LazyCallGraph::Node
&A
= *CG
.lookup(lookupFunction(*M
, "a"));
1893 LazyCallGraph::Node
&B
= *CG
.lookup(lookupFunction(*M
, "b"));
1894 LazyCallGraph::Node
&C
= *CG
.lookup(lookupFunction(*M
, "c"));
1895 LazyCallGraph::Node
&D
= *CG
.lookup(lookupFunction(*M
, "d"));
1896 LazyCallGraph::Node
&E
= *CG
.lookup(lookupFunction(*M
, "e"));
1897 LazyCallGraph::Node
&F
= *CG
.lookup(lookupFunction(*M
, "f"));
1898 LazyCallGraph::Node
&G
= *CG
.lookup(lookupFunction(*M
, "g"));
1899 LazyCallGraph::SCC
&AC
= *CG
.lookupSCC(A
);
1900 LazyCallGraph::SCC
&BC
= *CG
.lookupSCC(B
);
1901 LazyCallGraph::SCC
&CC
= *CG
.lookupSCC(C
);
1902 LazyCallGraph::SCC
&DC
= *CG
.lookupSCC(D
);
1903 LazyCallGraph::SCC
&EC
= *CG
.lookupSCC(E
);
1904 LazyCallGraph::SCC
&FC
= *CG
.lookupSCC(F
);
1905 LazyCallGraph::SCC
&GC
= *CG
.lookupSCC(G
);
1907 // Remove the extra edges that were used to force a particular post-order.
1908 RC
.switchTrivialInternalEdgeToRef(C
, D
);
1909 RC
.switchTrivialInternalEdgeToRef(D
, E
);
1911 // Check the initial post-order. We ensure this order with the extra edges
1912 // that are nuked above.
1913 ASSERT_EQ(7, RC
.size());
1914 EXPECT_EQ(&GC
, &RC
[0]);
1915 EXPECT_EQ(&FC
, &RC
[1]);
1916 EXPECT_EQ(&EC
, &RC
[2]);
1917 EXPECT_EQ(&DC
, &RC
[3]);
1918 EXPECT_EQ(&CC
, &RC
[4]);
1919 EXPECT_EQ(&BC
, &RC
[5]);
1920 EXPECT_EQ(&AC
, &RC
[6]);
1922 // Switch F -> B to a call edge. This merges B, D, and F into a single SCC,
1923 // and has to place the C and E SCCs on either side of it:
1933 EXPECT_TRUE(RC
.switchInternalEdgeToCall(
1934 F
, B
, [&](ArrayRef
<LazyCallGraph::SCC
*> MergedCs
) {
1935 ASSERT_EQ(2u, MergedCs
.size());
1936 EXPECT_EQ(&FC
, MergedCs
[0]);
1937 EXPECT_EQ(&DC
, MergedCs
[1]);
1939 EXPECT_EQ(3, BC
.size());
1941 // And make sure the postorder was updated.
1942 ASSERT_EQ(5, RC
.size());
1943 EXPECT_EQ(&GC
, &RC
[0]);
1944 EXPECT_EQ(&CC
, &RC
[1]);
1945 EXPECT_EQ(&BC
, &RC
[2]);
1946 EXPECT_EQ(&EC
, &RC
[3]);
1947 EXPECT_EQ(&AC
, &RC
[4]);
1950 // Test for IR containing constants using blockaddress constant expressions.
1951 // These are truly unique constructs: constant expressions with non-constant
1953 TEST(LazyCallGraphTest
, HandleBlockAddress
) {
1954 LLVMContext Context
;
1955 std::unique_ptr
<Module
> M
=
1956 parseAssembly(Context
, "define void @f() {\n"
1962 "define void @g(i8** %ptr) {\n"
1964 " store i8* blockaddress(@f, %bb), i8** %ptr\n"
1967 LazyCallGraph CG
= buildCG(*M
);
1970 auto I
= CG
.postorder_ref_scc_begin();
1971 LazyCallGraph::RefSCC
&FRC
= *I
++;
1972 LazyCallGraph::RefSCC
&GRC
= *I
++;
1973 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
1975 LazyCallGraph::Node
&F
= *CG
.lookup(lookupFunction(*M
, "f"));
1976 LazyCallGraph::Node
&G
= *CG
.lookup(lookupFunction(*M
, "g"));
1977 EXPECT_EQ(&FRC
, CG
.lookupRefSCC(F
));
1978 EXPECT_EQ(&GRC
, CG
.lookupRefSCC(G
));
1979 EXPECT_TRUE(GRC
.isParentOf(FRC
));
1982 // Test that a blockaddress that refers to itself creates no new RefSCC
1983 // connections. https://bugs.llvm.org/show_bug.cgi?id=40722
1984 TEST(LazyCallGraphTest
, HandleBlockAddress2
) {
1985 LLVMContext Context
;
1986 std::unique_ptr
<Module
> M
=
1987 parseAssembly(Context
, "define void @f() {\n"
1990 "define void @g(i8** %ptr) {\n"
1992 " store i8* blockaddress(@g, %bb), i8** %ptr\n"
1995 LazyCallGraph CG
= buildCG(*M
);
1998 auto I
= CG
.postorder_ref_scc_begin();
1999 LazyCallGraph::RefSCC
&GRC
= *I
++;
2000 LazyCallGraph::RefSCC
&FRC
= *I
++;
2001 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2003 LazyCallGraph::Node
&F
= *CG
.lookup(lookupFunction(*M
, "f"));
2004 LazyCallGraph::Node
&G
= *CG
.lookup(lookupFunction(*M
, "g"));
2005 EXPECT_EQ(&FRC
, CG
.lookupRefSCC(F
));
2006 EXPECT_EQ(&GRC
, CG
.lookupRefSCC(G
));
2007 EXPECT_FALSE(GRC
.isParentOf(FRC
));
2008 EXPECT_FALSE(FRC
.isParentOf(GRC
));
2011 TEST(LazyCallGraphTest
, ReplaceNodeFunction
) {
2012 LLVMContext Context
;
2013 // A graph with several different kinds of edges pointing at a particular
2015 std::unique_ptr
<Module
> M
=
2016 parseAssembly(Context
,
2017 "define void @a(i8** %ptr) {\n"
2019 " store i8* bitcast (void(i8**)* @d to i8*), i8** %ptr\n"
2022 "define void @b(i8** %ptr) {\n"
2024 " store i8* bitcast (void(i8**)* @d to i8*), i8** %ptr\n"
2025 " store i8* bitcast (void(i8**)* @d to i8*), i8** %ptr\n"
2026 " call void @d(i8** %ptr)"
2029 "define void @c(i8** %ptr) {\n"
2031 " call void @d(i8** %ptr)"
2032 " call void @d(i8** %ptr)"
2033 " store i8* bitcast (void(i8**)* @d to i8*), i8** %ptr\n"
2036 "define void @d(i8** %ptr) {\n"
2038 " store i8* bitcast (void(i8**)* @b to i8*), i8** %ptr\n"
2039 " call void @c(i8** %ptr)"
2040 " call void @d(i8** %ptr)"
2041 " store i8* bitcast (void(i8**)* @d to i8*), i8** %ptr\n"
2044 LazyCallGraph CG
= buildCG(*M
);
2046 // Force the graph to be fully expanded.
2048 auto I
= CG
.postorder_ref_scc_begin();
2049 LazyCallGraph::RefSCC
&RC1
= *I
++;
2050 LazyCallGraph::RefSCC
&RC2
= *I
++;
2051 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2053 ASSERT_EQ(2, RC1
.size());
2054 LazyCallGraph::SCC
&C1
= RC1
[0];
2055 LazyCallGraph::SCC
&C2
= RC1
[1];
2057 LazyCallGraph::Node
&AN
= *CG
.lookup(lookupFunction(*M
, "a"));
2058 LazyCallGraph::Node
&BN
= *CG
.lookup(lookupFunction(*M
, "b"));
2059 LazyCallGraph::Node
&CN
= *CG
.lookup(lookupFunction(*M
, "c"));
2060 LazyCallGraph::Node
&DN
= *CG
.lookup(lookupFunction(*M
, "d"));
2061 EXPECT_EQ(&C1
, CG
.lookupSCC(DN
));
2062 EXPECT_EQ(&C1
, CG
.lookupSCC(CN
));
2063 EXPECT_EQ(&C2
, CG
.lookupSCC(BN
));
2064 EXPECT_EQ(&RC1
, CG
.lookupRefSCC(DN
));
2065 EXPECT_EQ(&RC1
, CG
.lookupRefSCC(CN
));
2066 EXPECT_EQ(&RC1
, CG
.lookupRefSCC(BN
));
2067 EXPECT_EQ(&RC2
, CG
.lookupRefSCC(AN
));
2069 // Now we need to build a new function 'e' with the same signature as 'd'.
2070 Function
&D
= DN
.getFunction();
2071 Function
&E
= *Function::Create(D
.getFunctionType(), D
.getLinkage(), "e");
2072 D
.getParent()->getFunctionList().insert(D
.getIterator(), &E
);
2074 // Change each use of 'd' to use 'e'. This is particularly easy as they have
2076 D
.replaceAllUsesWith(&E
);
2078 // Splice the body of the old function into the new one.
2079 E
.getBasicBlockList().splice(E
.begin(), D
.getBasicBlockList());
2080 // And fix up the one argument.
2081 D
.arg_begin()->replaceAllUsesWith(&*E
.arg_begin());
2082 E
.arg_begin()->takeName(&*D
.arg_begin());
2084 // Now replace the function in the graph.
2085 RC1
.replaceNodeFunction(DN
, E
);
2087 EXPECT_EQ(&E
, &DN
.getFunction());
2088 EXPECT_EQ(&DN
, &(*CN
)[DN
].getNode());
2089 EXPECT_EQ(&DN
, &(*BN
)[DN
].getNode());
2092 TEST(LazyCallGraphTest
, RemoveFunctionWithSpurriousRef
) {
2093 LLVMContext Context
;
2094 // A graph with a couple of RefSCCs.
2095 std::unique_ptr
<Module
> M
=
2096 parseAssembly(Context
,
2097 "define void @a(i8** %ptr) {\n"
2099 " store i8* bitcast (void(i8**)* @d to i8*), i8** %ptr\n"
2102 "define void @b(i8** %ptr) {\n"
2104 " store i8* bitcast (void(i8**)* @c to i8*), i8** %ptr\n"
2107 "define void @c(i8** %ptr) {\n"
2109 " call void @d(i8** %ptr)"
2112 "define void @d(i8** %ptr) {\n"
2114 " call void @c(i8** %ptr)"
2115 " store i8* bitcast (void(i8**)* @b to i8*), i8** %ptr\n"
2118 "define void @dead() {\n"
2122 LazyCallGraph CG
= buildCG(*M
);
2124 // Insert spurious ref edges.
2125 LazyCallGraph::Node
&AN
= CG
.get(lookupFunction(*M
, "a"));
2126 LazyCallGraph::Node
&BN
= CG
.get(lookupFunction(*M
, "b"));
2127 LazyCallGraph::Node
&CN
= CG
.get(lookupFunction(*M
, "c"));
2128 LazyCallGraph::Node
&DN
= CG
.get(lookupFunction(*M
, "d"));
2129 LazyCallGraph::Node
&DeadN
= CG
.get(lookupFunction(*M
, "dead"));
2135 CG
.insertEdge(AN
, DeadN
, LazyCallGraph::Edge::Ref
);
2136 CG
.insertEdge(BN
, DeadN
, LazyCallGraph::Edge::Ref
);
2137 CG
.insertEdge(CN
, DeadN
, LazyCallGraph::Edge::Ref
);
2138 CG
.insertEdge(DN
, DeadN
, LazyCallGraph::Edge::Ref
);
2140 // Force the graph to be fully expanded.
2142 auto I
= CG
.postorder_ref_scc_begin();
2143 LazyCallGraph::RefSCC
&DeadRC
= *I
++;
2144 LazyCallGraph::RefSCC
&RC1
= *I
++;
2145 LazyCallGraph::RefSCC
&RC2
= *I
++;
2146 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2148 ASSERT_EQ(2, RC1
.size());
2149 LazyCallGraph::SCC
&C1
= RC1
[0];
2150 LazyCallGraph::SCC
&C2
= RC1
[1];
2152 EXPECT_EQ(&DeadRC
, CG
.lookupRefSCC(DeadN
));
2153 EXPECT_EQ(&C1
, CG
.lookupSCC(DN
));
2154 EXPECT_EQ(&C1
, CG
.lookupSCC(CN
));
2155 EXPECT_EQ(&C2
, CG
.lookupSCC(BN
));
2156 EXPECT_EQ(&RC1
, CG
.lookupRefSCC(DN
));
2157 EXPECT_EQ(&RC1
, CG
.lookupRefSCC(CN
));
2158 EXPECT_EQ(&RC1
, CG
.lookupRefSCC(BN
));
2159 EXPECT_EQ(&RC2
, CG
.lookupRefSCC(AN
));
2161 // Now delete 'dead'. There are no uses of this function but there are
2162 // spurious references.
2163 CG
.removeDeadFunction(DeadN
.getFunction());
2165 // The only observable change should be that the RefSCC is gone from the
2166 // postorder sequence.
2167 I
= CG
.postorder_ref_scc_begin();
2168 EXPECT_EQ(&RC1
, &*I
++);
2169 EXPECT_EQ(&RC2
, &*I
++);
2170 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);