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/IR/Verifier.h"
16 #include "llvm/Support/ErrorHandling.h"
17 #include "llvm/Support/SourceMgr.h"
18 #include "llvm/TargetParser/Triple.h"
19 #include "gtest/gtest.h"
26 std::unique_ptr
<Module
> parseAssembly(LLVMContext
&Context
,
27 const char *Assembly
) {
29 std::unique_ptr
<Module
> M
= parseAssemblyString(Assembly
, Error
, Context
);
32 raw_string_ostream
OS(ErrMsg
);
35 // A failure here means that the test itself is buggy.
37 report_fatal_error(ErrMsg
.c_str());
43 IR forming a call graph with a diamond of triangle-shaped SCCs:
57 All call edges go up between SCCs, and clockwise around the SCC.
59 static const char DiamondOfTriangles
[] =
60 "define void @a1() {\n"
67 "define void @a2() {\n"
72 "define void @a3() {\n"
77 "define void @b1() {\n"
83 "define void @b2() {\n"
88 "define void @b3() {\n"
93 "define void @c1() {\n"
99 "define void @c2() {\n"
104 "define void @c3() {\n"
109 "define void @d1() {\n"
114 "define void @d2() {\n"
119 "define void @d3() {\n"
126 IR forming a reference graph with a diamond of triangle-shaped RefSCCs
140 All call edges go up between RefSCCs, and clockwise around the RefSCC.
142 static const char DiamondOfTrianglesRefGraph
[] =
143 "define void @a1() {\n"
145 " %a = alloca void ()*\n"
146 " store void ()* @a2, void ()** %a\n"
147 " store void ()* @b2, void ()** %a\n"
148 " store void ()* @c3, void ()** %a\n"
151 "define void @a2() {\n"
153 " %a = alloca void ()*\n"
154 " store void ()* @a3, void ()** %a\n"
157 "define void @a3() {\n"
159 " %a = alloca void ()*\n"
160 " store void ()* @a1, void ()** %a\n"
163 "define void @b1() {\n"
165 " %a = alloca void ()*\n"
166 " store void ()* @b2, void ()** %a\n"
167 " store void ()* @d3, void ()** %a\n"
170 "define void @b2() {\n"
172 " %a = alloca void ()*\n"
173 " store void ()* @b3, void ()** %a\n"
176 "define void @b3() {\n"
178 " %a = alloca void ()*\n"
179 " store void ()* @b1, void ()** %a\n"
182 "define void @c1() {\n"
184 " %a = alloca void ()*\n"
185 " store void ()* @c2, void ()** %a\n"
186 " store void ()* @d2, void ()** %a\n"
189 "define void @c2() {\n"
191 " %a = alloca void ()*\n"
192 " store void ()* @c3, void ()** %a\n"
195 "define void @c3() {\n"
197 " %a = alloca void ()*\n"
198 " store void ()* @c1, void ()** %a\n"
201 "define void @d1() {\n"
203 " %a = alloca void ()*\n"
204 " store void ()* @d2, void ()** %a\n"
207 "define void @d2() {\n"
209 " %a = alloca void ()*\n"
210 " store void ()* @d3, void ()** %a\n"
213 "define void @d3() {\n"
215 " %a = alloca void ()*\n"
216 " store void ()* @d1, void ()** %a\n"
220 static LazyCallGraph
buildCG(Module
&M
) {
221 TargetLibraryInfoImpl
TLII(Triple(M
.getTargetTriple()));
222 TargetLibraryInfo
TLI(TLII
);
223 auto GetTLI
= [&TLI
](Function
&F
) -> TargetLibraryInfo
& { return TLI
; };
225 LazyCallGraph
CG(M
, GetTLI
);
229 TEST(LazyCallGraphTest
, BasicGraphFormation
) {
231 std::unique_ptr
<Module
> M
= parseAssembly(Context
, DiamondOfTriangles
);
232 LazyCallGraph CG
= buildCG(*M
);
234 // The order of the entry nodes should be stable w.r.t. the source order of
235 // the IR, and everything in our module is an entry node, so just directly
236 // build variables for each node.
238 LazyCallGraph::Node
&A1
= (I
++)->getNode();
239 EXPECT_EQ("a1", A1
.getFunction().getName());
240 LazyCallGraph::Node
&A2
= (I
++)->getNode();
241 EXPECT_EQ("a2", A2
.getFunction().getName());
242 LazyCallGraph::Node
&A3
= (I
++)->getNode();
243 EXPECT_EQ("a3", A3
.getFunction().getName());
244 LazyCallGraph::Node
&B1
= (I
++)->getNode();
245 EXPECT_EQ("b1", B1
.getFunction().getName());
246 LazyCallGraph::Node
&B2
= (I
++)->getNode();
247 EXPECT_EQ("b2", B2
.getFunction().getName());
248 LazyCallGraph::Node
&B3
= (I
++)->getNode();
249 EXPECT_EQ("b3", B3
.getFunction().getName());
250 LazyCallGraph::Node
&C1
= (I
++)->getNode();
251 EXPECT_EQ("c1", C1
.getFunction().getName());
252 LazyCallGraph::Node
&C2
= (I
++)->getNode();
253 EXPECT_EQ("c2", C2
.getFunction().getName());
254 LazyCallGraph::Node
&C3
= (I
++)->getNode();
255 EXPECT_EQ("c3", C3
.getFunction().getName());
256 LazyCallGraph::Node
&D1
= (I
++)->getNode();
257 EXPECT_EQ("d1", D1
.getFunction().getName());
258 LazyCallGraph::Node
&D2
= (I
++)->getNode();
259 EXPECT_EQ("d2", D2
.getFunction().getName());
260 LazyCallGraph::Node
&D3
= (I
++)->getNode();
261 EXPECT_EQ("d3", D3
.getFunction().getName());
262 EXPECT_EQ(CG
.end(), I
);
264 // Build vectors and sort them for the rest of the assertions to make them
265 // independent of order.
266 std::vector
<std::string
> Nodes
;
268 for (LazyCallGraph::Edge
&E
: A1
.populate())
269 Nodes
.push_back(std::string(E
.getFunction().getName()));
271 EXPECT_EQ("a2", Nodes
[0]);
272 EXPECT_EQ("b2", Nodes
[1]);
273 EXPECT_EQ("c3", Nodes
[2]);
277 EXPECT_EQ(A2
->end(), std::next(A2
->begin()));
278 EXPECT_EQ("a3", A2
->begin()->getFunction().getName());
280 EXPECT_EQ(A3
->end(), std::next(A3
->begin()));
281 EXPECT_EQ("a1", A3
->begin()->getFunction().getName());
283 for (LazyCallGraph::Edge
&E
: B1
.populate())
284 Nodes
.push_back(std::string(E
.getFunction().getName()));
286 EXPECT_EQ("b2", Nodes
[0]);
287 EXPECT_EQ("d3", Nodes
[1]);
291 EXPECT_EQ(B2
->end(), std::next(B2
->begin()));
292 EXPECT_EQ("b3", B2
->begin()->getFunction().getName());
294 EXPECT_EQ(B3
->end(), std::next(B3
->begin()));
295 EXPECT_EQ("b1", B3
->begin()->getFunction().getName());
297 for (LazyCallGraph::Edge
&E
: C1
.populate())
298 Nodes
.push_back(std::string(E
.getFunction().getName()));
300 EXPECT_EQ("c2", Nodes
[0]);
301 EXPECT_EQ("d2", Nodes
[1]);
305 EXPECT_EQ(C2
->end(), std::next(C2
->begin()));
306 EXPECT_EQ("c3", C2
->begin()->getFunction().getName());
308 EXPECT_EQ(C3
->end(), std::next(C3
->begin()));
309 EXPECT_EQ("c1", C3
->begin()->getFunction().getName());
312 EXPECT_EQ(D1
->end(), std::next(D1
->begin()));
313 EXPECT_EQ("d2", D1
->begin()->getFunction().getName());
315 EXPECT_EQ(D2
->end(), std::next(D2
->begin()));
316 EXPECT_EQ("d3", D2
->begin()->getFunction().getName());
318 EXPECT_EQ(D3
->end(), std::next(D3
->begin()));
319 EXPECT_EQ("d1", D3
->begin()->getFunction().getName());
321 // Now lets look at the RefSCCs and SCCs.
323 auto J
= CG
.postorder_ref_scc_begin();
325 LazyCallGraph::RefSCC
&D
= *J
++;
326 ASSERT_EQ(1, D
.size());
327 for (LazyCallGraph::Node
&N
: *D
.begin())
328 Nodes
.push_back(std::string(N
.getFunction().getName()));
330 EXPECT_EQ(3u, Nodes
.size());
331 EXPECT_EQ("d1", Nodes
[0]);
332 EXPECT_EQ("d2", Nodes
[1]);
333 EXPECT_EQ("d3", Nodes
[2]);
335 EXPECT_FALSE(D
.isParentOf(D
));
336 EXPECT_FALSE(D
.isChildOf(D
));
337 EXPECT_FALSE(D
.isAncestorOf(D
));
338 EXPECT_FALSE(D
.isDescendantOf(D
));
339 EXPECT_EQ(&D
, &*CG
.postorder_ref_scc_begin());
341 LazyCallGraph::RefSCC
&B
= *J
++;
342 ASSERT_EQ(1, B
.size());
343 for (LazyCallGraph::Node
&N
: *B
.begin())
344 Nodes
.push_back(std::string(N
.getFunction().getName()));
346 EXPECT_EQ(3u, Nodes
.size());
347 EXPECT_EQ("b1", Nodes
[0]);
348 EXPECT_EQ("b2", Nodes
[1]);
349 EXPECT_EQ("b3", Nodes
[2]);
351 EXPECT_TRUE(B
.isParentOf(D
));
352 EXPECT_FALSE(B
.isChildOf(D
));
353 EXPECT_TRUE(B
.isAncestorOf(D
));
354 EXPECT_FALSE(B
.isDescendantOf(D
));
355 EXPECT_EQ(&B
, &*std::next(CG
.postorder_ref_scc_begin()));
357 LazyCallGraph::RefSCC
&C
= *J
++;
358 ASSERT_EQ(1, C
.size());
359 for (LazyCallGraph::Node
&N
: *C
.begin())
360 Nodes
.push_back(std::string(N
.getFunction().getName()));
362 EXPECT_EQ(3u, Nodes
.size());
363 EXPECT_EQ("c1", Nodes
[0]);
364 EXPECT_EQ("c2", Nodes
[1]);
365 EXPECT_EQ("c3", Nodes
[2]);
367 EXPECT_FALSE(B
.isAncestorOf(C
));
368 EXPECT_FALSE(C
.isAncestorOf(B
));
369 EXPECT_TRUE(C
.isParentOf(D
));
370 EXPECT_FALSE(C
.isChildOf(D
));
371 EXPECT_TRUE(C
.isAncestorOf(D
));
372 EXPECT_FALSE(C
.isDescendantOf(D
));
373 EXPECT_EQ(&C
, &*std::next(CG
.postorder_ref_scc_begin(), 2));
375 LazyCallGraph::RefSCC
&A
= *J
++;
376 ASSERT_EQ(1, A
.size());
377 for (LazyCallGraph::Node
&N
: *A
.begin())
378 Nodes
.push_back(std::string(N
.getFunction().getName()));
380 EXPECT_EQ(3u, Nodes
.size());
381 EXPECT_EQ("a1", Nodes
[0]);
382 EXPECT_EQ("a2", Nodes
[1]);
383 EXPECT_EQ("a3", Nodes
[2]);
385 EXPECT_TRUE(A
.isParentOf(B
));
386 EXPECT_TRUE(A
.isParentOf(C
));
387 EXPECT_FALSE(A
.isParentOf(D
));
388 EXPECT_TRUE(A
.isAncestorOf(B
));
389 EXPECT_TRUE(A
.isAncestorOf(C
));
390 EXPECT_TRUE(A
.isAncestorOf(D
));
391 EXPECT_EQ(&A
, &*std::next(CG
.postorder_ref_scc_begin(), 3));
393 EXPECT_EQ(CG
.postorder_ref_scc_end(), J
);
394 EXPECT_EQ(J
, std::next(CG
.postorder_ref_scc_begin(), 4));
397 static Function
&lookupFunction(Module
&M
, StringRef Name
) {
398 for (Function
&F
: M
)
399 if (F
.getName() == Name
)
401 report_fatal_error("Couldn't find function!");
404 TEST(LazyCallGraphTest
, BasicGraphMutation
) {
406 std::unique_ptr
<Module
> M
= parseAssembly(Context
, "define void @a() {\n"
412 "define void @b() {\n"
416 "define void @c() {\n"
420 LazyCallGraph CG
= buildCG(*M
);
422 LazyCallGraph::Node
&A
= CG
.get(lookupFunction(*M
, "a"));
423 LazyCallGraph::Node
&B
= CG
.get(lookupFunction(*M
, "b"));
425 EXPECT_EQ(2, std::distance(A
->begin(), A
->end()));
427 EXPECT_EQ(0, std::distance(B
->begin(), B
->end()));
429 LazyCallGraph::Node
&C
= CG
.get(lookupFunction(*M
, "c"));
431 CG
.insertEdge(B
, C
, LazyCallGraph::Edge::Call
);
432 EXPECT_EQ(1, std::distance(B
->begin(), B
->end()));
433 EXPECT_EQ(0, std::distance(C
->begin(), C
->end()));
435 CG
.insertEdge(C
, B
, LazyCallGraph::Edge::Call
);
436 EXPECT_EQ(1, std::distance(C
->begin(), C
->end()));
437 EXPECT_EQ(&B
, &C
->begin()->getNode());
439 CG
.insertEdge(C
, C
, LazyCallGraph::Edge::Call
);
440 EXPECT_EQ(2, std::distance(C
->begin(), C
->end()));
441 EXPECT_EQ(&B
, &C
->begin()->getNode());
442 EXPECT_EQ(&C
, &std::next(C
->begin())->getNode());
445 EXPECT_EQ(1, std::distance(C
->begin(), C
->end()));
446 EXPECT_EQ(&C
, &C
->begin()->getNode());
449 EXPECT_EQ(0, std::distance(C
->begin(), C
->end()));
452 EXPECT_EQ(0, std::distance(B
->begin(), B
->end()));
455 TEST(LazyCallGraphTest
, InnerSCCFormation
) {
457 std::unique_ptr
<Module
> M
= parseAssembly(Context
, DiamondOfTriangles
);
458 LazyCallGraph CG
= buildCG(*M
);
460 // Now mutate the graph to connect every node into a single RefSCC to ensure
461 // that our inner SCC formation handles the rest.
462 LazyCallGraph::Node
&D1
= CG
.get(lookupFunction(*M
, "d1"));
463 LazyCallGraph::Node
&A1
= CG
.get(lookupFunction(*M
, "a1"));
466 CG
.insertEdge(D1
, A1
, LazyCallGraph::Edge::Ref
);
468 // Build vectors and sort them for the rest of the assertions to make them
469 // independent of order.
470 std::vector
<std::string
> Nodes
;
472 // We should build a single RefSCC for the entire graph.
474 auto I
= CG
.postorder_ref_scc_begin();
475 LazyCallGraph::RefSCC
&RC
= *I
++;
476 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
478 // Now walk the four SCCs which should be in post-order.
480 LazyCallGraph::SCC
&D
= *J
++;
481 for (LazyCallGraph::Node
&N
: D
)
482 Nodes
.push_back(std::string(N
.getFunction().getName()));
484 EXPECT_EQ(3u, Nodes
.size());
485 EXPECT_EQ("d1", Nodes
[0]);
486 EXPECT_EQ("d2", Nodes
[1]);
487 EXPECT_EQ("d3", Nodes
[2]);
490 LazyCallGraph::SCC
&B
= *J
++;
491 for (LazyCallGraph::Node
&N
: B
)
492 Nodes
.push_back(std::string(N
.getFunction().getName()));
494 EXPECT_EQ(3u, Nodes
.size());
495 EXPECT_EQ("b1", Nodes
[0]);
496 EXPECT_EQ("b2", Nodes
[1]);
497 EXPECT_EQ("b3", Nodes
[2]);
500 LazyCallGraph::SCC
&C
= *J
++;
501 for (LazyCallGraph::Node
&N
: C
)
502 Nodes
.push_back(std::string(N
.getFunction().getName()));
504 EXPECT_EQ(3u, Nodes
.size());
505 EXPECT_EQ("c1", Nodes
[0]);
506 EXPECT_EQ("c2", Nodes
[1]);
507 EXPECT_EQ("c3", Nodes
[2]);
510 LazyCallGraph::SCC
&A
= *J
++;
511 for (LazyCallGraph::Node
&N
: A
)
512 Nodes
.push_back(std::string(N
.getFunction().getName()));
514 EXPECT_EQ(3u, Nodes
.size());
515 EXPECT_EQ("a1", Nodes
[0]);
516 EXPECT_EQ("a2", Nodes
[1]);
517 EXPECT_EQ("a3", Nodes
[2]);
520 EXPECT_EQ(RC
.end(), J
);
523 TEST(LazyCallGraphTest
, MultiArmSCC
) {
525 // Two interlocking cycles. The really useful thing about this SCC is that it
526 // will require Tarjan's DFS to backtrack and finish processing all of the
527 // children of each node in the SCC. Since this involves call edges, both
528 // Tarjan implementations will have to successfully navigate the structure.
529 std::unique_ptr
<Module
> M
= parseAssembly(Context
, "define void @f1() {\n"
535 "define void @f2() {\n"
540 "define void @f3() {\n"
545 "define void @f4() {\n"
550 "define void @f5() {\n"
555 LazyCallGraph CG
= buildCG(*M
);
557 // Force the graph to be fully expanded.
559 auto I
= CG
.postorder_ref_scc_begin();
560 LazyCallGraph::RefSCC
&RC
= *I
++;
561 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
563 LazyCallGraph::Node
&N1
= *CG
.lookup(lookupFunction(*M
, "f1"));
564 LazyCallGraph::Node
&N2
= *CG
.lookup(lookupFunction(*M
, "f2"));
565 LazyCallGraph::Node
&N3
= *CG
.lookup(lookupFunction(*M
, "f3"));
566 LazyCallGraph::Node
&N4
= *CG
.lookup(lookupFunction(*M
, "f4"));
567 LazyCallGraph::Node
&N5
= *CG
.lookup(lookupFunction(*M
, "f4"));
568 EXPECT_EQ(&RC
, CG
.lookupRefSCC(N1
));
569 EXPECT_EQ(&RC
, CG
.lookupRefSCC(N2
));
570 EXPECT_EQ(&RC
, CG
.lookupRefSCC(N3
));
571 EXPECT_EQ(&RC
, CG
.lookupRefSCC(N4
));
572 EXPECT_EQ(&RC
, CG
.lookupRefSCC(N5
));
574 ASSERT_EQ(1, RC
.size());
576 LazyCallGraph::SCC
&C
= *RC
.begin();
577 EXPECT_EQ(&C
, CG
.lookupSCC(N1
));
578 EXPECT_EQ(&C
, CG
.lookupSCC(N2
));
579 EXPECT_EQ(&C
, CG
.lookupSCC(N3
));
580 EXPECT_EQ(&C
, CG
.lookupSCC(N4
));
581 EXPECT_EQ(&C
, CG
.lookupSCC(N5
));
584 TEST(LazyCallGraphTest
, OutgoingEdgeMutation
) {
586 std::unique_ptr
<Module
> M
= parseAssembly(Context
, "define void @a() {\n"
592 "define void @b() {\n"
597 "define void @c() {\n"
602 "define void @d() {\n"
606 LazyCallGraph CG
= buildCG(*M
);
608 // Force the graph to be fully expanded.
610 for (LazyCallGraph::RefSCC
&RC
: CG
.postorder_ref_sccs())
611 dbgs() << "Formed RefSCC: " << RC
<< "\n";
613 LazyCallGraph::Node
&A
= *CG
.lookup(lookupFunction(*M
, "a"));
614 LazyCallGraph::Node
&B
= *CG
.lookup(lookupFunction(*M
, "b"));
615 LazyCallGraph::Node
&C
= *CG
.lookup(lookupFunction(*M
, "c"));
616 LazyCallGraph::Node
&D
= *CG
.lookup(lookupFunction(*M
, "d"));
617 LazyCallGraph::SCC
&AC
= *CG
.lookupSCC(A
);
618 LazyCallGraph::SCC
&BC
= *CG
.lookupSCC(B
);
619 LazyCallGraph::SCC
&CC
= *CG
.lookupSCC(C
);
620 LazyCallGraph::SCC
&DC
= *CG
.lookupSCC(D
);
621 LazyCallGraph::RefSCC
&ARC
= *CG
.lookupRefSCC(A
);
622 LazyCallGraph::RefSCC
&BRC
= *CG
.lookupRefSCC(B
);
623 LazyCallGraph::RefSCC
&CRC
= *CG
.lookupRefSCC(C
);
624 LazyCallGraph::RefSCC
&DRC
= *CG
.lookupRefSCC(D
);
625 EXPECT_TRUE(ARC
.isParentOf(BRC
));
626 EXPECT_TRUE(AC
.isParentOf(BC
));
627 EXPECT_TRUE(ARC
.isParentOf(CRC
));
628 EXPECT_TRUE(AC
.isParentOf(CC
));
629 EXPECT_FALSE(ARC
.isParentOf(DRC
));
630 EXPECT_FALSE(AC
.isParentOf(DC
));
631 EXPECT_TRUE(ARC
.isAncestorOf(DRC
));
632 EXPECT_TRUE(AC
.isAncestorOf(DC
));
633 EXPECT_FALSE(DRC
.isChildOf(ARC
));
634 EXPECT_FALSE(DC
.isChildOf(AC
));
635 EXPECT_TRUE(DRC
.isDescendantOf(ARC
));
636 EXPECT_TRUE(DC
.isDescendantOf(AC
));
637 EXPECT_TRUE(DRC
.isChildOf(BRC
));
638 EXPECT_TRUE(DC
.isChildOf(BC
));
639 EXPECT_TRUE(DRC
.isChildOf(CRC
));
640 EXPECT_TRUE(DC
.isChildOf(CC
));
642 EXPECT_EQ(2, std::distance(A
->begin(), A
->end()));
643 ARC
.insertOutgoingEdge(A
, D
, LazyCallGraph::Edge::Call
);
644 EXPECT_EQ(3, std::distance(A
->begin(), A
->end()));
645 const LazyCallGraph::Edge
&NewE
= (*A
)[D
];
647 EXPECT_TRUE(NewE
.isCall());
648 EXPECT_EQ(&D
, &NewE
.getNode());
650 // Only the parent and child tests sholud have changed. The rest of the graph
652 EXPECT_TRUE(ARC
.isParentOf(DRC
));
653 EXPECT_TRUE(AC
.isParentOf(DC
));
654 EXPECT_TRUE(ARC
.isAncestorOf(DRC
));
655 EXPECT_TRUE(AC
.isAncestorOf(DC
));
656 EXPECT_TRUE(DRC
.isChildOf(ARC
));
657 EXPECT_TRUE(DC
.isChildOf(AC
));
658 EXPECT_TRUE(DRC
.isDescendantOf(ARC
));
659 EXPECT_TRUE(DC
.isDescendantOf(AC
));
660 EXPECT_EQ(&AC
, CG
.lookupSCC(A
));
661 EXPECT_EQ(&BC
, CG
.lookupSCC(B
));
662 EXPECT_EQ(&CC
, CG
.lookupSCC(C
));
663 EXPECT_EQ(&DC
, CG
.lookupSCC(D
));
664 EXPECT_EQ(&ARC
, CG
.lookupRefSCC(A
));
665 EXPECT_EQ(&BRC
, CG
.lookupRefSCC(B
));
666 EXPECT_EQ(&CRC
, CG
.lookupRefSCC(C
));
667 EXPECT_EQ(&DRC
, CG
.lookupRefSCC(D
));
669 ARC
.switchOutgoingEdgeToRef(A
, D
);
670 EXPECT_FALSE(NewE
.isCall());
672 // Verify the reference graph remains the same but the SCC graph is updated.
673 EXPECT_TRUE(ARC
.isParentOf(DRC
));
674 EXPECT_FALSE(AC
.isParentOf(DC
));
675 EXPECT_TRUE(ARC
.isAncestorOf(DRC
));
676 EXPECT_TRUE(AC
.isAncestorOf(DC
));
677 EXPECT_TRUE(DRC
.isChildOf(ARC
));
678 EXPECT_FALSE(DC
.isChildOf(AC
));
679 EXPECT_TRUE(DRC
.isDescendantOf(ARC
));
680 EXPECT_TRUE(DC
.isDescendantOf(AC
));
681 EXPECT_EQ(&AC
, CG
.lookupSCC(A
));
682 EXPECT_EQ(&BC
, CG
.lookupSCC(B
));
683 EXPECT_EQ(&CC
, CG
.lookupSCC(C
));
684 EXPECT_EQ(&DC
, CG
.lookupSCC(D
));
685 EXPECT_EQ(&ARC
, CG
.lookupRefSCC(A
));
686 EXPECT_EQ(&BRC
, CG
.lookupRefSCC(B
));
687 EXPECT_EQ(&CRC
, CG
.lookupRefSCC(C
));
688 EXPECT_EQ(&DRC
, CG
.lookupRefSCC(D
));
690 ARC
.switchOutgoingEdgeToCall(A
, D
);
691 EXPECT_TRUE(NewE
.isCall());
693 // Verify the reference graph remains the same but the SCC graph is updated.
694 EXPECT_TRUE(ARC
.isParentOf(DRC
));
695 EXPECT_TRUE(AC
.isParentOf(DC
));
696 EXPECT_TRUE(ARC
.isAncestorOf(DRC
));
697 EXPECT_TRUE(AC
.isAncestorOf(DC
));
698 EXPECT_TRUE(DRC
.isChildOf(ARC
));
699 EXPECT_TRUE(DC
.isChildOf(AC
));
700 EXPECT_TRUE(DRC
.isDescendantOf(ARC
));
701 EXPECT_TRUE(DC
.isDescendantOf(AC
));
702 EXPECT_EQ(&AC
, CG
.lookupSCC(A
));
703 EXPECT_EQ(&BC
, CG
.lookupSCC(B
));
704 EXPECT_EQ(&CC
, CG
.lookupSCC(C
));
705 EXPECT_EQ(&DC
, CG
.lookupSCC(D
));
706 EXPECT_EQ(&ARC
, CG
.lookupRefSCC(A
));
707 EXPECT_EQ(&BRC
, CG
.lookupRefSCC(B
));
708 EXPECT_EQ(&CRC
, CG
.lookupRefSCC(C
));
709 EXPECT_EQ(&DRC
, CG
.lookupRefSCC(D
));
711 ARC
.removeOutgoingEdge(A
, D
);
712 EXPECT_EQ(2, std::distance(A
->begin(), A
->end()));
714 // Now the parent and child tests fail again but the rest remains the same.
715 EXPECT_FALSE(ARC
.isParentOf(DRC
));
716 EXPECT_FALSE(AC
.isParentOf(DC
));
717 EXPECT_TRUE(ARC
.isAncestorOf(DRC
));
718 EXPECT_TRUE(AC
.isAncestorOf(DC
));
719 EXPECT_FALSE(DRC
.isChildOf(ARC
));
720 EXPECT_FALSE(DC
.isChildOf(AC
));
721 EXPECT_TRUE(DRC
.isDescendantOf(ARC
));
722 EXPECT_TRUE(DC
.isDescendantOf(AC
));
723 EXPECT_EQ(&AC
, CG
.lookupSCC(A
));
724 EXPECT_EQ(&BC
, CG
.lookupSCC(B
));
725 EXPECT_EQ(&CC
, CG
.lookupSCC(C
));
726 EXPECT_EQ(&DC
, CG
.lookupSCC(D
));
727 EXPECT_EQ(&ARC
, CG
.lookupRefSCC(A
));
728 EXPECT_EQ(&BRC
, CG
.lookupRefSCC(B
));
729 EXPECT_EQ(&CRC
, CG
.lookupRefSCC(C
));
730 EXPECT_EQ(&DRC
, CG
.lookupRefSCC(D
));
733 TEST(LazyCallGraphTest
, IncomingEdgeInsertion
) {
735 // We want to ensure we can add edges even across complex diamond graphs, so
736 // we use the diamond of triangles graph defined above. The ascii diagram is
737 // repeated here for easy reference.
751 std::unique_ptr
<Module
> M
= parseAssembly(Context
, DiamondOfTriangles
);
752 LazyCallGraph CG
= buildCG(*M
);
754 // Force the graph to be fully expanded.
756 for (LazyCallGraph::RefSCC
&RC
: CG
.postorder_ref_sccs())
757 dbgs() << "Formed RefSCC: " << RC
<< "\n";
759 LazyCallGraph::Node
&A1
= *CG
.lookup(lookupFunction(*M
, "a1"));
760 LazyCallGraph::Node
&A2
= *CG
.lookup(lookupFunction(*M
, "a2"));
761 LazyCallGraph::Node
&A3
= *CG
.lookup(lookupFunction(*M
, "a3"));
762 LazyCallGraph::Node
&B1
= *CG
.lookup(lookupFunction(*M
, "b1"));
763 LazyCallGraph::Node
&B2
= *CG
.lookup(lookupFunction(*M
, "b2"));
764 LazyCallGraph::Node
&B3
= *CG
.lookup(lookupFunction(*M
, "b3"));
765 LazyCallGraph::Node
&C1
= *CG
.lookup(lookupFunction(*M
, "c1"));
766 LazyCallGraph::Node
&C2
= *CG
.lookup(lookupFunction(*M
, "c2"));
767 LazyCallGraph::Node
&C3
= *CG
.lookup(lookupFunction(*M
, "c3"));
768 LazyCallGraph::Node
&D1
= *CG
.lookup(lookupFunction(*M
, "d1"));
769 LazyCallGraph::Node
&D2
= *CG
.lookup(lookupFunction(*M
, "d2"));
770 LazyCallGraph::Node
&D3
= *CG
.lookup(lookupFunction(*M
, "d3"));
771 LazyCallGraph::RefSCC
&ARC
= *CG
.lookupRefSCC(A1
);
772 LazyCallGraph::RefSCC
&BRC
= *CG
.lookupRefSCC(B1
);
773 LazyCallGraph::RefSCC
&CRC
= *CG
.lookupRefSCC(C1
);
774 LazyCallGraph::RefSCC
&DRC
= *CG
.lookupRefSCC(D1
);
775 ASSERT_EQ(&ARC
, CG
.lookupRefSCC(A2
));
776 ASSERT_EQ(&ARC
, CG
.lookupRefSCC(A3
));
777 ASSERT_EQ(&BRC
, CG
.lookupRefSCC(B2
));
778 ASSERT_EQ(&BRC
, CG
.lookupRefSCC(B3
));
779 ASSERT_EQ(&CRC
, CG
.lookupRefSCC(C2
));
780 ASSERT_EQ(&CRC
, CG
.lookupRefSCC(C3
));
781 ASSERT_EQ(&DRC
, CG
.lookupRefSCC(D2
));
782 ASSERT_EQ(&DRC
, CG
.lookupRefSCC(D3
));
783 ASSERT_EQ(1, std::distance(D2
->begin(), D2
->end()));
785 // Add an edge to make the graph:
798 auto MergedRCs
= CRC
.insertIncomingRefEdge(D2
, C2
);
799 // Make sure we connected the nodes.
800 for (LazyCallGraph::Edge E
: *D2
) {
801 if (&E
.getNode() == &D3
)
803 EXPECT_EQ(&C2
, &E
.getNode());
805 // And marked the D ref-SCC as no longer valid.
806 EXPECT_EQ(1u, MergedRCs
.size());
807 EXPECT_EQ(&DRC
, MergedRCs
[0]);
809 // Make sure we have the correct nodes in the SCC sets.
810 EXPECT_EQ(&ARC
, CG
.lookupRefSCC(A1
));
811 EXPECT_EQ(&ARC
, CG
.lookupRefSCC(A2
));
812 EXPECT_EQ(&ARC
, CG
.lookupRefSCC(A3
));
813 EXPECT_EQ(&BRC
, CG
.lookupRefSCC(B1
));
814 EXPECT_EQ(&BRC
, CG
.lookupRefSCC(B2
));
815 EXPECT_EQ(&BRC
, CG
.lookupRefSCC(B3
));
816 EXPECT_EQ(&CRC
, CG
.lookupRefSCC(C1
));
817 EXPECT_EQ(&CRC
, CG
.lookupRefSCC(C2
));
818 EXPECT_EQ(&CRC
, CG
.lookupRefSCC(C3
));
819 EXPECT_EQ(&CRC
, CG
.lookupRefSCC(D1
));
820 EXPECT_EQ(&CRC
, CG
.lookupRefSCC(D2
));
821 EXPECT_EQ(&CRC
, CG
.lookupRefSCC(D3
));
823 // And that ancestry tests have been updated.
824 EXPECT_TRUE(ARC
.isParentOf(CRC
));
825 EXPECT_TRUE(BRC
.isParentOf(CRC
));
827 // And verify the post-order walk reflects the updated structure.
828 auto I
= CG
.postorder_ref_scc_begin(), E
= CG
.postorder_ref_scc_end();
830 EXPECT_EQ(&CRC
, &*I
) << "Actual RefSCC: " << *I
;
832 EXPECT_EQ(&BRC
, &*I
) << "Actual RefSCC: " << *I
;
834 EXPECT_EQ(&ARC
, &*I
) << "Actual RefSCC: " << *I
;
838 TEST(LazyCallGraphTest
, IncomingEdgeInsertionRefGraph
) {
840 // Another variation of the above test but with all the edges switched to
841 // references rather than calls.
842 std::unique_ptr
<Module
> M
=
843 parseAssembly(Context
, DiamondOfTrianglesRefGraph
);
844 LazyCallGraph CG
= buildCG(*M
);
846 // Force the graph to be fully expanded.
848 for (LazyCallGraph::RefSCC
&RC
: CG
.postorder_ref_sccs())
849 dbgs() << "Formed RefSCC: " << RC
<< "\n";
851 LazyCallGraph::Node
&A1
= *CG
.lookup(lookupFunction(*M
, "a1"));
852 LazyCallGraph::Node
&A2
= *CG
.lookup(lookupFunction(*M
, "a2"));
853 LazyCallGraph::Node
&A3
= *CG
.lookup(lookupFunction(*M
, "a3"));
854 LazyCallGraph::Node
&B1
= *CG
.lookup(lookupFunction(*M
, "b1"));
855 LazyCallGraph::Node
&B2
= *CG
.lookup(lookupFunction(*M
, "b2"));
856 LazyCallGraph::Node
&B3
= *CG
.lookup(lookupFunction(*M
, "b3"));
857 LazyCallGraph::Node
&C1
= *CG
.lookup(lookupFunction(*M
, "c1"));
858 LazyCallGraph::Node
&C2
= *CG
.lookup(lookupFunction(*M
, "c2"));
859 LazyCallGraph::Node
&C3
= *CG
.lookup(lookupFunction(*M
, "c3"));
860 LazyCallGraph::Node
&D1
= *CG
.lookup(lookupFunction(*M
, "d1"));
861 LazyCallGraph::Node
&D2
= *CG
.lookup(lookupFunction(*M
, "d2"));
862 LazyCallGraph::Node
&D3
= *CG
.lookup(lookupFunction(*M
, "d3"));
863 LazyCallGraph::RefSCC
&ARC
= *CG
.lookupRefSCC(A1
);
864 LazyCallGraph::RefSCC
&BRC
= *CG
.lookupRefSCC(B1
);
865 LazyCallGraph::RefSCC
&CRC
= *CG
.lookupRefSCC(C1
);
866 LazyCallGraph::RefSCC
&DRC
= *CG
.lookupRefSCC(D1
);
867 ASSERT_EQ(&ARC
, CG
.lookupRefSCC(A2
));
868 ASSERT_EQ(&ARC
, CG
.lookupRefSCC(A3
));
869 ASSERT_EQ(&BRC
, CG
.lookupRefSCC(B2
));
870 ASSERT_EQ(&BRC
, CG
.lookupRefSCC(B3
));
871 ASSERT_EQ(&CRC
, CG
.lookupRefSCC(C2
));
872 ASSERT_EQ(&CRC
, CG
.lookupRefSCC(C3
));
873 ASSERT_EQ(&DRC
, CG
.lookupRefSCC(D2
));
874 ASSERT_EQ(&DRC
, CG
.lookupRefSCC(D3
));
875 ASSERT_EQ(1, std::distance(D2
->begin(), D2
->end()));
877 // Add an edge to make the graph:
890 auto MergedRCs
= CRC
.insertIncomingRefEdge(D2
, C2
);
891 // Make sure we connected the nodes.
892 for (LazyCallGraph::Edge E
: *D2
) {
893 if (&E
.getNode() == &D3
)
895 EXPECT_EQ(&C2
, &E
.getNode());
897 // And marked the D ref-SCC as no longer valid.
898 EXPECT_EQ(1u, MergedRCs
.size());
899 EXPECT_EQ(&DRC
, MergedRCs
[0]);
901 // Make sure we have the correct nodes in the SCC sets.
902 EXPECT_EQ(&ARC
, CG
.lookupRefSCC(A1
));
903 EXPECT_EQ(&ARC
, CG
.lookupRefSCC(A2
));
904 EXPECT_EQ(&ARC
, CG
.lookupRefSCC(A3
));
905 EXPECT_EQ(&BRC
, CG
.lookupRefSCC(B1
));
906 EXPECT_EQ(&BRC
, CG
.lookupRefSCC(B2
));
907 EXPECT_EQ(&BRC
, CG
.lookupRefSCC(B3
));
908 EXPECT_EQ(&CRC
, CG
.lookupRefSCC(C1
));
909 EXPECT_EQ(&CRC
, CG
.lookupRefSCC(C2
));
910 EXPECT_EQ(&CRC
, CG
.lookupRefSCC(C3
));
911 EXPECT_EQ(&CRC
, CG
.lookupRefSCC(D1
));
912 EXPECT_EQ(&CRC
, CG
.lookupRefSCC(D2
));
913 EXPECT_EQ(&CRC
, CG
.lookupRefSCC(D3
));
915 // And that ancestry tests have been updated.
916 EXPECT_TRUE(ARC
.isParentOf(CRC
));
917 EXPECT_TRUE(BRC
.isParentOf(CRC
));
919 // And verify the post-order walk reflects the updated structure.
920 auto I
= CG
.postorder_ref_scc_begin(), E
= CG
.postorder_ref_scc_end();
922 EXPECT_EQ(&CRC
, &*I
) << "Actual RefSCC: " << *I
;
924 EXPECT_EQ(&BRC
, &*I
) << "Actual RefSCC: " << *I
;
926 EXPECT_EQ(&ARC
, &*I
) << "Actual RefSCC: " << *I
;
930 TEST(LazyCallGraphTest
, IncomingEdgeInsertionLargeCallCycle
) {
932 std::unique_ptr
<Module
> M
= parseAssembly(Context
, "define void @a() {\n"
937 "define void @b() {\n"
942 "define void @c() {\n"
947 "define void @d() {\n"
951 LazyCallGraph CG
= buildCG(*M
);
953 // Force the graph to be fully expanded.
955 for (LazyCallGraph::RefSCC
&RC
: CG
.postorder_ref_sccs())
956 dbgs() << "Formed RefSCC: " << RC
<< "\n";
958 LazyCallGraph::Node
&A
= *CG
.lookup(lookupFunction(*M
, "a"));
959 LazyCallGraph::Node
&B
= *CG
.lookup(lookupFunction(*M
, "b"));
960 LazyCallGraph::Node
&C
= *CG
.lookup(lookupFunction(*M
, "c"));
961 LazyCallGraph::Node
&D
= *CG
.lookup(lookupFunction(*M
, "d"));
962 LazyCallGraph::SCC
&AC
= *CG
.lookupSCC(A
);
963 LazyCallGraph::SCC
&BC
= *CG
.lookupSCC(B
);
964 LazyCallGraph::SCC
&CC
= *CG
.lookupSCC(C
);
965 LazyCallGraph::SCC
&DC
= *CG
.lookupSCC(D
);
966 LazyCallGraph::RefSCC
&ARC
= *CG
.lookupRefSCC(A
);
967 LazyCallGraph::RefSCC
&BRC
= *CG
.lookupRefSCC(B
);
968 LazyCallGraph::RefSCC
&CRC
= *CG
.lookupRefSCC(C
);
969 LazyCallGraph::RefSCC
&DRC
= *CG
.lookupRefSCC(D
);
971 // Connect the top to the bottom forming a large RefSCC made up mostly of calls.
972 auto MergedRCs
= ARC
.insertIncomingRefEdge(D
, A
);
973 // Make sure we connected the nodes.
974 EXPECT_NE(D
->begin(), D
->end());
975 EXPECT_EQ(&A
, &D
->begin()->getNode());
977 // Check that we have the dead RCs, but ignore the order.
978 EXPECT_EQ(3u, MergedRCs
.size());
979 EXPECT_NE(find(MergedRCs
, &BRC
), MergedRCs
.end());
980 EXPECT_NE(find(MergedRCs
, &CRC
), MergedRCs
.end());
981 EXPECT_NE(find(MergedRCs
, &DRC
), MergedRCs
.end());
983 // Make sure the nodes point to the right place now.
984 EXPECT_EQ(&ARC
, CG
.lookupRefSCC(A
));
985 EXPECT_EQ(&ARC
, CG
.lookupRefSCC(B
));
986 EXPECT_EQ(&ARC
, CG
.lookupRefSCC(C
));
987 EXPECT_EQ(&ARC
, CG
.lookupRefSCC(D
));
989 // Check that the SCCs are in postorder.
990 EXPECT_EQ(4, ARC
.size());
991 EXPECT_EQ(&DC
, &ARC
[0]);
992 EXPECT_EQ(&CC
, &ARC
[1]);
993 EXPECT_EQ(&BC
, &ARC
[2]);
994 EXPECT_EQ(&AC
, &ARC
[3]);
996 // And verify the post-order walk reflects the updated structure.
997 auto I
= CG
.postorder_ref_scc_begin(), E
= CG
.postorder_ref_scc_end();
999 EXPECT_EQ(&ARC
, &*I
) << "Actual RefSCC: " << *I
;
1003 TEST(LazyCallGraphTest
, IncomingEdgeInsertionLargeRefCycle
) {
1004 LLVMContext Context
;
1005 std::unique_ptr
<Module
> M
=
1006 parseAssembly(Context
, "define void @a() {\n"
1008 " %p = alloca void ()*\n"
1009 " store void ()* @b, void ()** %p\n"
1012 "define void @b() {\n"
1014 " %p = alloca void ()*\n"
1015 " store void ()* @c, void ()** %p\n"
1018 "define void @c() {\n"
1020 " %p = alloca void ()*\n"
1021 " store void ()* @d, void ()** %p\n"
1024 "define void @d() {\n"
1028 LazyCallGraph CG
= buildCG(*M
);
1030 // Force the graph to be fully expanded.
1032 for (LazyCallGraph::RefSCC
&RC
: CG
.postorder_ref_sccs())
1033 dbgs() << "Formed RefSCC: " << RC
<< "\n";
1035 LazyCallGraph::Node
&A
= *CG
.lookup(lookupFunction(*M
, "a"));
1036 LazyCallGraph::Node
&B
= *CG
.lookup(lookupFunction(*M
, "b"));
1037 LazyCallGraph::Node
&C
= *CG
.lookup(lookupFunction(*M
, "c"));
1038 LazyCallGraph::Node
&D
= *CG
.lookup(lookupFunction(*M
, "d"));
1039 LazyCallGraph::RefSCC
&ARC
= *CG
.lookupRefSCC(A
);
1040 LazyCallGraph::RefSCC
&BRC
= *CG
.lookupRefSCC(B
);
1041 LazyCallGraph::RefSCC
&CRC
= *CG
.lookupRefSCC(C
);
1042 LazyCallGraph::RefSCC
&DRC
= *CG
.lookupRefSCC(D
);
1044 // Connect the top to the bottom forming a large RefSCC made up just of
1046 auto MergedRCs
= ARC
.insertIncomingRefEdge(D
, A
);
1047 // Make sure we connected the nodes.
1048 EXPECT_NE(D
->begin(), D
->end());
1049 EXPECT_EQ(&A
, &D
->begin()->getNode());
1051 // Check that we have the dead RCs, but ignore the order.
1052 EXPECT_EQ(3u, MergedRCs
.size());
1053 EXPECT_NE(find(MergedRCs
, &BRC
), MergedRCs
.end());
1054 EXPECT_NE(find(MergedRCs
, &CRC
), MergedRCs
.end());
1055 EXPECT_NE(find(MergedRCs
, &DRC
), MergedRCs
.end());
1057 // Make sure the nodes point to the right place now.
1058 EXPECT_EQ(&ARC
, CG
.lookupRefSCC(A
));
1059 EXPECT_EQ(&ARC
, CG
.lookupRefSCC(B
));
1060 EXPECT_EQ(&ARC
, CG
.lookupRefSCC(C
));
1061 EXPECT_EQ(&ARC
, CG
.lookupRefSCC(D
));
1063 // And verify the post-order walk reflects the updated structure.
1064 auto I
= CG
.postorder_ref_scc_begin(), End
= CG
.postorder_ref_scc_end();
1066 EXPECT_EQ(&ARC
, &*I
) << "Actual RefSCC: " << *I
;
1067 EXPECT_EQ(++I
, End
);
1070 TEST(LazyCallGraphTest
, InlineAndDeleteFunction
) {
1071 LLVMContext Context
;
1072 // We want to ensure we can delete nodes from relatively complex graphs and
1073 // so use the diamond of triangles graph defined above.
1075 // The ascii diagram is repeated here for easy reference.
1089 std::unique_ptr
<Module
> M
= parseAssembly(Context
, DiamondOfTriangles
);
1090 LazyCallGraph CG
= buildCG(*M
);
1092 // Force the graph to be fully expanded.
1094 for (LazyCallGraph::RefSCC
&RC
: CG
.postorder_ref_sccs())
1095 dbgs() << "Formed RefSCC: " << RC
<< "\n";
1097 LazyCallGraph::Node
&A1
= *CG
.lookup(lookupFunction(*M
, "a1"));
1098 LazyCallGraph::Node
&A2
= *CG
.lookup(lookupFunction(*M
, "a2"));
1099 LazyCallGraph::Node
&A3
= *CG
.lookup(lookupFunction(*M
, "a3"));
1100 LazyCallGraph::Node
&B1
= *CG
.lookup(lookupFunction(*M
, "b1"));
1101 LazyCallGraph::Node
&B2
= *CG
.lookup(lookupFunction(*M
, "b2"));
1102 LazyCallGraph::Node
&B3
= *CG
.lookup(lookupFunction(*M
, "b3"));
1103 LazyCallGraph::Node
&C1
= *CG
.lookup(lookupFunction(*M
, "c1"));
1104 LazyCallGraph::Node
&C2
= *CG
.lookup(lookupFunction(*M
, "c2"));
1105 LazyCallGraph::Node
&C3
= *CG
.lookup(lookupFunction(*M
, "c3"));
1106 LazyCallGraph::Node
&D1
= *CG
.lookup(lookupFunction(*M
, "d1"));
1107 LazyCallGraph::Node
&D2
= *CG
.lookup(lookupFunction(*M
, "d2"));
1108 LazyCallGraph::Node
&D3
= *CG
.lookup(lookupFunction(*M
, "d3"));
1109 LazyCallGraph::RefSCC
&ARC
= *CG
.lookupRefSCC(A1
);
1110 LazyCallGraph::RefSCC
&BRC
= *CG
.lookupRefSCC(B1
);
1111 LazyCallGraph::RefSCC
&CRC
= *CG
.lookupRefSCC(C1
);
1112 LazyCallGraph::RefSCC
&DRC
= *CG
.lookupRefSCC(D1
);
1113 ASSERT_EQ(&ARC
, CG
.lookupRefSCC(A2
));
1114 ASSERT_EQ(&ARC
, CG
.lookupRefSCC(A3
));
1115 ASSERT_EQ(&BRC
, CG
.lookupRefSCC(B2
));
1116 ASSERT_EQ(&BRC
, CG
.lookupRefSCC(B3
));
1117 ASSERT_EQ(&CRC
, CG
.lookupRefSCC(C2
));
1118 ASSERT_EQ(&CRC
, CG
.lookupRefSCC(C3
));
1119 ASSERT_EQ(&DRC
, CG
.lookupRefSCC(D2
));
1120 ASSERT_EQ(&DRC
, CG
.lookupRefSCC(D3
));
1121 ASSERT_EQ(1, std::distance(D2
->begin(), D2
->end()));
1123 // Delete d2 from the graph, as if it had been inlined.
1137 Function
&D2F
= D2
.getFunction();
1138 CallInst
*C1Call
= nullptr, *D1Call
= nullptr;
1139 for (User
*U
: D2F
.users()) {
1140 CallInst
*CI
= dyn_cast
<CallInst
>(U
);
1141 ASSERT_TRUE(CI
) << "Expected a call: " << *U
;
1142 if (CI
->getParent()->getParent() == &C1
.getFunction()) {
1143 ASSERT_EQ(nullptr, C1Call
) << "Found too many C1 calls: " << *CI
;
1145 } else if (CI
->getParent()->getParent() == &D1
.getFunction()) {
1146 ASSERT_EQ(nullptr, D1Call
) << "Found too many D1 calls: " << *CI
;
1149 FAIL() << "Found an unexpected call instruction: " << *CI
;
1152 ASSERT_NE(C1Call
, nullptr);
1153 ASSERT_NE(D1Call
, nullptr);
1154 ASSERT_EQ(&D2F
, C1Call
->getCalledFunction());
1155 ASSERT_EQ(&D2F
, D1Call
->getCalledFunction());
1156 C1Call
->setCalledFunction(&D3
.getFunction());
1157 D1Call
->setCalledFunction(&D3
.getFunction());
1158 ASSERT_EQ(0u, D2F
.getNumUses());
1160 // Insert new edges first.
1161 CRC
.insertTrivialCallEdge(C1
, D3
);
1162 DRC
.insertTrivialCallEdge(D1
, D3
);
1164 // Then remove the old ones.
1165 LazyCallGraph::SCC
&DC
= *CG
.lookupSCC(D2
);
1166 auto NewCs
= DRC
.switchInternalEdgeToRef(D1
, D2
);
1167 EXPECT_EQ(&DC
, CG
.lookupSCC(D2
));
1168 EXPECT_EQ(NewCs
.end(), std::next(NewCs
.begin()));
1169 LazyCallGraph::SCC
&NewDC
= *NewCs
.begin();
1170 EXPECT_EQ(&NewDC
, CG
.lookupSCC(D1
));
1171 EXPECT_EQ(&NewDC
, CG
.lookupSCC(D3
));
1172 auto NewRCs
= DRC
.removeInternalRefEdges({{&D1
, &D2
}});
1173 ASSERT_EQ(2u, NewRCs
.size());
1174 LazyCallGraph::RefSCC
&NewDRC
= *NewRCs
[0];
1175 EXPECT_EQ(&NewDRC
, CG
.lookupRefSCC(D1
));
1176 EXPECT_EQ(&NewDRC
, CG
.lookupRefSCC(D3
));
1177 LazyCallGraph::RefSCC
&D2RC
= *NewRCs
[1];
1178 EXPECT_EQ(&D2RC
, CG
.lookupRefSCC(D2
));
1179 EXPECT_FALSE(NewDRC
.isParentOf(D2RC
));
1180 EXPECT_TRUE(CRC
.isParentOf(D2RC
));
1181 EXPECT_TRUE(CRC
.isParentOf(NewDRC
));
1182 EXPECT_TRUE(D2RC
.isParentOf(NewDRC
));
1183 CRC
.removeOutgoingEdge(C1
, D2
);
1184 EXPECT_FALSE(CRC
.isParentOf(D2RC
));
1185 EXPECT_TRUE(CRC
.isParentOf(NewDRC
));
1186 EXPECT_TRUE(D2RC
.isParentOf(NewDRC
));
1188 // Now that we've updated the call graph, D2 is dead, so remove it.
1189 CG
.markDeadFunction(D2F
);
1190 CG
.removeDeadFunctions({&D2F
});
1192 // Check that the graph still looks the same.
1193 EXPECT_EQ(&ARC
, CG
.lookupRefSCC(A1
));
1194 EXPECT_EQ(&ARC
, CG
.lookupRefSCC(A2
));
1195 EXPECT_EQ(&ARC
, CG
.lookupRefSCC(A3
));
1196 EXPECT_EQ(&BRC
, CG
.lookupRefSCC(B1
));
1197 EXPECT_EQ(&BRC
, CG
.lookupRefSCC(B2
));
1198 EXPECT_EQ(&BRC
, CG
.lookupRefSCC(B3
));
1199 EXPECT_EQ(&CRC
, CG
.lookupRefSCC(C1
));
1200 EXPECT_EQ(&CRC
, CG
.lookupRefSCC(C2
));
1201 EXPECT_EQ(&CRC
, CG
.lookupRefSCC(C3
));
1202 EXPECT_EQ(&NewDRC
, CG
.lookupRefSCC(D1
));
1203 EXPECT_EQ(&NewDRC
, CG
.lookupRefSCC(D3
));
1204 EXPECT_TRUE(CRC
.isParentOf(NewDRC
));
1206 // Verify the post-order walk hasn't changed.
1207 auto I
= CG
.postorder_ref_scc_begin(), E
= CG
.postorder_ref_scc_end();
1209 EXPECT_EQ(&NewDRC
, &*I
) << "Actual RefSCC: " << *I
;
1211 EXPECT_EQ(&BRC
, &*I
) << "Actual RefSCC: " << *I
;
1213 EXPECT_EQ(&CRC
, &*I
) << "Actual RefSCC: " << *I
;
1215 EXPECT_EQ(&ARC
, &*I
) << "Actual RefSCC: " << *I
;
1219 TEST(LazyCallGraphTest
, InternalEdgeMutation
) {
1220 LLVMContext Context
;
1221 std::unique_ptr
<Module
> M
= parseAssembly(Context
, "define void @a() {\n"
1226 "define void @b() {\n"
1231 "define void @c() {\n"
1236 LazyCallGraph CG
= buildCG(*M
);
1238 // Force the graph to be fully expanded.
1240 auto I
= CG
.postorder_ref_scc_begin();
1241 LazyCallGraph::RefSCC
&RC
= *I
++;
1242 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
1244 LazyCallGraph::Node
&A
= *CG
.lookup(lookupFunction(*M
, "a"));
1245 LazyCallGraph::Node
&B
= *CG
.lookup(lookupFunction(*M
, "b"));
1246 LazyCallGraph::Node
&C
= *CG
.lookup(lookupFunction(*M
, "c"));
1247 EXPECT_EQ(&RC
, CG
.lookupRefSCC(A
));
1248 EXPECT_EQ(&RC
, CG
.lookupRefSCC(B
));
1249 EXPECT_EQ(&RC
, CG
.lookupRefSCC(C
));
1250 EXPECT_EQ(1, RC
.size());
1251 EXPECT_EQ(&*RC
.begin(), CG
.lookupSCC(A
));
1252 EXPECT_EQ(&*RC
.begin(), CG
.lookupSCC(B
));
1253 EXPECT_EQ(&*RC
.begin(), CG
.lookupSCC(C
));
1255 // Insert an edge from 'a' to 'c'. Nothing changes about the graph.
1256 RC
.insertInternalRefEdge(A
, C
);
1257 EXPECT_EQ(2, std::distance(A
->begin(), A
->end()));
1258 EXPECT_EQ(&RC
, CG
.lookupRefSCC(A
));
1259 EXPECT_EQ(&RC
, CG
.lookupRefSCC(B
));
1260 EXPECT_EQ(&RC
, CG
.lookupRefSCC(C
));
1261 EXPECT_EQ(1, RC
.size());
1262 EXPECT_EQ(&*RC
.begin(), CG
.lookupSCC(A
));
1263 EXPECT_EQ(&*RC
.begin(), CG
.lookupSCC(B
));
1264 EXPECT_EQ(&*RC
.begin(), CG
.lookupSCC(C
));
1266 // Switch the call edge from 'b' to 'c' to a ref edge. This will break the
1267 // call cycle and cause us to form more SCCs. The RefSCC will remain the same
1269 auto NewCs
= RC
.switchInternalEdgeToRef(B
, C
);
1270 EXPECT_EQ(&RC
, CG
.lookupRefSCC(A
));
1271 EXPECT_EQ(&RC
, CG
.lookupRefSCC(B
));
1272 EXPECT_EQ(&RC
, CG
.lookupRefSCC(C
));
1273 auto J
= RC
.begin();
1274 // The SCCs must be in *post-order* which means successors before
1275 // predecessors. At this point we have call edges from C to A and from A to
1276 // B. The only valid postorder is B, A, C.
1277 EXPECT_EQ(&*J
++, CG
.lookupSCC(B
));
1278 EXPECT_EQ(&*J
++, CG
.lookupSCC(A
));
1279 EXPECT_EQ(&*J
++, CG
.lookupSCC(C
));
1280 EXPECT_EQ(RC
.end(), J
);
1281 // And the returned range must be the slice of this sequence containing new
1283 EXPECT_EQ(RC
.begin(), NewCs
.begin());
1284 EXPECT_EQ(std::prev(RC
.end()), NewCs
.end());
1286 // Test turning the ref edge from A to C into a call edge. This will form an
1287 // SCC out of A and C. Since we previously had a call edge from C to A, the
1288 // C SCC should be preserved and have A merged into it while the A SCC should
1290 LazyCallGraph::SCC
&AC
= *CG
.lookupSCC(A
);
1291 LazyCallGraph::SCC
&CC
= *CG
.lookupSCC(C
);
1292 EXPECT_TRUE(RC
.switchInternalEdgeToCall(A
, C
, [&](ArrayRef
<LazyCallGraph::SCC
*> MergedCs
) {
1293 ASSERT_EQ(1u, MergedCs
.size());
1294 EXPECT_EQ(&AC
, MergedCs
[0]);
1296 EXPECT_EQ(2, CC
.size());
1297 EXPECT_EQ(&CC
, CG
.lookupSCC(A
));
1298 EXPECT_EQ(&CC
, CG
.lookupSCC(C
));
1300 EXPECT_EQ(&*J
++, CG
.lookupSCC(B
));
1301 EXPECT_EQ(&*J
++, CG
.lookupSCC(C
));
1302 EXPECT_EQ(RC
.end(), J
);
1305 TEST(LazyCallGraphTest
, InternalEdgeRemoval
) {
1306 LLVMContext Context
;
1307 // A nice fully connected (including self-edges) RefSCC.
1308 std::unique_ptr
<Module
> M
= parseAssembly(
1309 Context
, "define void @a(i8** %ptr) {\n"
1311 " store i8* bitcast (void(i8**)* @a to i8*), i8** %ptr\n"
1312 " store i8* bitcast (void(i8**)* @b to i8*), i8** %ptr\n"
1313 " store i8* bitcast (void(i8**)* @c to i8*), i8** %ptr\n"
1316 "define void @b(i8** %ptr) {\n"
1318 " store i8* bitcast (void(i8**)* @a to i8*), i8** %ptr\n"
1319 " store i8* bitcast (void(i8**)* @b to i8*), i8** %ptr\n"
1320 " store i8* bitcast (void(i8**)* @c to i8*), i8** %ptr\n"
1323 "define void @c(i8** %ptr) {\n"
1325 " store i8* bitcast (void(i8**)* @a to i8*), i8** %ptr\n"
1326 " store i8* bitcast (void(i8**)* @b to i8*), i8** %ptr\n"
1327 " store i8* bitcast (void(i8**)* @c to i8*), i8** %ptr\n"
1330 LazyCallGraph CG
= buildCG(*M
);
1332 // Force the graph to be fully expanded.
1334 auto I
= CG
.postorder_ref_scc_begin(), E
= CG
.postorder_ref_scc_end();
1335 LazyCallGraph::RefSCC
&RC
= *I
;
1336 EXPECT_EQ(E
, std::next(I
));
1338 LazyCallGraph::Node
&A
= *CG
.lookup(lookupFunction(*M
, "a"));
1339 LazyCallGraph::Node
&B
= *CG
.lookup(lookupFunction(*M
, "b"));
1340 LazyCallGraph::Node
&C
= *CG
.lookup(lookupFunction(*M
, "c"));
1341 EXPECT_EQ(&RC
, CG
.lookupRefSCC(A
));
1342 EXPECT_EQ(&RC
, CG
.lookupRefSCC(B
));
1343 EXPECT_EQ(&RC
, CG
.lookupRefSCC(C
));
1345 // Remove the edge from b -> a, which should leave the 3 functions still in
1346 // a single connected component because of a -> b -> c -> a.
1347 SmallVector
<LazyCallGraph::RefSCC
*, 1> NewRCs
=
1348 RC
.removeInternalRefEdges({{&B
, &A
}});
1349 EXPECT_EQ(0u, NewRCs
.size());
1350 EXPECT_EQ(&RC
, CG
.lookupRefSCC(A
));
1351 EXPECT_EQ(&RC
, CG
.lookupRefSCC(B
));
1352 EXPECT_EQ(&RC
, CG
.lookupRefSCC(C
));
1353 auto J
= CG
.postorder_ref_scc_begin();
1355 EXPECT_EQ(&RC
, &*J
);
1356 EXPECT_EQ(E
, std::next(J
));
1358 // Increment I before we actually mutate the structure so that it remains
1359 // a valid iterator.
1362 // Remove the edge from c -> a, which should leave 'a' in the original RefSCC
1363 // and form a new RefSCC for 'b' and 'c'.
1364 NewRCs
= RC
.removeInternalRefEdges({{&C
, &A
}});
1365 ASSERT_EQ(2u, NewRCs
.size());
1366 LazyCallGraph::RefSCC
&BCRC
= *NewRCs
[0];
1367 LazyCallGraph::RefSCC
&ARC
= *NewRCs
[1];
1368 EXPECT_EQ(&ARC
, CG
.lookupRefSCC(A
));
1369 EXPECT_EQ(1, std::distance(ARC
.begin(), ARC
.end()));
1370 EXPECT_EQ(&BCRC
, CG
.lookupRefSCC(B
));
1371 EXPECT_EQ(&BCRC
, CG
.lookupRefSCC(C
));
1372 J
= CG
.postorder_ref_scc_begin();
1374 EXPECT_EQ(&BCRC
, &*J
);
1377 EXPECT_EQ(&ARC
, &*J
);
1383 TEST(LazyCallGraphTest
, InternalMultiEdgeRemoval
) {
1384 LLVMContext Context
;
1385 // A nice fully connected (including self-edges) RefSCC.
1386 std::unique_ptr
<Module
> M
= parseAssembly(
1387 Context
, "define void @a(i8** %ptr) {\n"
1389 " store i8* bitcast (void(i8**)* @a to i8*), i8** %ptr\n"
1390 " store i8* bitcast (void(i8**)* @b to i8*), i8** %ptr\n"
1391 " store i8* bitcast (void(i8**)* @c to i8*), i8** %ptr\n"
1394 "define void @b(i8** %ptr) {\n"
1396 " store i8* bitcast (void(i8**)* @a to i8*), i8** %ptr\n"
1397 " store i8* bitcast (void(i8**)* @b to i8*), i8** %ptr\n"
1398 " store i8* bitcast (void(i8**)* @c to i8*), i8** %ptr\n"
1401 "define void @c(i8** %ptr) {\n"
1403 " store i8* bitcast (void(i8**)* @a to i8*), i8** %ptr\n"
1404 " store i8* bitcast (void(i8**)* @b to i8*), i8** %ptr\n"
1405 " store i8* bitcast (void(i8**)* @c to i8*), i8** %ptr\n"
1408 LazyCallGraph CG
= buildCG(*M
);
1410 // Force the graph to be fully expanded.
1412 auto I
= CG
.postorder_ref_scc_begin(), E
= CG
.postorder_ref_scc_end();
1413 LazyCallGraph::RefSCC
&RC
= *I
;
1414 EXPECT_EQ(E
, std::next(I
));
1416 LazyCallGraph::Node
&A
= *CG
.lookup(lookupFunction(*M
, "a"));
1417 LazyCallGraph::Node
&B
= *CG
.lookup(lookupFunction(*M
, "b"));
1418 LazyCallGraph::Node
&C
= *CG
.lookup(lookupFunction(*M
, "c"));
1419 EXPECT_EQ(&RC
, CG
.lookupRefSCC(A
));
1420 EXPECT_EQ(&RC
, CG
.lookupRefSCC(B
));
1421 EXPECT_EQ(&RC
, CG
.lookupRefSCC(C
));
1423 // Increment I before we actually mutate the structure so that it remains
1424 // a valid iterator.
1427 // Remove the edges from b -> a and b -> c, leaving b in its own RefSCC.
1428 SmallVector
<LazyCallGraph::RefSCC
*, 1> NewRCs
=
1429 RC
.removeInternalRefEdges({{&B
, &A
}, {&B
, &C
}});
1431 ASSERT_EQ(2u, NewRCs
.size());
1432 LazyCallGraph::RefSCC
&BRC
= *NewRCs
[0];
1433 LazyCallGraph::RefSCC
&ACRC
= *NewRCs
[1];
1434 EXPECT_EQ(&BRC
, CG
.lookupRefSCC(B
));
1435 EXPECT_EQ(1, std::distance(BRC
.begin(), BRC
.end()));
1436 EXPECT_EQ(&ACRC
, CG
.lookupRefSCC(A
));
1437 EXPECT_EQ(&ACRC
, CG
.lookupRefSCC(C
));
1438 auto J
= CG
.postorder_ref_scc_begin();
1440 EXPECT_EQ(&BRC
, &*J
);
1443 EXPECT_EQ(&ACRC
, &*J
);
1449 TEST(LazyCallGraphTest
, InternalNoOpEdgeRemoval
) {
1450 LLVMContext Context
;
1451 // A graph with a single cycle formed both from call and reference edges
1452 // which makes the reference edges trivial to delete. The graph looks like:
1454 // Reference edges: a -> b -> c -> a
1455 // Call edges: a -> c -> b -> a
1456 std::unique_ptr
<Module
> M
= parseAssembly(
1457 Context
, "define void @a(i8** %ptr) {\n"
1459 " call void @b(i8** %ptr)\n"
1460 " store i8* bitcast (void(i8**)* @c to i8*), i8** %ptr\n"
1463 "define void @b(i8** %ptr) {\n"
1465 " store i8* bitcast (void(i8**)* @a to i8*), i8** %ptr\n"
1466 " call void @c(i8** %ptr)\n"
1469 "define void @c(i8** %ptr) {\n"
1471 " call void @a(i8** %ptr)\n"
1472 " store i8* bitcast (void(i8**)* @b to i8*), i8** %ptr\n"
1475 LazyCallGraph CG
= buildCG(*M
);
1477 // Force the graph to be fully expanded.
1479 auto I
= CG
.postorder_ref_scc_begin(), E
= CG
.postorder_ref_scc_end();
1480 LazyCallGraph::RefSCC
&RC
= *I
;
1481 EXPECT_EQ(E
, std::next(I
));
1483 LazyCallGraph::SCC
&C
= *RC
.begin();
1484 EXPECT_EQ(RC
.end(), std::next(RC
.begin()));
1486 LazyCallGraph::Node
&AN
= *CG
.lookup(lookupFunction(*M
, "a"));
1487 LazyCallGraph::Node
&BN
= *CG
.lookup(lookupFunction(*M
, "b"));
1488 LazyCallGraph::Node
&CN
= *CG
.lookup(lookupFunction(*M
, "c"));
1489 EXPECT_EQ(&RC
, CG
.lookupRefSCC(AN
));
1490 EXPECT_EQ(&RC
, CG
.lookupRefSCC(BN
));
1491 EXPECT_EQ(&RC
, CG
.lookupRefSCC(CN
));
1492 EXPECT_EQ(&C
, CG
.lookupSCC(AN
));
1493 EXPECT_EQ(&C
, CG
.lookupSCC(BN
));
1494 EXPECT_EQ(&C
, CG
.lookupSCC(CN
));
1496 // Remove the edge from a -> c which doesn't change anything.
1497 SmallVector
<LazyCallGraph::RefSCC
*, 1> NewRCs
=
1498 RC
.removeInternalRefEdges({{&AN
, &CN
}});
1499 EXPECT_EQ(0u, NewRCs
.size());
1500 EXPECT_EQ(&RC
, CG
.lookupRefSCC(AN
));
1501 EXPECT_EQ(&RC
, CG
.lookupRefSCC(BN
));
1502 EXPECT_EQ(&RC
, CG
.lookupRefSCC(CN
));
1503 EXPECT_EQ(&C
, CG
.lookupSCC(AN
));
1504 EXPECT_EQ(&C
, CG
.lookupSCC(BN
));
1505 EXPECT_EQ(&C
, CG
.lookupSCC(CN
));
1506 auto J
= CG
.postorder_ref_scc_begin();
1508 EXPECT_EQ(&RC
, &*J
);
1509 EXPECT_EQ(E
, std::next(J
));
1511 // Remove the edge from b -> a and c -> b; again this doesn't change
1513 NewRCs
= RC
.removeInternalRefEdges({{&BN
, &AN
}});
1514 NewRCs
= RC
.removeInternalRefEdges({{&CN
, &BN
}});
1515 EXPECT_EQ(0u, NewRCs
.size());
1516 EXPECT_EQ(&RC
, CG
.lookupRefSCC(AN
));
1517 EXPECT_EQ(&RC
, CG
.lookupRefSCC(BN
));
1518 EXPECT_EQ(&RC
, CG
.lookupRefSCC(CN
));
1519 EXPECT_EQ(&C
, CG
.lookupSCC(AN
));
1520 EXPECT_EQ(&C
, CG
.lookupSCC(BN
));
1521 EXPECT_EQ(&C
, CG
.lookupSCC(CN
));
1522 J
= CG
.postorder_ref_scc_begin();
1524 EXPECT_EQ(&RC
, &*J
);
1525 EXPECT_EQ(E
, std::next(J
));
1528 TEST(LazyCallGraphTest
, InternalCallEdgeToRef
) {
1529 LLVMContext Context
;
1530 // A nice fully connected (including self-edges) SCC (and RefSCC)
1531 std::unique_ptr
<Module
> M
= parseAssembly(Context
, "define void @a() {\n"
1538 "define void @b() {\n"
1545 "define void @c() {\n"
1552 LazyCallGraph CG
= buildCG(*M
);
1554 // Force the graph to be fully expanded.
1556 auto I
= CG
.postorder_ref_scc_begin();
1557 LazyCallGraph::RefSCC
&RC
= *I
++;
1558 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
1560 EXPECT_EQ(1, RC
.size());
1561 LazyCallGraph::SCC
&AC
= *RC
.begin();
1563 LazyCallGraph::Node
&AN
= *CG
.lookup(lookupFunction(*M
, "a"));
1564 LazyCallGraph::Node
&BN
= *CG
.lookup(lookupFunction(*M
, "b"));
1565 LazyCallGraph::Node
&CN
= *CG
.lookup(lookupFunction(*M
, "c"));
1566 EXPECT_EQ(&AC
, CG
.lookupSCC(AN
));
1567 EXPECT_EQ(&AC
, CG
.lookupSCC(BN
));
1568 EXPECT_EQ(&AC
, CG
.lookupSCC(CN
));
1570 // Remove the call edge from b -> a to a ref edge, which should leave the
1571 // 3 functions still in a single connected component because of a -> b ->
1573 auto NewCs
= RC
.switchInternalEdgeToRef(BN
, AN
);
1574 EXPECT_EQ(NewCs
.begin(), NewCs
.end());
1575 EXPECT_EQ(1, RC
.size());
1576 EXPECT_EQ(&AC
, CG
.lookupSCC(AN
));
1577 EXPECT_EQ(&AC
, CG
.lookupSCC(BN
));
1578 EXPECT_EQ(&AC
, CG
.lookupSCC(CN
));
1580 // Remove the edge from c -> a, which should leave 'a' in the original SCC
1581 // and form a new SCC for 'b' and 'c'.
1582 NewCs
= RC
.switchInternalEdgeToRef(CN
, AN
);
1583 EXPECT_EQ(1, std::distance(NewCs
.begin(), NewCs
.end()));
1584 EXPECT_EQ(2, RC
.size());
1585 EXPECT_EQ(&AC
, CG
.lookupSCC(AN
));
1586 LazyCallGraph::SCC
&BC
= *CG
.lookupSCC(BN
);
1587 EXPECT_NE(&BC
, &AC
);
1588 EXPECT_EQ(&BC
, CG
.lookupSCC(CN
));
1589 auto J
= RC
.find(AC
);
1590 EXPECT_EQ(&AC
, &*J
);
1592 EXPECT_EQ(&BC
, &*J
);
1593 EXPECT_EQ(RC
.begin(), J
);
1594 EXPECT_EQ(J
, NewCs
.begin());
1596 // Remove the edge from c -> b, which should leave 'b' in the original SCC
1597 // and form a new SCC for 'c'. It shouldn't change 'a's SCC.
1598 NewCs
= RC
.switchInternalEdgeToRef(CN
, BN
);
1599 EXPECT_EQ(1, std::distance(NewCs
.begin(), NewCs
.end()));
1600 EXPECT_EQ(3, RC
.size());
1601 EXPECT_EQ(&AC
, CG
.lookupSCC(AN
));
1602 EXPECT_EQ(&BC
, CG
.lookupSCC(BN
));
1603 LazyCallGraph::SCC
&CC
= *CG
.lookupSCC(CN
);
1604 EXPECT_NE(&CC
, &AC
);
1605 EXPECT_NE(&CC
, &BC
);
1607 EXPECT_EQ(&AC
, &*J
);
1609 EXPECT_EQ(&BC
, &*J
);
1611 EXPECT_EQ(&CC
, &*J
);
1612 EXPECT_EQ(RC
.begin(), J
);
1613 EXPECT_EQ(J
, NewCs
.begin());
1616 TEST(LazyCallGraphTest
, InternalRefEdgeToCall
) {
1617 LLVMContext Context
;
1618 // Basic tests for making a ref edge a call. This hits the basics of the
1620 std::unique_ptr
<Module
> M
=
1621 parseAssembly(Context
, "define void @a() {\n"
1625 " store void()* @d, void()** undef\n"
1628 "define void @b() {\n"
1630 " store void()* @c, void()** undef\n"
1634 "define void @c() {\n"
1636 " store void()* @b, void()** undef\n"
1640 "define void @d() {\n"
1642 " store void()* @a, void()** undef\n"
1645 LazyCallGraph CG
= buildCG(*M
);
1647 // Force the graph to be fully expanded.
1649 auto I
= CG
.postorder_ref_scc_begin();
1650 LazyCallGraph::RefSCC
&RC
= *I
++;
1651 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
1653 LazyCallGraph::Node
&A
= *CG
.lookup(lookupFunction(*M
, "a"));
1654 LazyCallGraph::Node
&B
= *CG
.lookup(lookupFunction(*M
, "b"));
1655 LazyCallGraph::Node
&C
= *CG
.lookup(lookupFunction(*M
, "c"));
1656 LazyCallGraph::Node
&D
= *CG
.lookup(lookupFunction(*M
, "d"));
1657 LazyCallGraph::SCC
&AC
= *CG
.lookupSCC(A
);
1658 LazyCallGraph::SCC
&BC
= *CG
.lookupSCC(B
);
1659 LazyCallGraph::SCC
&CC
= *CG
.lookupSCC(C
);
1660 LazyCallGraph::SCC
&DC
= *CG
.lookupSCC(D
);
1662 // Check the initial post-order. Note that B and C could be flipped here (and
1663 // in our mutation) without changing the nature of this test.
1664 ASSERT_EQ(4, RC
.size());
1665 EXPECT_EQ(&DC
, &RC
[0]);
1666 EXPECT_EQ(&BC
, &RC
[1]);
1667 EXPECT_EQ(&CC
, &RC
[2]);
1668 EXPECT_EQ(&AC
, &RC
[3]);
1670 // Switch the ref edge from A -> D to a call edge. This should have no
1671 // effect as it is already in postorder and no new cycles are formed.
1672 EXPECT_FALSE(RC
.switchInternalEdgeToCall(A
, D
));
1673 ASSERT_EQ(4, RC
.size());
1674 EXPECT_EQ(&DC
, &RC
[0]);
1675 EXPECT_EQ(&BC
, &RC
[1]);
1676 EXPECT_EQ(&CC
, &RC
[2]);
1677 EXPECT_EQ(&AC
, &RC
[3]);
1679 // Switch B -> C to a call edge. This doesn't form any new cycles but does
1680 // require reordering the SCCs.
1681 EXPECT_FALSE(RC
.switchInternalEdgeToCall(B
, C
));
1682 ASSERT_EQ(4, RC
.size());
1683 EXPECT_EQ(&DC
, &RC
[0]);
1684 EXPECT_EQ(&CC
, &RC
[1]);
1685 EXPECT_EQ(&BC
, &RC
[2]);
1686 EXPECT_EQ(&AC
, &RC
[3]);
1688 // Switch C -> B to a call edge. This forms a cycle and forces merging SCCs.
1689 EXPECT_TRUE(RC
.switchInternalEdgeToCall(C
, B
, [&](ArrayRef
<LazyCallGraph::SCC
*> MergedCs
) {
1690 ASSERT_EQ(1u, MergedCs
.size());
1691 EXPECT_EQ(&CC
, MergedCs
[0]);
1693 ASSERT_EQ(3, RC
.size());
1694 EXPECT_EQ(&DC
, &RC
[0]);
1695 EXPECT_EQ(&BC
, &RC
[1]);
1696 EXPECT_EQ(&AC
, &RC
[2]);
1697 EXPECT_EQ(2, BC
.size());
1698 EXPECT_EQ(&BC
, CG
.lookupSCC(B
));
1699 EXPECT_EQ(&BC
, CG
.lookupSCC(C
));
1702 TEST(LazyCallGraphTest
, InternalRefEdgeToCallNoCycleInterleaved
) {
1703 LLVMContext Context
;
1704 // Test for having a post-order prior to changing a ref edge to a call edge
1705 // with SCCs connecting to the source and connecting to the target, but not
1706 // connecting to both, interleaved between the source and target. This
1707 // ensures we correctly partition the range rather than simply moving one or
1709 std::unique_ptr
<Module
> M
=
1710 parseAssembly(Context
, "define void @a() {\n"
1712 " call void @b1()\n"
1713 " call void @c1()\n"
1716 "define void @b1() {\n"
1718 " call void @c1()\n"
1719 " call void @b2()\n"
1722 "define void @c1() {\n"
1724 " call void @b2()\n"
1725 " call void @c2()\n"
1728 "define void @b2() {\n"
1730 " call void @c2()\n"
1731 " call void @b3()\n"
1734 "define void @c2() {\n"
1736 " call void @b3()\n"
1737 " call void @c3()\n"
1740 "define void @b3() {\n"
1742 " call void @c3()\n"
1746 "define void @c3() {\n"
1748 " store void()* @b1, void()** undef\n"
1752 "define void @d() {\n"
1754 " store void()* @a, void()** undef\n"
1757 LazyCallGraph CG
= buildCG(*M
);
1759 // Force the graph to be fully expanded.
1761 auto I
= CG
.postorder_ref_scc_begin();
1762 LazyCallGraph::RefSCC
&RC
= *I
++;
1763 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
1765 LazyCallGraph::Node
&A
= *CG
.lookup(lookupFunction(*M
, "a"));
1766 LazyCallGraph::Node
&B1
= *CG
.lookup(lookupFunction(*M
, "b1"));
1767 LazyCallGraph::Node
&B2
= *CG
.lookup(lookupFunction(*M
, "b2"));
1768 LazyCallGraph::Node
&B3
= *CG
.lookup(lookupFunction(*M
, "b3"));
1769 LazyCallGraph::Node
&C1
= *CG
.lookup(lookupFunction(*M
, "c1"));
1770 LazyCallGraph::Node
&C2
= *CG
.lookup(lookupFunction(*M
, "c2"));
1771 LazyCallGraph::Node
&C3
= *CG
.lookup(lookupFunction(*M
, "c3"));
1772 LazyCallGraph::Node
&D
= *CG
.lookup(lookupFunction(*M
, "d"));
1773 LazyCallGraph::SCC
&AC
= *CG
.lookupSCC(A
);
1774 LazyCallGraph::SCC
&B1C
= *CG
.lookupSCC(B1
);
1775 LazyCallGraph::SCC
&B2C
= *CG
.lookupSCC(B2
);
1776 LazyCallGraph::SCC
&B3C
= *CG
.lookupSCC(B3
);
1777 LazyCallGraph::SCC
&C1C
= *CG
.lookupSCC(C1
);
1778 LazyCallGraph::SCC
&C2C
= *CG
.lookupSCC(C2
);
1779 LazyCallGraph::SCC
&C3C
= *CG
.lookupSCC(C3
);
1780 LazyCallGraph::SCC
&DC
= *CG
.lookupSCC(D
);
1782 // Several call edges are initially present to force a particual post-order.
1783 // Remove them now, leaving an interleaved post-order pattern.
1784 RC
.switchTrivialInternalEdgeToRef(B3
, C3
);
1785 RC
.switchTrivialInternalEdgeToRef(C2
, B3
);
1786 RC
.switchTrivialInternalEdgeToRef(B2
, C2
);
1787 RC
.switchTrivialInternalEdgeToRef(C1
, B2
);
1788 RC
.switchTrivialInternalEdgeToRef(B1
, C1
);
1790 // Check the initial post-order. We ensure this order with the extra edges
1791 // that are nuked above.
1792 ASSERT_EQ(8, RC
.size());
1793 EXPECT_EQ(&DC
, &RC
[0]);
1794 EXPECT_EQ(&C3C
, &RC
[1]);
1795 EXPECT_EQ(&B3C
, &RC
[2]);
1796 EXPECT_EQ(&C2C
, &RC
[3]);
1797 EXPECT_EQ(&B2C
, &RC
[4]);
1798 EXPECT_EQ(&C1C
, &RC
[5]);
1799 EXPECT_EQ(&B1C
, &RC
[6]);
1800 EXPECT_EQ(&AC
, &RC
[7]);
1802 // Switch C3 -> B1 to a call edge. This doesn't form any new cycles but does
1803 // require reordering the SCCs in the face of tricky internal node
1805 EXPECT_FALSE(RC
.switchInternalEdgeToCall(C3
, B1
));
1806 ASSERT_EQ(8, RC
.size());
1807 EXPECT_EQ(&DC
, &RC
[0]);
1808 EXPECT_EQ(&B3C
, &RC
[1]);
1809 EXPECT_EQ(&B2C
, &RC
[2]);
1810 EXPECT_EQ(&B1C
, &RC
[3]);
1811 EXPECT_EQ(&C3C
, &RC
[4]);
1812 EXPECT_EQ(&C2C
, &RC
[5]);
1813 EXPECT_EQ(&C1C
, &RC
[6]);
1814 EXPECT_EQ(&AC
, &RC
[7]);
1817 TEST(LazyCallGraphTest
, InternalRefEdgeToCallBothPartitionAndMerge
) {
1818 LLVMContext Context
;
1819 // Test for having a postorder where between the source and target are all
1820 // three kinds of other SCCs:
1821 // 1) One connected to the target only that have to be shifted below the
1823 // 2) One connected to the source only that have to be shifted below the
1825 // 3) One connected to both source and target that has to remain and get
1828 // To achieve this we construct a heavily connected graph to force
1829 // a particular post-order. Then we remove the forcing edges and connect
1832 // Diagram for the graph we want on the left and the graph we use to force
1833 // the ordering on the right. Edges point down or right.
1845 // And we form a cycle by connecting F to B.
1846 std::unique_ptr
<Module
> M
=
1847 parseAssembly(Context
, "define void @a() {\n"
1853 "define void @b() {\n"
1859 "define void @c() {\n"
1865 "define void @d() {\n"
1871 "define void @e() {\n"
1876 "define void @f() {\n"
1878 " store void()* @b, void()** undef\n"
1882 "define void @g() {\n"
1884 " store void()* @a, void()** undef\n"
1887 LazyCallGraph CG
= buildCG(*M
);
1889 // Force the graph to be fully expanded.
1891 auto I
= CG
.postorder_ref_scc_begin();
1892 LazyCallGraph::RefSCC
&RC
= *I
++;
1893 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
1895 LazyCallGraph::Node
&A
= *CG
.lookup(lookupFunction(*M
, "a"));
1896 LazyCallGraph::Node
&B
= *CG
.lookup(lookupFunction(*M
, "b"));
1897 LazyCallGraph::Node
&C
= *CG
.lookup(lookupFunction(*M
, "c"));
1898 LazyCallGraph::Node
&D
= *CG
.lookup(lookupFunction(*M
, "d"));
1899 LazyCallGraph::Node
&E
= *CG
.lookup(lookupFunction(*M
, "e"));
1900 LazyCallGraph::Node
&F
= *CG
.lookup(lookupFunction(*M
, "f"));
1901 LazyCallGraph::Node
&G
= *CG
.lookup(lookupFunction(*M
, "g"));
1902 LazyCallGraph::SCC
&AC
= *CG
.lookupSCC(A
);
1903 LazyCallGraph::SCC
&BC
= *CG
.lookupSCC(B
);
1904 LazyCallGraph::SCC
&CC
= *CG
.lookupSCC(C
);
1905 LazyCallGraph::SCC
&DC
= *CG
.lookupSCC(D
);
1906 LazyCallGraph::SCC
&EC
= *CG
.lookupSCC(E
);
1907 LazyCallGraph::SCC
&FC
= *CG
.lookupSCC(F
);
1908 LazyCallGraph::SCC
&GC
= *CG
.lookupSCC(G
);
1910 // Remove the extra edges that were used to force a particular post-order.
1911 RC
.switchTrivialInternalEdgeToRef(C
, D
);
1912 RC
.switchTrivialInternalEdgeToRef(D
, E
);
1914 // Check the initial post-order. We ensure this order with the extra edges
1915 // that are nuked above.
1916 ASSERT_EQ(7, RC
.size());
1917 EXPECT_EQ(&GC
, &RC
[0]);
1918 EXPECT_EQ(&FC
, &RC
[1]);
1919 EXPECT_EQ(&EC
, &RC
[2]);
1920 EXPECT_EQ(&DC
, &RC
[3]);
1921 EXPECT_EQ(&CC
, &RC
[4]);
1922 EXPECT_EQ(&BC
, &RC
[5]);
1923 EXPECT_EQ(&AC
, &RC
[6]);
1925 // Switch F -> B to a call edge. This merges B, D, and F into a single SCC,
1926 // and has to place the C and E SCCs on either side of it:
1936 EXPECT_TRUE(RC
.switchInternalEdgeToCall(
1937 F
, B
, [&](ArrayRef
<LazyCallGraph::SCC
*> MergedCs
) {
1938 ASSERT_EQ(2u, MergedCs
.size());
1939 EXPECT_EQ(&FC
, MergedCs
[0]);
1940 EXPECT_EQ(&DC
, MergedCs
[1]);
1942 EXPECT_EQ(3, BC
.size());
1944 // And make sure the postorder was updated.
1945 ASSERT_EQ(5, RC
.size());
1946 EXPECT_EQ(&GC
, &RC
[0]);
1947 EXPECT_EQ(&CC
, &RC
[1]);
1948 EXPECT_EQ(&BC
, &RC
[2]);
1949 EXPECT_EQ(&EC
, &RC
[3]);
1950 EXPECT_EQ(&AC
, &RC
[4]);
1953 // Test for IR containing constants using blockaddress constant expressions.
1954 // These are truly unique constructs: constant expressions with non-constant
1956 TEST(LazyCallGraphTest
, HandleBlockAddress
) {
1957 LLVMContext Context
;
1958 std::unique_ptr
<Module
> M
=
1959 parseAssembly(Context
, "define void @f() {\n"
1965 "define void @g(i8** %ptr) {\n"
1967 " store i8* blockaddress(@f, %bb), i8** %ptr\n"
1970 LazyCallGraph CG
= buildCG(*M
);
1973 auto I
= CG
.postorder_ref_scc_begin();
1974 LazyCallGraph::RefSCC
&FRC
= *I
++;
1975 LazyCallGraph::RefSCC
&GRC
= *I
++;
1976 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
1978 LazyCallGraph::Node
&F
= *CG
.lookup(lookupFunction(*M
, "f"));
1979 LazyCallGraph::Node
&G
= *CG
.lookup(lookupFunction(*M
, "g"));
1980 EXPECT_EQ(&FRC
, CG
.lookupRefSCC(F
));
1981 EXPECT_EQ(&GRC
, CG
.lookupRefSCC(G
));
1982 EXPECT_FALSE(GRC
.isParentOf(FRC
));
1983 EXPECT_FALSE(FRC
.isParentOf(GRC
));
1986 // Test that a blockaddress that refers to itself creates no new RefSCC
1987 // connections. https://bugs.llvm.org/show_bug.cgi?id=40722
1988 TEST(LazyCallGraphTest
, HandleBlockAddress2
) {
1989 LLVMContext Context
;
1990 std::unique_ptr
<Module
> M
=
1991 parseAssembly(Context
, "define void @f() {\n"
1994 "define void @g(i8** %ptr) {\n"
1996 " store i8* blockaddress(@g, %bb), i8** %ptr\n"
1999 LazyCallGraph CG
= buildCG(*M
);
2002 auto I
= CG
.postorder_ref_scc_begin();
2003 LazyCallGraph::RefSCC
&FRC
= *I
++;
2004 LazyCallGraph::RefSCC
&GRC
= *I
++;
2005 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2007 LazyCallGraph::Node
&F
= *CG
.lookup(lookupFunction(*M
, "f"));
2008 LazyCallGraph::Node
&G
= *CG
.lookup(lookupFunction(*M
, "g"));
2009 EXPECT_EQ(&FRC
, CG
.lookupRefSCC(F
));
2010 EXPECT_EQ(&GRC
, CG
.lookupRefSCC(G
));
2011 EXPECT_FALSE(GRC
.isParentOf(FRC
));
2012 EXPECT_FALSE(FRC
.isParentOf(GRC
));
2015 TEST(LazyCallGraphTest
, ReplaceNodeFunction
) {
2016 LLVMContext Context
;
2017 // A graph with several different kinds of edges pointing at a particular
2019 std::unique_ptr
<Module
> M
=
2020 parseAssembly(Context
,
2021 "define void @a(i8** %ptr) {\n"
2023 " store i8* bitcast (void(i8**)* @d to i8*), i8** %ptr\n"
2026 "define void @b(i8** %ptr) {\n"
2028 " store i8* bitcast (void(i8**)* @d to i8*), i8** %ptr\n"
2029 " store i8* bitcast (void(i8**)* @d to i8*), i8** %ptr\n"
2030 " call void @d(i8** %ptr)"
2033 "define void @c(i8** %ptr) {\n"
2035 " call void @d(i8** %ptr)"
2036 " call void @d(i8** %ptr)"
2037 " store i8* bitcast (void(i8**)* @d to i8*), i8** %ptr\n"
2040 "define void @d(i8** %ptr) {\n"
2042 " store i8* bitcast (void(i8**)* @b to i8*), i8** %ptr\n"
2043 " call void @c(i8** %ptr)"
2044 " call void @d(i8** %ptr)"
2045 " store i8* bitcast (void(i8**)* @d to i8*), i8** %ptr\n"
2048 LazyCallGraph CG
= buildCG(*M
);
2050 // Force the graph to be fully expanded.
2052 auto I
= CG
.postorder_ref_scc_begin();
2053 LazyCallGraph::RefSCC
&RC1
= *I
++;
2054 LazyCallGraph::RefSCC
&RC2
= *I
++;
2055 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2057 ASSERT_EQ(2, RC1
.size());
2058 LazyCallGraph::SCC
&C1
= RC1
[0];
2059 LazyCallGraph::SCC
&C2
= RC1
[1];
2061 LazyCallGraph::Node
&AN
= *CG
.lookup(lookupFunction(*M
, "a"));
2062 LazyCallGraph::Node
&BN
= *CG
.lookup(lookupFunction(*M
, "b"));
2063 LazyCallGraph::Node
&CN
= *CG
.lookup(lookupFunction(*M
, "c"));
2064 LazyCallGraph::Node
&DN
= *CG
.lookup(lookupFunction(*M
, "d"));
2065 EXPECT_EQ(&C1
, CG
.lookupSCC(DN
));
2066 EXPECT_EQ(&C1
, CG
.lookupSCC(CN
));
2067 EXPECT_EQ(&C2
, CG
.lookupSCC(BN
));
2068 EXPECT_EQ(&RC1
, CG
.lookupRefSCC(DN
));
2069 EXPECT_EQ(&RC1
, CG
.lookupRefSCC(CN
));
2070 EXPECT_EQ(&RC1
, CG
.lookupRefSCC(BN
));
2071 EXPECT_EQ(&RC2
, CG
.lookupRefSCC(AN
));
2073 // Now we need to build a new function 'e' with the same signature as 'd'.
2074 Function
&D
= DN
.getFunction();
2075 Function
&E
= *Function::Create(D
.getFunctionType(), D
.getLinkage(), "e");
2076 D
.getParent()->getFunctionList().insert(D
.getIterator(), &E
);
2078 // Change each use of 'd' to use 'e'. This is particularly easy as they have
2080 D
.replaceAllUsesWith(&E
);
2082 // Splice the body of the old function into the new one.
2083 E
.splice(E
.begin(), &D
);
2084 // And fix up the one argument.
2085 D
.arg_begin()->replaceAllUsesWith(&*E
.arg_begin());
2086 E
.arg_begin()->takeName(&*D
.arg_begin());
2088 // Now replace the function in the graph.
2089 RC1
.replaceNodeFunction(DN
, E
);
2091 EXPECT_EQ(&E
, &DN
.getFunction());
2092 EXPECT_EQ(&DN
, &(*CN
)[DN
].getNode());
2093 EXPECT_EQ(&DN
, &(*BN
)[DN
].getNode());
2096 TEST(LazyCallGraphTest
, RemoveFunctionWithSpuriousRef
) {
2097 LLVMContext Context
;
2098 // A graph with a couple of RefSCCs.
2099 std::unique_ptr
<Module
> M
=
2100 parseAssembly(Context
,
2101 "define void @a(i8** %ptr) {\n"
2103 " store i8* bitcast (void(i8**)* @d to i8*), i8** %ptr\n"
2106 "define void @b(i8** %ptr) {\n"
2108 " store i8* bitcast (void(i8**)* @c to i8*), i8** %ptr\n"
2111 "define void @c(i8** %ptr) {\n"
2113 " call void @d(i8** %ptr)"
2116 "define void @d(i8** %ptr) {\n"
2118 " call void @c(i8** %ptr)"
2119 " store i8* bitcast (void(i8**)* @b to i8*), i8** %ptr\n"
2122 "define void @dead() {\n"
2126 LazyCallGraph CG
= buildCG(*M
);
2128 // Insert spurious ref edges.
2129 LazyCallGraph::Node
&AN
= CG
.get(lookupFunction(*M
, "a"));
2130 LazyCallGraph::Node
&BN
= CG
.get(lookupFunction(*M
, "b"));
2131 LazyCallGraph::Node
&CN
= CG
.get(lookupFunction(*M
, "c"));
2132 LazyCallGraph::Node
&DN
= CG
.get(lookupFunction(*M
, "d"));
2133 LazyCallGraph::Node
&DeadN
= CG
.get(lookupFunction(*M
, "dead"));
2139 CG
.insertEdge(AN
, DeadN
, LazyCallGraph::Edge::Ref
);
2140 CG
.insertEdge(BN
, DeadN
, LazyCallGraph::Edge::Ref
);
2141 CG
.insertEdge(CN
, DeadN
, LazyCallGraph::Edge::Ref
);
2142 CG
.insertEdge(DN
, DeadN
, LazyCallGraph::Edge::Ref
);
2144 // Force the graph to be fully expanded.
2146 auto I
= CG
.postorder_ref_scc_begin();
2147 LazyCallGraph::RefSCC
&DeadRC
= *I
++;
2148 LazyCallGraph::RefSCC
&RC1
= *I
++;
2149 LazyCallGraph::RefSCC
&RC2
= *I
++;
2150 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2152 ASSERT_EQ(2, RC1
.size());
2153 LazyCallGraph::SCC
&C1
= RC1
[0];
2154 LazyCallGraph::SCC
&C2
= RC1
[1];
2156 EXPECT_EQ(&DeadRC
, CG
.lookupRefSCC(DeadN
));
2157 EXPECT_EQ(&C1
, CG
.lookupSCC(DN
));
2158 EXPECT_EQ(&C1
, CG
.lookupSCC(CN
));
2159 EXPECT_EQ(&C2
, CG
.lookupSCC(BN
));
2160 EXPECT_EQ(&RC1
, CG
.lookupRefSCC(DN
));
2161 EXPECT_EQ(&RC1
, CG
.lookupRefSCC(CN
));
2162 EXPECT_EQ(&RC1
, CG
.lookupRefSCC(BN
));
2163 EXPECT_EQ(&RC2
, CG
.lookupRefSCC(AN
));
2165 // Now delete 'dead'. There are no uses of this function but there are
2166 // spurious references.
2167 CG
.markDeadFunction(DeadN
.getFunction());
2168 CG
.removeDeadFunctions({&DeadN
.getFunction()});
2170 // The only observable change should be that the RefSCC is gone from the
2171 // postorder sequence.
2172 I
= CG
.postorder_ref_scc_begin();
2173 EXPECT_EQ(&RC1
, &*I
++);
2174 EXPECT_EQ(&RC2
, &*I
++);
2175 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2178 TEST(LazyCallGraphTest
, RemoveFunctionWithSpuriousRefRecursive
) {
2179 LLVMContext Context
;
2180 std::unique_ptr
<Module
> M
=
2181 parseAssembly(Context
, "define void @a(ptr %p) {\n"
2182 " store ptr @b, ptr %p\n"
2185 "define void @b(ptr %p) {\n"
2186 " store ptr @c, ptr %p\n"
2189 "define void @c(ptr %p) {\n"
2192 LazyCallGraph CG
= buildCG(*M
);
2194 LazyCallGraph::Node
&AN
= CG
.get(lookupFunction(*M
, "a"));
2195 LazyCallGraph::Node
&BN
= CG
.get(lookupFunction(*M
, "b"));
2196 LazyCallGraph::Node
&CN
= CG
.get(lookupFunction(*M
, "c"));
2200 // Insert spurious ref edge.
2201 CG
.insertEdge(CN
, AN
, LazyCallGraph::Edge::Ref
);
2203 // Force the graph to be fully expanded.
2205 auto I
= CG
.postorder_ref_scc_begin();
2206 LazyCallGraph::RefSCC
&RC
= *I
++;
2207 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2209 ASSERT_EQ(RC
.size(), 3);
2211 EXPECT_EQ(&RC
, CG
.lookupRefSCC(AN
));
2212 EXPECT_EQ(&RC
, CG
.lookupRefSCC(BN
));
2213 EXPECT_EQ(&RC
, CG
.lookupRefSCC(CN
));
2215 // Now delete 'a'. There are no uses of this function but there are
2216 // spurious references.
2217 CG
.markDeadFunction(AN
.getFunction());
2218 CG
.removeDeadFunctions({&AN
.getFunction()});
2220 // The only observable change should be that the RefSCC is gone from the
2221 // postorder sequence.
2222 I
= CG
.postorder_ref_scc_begin();
2223 EXPECT_EQ(CG
.lookupRefSCC(CN
), &*I
++);
2224 EXPECT_EQ(CG
.lookupRefSCC(BN
), &*I
++);
2225 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2228 TEST(LazyCallGraphTest
, RemoveFunctionWithSpuriousRefRecursive2
) {
2229 LLVMContext Context
;
2230 std::unique_ptr
<Module
> M
=
2231 parseAssembly(Context
, "define void @a(ptr %p) {\n"
2232 " store ptr @b, ptr %p\n"
2235 "define void @b(ptr %p) {\n"
2236 " store ptr @c, ptr %p\n"
2239 "define void @c(ptr %p) {\n"
2240 " store ptr @b, ptr %p\n"
2241 " store ptr @d, ptr %p\n"
2244 "define void @d(ptr %p) {\n"
2247 LazyCallGraph CG
= buildCG(*M
);
2249 LazyCallGraph::Node
&AN
= CG
.get(lookupFunction(*M
, "a"));
2250 LazyCallGraph::Node
&BN
= CG
.get(lookupFunction(*M
, "b"));
2251 LazyCallGraph::Node
&CN
= CG
.get(lookupFunction(*M
, "c"));
2252 LazyCallGraph::Node
&DN
= CG
.get(lookupFunction(*M
, "d"));
2257 // Insert spurious ref edge.
2258 CG
.insertEdge(DN
, AN
, LazyCallGraph::Edge::Ref
);
2260 // Force the graph to be fully expanded.
2262 auto I
= CG
.postorder_ref_scc_begin();
2263 LazyCallGraph::RefSCC
&RC
= *I
++;
2264 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2266 ASSERT_EQ(4, RC
.size());
2268 EXPECT_EQ(&RC
, CG
.lookupRefSCC(AN
));
2269 EXPECT_EQ(&RC
, CG
.lookupRefSCC(BN
));
2270 EXPECT_EQ(&RC
, CG
.lookupRefSCC(CN
));
2271 EXPECT_EQ(&RC
, CG
.lookupRefSCC(DN
));
2273 // Now delete 'a'. There are no uses of this function but there are
2274 // spurious references.
2275 CG
.markDeadFunction(AN
.getFunction());
2276 CG
.removeDeadFunctions({&AN
.getFunction()});
2278 // The only observable change should be that the RefSCC is gone from the
2279 // postorder sequence.
2280 I
= CG
.postorder_ref_scc_begin();
2281 EXPECT_EQ(CG
.lookupRefSCC(DN
), &*I
++);
2282 EXPECT_EQ(CG
.lookupRefSCC(CN
), &*I
);
2283 EXPECT_EQ(CG
.lookupRefSCC(BN
), &*I
++);
2284 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2287 TEST(LazyCallGraphTest
, RemoveFunctionWithSpuriousRefRecursive3
) {
2288 LLVMContext Context
;
2289 std::unique_ptr
<Module
> M
=
2290 parseAssembly(Context
, "define void @a(ptr %p) {\n"
2291 " store ptr @b, ptr %p\n"
2294 "define void @b(ptr %p) {\n"
2295 " store ptr @c, ptr %p\n"
2298 "define void @c(ptr %p) {\n"
2301 LazyCallGraph CG
= buildCG(*M
);
2303 LazyCallGraph::Node
&AN
= CG
.get(lookupFunction(*M
, "a"));
2304 LazyCallGraph::Node
&BN
= CG
.get(lookupFunction(*M
, "b"));
2305 LazyCallGraph::Node
&CN
= CG
.get(lookupFunction(*M
, "c"));
2309 // Insert spurious ref edges.
2310 CG
.insertEdge(CN
, AN
, LazyCallGraph::Edge::Ref
);
2311 CG
.insertEdge(BN
, AN
, LazyCallGraph::Edge::Ref
);
2313 // Force the graph to be fully expanded.
2315 auto I
= CG
.postorder_ref_scc_begin();
2316 LazyCallGraph::RefSCC
&RC
= *I
++;
2317 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2319 ASSERT_EQ(RC
.size(), 3);
2321 EXPECT_EQ(&RC
, CG
.lookupRefSCC(AN
));
2322 EXPECT_EQ(&RC
, CG
.lookupRefSCC(BN
));
2323 EXPECT_EQ(&RC
, CG
.lookupRefSCC(CN
));
2325 // Now delete 'a'. There are no uses of this function but there are
2326 // spurious references.
2327 CG
.markDeadFunction(AN
.getFunction());
2328 CG
.removeDeadFunctions({&AN
.getFunction()});
2330 // The only observable change should be that the RefSCC is gone from the
2331 // postorder sequence.
2332 I
= CG
.postorder_ref_scc_begin();
2333 EXPECT_EQ(CG
.lookupRefSCC(CN
), &*I
++);
2334 EXPECT_EQ(CG
.lookupRefSCC(BN
), &*I
++);
2335 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2338 TEST(LazyCallGraphTest
, AddSplitFunction1
) {
2339 LLVMContext Context
;
2340 std::unique_ptr
<Module
> M
= parseAssembly(Context
, "define void @f() {\n"
2343 LazyCallGraph CG
= buildCG(*M
);
2345 Function
&F
= lookupFunction(*M
, "f");
2346 LazyCallGraph::Node
&FN
= CG
.get(F
);
2348 // Force the graph to be fully expanded.
2350 auto I
= CG
.postorder_ref_scc_begin();
2351 LazyCallGraph::RefSCC
*ORC
= &*I
++;
2352 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2354 auto *G
= Function::Create(F
.getFunctionType(), F
.getLinkage(),
2355 F
.getAddressSpace(), "g", F
.getParent());
2356 BasicBlock
*GBB
= BasicBlock::Create(Context
, "", G
);
2357 (void)ReturnInst::Create(Context
, GBB
);
2359 // Create f -call-> g.
2360 (void)CallInst::Create(G
, {}, "", F
.getEntryBlock().begin());
2362 EXPECT_FALSE(verifyModule(*M
, &errs()));
2364 CG
.addSplitFunction(F
, *G
);
2366 LazyCallGraph::Node
*GN
= CG
.lookup(*G
);
2369 I
= CG
.postorder_ref_scc_begin();
2370 LazyCallGraph::RefSCC
*RC1
= &*I
++;
2371 EXPECT_EQ(RC1
, CG
.lookupRefSCC(*GN
));
2372 LazyCallGraph::RefSCC
*RC2
= &*I
++;
2373 EXPECT_EQ(RC2
, ORC
);
2374 EXPECT_EQ(RC2
, CG
.lookupRefSCC(FN
));
2375 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2378 TEST(LazyCallGraphTest
, AddSplitFunction2
) {
2379 LLVMContext Context
;
2380 std::unique_ptr
<Module
> M
= parseAssembly(Context
, "define void @f() {\n"
2383 LazyCallGraph CG
= buildCG(*M
);
2385 Function
&F
= lookupFunction(*M
, "f");
2386 LazyCallGraph::Node
&FN
= CG
.get(F
);
2388 // Force the graph to be fully expanded.
2390 auto I
= CG
.postorder_ref_scc_begin();
2391 LazyCallGraph::RefSCC
*ORC
= &*I
++;
2392 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2394 auto *G
= Function::Create(F
.getFunctionType(), F
.getLinkage(),
2395 F
.getAddressSpace(), "g", F
.getParent());
2396 BasicBlock
*GBB
= BasicBlock::Create(Context
, "", G
);
2397 (void)ReturnInst::Create(Context
, GBB
);
2399 // Create f -ref-> g.
2400 (void)CastInst::CreatePointerCast(G
, PointerType::getUnqual(Context
), "",
2401 F
.getEntryBlock().begin());
2403 EXPECT_FALSE(verifyModule(*M
, &errs()));
2405 CG
.addSplitFunction(F
, *G
);
2407 LazyCallGraph::Node
*GN
= CG
.lookup(*G
);
2410 I
= CG
.postorder_ref_scc_begin();
2411 LazyCallGraph::RefSCC
*RC1
= &*I
++;
2412 EXPECT_EQ(RC1
, CG
.lookupRefSCC(*GN
));
2413 LazyCallGraph::RefSCC
*RC2
= &*I
++;
2414 EXPECT_EQ(RC2
, ORC
);
2415 EXPECT_EQ(RC2
, CG
.lookupRefSCC(FN
));
2416 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2419 TEST(LazyCallGraphTest
, AddSplitFunction3
) {
2420 LLVMContext Context
;
2421 std::unique_ptr
<Module
> M
= parseAssembly(Context
, "define void @f() {\n"
2424 LazyCallGraph CG
= buildCG(*M
);
2426 Function
&F
= lookupFunction(*M
, "f");
2427 LazyCallGraph::Node
&FN
= CG
.get(F
);
2429 // Force the graph to be fully expanded.
2431 auto I
= CG
.postorder_ref_scc_begin();
2432 LazyCallGraph::RefSCC
*ORC
= &*I
++;
2433 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2435 auto *G
= Function::Create(F
.getFunctionType(), F
.getLinkage(),
2436 F
.getAddressSpace(), "g", F
.getParent());
2437 BasicBlock
*GBB
= BasicBlock::Create(Context
, "", G
);
2438 // Create g -ref-> f.
2439 (void)CastInst::CreatePointerCast(&F
, PointerType::getUnqual(Context
), "",
2441 (void)ReturnInst::Create(Context
, GBB
);
2443 // Create f -call-> g.
2444 (void)CallInst::Create(G
, {}, "", F
.getEntryBlock().begin());
2446 EXPECT_FALSE(verifyModule(*M
, &errs()));
2448 CG
.addSplitFunction(F
, *G
);
2450 LazyCallGraph::Node
*GN
= CG
.lookup(*G
);
2453 I
= CG
.postorder_ref_scc_begin();
2454 LazyCallGraph::RefSCC
*RC
= &*I
++;
2455 EXPECT_EQ(RC
, CG
.lookupRefSCC(*GN
));
2457 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2459 EXPECT_EQ(2, RC
->size());
2460 EXPECT_EQ(CG
.lookupSCC(*GN
), &(*RC
)[0]);
2461 EXPECT_EQ(CG
.lookupSCC(FN
), &(*RC
)[1]);
2464 TEST(LazyCallGraphTest
, AddSplitFunction4
) {
2465 LLVMContext Context
;
2466 std::unique_ptr
<Module
> M
= parseAssembly(Context
, "define void @f() {\n"
2469 LazyCallGraph CG
= buildCG(*M
);
2471 Function
&F
= lookupFunction(*M
, "f");
2472 LazyCallGraph::Node
&FN
= CG
.get(F
);
2474 // Force the graph to be fully expanded.
2476 auto I
= CG
.postorder_ref_scc_begin();
2477 LazyCallGraph::RefSCC
*ORC
= &*I
++;
2478 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2480 auto *G
= Function::Create(F
.getFunctionType(), F
.getLinkage(),
2481 F
.getAddressSpace(), "g", F
.getParent());
2482 BasicBlock
*GBB
= BasicBlock::Create(Context
, "", G
);
2483 // Create g -ref-> f.
2484 (void)CastInst::CreatePointerCast(&F
, PointerType::getUnqual(Context
), "",
2486 (void)ReturnInst::Create(Context
, GBB
);
2488 // Create f -ref-> g.
2489 (void)CastInst::CreatePointerCast(G
, PointerType::getUnqual(Context
), "",
2490 F
.getEntryBlock().begin());
2492 EXPECT_FALSE(verifyModule(*M
, &errs()));
2494 CG
.addSplitFunction(F
, *G
);
2496 LazyCallGraph::Node
*GN
= CG
.lookup(*G
);
2499 I
= CG
.postorder_ref_scc_begin();
2500 LazyCallGraph::RefSCC
*RC
= &*I
++;
2501 EXPECT_EQ(RC
, CG
.lookupRefSCC(*GN
));
2503 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2505 // Order doesn't matter for sibling SCCs.
2506 EXPECT_EQ(2, RC
->size());
2507 EXPECT_EQ(&CG
.lookupSCC(*GN
)->getOuterRefSCC(), RC
);
2508 EXPECT_EQ(&CG
.lookupSCC(FN
)->getOuterRefSCC(), RC
);
2511 TEST(LazyCallGraphTest
, AddSplitFunction5
) {
2512 LLVMContext Context
;
2513 std::unique_ptr
<Module
> M
= parseAssembly(Context
, "define void @f() {\n"
2516 LazyCallGraph CG
= buildCG(*M
);
2518 Function
&F
= lookupFunction(*M
, "f");
2519 LazyCallGraph::Node
&FN
= CG
.get(F
);
2521 // Force the graph to be fully expanded.
2523 auto I
= CG
.postorder_ref_scc_begin();
2524 LazyCallGraph::RefSCC
*ORC
= &*I
++;
2525 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2527 auto *G
= Function::Create(F
.getFunctionType(), F
.getLinkage(),
2528 F
.getAddressSpace(), "g", F
.getParent());
2529 BasicBlock
*GBB
= BasicBlock::Create(Context
, "", G
);
2530 // Create g -call-> f.
2531 (void)CallInst::Create(&F
, {}, "", GBB
);
2532 (void)ReturnInst::Create(Context
, GBB
);
2534 // Create f -ref-> g.
2535 (void)CastInst::CreatePointerCast(G
, PointerType::getUnqual(Context
), "",
2536 F
.getEntryBlock().begin());
2538 EXPECT_FALSE(verifyModule(*M
, &errs()));
2540 CG
.addSplitFunction(F
, *G
);
2542 LazyCallGraph::Node
*GN
= CG
.lookup(*G
);
2545 I
= CG
.postorder_ref_scc_begin();
2546 LazyCallGraph::RefSCC
*RC
= &*I
++;
2547 EXPECT_EQ(RC
, CG
.lookupRefSCC(*GN
));
2549 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2551 EXPECT_EQ(2, RC
->size());
2552 EXPECT_EQ(CG
.lookupSCC(FN
), &(*RC
)[0]);
2553 EXPECT_EQ(CG
.lookupSCC(*GN
), &(*RC
)[1]);
2556 TEST(LazyCallGraphTest
, AddSplitFunction6
) {
2557 LLVMContext Context
;
2558 std::unique_ptr
<Module
> M
= parseAssembly(Context
, "define void @f() {\n"
2561 LazyCallGraph CG
= buildCG(*M
);
2563 Function
&F
= lookupFunction(*M
, "f");
2564 LazyCallGraph::Node
&FN
= CG
.get(F
);
2566 // Force the graph to be fully expanded.
2568 auto I
= CG
.postorder_ref_scc_begin();
2569 LazyCallGraph::RefSCC
*ORC
= &*I
++;
2570 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2572 auto *G
= Function::Create(F
.getFunctionType(), F
.getLinkage(),
2573 F
.getAddressSpace(), "g", F
.getParent());
2574 BasicBlock
*GBB
= BasicBlock::Create(Context
, "", G
);
2575 // Create g -call-> f.
2576 (void)CallInst::Create(&F
, {}, "", GBB
);
2577 (void)ReturnInst::Create(Context
, GBB
);
2579 // Create f -call-> g.
2580 (void)CallInst::Create(G
, {}, "", F
.getEntryBlock().begin());
2582 EXPECT_FALSE(verifyModule(*M
, &errs()));
2584 CG
.addSplitFunction(F
, *G
);
2586 LazyCallGraph::Node
*GN
= CG
.lookup(*G
);
2589 I
= CG
.postorder_ref_scc_begin();
2590 LazyCallGraph::RefSCC
*RC
= &*I
++;
2591 EXPECT_EQ(RC
, CG
.lookupRefSCC(*GN
));
2593 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2595 EXPECT_EQ(1, RC
->size());
2596 EXPECT_EQ(CG
.lookupSCC(FN
), &(*RC
)[0]);
2597 EXPECT_EQ(CG
.lookupSCC(*GN
), &(*RC
)[0]);
2600 TEST(LazyCallGraphTest
, AddSplitFunction7
) {
2601 LLVMContext Context
;
2602 std::unique_ptr
<Module
> M
= parseAssembly(Context
, "define void @f() {\n"
2603 " call void @f2()\n"
2606 "define void @f2() {\n"
2610 LazyCallGraph CG
= buildCG(*M
);
2612 Function
&F
= lookupFunction(*M
, "f");
2613 LazyCallGraph::Node
&FN
= CG
.get(F
);
2614 Function
&F2
= lookupFunction(*M
, "f2");
2615 LazyCallGraph::Node
&F2N
= CG
.get(F2
);
2617 // Force the graph to be fully expanded.
2619 auto I
= CG
.postorder_ref_scc_begin();
2620 LazyCallGraph::RefSCC
*ORC
= &*I
++;
2621 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2623 auto *G
= Function::Create(F
.getFunctionType(), F
.getLinkage(),
2624 F
.getAddressSpace(), "g", F
.getParent());
2625 BasicBlock
*GBB
= BasicBlock::Create(Context
, "", G
);
2626 // Create g -call-> f2.
2627 (void)CallInst::Create(&F2
, {}, "", GBB
);
2628 (void)ReturnInst::Create(Context
, GBB
);
2630 // Create f -call-> g.
2631 (void)CallInst::Create(G
, {}, "", F
.getEntryBlock().begin());
2633 EXPECT_FALSE(verifyModule(*M
, &errs()));
2635 CG
.addSplitFunction(F
, *G
);
2637 LazyCallGraph::Node
*GN
= CG
.lookup(*G
);
2640 I
= CG
.postorder_ref_scc_begin();
2641 LazyCallGraph::RefSCC
*RC
= &*I
++;
2642 EXPECT_EQ(RC
, CG
.lookupRefSCC(*GN
));
2644 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2646 EXPECT_EQ(1, RC
->size());
2647 EXPECT_EQ(CG
.lookupSCC(FN
), &(*RC
)[0]);
2648 EXPECT_EQ(CG
.lookupSCC(F2N
), &(*RC
)[0]);
2649 EXPECT_EQ(CG
.lookupSCC(*GN
), &(*RC
)[0]);
2652 TEST(LazyCallGraphTest
, AddSplitFunction8
) {
2653 LLVMContext Context
;
2654 std::unique_ptr
<Module
> M
= parseAssembly(Context
, "define void @f() {\n"
2655 " call void @f2()\n"
2658 "define void @f2() {\n"
2662 LazyCallGraph CG
= buildCG(*M
);
2664 Function
&F
= lookupFunction(*M
, "f");
2665 LazyCallGraph::Node
&FN
= CG
.get(F
);
2666 Function
&F2
= lookupFunction(*M
, "f2");
2667 LazyCallGraph::Node
&F2N
= CG
.get(F2
);
2669 // Force the graph to be fully expanded.
2671 auto I
= CG
.postorder_ref_scc_begin();
2672 LazyCallGraph::RefSCC
*ORC
= &*I
++;
2673 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2675 auto *G
= Function::Create(F
.getFunctionType(), F
.getLinkage(),
2676 F
.getAddressSpace(), "g", F
.getParent());
2677 BasicBlock
*GBB
= BasicBlock::Create(Context
, "", G
);
2678 // Create g -call-> f2.
2679 (void)CallInst::Create(&F2
, {}, "", GBB
);
2680 (void)ReturnInst::Create(Context
, GBB
);
2682 // Create f -ref-> g.
2683 (void)CastInst::CreatePointerCast(G
, PointerType::getUnqual(Context
), "",
2684 F
.getEntryBlock().begin());
2686 EXPECT_FALSE(verifyModule(*M
, &errs()));
2688 CG
.addSplitFunction(F
, *G
);
2690 LazyCallGraph::Node
*GN
= CG
.lookup(*G
);
2693 I
= CG
.postorder_ref_scc_begin();
2694 LazyCallGraph::RefSCC
*RC
= &*I
++;
2695 EXPECT_EQ(RC
, CG
.lookupRefSCC(*GN
));
2697 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2699 EXPECT_EQ(2, RC
->size());
2700 EXPECT_EQ(CG
.lookupSCC(FN
), &(*RC
)[0]);
2701 EXPECT_EQ(CG
.lookupSCC(F2N
), &(*RC
)[0]);
2702 EXPECT_EQ(CG
.lookupSCC(*GN
), &(*RC
)[1]);
2705 TEST(LazyCallGraphTest
, AddSplitFunction9
) {
2706 LLVMContext Context
;
2707 std::unique_ptr
<Module
> M
= parseAssembly(Context
, "define void @f() {\n"
2708 " call void @f2()\n"
2711 "define void @f2() {\n"
2715 LazyCallGraph CG
= buildCG(*M
);
2717 Function
&F
= lookupFunction(*M
, "f");
2718 LazyCallGraph::Node
&FN
= CG
.get(F
);
2719 Function
&F2
= lookupFunction(*M
, "f2");
2720 LazyCallGraph::Node
&F2N
= CG
.get(F2
);
2722 // Force the graph to be fully expanded.
2724 auto I
= CG
.postorder_ref_scc_begin();
2725 LazyCallGraph::RefSCC
*ORC
= &*I
++;
2726 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2728 auto *G
= Function::Create(F
.getFunctionType(), F
.getLinkage(),
2729 F
.getAddressSpace(), "g", F
.getParent());
2730 BasicBlock
*GBB
= BasicBlock::Create(Context
, "", G
);
2731 // Create g -ref-> f2.
2732 (void)CastInst::CreatePointerCast(&F2
, PointerType::getUnqual(Context
), "",
2734 (void)ReturnInst::Create(Context
, GBB
);
2736 // Create f -call-> g.
2737 (void)CallInst::Create(G
, {}, "", F
.getEntryBlock().begin());
2739 EXPECT_FALSE(verifyModule(*M
, &errs()));
2741 CG
.addSplitFunction(F
, *G
);
2743 LazyCallGraph::Node
*GN
= CG
.lookup(*G
);
2746 I
= CG
.postorder_ref_scc_begin();
2747 LazyCallGraph::RefSCC
*RC
= &*I
++;
2748 EXPECT_EQ(RC
, CG
.lookupRefSCC(*GN
));
2750 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2752 EXPECT_EQ(2, RC
->size());
2753 EXPECT_EQ(CG
.lookupSCC(*GN
), &(*RC
)[0]);
2754 EXPECT_EQ(CG
.lookupSCC(FN
), &(*RC
)[1]);
2755 EXPECT_EQ(CG
.lookupSCC(F2N
), &(*RC
)[1]);
2758 TEST(LazyCallGraphTest
, AddSplitFunctions1
) {
2759 LLVMContext Context
;
2760 std::unique_ptr
<Module
> M
= parseAssembly(Context
, "define void @f() {\n"
2763 LazyCallGraph CG
= buildCG(*M
);
2765 Function
&F
= lookupFunction(*M
, "f");
2766 LazyCallGraph::Node
&FN
= CG
.get(F
);
2768 // Force the graph to be fully expanded.
2770 auto I
= CG
.postorder_ref_scc_begin();
2771 LazyCallGraph::RefSCC
*ORC
= &*I
++;
2772 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2774 auto *G
= Function::Create(F
.getFunctionType(), F
.getLinkage(),
2775 F
.getAddressSpace(), "g", F
.getParent());
2776 BasicBlock
*GBB
= BasicBlock::Create(Context
, "", G
);
2777 (void)ReturnInst::Create(Context
, GBB
);
2779 // Create f -ref-> g.
2780 (void)CastInst::CreatePointerCast(G
, PointerType::getUnqual(Context
), "",
2781 F
.getEntryBlock().begin());
2783 EXPECT_FALSE(verifyModule(*M
, &errs()));
2785 CG
.addSplitRefRecursiveFunctions(F
, SmallVector
<Function
*, 1>({G
}));
2787 LazyCallGraph::Node
*GN
= CG
.lookup(*G
);
2790 I
= CG
.postorder_ref_scc_begin();
2791 LazyCallGraph::RefSCC
*RC1
= &*I
++;
2792 EXPECT_EQ(RC1
, CG
.lookupRefSCC(*GN
));
2793 LazyCallGraph::RefSCC
*RC2
= &*I
++;
2794 EXPECT_EQ(RC2
, ORC
);
2795 EXPECT_EQ(RC2
, CG
.lookupRefSCC(FN
));
2796 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2799 TEST(LazyCallGraphTest
, AddSplitFunctions2
) {
2800 LLVMContext Context
;
2801 std::unique_ptr
<Module
> M
= parseAssembly(Context
, "define void @f() {\n"
2804 LazyCallGraph CG
= buildCG(*M
);
2806 Function
&F
= lookupFunction(*M
, "f");
2807 LazyCallGraph::Node
&FN
= CG
.get(F
);
2809 // Force the graph to be fully expanded.
2811 auto I
= CG
.postorder_ref_scc_begin();
2812 LazyCallGraph::RefSCC
*ORC
= &*I
++;
2813 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2815 auto *G
= Function::Create(F
.getFunctionType(), F
.getLinkage(),
2816 F
.getAddressSpace(), "g", F
.getParent());
2817 BasicBlock
*GBB
= BasicBlock::Create(Context
, "", G
);
2818 // Create g -ref-> f.
2819 (void)CastInst::CreatePointerCast(&F
, PointerType::getUnqual(Context
), "",
2821 (void)ReturnInst::Create(Context
, GBB
);
2823 // Create f -ref-> g.
2824 (void)CastInst::CreatePointerCast(G
, PointerType::getUnqual(Context
), "",
2825 F
.getEntryBlock().begin());
2827 EXPECT_FALSE(verifyModule(*M
, &errs()));
2829 CG
.addSplitRefRecursiveFunctions(F
, SmallVector
<Function
*, 1>({G
}));
2831 LazyCallGraph::Node
*GN
= CG
.lookup(*G
);
2834 I
= CG
.postorder_ref_scc_begin();
2835 LazyCallGraph::RefSCC
*RC
= &*I
++;
2836 EXPECT_EQ(RC
, CG
.lookupRefSCC(*GN
));
2838 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2840 // Order doesn't matter for sibling SCCs.
2841 EXPECT_EQ(2, RC
->size());
2842 EXPECT_EQ(&CG
.lookupSCC(*GN
)->getOuterRefSCC(), RC
);
2843 EXPECT_EQ(&CG
.lookupSCC(FN
)->getOuterRefSCC(), RC
);
2846 TEST(LazyCallGraphTest
, AddSplitFunctions3
) {
2847 LLVMContext Context
;
2848 std::unique_ptr
<Module
> M
= parseAssembly(Context
, "define void @f() {\n"
2851 LazyCallGraph CG
= buildCG(*M
);
2853 Function
&F
= lookupFunction(*M
, "f");
2854 LazyCallGraph::Node
&FN
= CG
.get(F
);
2856 // Force the graph to be fully expanded.
2858 auto I
= CG
.postorder_ref_scc_begin();
2859 LazyCallGraph::RefSCC
*ORC
= &*I
++;
2860 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2862 auto *G1
= Function::Create(F
.getFunctionType(), F
.getLinkage(),
2863 F
.getAddressSpace(), "g1", F
.getParent());
2864 auto *G2
= Function::Create(F
.getFunctionType(), F
.getLinkage(),
2865 F
.getAddressSpace(), "g2", F
.getParent());
2866 BasicBlock
*G1BB
= BasicBlock::Create(Context
, "", G1
);
2867 BasicBlock
*G2BB
= BasicBlock::Create(Context
, "", G2
);
2868 // Create g1 -ref-> g2 and g2 -ref-> g1.
2869 (void)CastInst::CreatePointerCast(G2
, PointerType::getUnqual(Context
), "",
2871 (void)CastInst::CreatePointerCast(G1
, PointerType::getUnqual(Context
), "",
2873 (void)ReturnInst::Create(Context
, G1BB
);
2874 (void)ReturnInst::Create(Context
, G2BB
);
2876 // Create f -ref-> g1 and f -ref-> g2.
2877 (void)CastInst::CreatePointerCast(G1
, PointerType::getUnqual(Context
), "",
2878 F
.getEntryBlock().begin());
2879 (void)CastInst::CreatePointerCast(G2
, PointerType::getUnqual(Context
), "",
2880 F
.getEntryBlock().begin());
2882 EXPECT_FALSE(verifyModule(*M
, &errs()));
2884 CG
.addSplitRefRecursiveFunctions(F
, SmallVector
<Function
*, 1>({G1
, G2
}));
2886 LazyCallGraph::Node
*G1N
= CG
.lookup(*G1
);
2888 LazyCallGraph::Node
*G2N
= CG
.lookup(*G2
);
2891 I
= CG
.postorder_ref_scc_begin();
2892 LazyCallGraph::RefSCC
*RC1
= &*I
++;
2893 EXPECT_EQ(2, RC1
->size());
2894 EXPECT_EQ(RC1
, CG
.lookupRefSCC(*G1N
));
2895 EXPECT_EQ(RC1
, CG
.lookupRefSCC(*G2N
));
2896 LazyCallGraph::RefSCC
*RC2
= &*I
++;
2897 EXPECT_EQ(RC2
, ORC
);
2898 EXPECT_EQ(RC2
, CG
.lookupRefSCC(FN
));
2899 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2902 TEST(LazyCallGraphTest
, AddSplitFunctions4
) {
2903 LLVMContext Context
;
2904 std::unique_ptr
<Module
> M
= parseAssembly(Context
, "define void @f() {\n"
2907 LazyCallGraph CG
= buildCG(*M
);
2909 Function
&F
= lookupFunction(*M
, "f");
2910 LazyCallGraph::Node
&FN
= CG
.get(F
);
2912 // Force the graph to be fully expanded.
2914 auto I
= CG
.postorder_ref_scc_begin();
2915 LazyCallGraph::RefSCC
*ORC
= &*I
++;
2916 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2918 auto *G1
= Function::Create(F
.getFunctionType(), F
.getLinkage(),
2919 F
.getAddressSpace(), "g1", F
.getParent());
2920 auto *G2
= Function::Create(F
.getFunctionType(), F
.getLinkage(),
2921 F
.getAddressSpace(), "g2", F
.getParent());
2922 BasicBlock
*G1BB
= BasicBlock::Create(Context
, "", G1
);
2923 BasicBlock
*G2BB
= BasicBlock::Create(Context
, "", G2
);
2924 // Create g1 -ref-> g2 and g2 -ref-> g1.
2925 (void)CastInst::CreatePointerCast(G2
, PointerType::getUnqual(Context
), "",
2927 (void)CastInst::CreatePointerCast(G1
, PointerType::getUnqual(Context
), "",
2929 // Create g2 -ref-> f.
2930 (void)CastInst::CreatePointerCast(&F
, PointerType::getUnqual(Context
), "",
2932 (void)ReturnInst::Create(Context
, G1BB
);
2933 (void)ReturnInst::Create(Context
, G2BB
);
2935 // Create f -ref-> g1 and f -ref-> g2.
2936 (void)CastInst::CreatePointerCast(G1
, PointerType::getUnqual(Context
), "",
2937 F
.getEntryBlock().begin());
2938 (void)CastInst::CreatePointerCast(G2
, PointerType::getUnqual(Context
), "",
2939 F
.getEntryBlock().begin());
2941 EXPECT_FALSE(verifyModule(*M
, &errs()));
2943 CG
.addSplitRefRecursiveFunctions(F
, SmallVector
<Function
*, 1>({G1
, G2
}));
2945 LazyCallGraph::Node
*G1N
= CG
.lookup(*G1
);
2947 LazyCallGraph::Node
*G2N
= CG
.lookup(*G2
);
2950 I
= CG
.postorder_ref_scc_begin();
2951 LazyCallGraph::RefSCC
*RC
= &*I
++;
2953 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2955 // Order doesn't matter for sibling SCCs.
2956 EXPECT_EQ(3, RC
->size());
2957 EXPECT_EQ(&CG
.lookupSCC(FN
)->getOuterRefSCC(), RC
);
2958 EXPECT_EQ(&CG
.lookupSCC(*G1N
)->getOuterRefSCC(), RC
);
2959 EXPECT_EQ(&CG
.lookupSCC(*G2N
)->getOuterRefSCC(), RC
);
2960 EXPECT_EQ(RC
, CG
.lookupRefSCC(*G1N
));
2961 EXPECT_EQ(RC
, CG
.lookupRefSCC(*G2N
));
2964 TEST(LazyCallGraphTest
, AddSplitFunctions5
) {
2965 LLVMContext Context
;
2966 std::unique_ptr
<Module
> M
=
2967 parseAssembly(Context
, "define void @f() {\n"
2968 " %1 = bitcast void ()* @f2 to i8*\n"
2971 "define void @f2() {\n"
2975 LazyCallGraph CG
= buildCG(*M
);
2977 Function
&F
= lookupFunction(*M
, "f");
2978 LazyCallGraph::Node
&FN
= CG
.get(F
);
2979 Function
&F2
= lookupFunction(*M
, "f2");
2980 LazyCallGraph::Node
&F2N
= CG
.get(F
);
2982 // Force the graph to be fully expanded.
2984 auto I
= CG
.postorder_ref_scc_begin();
2985 LazyCallGraph::RefSCC
*ORC
= &*I
++;
2986 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2988 auto *G1
= Function::Create(F
.getFunctionType(), F
.getLinkage(),
2989 F
.getAddressSpace(), "g1", F
.getParent());
2990 auto *G2
= Function::Create(F
.getFunctionType(), F
.getLinkage(),
2991 F
.getAddressSpace(), "g2", F
.getParent());
2992 BasicBlock
*G1BB
= BasicBlock::Create(Context
, "", G1
);
2993 BasicBlock
*G2BB
= BasicBlock::Create(Context
, "", G2
);
2994 // Create g1 -ref-> g2 and g2 -ref-> g1.
2995 (void)CastInst::CreatePointerCast(G2
, PointerType::getUnqual(Context
), "",
2997 (void)CastInst::CreatePointerCast(G1
, PointerType::getUnqual(Context
), "",
2999 // Create g2 -ref-> f2.
3000 (void)CastInst::CreatePointerCast(&F2
, PointerType::getUnqual(Context
), "",
3002 (void)ReturnInst::Create(Context
, G1BB
);
3003 (void)ReturnInst::Create(Context
, G2BB
);
3005 // Create f -ref-> g1 and f -ref-> g2.
3006 (void)CastInst::CreatePointerCast(G1
, PointerType::getUnqual(Context
), "",
3007 F
.getEntryBlock().begin());
3008 (void)CastInst::CreatePointerCast(G2
, PointerType::getUnqual(Context
), "",
3009 F
.getEntryBlock().begin());
3011 EXPECT_FALSE(verifyModule(*M
, &errs()));
3013 CG
.addSplitRefRecursiveFunctions(F
, SmallVector
<Function
*, 1>({G1
, G2
}));
3015 LazyCallGraph::Node
*G1N
= CG
.lookup(*G1
);
3017 LazyCallGraph::Node
*G2N
= CG
.lookup(*G2
);
3020 I
= CG
.postorder_ref_scc_begin();
3021 LazyCallGraph::RefSCC
*RC
= &*I
++;
3022 EXPECT_EQ(4, RC
->size());
3024 EXPECT_EQ(RC
, CG
.lookupRefSCC(*G1N
));
3025 EXPECT_EQ(RC
, CG
.lookupRefSCC(*G2N
));
3026 EXPECT_EQ(RC
, CG
.lookupRefSCC(FN
));
3027 EXPECT_EQ(RC
, CG
.lookupRefSCC(F2N
));
3028 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);