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(OS
.str().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
.removeInternalRefEdge(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
.removeDeadFunction(D2F
);
1191 // Check that the graph still looks the same.
1192 EXPECT_EQ(&ARC
, CG
.lookupRefSCC(A1
));
1193 EXPECT_EQ(&ARC
, CG
.lookupRefSCC(A2
));
1194 EXPECT_EQ(&ARC
, CG
.lookupRefSCC(A3
));
1195 EXPECT_EQ(&BRC
, CG
.lookupRefSCC(B1
));
1196 EXPECT_EQ(&BRC
, CG
.lookupRefSCC(B2
));
1197 EXPECT_EQ(&BRC
, CG
.lookupRefSCC(B3
));
1198 EXPECT_EQ(&CRC
, CG
.lookupRefSCC(C1
));
1199 EXPECT_EQ(&CRC
, CG
.lookupRefSCC(C2
));
1200 EXPECT_EQ(&CRC
, CG
.lookupRefSCC(C3
));
1201 EXPECT_EQ(&NewDRC
, CG
.lookupRefSCC(D1
));
1202 EXPECT_EQ(&NewDRC
, CG
.lookupRefSCC(D3
));
1203 EXPECT_TRUE(CRC
.isParentOf(NewDRC
));
1205 // Verify the post-order walk hasn't changed.
1206 auto I
= CG
.postorder_ref_scc_begin(), E
= CG
.postorder_ref_scc_end();
1208 EXPECT_EQ(&NewDRC
, &*I
) << "Actual RefSCC: " << *I
;
1210 EXPECT_EQ(&BRC
, &*I
) << "Actual RefSCC: " << *I
;
1212 EXPECT_EQ(&CRC
, &*I
) << "Actual RefSCC: " << *I
;
1214 EXPECT_EQ(&ARC
, &*I
) << "Actual RefSCC: " << *I
;
1218 TEST(LazyCallGraphTest
, InternalEdgeMutation
) {
1219 LLVMContext Context
;
1220 std::unique_ptr
<Module
> M
= parseAssembly(Context
, "define void @a() {\n"
1225 "define void @b() {\n"
1230 "define void @c() {\n"
1235 LazyCallGraph CG
= buildCG(*M
);
1237 // Force the graph to be fully expanded.
1239 auto I
= CG
.postorder_ref_scc_begin();
1240 LazyCallGraph::RefSCC
&RC
= *I
++;
1241 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
1243 LazyCallGraph::Node
&A
= *CG
.lookup(lookupFunction(*M
, "a"));
1244 LazyCallGraph::Node
&B
= *CG
.lookup(lookupFunction(*M
, "b"));
1245 LazyCallGraph::Node
&C
= *CG
.lookup(lookupFunction(*M
, "c"));
1246 EXPECT_EQ(&RC
, CG
.lookupRefSCC(A
));
1247 EXPECT_EQ(&RC
, CG
.lookupRefSCC(B
));
1248 EXPECT_EQ(&RC
, CG
.lookupRefSCC(C
));
1249 EXPECT_EQ(1, RC
.size());
1250 EXPECT_EQ(&*RC
.begin(), CG
.lookupSCC(A
));
1251 EXPECT_EQ(&*RC
.begin(), CG
.lookupSCC(B
));
1252 EXPECT_EQ(&*RC
.begin(), CG
.lookupSCC(C
));
1254 // Insert an edge from 'a' to 'c'. Nothing changes about the graph.
1255 RC
.insertInternalRefEdge(A
, C
);
1256 EXPECT_EQ(2, std::distance(A
->begin(), A
->end()));
1257 EXPECT_EQ(&RC
, CG
.lookupRefSCC(A
));
1258 EXPECT_EQ(&RC
, CG
.lookupRefSCC(B
));
1259 EXPECT_EQ(&RC
, CG
.lookupRefSCC(C
));
1260 EXPECT_EQ(1, RC
.size());
1261 EXPECT_EQ(&*RC
.begin(), CG
.lookupSCC(A
));
1262 EXPECT_EQ(&*RC
.begin(), CG
.lookupSCC(B
));
1263 EXPECT_EQ(&*RC
.begin(), CG
.lookupSCC(C
));
1265 // Switch the call edge from 'b' to 'c' to a ref edge. This will break the
1266 // call cycle and cause us to form more SCCs. The RefSCC will remain the same
1268 auto NewCs
= RC
.switchInternalEdgeToRef(B
, C
);
1269 EXPECT_EQ(&RC
, CG
.lookupRefSCC(A
));
1270 EXPECT_EQ(&RC
, CG
.lookupRefSCC(B
));
1271 EXPECT_EQ(&RC
, CG
.lookupRefSCC(C
));
1272 auto J
= RC
.begin();
1273 // The SCCs must be in *post-order* which means successors before
1274 // predecessors. At this point we have call edges from C to A and from A to
1275 // B. The only valid postorder is B, A, C.
1276 EXPECT_EQ(&*J
++, CG
.lookupSCC(B
));
1277 EXPECT_EQ(&*J
++, CG
.lookupSCC(A
));
1278 EXPECT_EQ(&*J
++, CG
.lookupSCC(C
));
1279 EXPECT_EQ(RC
.end(), J
);
1280 // And the returned range must be the slice of this sequence containing new
1282 EXPECT_EQ(RC
.begin(), NewCs
.begin());
1283 EXPECT_EQ(std::prev(RC
.end()), NewCs
.end());
1285 // Test turning the ref edge from A to C into a call edge. This will form an
1286 // SCC out of A and C. Since we previously had a call edge from C to A, the
1287 // C SCC should be preserved and have A merged into it while the A SCC should
1289 LazyCallGraph::SCC
&AC
= *CG
.lookupSCC(A
);
1290 LazyCallGraph::SCC
&CC
= *CG
.lookupSCC(C
);
1291 EXPECT_TRUE(RC
.switchInternalEdgeToCall(A
, C
, [&](ArrayRef
<LazyCallGraph::SCC
*> MergedCs
) {
1292 ASSERT_EQ(1u, MergedCs
.size());
1293 EXPECT_EQ(&AC
, MergedCs
[0]);
1295 EXPECT_EQ(2, CC
.size());
1296 EXPECT_EQ(&CC
, CG
.lookupSCC(A
));
1297 EXPECT_EQ(&CC
, CG
.lookupSCC(C
));
1299 EXPECT_EQ(&*J
++, CG
.lookupSCC(B
));
1300 EXPECT_EQ(&*J
++, CG
.lookupSCC(C
));
1301 EXPECT_EQ(RC
.end(), J
);
1304 TEST(LazyCallGraphTest
, InternalEdgeRemoval
) {
1305 LLVMContext Context
;
1306 // A nice fully connected (including self-edges) RefSCC.
1307 std::unique_ptr
<Module
> M
= parseAssembly(
1308 Context
, "define void @a(i8** %ptr) {\n"
1310 " store i8* bitcast (void(i8**)* @a to i8*), i8** %ptr\n"
1311 " store i8* bitcast (void(i8**)* @b to i8*), i8** %ptr\n"
1312 " store i8* bitcast (void(i8**)* @c to i8*), i8** %ptr\n"
1315 "define void @b(i8** %ptr) {\n"
1317 " store i8* bitcast (void(i8**)* @a to i8*), i8** %ptr\n"
1318 " store i8* bitcast (void(i8**)* @b to i8*), i8** %ptr\n"
1319 " store i8* bitcast (void(i8**)* @c to i8*), i8** %ptr\n"
1322 "define void @c(i8** %ptr) {\n"
1324 " store i8* bitcast (void(i8**)* @a to i8*), i8** %ptr\n"
1325 " store i8* bitcast (void(i8**)* @b to i8*), i8** %ptr\n"
1326 " store i8* bitcast (void(i8**)* @c to i8*), i8** %ptr\n"
1329 LazyCallGraph CG
= buildCG(*M
);
1331 // Force the graph to be fully expanded.
1333 auto I
= CG
.postorder_ref_scc_begin(), E
= CG
.postorder_ref_scc_end();
1334 LazyCallGraph::RefSCC
&RC
= *I
;
1335 EXPECT_EQ(E
, std::next(I
));
1337 LazyCallGraph::Node
&A
= *CG
.lookup(lookupFunction(*M
, "a"));
1338 LazyCallGraph::Node
&B
= *CG
.lookup(lookupFunction(*M
, "b"));
1339 LazyCallGraph::Node
&C
= *CG
.lookup(lookupFunction(*M
, "c"));
1340 EXPECT_EQ(&RC
, CG
.lookupRefSCC(A
));
1341 EXPECT_EQ(&RC
, CG
.lookupRefSCC(B
));
1342 EXPECT_EQ(&RC
, CG
.lookupRefSCC(C
));
1344 // Remove the edge from b -> a, which should leave the 3 functions still in
1345 // a single connected component because of a -> b -> c -> a.
1346 SmallVector
<LazyCallGraph::RefSCC
*, 1> NewRCs
=
1347 RC
.removeInternalRefEdge(B
, {&A
});
1348 EXPECT_EQ(0u, NewRCs
.size());
1349 EXPECT_EQ(&RC
, CG
.lookupRefSCC(A
));
1350 EXPECT_EQ(&RC
, CG
.lookupRefSCC(B
));
1351 EXPECT_EQ(&RC
, CG
.lookupRefSCC(C
));
1352 auto J
= CG
.postorder_ref_scc_begin();
1354 EXPECT_EQ(&RC
, &*J
);
1355 EXPECT_EQ(E
, std::next(J
));
1357 // Increment I before we actually mutate the structure so that it remains
1358 // a valid iterator.
1361 // Remove the edge from c -> a, which should leave 'a' in the original RefSCC
1362 // and form a new RefSCC for 'b' and 'c'.
1363 NewRCs
= RC
.removeInternalRefEdge(C
, {&A
});
1364 ASSERT_EQ(2u, NewRCs
.size());
1365 LazyCallGraph::RefSCC
&BCRC
= *NewRCs
[0];
1366 LazyCallGraph::RefSCC
&ARC
= *NewRCs
[1];
1367 EXPECT_EQ(&ARC
, CG
.lookupRefSCC(A
));
1368 EXPECT_EQ(1, std::distance(ARC
.begin(), ARC
.end()));
1369 EXPECT_EQ(&BCRC
, CG
.lookupRefSCC(B
));
1370 EXPECT_EQ(&BCRC
, CG
.lookupRefSCC(C
));
1371 J
= CG
.postorder_ref_scc_begin();
1373 EXPECT_EQ(&BCRC
, &*J
);
1376 EXPECT_EQ(&ARC
, &*J
);
1382 TEST(LazyCallGraphTest
, InternalMultiEdgeRemoval
) {
1383 LLVMContext Context
;
1384 // A nice fully connected (including self-edges) RefSCC.
1385 std::unique_ptr
<Module
> M
= parseAssembly(
1386 Context
, "define void @a(i8** %ptr) {\n"
1388 " store i8* bitcast (void(i8**)* @a to i8*), i8** %ptr\n"
1389 " store i8* bitcast (void(i8**)* @b to i8*), i8** %ptr\n"
1390 " store i8* bitcast (void(i8**)* @c to i8*), i8** %ptr\n"
1393 "define void @b(i8** %ptr) {\n"
1395 " store i8* bitcast (void(i8**)* @a to i8*), i8** %ptr\n"
1396 " store i8* bitcast (void(i8**)* @b to i8*), i8** %ptr\n"
1397 " store i8* bitcast (void(i8**)* @c to i8*), i8** %ptr\n"
1400 "define void @c(i8** %ptr) {\n"
1402 " store i8* bitcast (void(i8**)* @a to i8*), i8** %ptr\n"
1403 " store i8* bitcast (void(i8**)* @b to i8*), i8** %ptr\n"
1404 " store i8* bitcast (void(i8**)* @c to i8*), i8** %ptr\n"
1407 LazyCallGraph CG
= buildCG(*M
);
1409 // Force the graph to be fully expanded.
1411 auto I
= CG
.postorder_ref_scc_begin(), E
= CG
.postorder_ref_scc_end();
1412 LazyCallGraph::RefSCC
&RC
= *I
;
1413 EXPECT_EQ(E
, std::next(I
));
1415 LazyCallGraph::Node
&A
= *CG
.lookup(lookupFunction(*M
, "a"));
1416 LazyCallGraph::Node
&B
= *CG
.lookup(lookupFunction(*M
, "b"));
1417 LazyCallGraph::Node
&C
= *CG
.lookup(lookupFunction(*M
, "c"));
1418 EXPECT_EQ(&RC
, CG
.lookupRefSCC(A
));
1419 EXPECT_EQ(&RC
, CG
.lookupRefSCC(B
));
1420 EXPECT_EQ(&RC
, CG
.lookupRefSCC(C
));
1422 // Increment I before we actually mutate the structure so that it remains
1423 // a valid iterator.
1426 // Remove the edges from b -> a and b -> c, leaving b in its own RefSCC.
1427 SmallVector
<LazyCallGraph::RefSCC
*, 1> NewRCs
=
1428 RC
.removeInternalRefEdge(B
, {&A
, &C
});
1430 ASSERT_EQ(2u, NewRCs
.size());
1431 LazyCallGraph::RefSCC
&BRC
= *NewRCs
[0];
1432 LazyCallGraph::RefSCC
&ACRC
= *NewRCs
[1];
1433 EXPECT_EQ(&BRC
, CG
.lookupRefSCC(B
));
1434 EXPECT_EQ(1, std::distance(BRC
.begin(), BRC
.end()));
1435 EXPECT_EQ(&ACRC
, CG
.lookupRefSCC(A
));
1436 EXPECT_EQ(&ACRC
, CG
.lookupRefSCC(C
));
1437 auto J
= CG
.postorder_ref_scc_begin();
1439 EXPECT_EQ(&BRC
, &*J
);
1442 EXPECT_EQ(&ACRC
, &*J
);
1448 TEST(LazyCallGraphTest
, InternalNoOpEdgeRemoval
) {
1449 LLVMContext Context
;
1450 // A graph with a single cycle formed both from call and reference edges
1451 // which makes the reference edges trivial to delete. The graph looks like:
1453 // Reference edges: a -> b -> c -> a
1454 // Call edges: a -> c -> b -> a
1455 std::unique_ptr
<Module
> M
= parseAssembly(
1456 Context
, "define void @a(i8** %ptr) {\n"
1458 " call void @b(i8** %ptr)\n"
1459 " store i8* bitcast (void(i8**)* @c to i8*), i8** %ptr\n"
1462 "define void @b(i8** %ptr) {\n"
1464 " store i8* bitcast (void(i8**)* @a to i8*), i8** %ptr\n"
1465 " call void @c(i8** %ptr)\n"
1468 "define void @c(i8** %ptr) {\n"
1470 " call void @a(i8** %ptr)\n"
1471 " store i8* bitcast (void(i8**)* @b to i8*), i8** %ptr\n"
1474 LazyCallGraph CG
= buildCG(*M
);
1476 // Force the graph to be fully expanded.
1478 auto I
= CG
.postorder_ref_scc_begin(), E
= CG
.postorder_ref_scc_end();
1479 LazyCallGraph::RefSCC
&RC
= *I
;
1480 EXPECT_EQ(E
, std::next(I
));
1482 LazyCallGraph::SCC
&C
= *RC
.begin();
1483 EXPECT_EQ(RC
.end(), std::next(RC
.begin()));
1485 LazyCallGraph::Node
&AN
= *CG
.lookup(lookupFunction(*M
, "a"));
1486 LazyCallGraph::Node
&BN
= *CG
.lookup(lookupFunction(*M
, "b"));
1487 LazyCallGraph::Node
&CN
= *CG
.lookup(lookupFunction(*M
, "c"));
1488 EXPECT_EQ(&RC
, CG
.lookupRefSCC(AN
));
1489 EXPECT_EQ(&RC
, CG
.lookupRefSCC(BN
));
1490 EXPECT_EQ(&RC
, CG
.lookupRefSCC(CN
));
1491 EXPECT_EQ(&C
, CG
.lookupSCC(AN
));
1492 EXPECT_EQ(&C
, CG
.lookupSCC(BN
));
1493 EXPECT_EQ(&C
, CG
.lookupSCC(CN
));
1495 // Remove the edge from a -> c which doesn't change anything.
1496 SmallVector
<LazyCallGraph::RefSCC
*, 1> NewRCs
=
1497 RC
.removeInternalRefEdge(AN
, {&CN
});
1498 EXPECT_EQ(0u, NewRCs
.size());
1499 EXPECT_EQ(&RC
, CG
.lookupRefSCC(AN
));
1500 EXPECT_EQ(&RC
, CG
.lookupRefSCC(BN
));
1501 EXPECT_EQ(&RC
, CG
.lookupRefSCC(CN
));
1502 EXPECT_EQ(&C
, CG
.lookupSCC(AN
));
1503 EXPECT_EQ(&C
, CG
.lookupSCC(BN
));
1504 EXPECT_EQ(&C
, CG
.lookupSCC(CN
));
1505 auto J
= CG
.postorder_ref_scc_begin();
1507 EXPECT_EQ(&RC
, &*J
);
1508 EXPECT_EQ(E
, std::next(J
));
1510 // Remove the edge from b -> a and c -> b; again this doesn't change
1512 NewRCs
= RC
.removeInternalRefEdge(BN
, {&AN
});
1513 NewRCs
= RC
.removeInternalRefEdge(CN
, {&BN
});
1514 EXPECT_EQ(0u, NewRCs
.size());
1515 EXPECT_EQ(&RC
, CG
.lookupRefSCC(AN
));
1516 EXPECT_EQ(&RC
, CG
.lookupRefSCC(BN
));
1517 EXPECT_EQ(&RC
, CG
.lookupRefSCC(CN
));
1518 EXPECT_EQ(&C
, CG
.lookupSCC(AN
));
1519 EXPECT_EQ(&C
, CG
.lookupSCC(BN
));
1520 EXPECT_EQ(&C
, CG
.lookupSCC(CN
));
1521 J
= CG
.postorder_ref_scc_begin();
1523 EXPECT_EQ(&RC
, &*J
);
1524 EXPECT_EQ(E
, std::next(J
));
1527 TEST(LazyCallGraphTest
, InternalCallEdgeToRef
) {
1528 LLVMContext Context
;
1529 // A nice fully connected (including self-edges) SCC (and RefSCC)
1530 std::unique_ptr
<Module
> M
= parseAssembly(Context
, "define void @a() {\n"
1537 "define void @b() {\n"
1544 "define void @c() {\n"
1551 LazyCallGraph CG
= buildCG(*M
);
1553 // Force the graph to be fully expanded.
1555 auto I
= CG
.postorder_ref_scc_begin();
1556 LazyCallGraph::RefSCC
&RC
= *I
++;
1557 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
1559 EXPECT_EQ(1, RC
.size());
1560 LazyCallGraph::SCC
&AC
= *RC
.begin();
1562 LazyCallGraph::Node
&AN
= *CG
.lookup(lookupFunction(*M
, "a"));
1563 LazyCallGraph::Node
&BN
= *CG
.lookup(lookupFunction(*M
, "b"));
1564 LazyCallGraph::Node
&CN
= *CG
.lookup(lookupFunction(*M
, "c"));
1565 EXPECT_EQ(&AC
, CG
.lookupSCC(AN
));
1566 EXPECT_EQ(&AC
, CG
.lookupSCC(BN
));
1567 EXPECT_EQ(&AC
, CG
.lookupSCC(CN
));
1569 // Remove the call edge from b -> a to a ref edge, which should leave the
1570 // 3 functions still in a single connected component because of a -> b ->
1572 auto NewCs
= RC
.switchInternalEdgeToRef(BN
, AN
);
1573 EXPECT_EQ(NewCs
.begin(), NewCs
.end());
1574 EXPECT_EQ(1, RC
.size());
1575 EXPECT_EQ(&AC
, CG
.lookupSCC(AN
));
1576 EXPECT_EQ(&AC
, CG
.lookupSCC(BN
));
1577 EXPECT_EQ(&AC
, CG
.lookupSCC(CN
));
1579 // Remove the edge from c -> a, which should leave 'a' in the original SCC
1580 // and form a new SCC for 'b' and 'c'.
1581 NewCs
= RC
.switchInternalEdgeToRef(CN
, AN
);
1582 EXPECT_EQ(1, std::distance(NewCs
.begin(), NewCs
.end()));
1583 EXPECT_EQ(2, RC
.size());
1584 EXPECT_EQ(&AC
, CG
.lookupSCC(AN
));
1585 LazyCallGraph::SCC
&BC
= *CG
.lookupSCC(BN
);
1586 EXPECT_NE(&BC
, &AC
);
1587 EXPECT_EQ(&BC
, CG
.lookupSCC(CN
));
1588 auto J
= RC
.find(AC
);
1589 EXPECT_EQ(&AC
, &*J
);
1591 EXPECT_EQ(&BC
, &*J
);
1592 EXPECT_EQ(RC
.begin(), J
);
1593 EXPECT_EQ(J
, NewCs
.begin());
1595 // Remove the edge from c -> b, which should leave 'b' in the original SCC
1596 // and form a new SCC for 'c'. It shouldn't change 'a's SCC.
1597 NewCs
= RC
.switchInternalEdgeToRef(CN
, BN
);
1598 EXPECT_EQ(1, std::distance(NewCs
.begin(), NewCs
.end()));
1599 EXPECT_EQ(3, RC
.size());
1600 EXPECT_EQ(&AC
, CG
.lookupSCC(AN
));
1601 EXPECT_EQ(&BC
, CG
.lookupSCC(BN
));
1602 LazyCallGraph::SCC
&CC
= *CG
.lookupSCC(CN
);
1603 EXPECT_NE(&CC
, &AC
);
1604 EXPECT_NE(&CC
, &BC
);
1606 EXPECT_EQ(&AC
, &*J
);
1608 EXPECT_EQ(&BC
, &*J
);
1610 EXPECT_EQ(&CC
, &*J
);
1611 EXPECT_EQ(RC
.begin(), J
);
1612 EXPECT_EQ(J
, NewCs
.begin());
1615 TEST(LazyCallGraphTest
, InternalRefEdgeToCall
) {
1616 LLVMContext Context
;
1617 // Basic tests for making a ref edge a call. This hits the basics of the
1619 std::unique_ptr
<Module
> M
=
1620 parseAssembly(Context
, "define void @a() {\n"
1624 " store void()* @d, void()** undef\n"
1627 "define void @b() {\n"
1629 " store void()* @c, void()** undef\n"
1633 "define void @c() {\n"
1635 " store void()* @b, void()** undef\n"
1639 "define void @d() {\n"
1641 " store void()* @a, void()** undef\n"
1644 LazyCallGraph CG
= buildCG(*M
);
1646 // Force the graph to be fully expanded.
1648 auto I
= CG
.postorder_ref_scc_begin();
1649 LazyCallGraph::RefSCC
&RC
= *I
++;
1650 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
1652 LazyCallGraph::Node
&A
= *CG
.lookup(lookupFunction(*M
, "a"));
1653 LazyCallGraph::Node
&B
= *CG
.lookup(lookupFunction(*M
, "b"));
1654 LazyCallGraph::Node
&C
= *CG
.lookup(lookupFunction(*M
, "c"));
1655 LazyCallGraph::Node
&D
= *CG
.lookup(lookupFunction(*M
, "d"));
1656 LazyCallGraph::SCC
&AC
= *CG
.lookupSCC(A
);
1657 LazyCallGraph::SCC
&BC
= *CG
.lookupSCC(B
);
1658 LazyCallGraph::SCC
&CC
= *CG
.lookupSCC(C
);
1659 LazyCallGraph::SCC
&DC
= *CG
.lookupSCC(D
);
1661 // Check the initial post-order. Note that B and C could be flipped here (and
1662 // in our mutation) without changing the nature of this test.
1663 ASSERT_EQ(4, RC
.size());
1664 EXPECT_EQ(&DC
, &RC
[0]);
1665 EXPECT_EQ(&BC
, &RC
[1]);
1666 EXPECT_EQ(&CC
, &RC
[2]);
1667 EXPECT_EQ(&AC
, &RC
[3]);
1669 // Switch the ref edge from A -> D to a call edge. This should have no
1670 // effect as it is already in postorder and no new cycles are formed.
1671 EXPECT_FALSE(RC
.switchInternalEdgeToCall(A
, D
));
1672 ASSERT_EQ(4, RC
.size());
1673 EXPECT_EQ(&DC
, &RC
[0]);
1674 EXPECT_EQ(&BC
, &RC
[1]);
1675 EXPECT_EQ(&CC
, &RC
[2]);
1676 EXPECT_EQ(&AC
, &RC
[3]);
1678 // Switch B -> C to a call edge. This doesn't form any new cycles but does
1679 // require reordering the SCCs.
1680 EXPECT_FALSE(RC
.switchInternalEdgeToCall(B
, C
));
1681 ASSERT_EQ(4, RC
.size());
1682 EXPECT_EQ(&DC
, &RC
[0]);
1683 EXPECT_EQ(&CC
, &RC
[1]);
1684 EXPECT_EQ(&BC
, &RC
[2]);
1685 EXPECT_EQ(&AC
, &RC
[3]);
1687 // Switch C -> B to a call edge. This forms a cycle and forces merging SCCs.
1688 EXPECT_TRUE(RC
.switchInternalEdgeToCall(C
, B
, [&](ArrayRef
<LazyCallGraph::SCC
*> MergedCs
) {
1689 ASSERT_EQ(1u, MergedCs
.size());
1690 EXPECT_EQ(&CC
, MergedCs
[0]);
1692 ASSERT_EQ(3, RC
.size());
1693 EXPECT_EQ(&DC
, &RC
[0]);
1694 EXPECT_EQ(&BC
, &RC
[1]);
1695 EXPECT_EQ(&AC
, &RC
[2]);
1696 EXPECT_EQ(2, BC
.size());
1697 EXPECT_EQ(&BC
, CG
.lookupSCC(B
));
1698 EXPECT_EQ(&BC
, CG
.lookupSCC(C
));
1701 TEST(LazyCallGraphTest
, InternalRefEdgeToCallNoCycleInterleaved
) {
1702 LLVMContext Context
;
1703 // Test for having a post-order prior to changing a ref edge to a call edge
1704 // with SCCs connecting to the source and connecting to the target, but not
1705 // connecting to both, interleaved between the source and target. This
1706 // ensures we correctly partition the range rather than simply moving one or
1708 std::unique_ptr
<Module
> M
=
1709 parseAssembly(Context
, "define void @a() {\n"
1711 " call void @b1()\n"
1712 " call void @c1()\n"
1715 "define void @b1() {\n"
1717 " call void @c1()\n"
1718 " call void @b2()\n"
1721 "define void @c1() {\n"
1723 " call void @b2()\n"
1724 " call void @c2()\n"
1727 "define void @b2() {\n"
1729 " call void @c2()\n"
1730 " call void @b3()\n"
1733 "define void @c2() {\n"
1735 " call void @b3()\n"
1736 " call void @c3()\n"
1739 "define void @b3() {\n"
1741 " call void @c3()\n"
1745 "define void @c3() {\n"
1747 " store void()* @b1, void()** undef\n"
1751 "define void @d() {\n"
1753 " store void()* @a, void()** undef\n"
1756 LazyCallGraph CG
= buildCG(*M
);
1758 // Force the graph to be fully expanded.
1760 auto I
= CG
.postorder_ref_scc_begin();
1761 LazyCallGraph::RefSCC
&RC
= *I
++;
1762 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
1764 LazyCallGraph::Node
&A
= *CG
.lookup(lookupFunction(*M
, "a"));
1765 LazyCallGraph::Node
&B1
= *CG
.lookup(lookupFunction(*M
, "b1"));
1766 LazyCallGraph::Node
&B2
= *CG
.lookup(lookupFunction(*M
, "b2"));
1767 LazyCallGraph::Node
&B3
= *CG
.lookup(lookupFunction(*M
, "b3"));
1768 LazyCallGraph::Node
&C1
= *CG
.lookup(lookupFunction(*M
, "c1"));
1769 LazyCallGraph::Node
&C2
= *CG
.lookup(lookupFunction(*M
, "c2"));
1770 LazyCallGraph::Node
&C3
= *CG
.lookup(lookupFunction(*M
, "c3"));
1771 LazyCallGraph::Node
&D
= *CG
.lookup(lookupFunction(*M
, "d"));
1772 LazyCallGraph::SCC
&AC
= *CG
.lookupSCC(A
);
1773 LazyCallGraph::SCC
&B1C
= *CG
.lookupSCC(B1
);
1774 LazyCallGraph::SCC
&B2C
= *CG
.lookupSCC(B2
);
1775 LazyCallGraph::SCC
&B3C
= *CG
.lookupSCC(B3
);
1776 LazyCallGraph::SCC
&C1C
= *CG
.lookupSCC(C1
);
1777 LazyCallGraph::SCC
&C2C
= *CG
.lookupSCC(C2
);
1778 LazyCallGraph::SCC
&C3C
= *CG
.lookupSCC(C3
);
1779 LazyCallGraph::SCC
&DC
= *CG
.lookupSCC(D
);
1781 // Several call edges are initially present to force a particual post-order.
1782 // Remove them now, leaving an interleaved post-order pattern.
1783 RC
.switchTrivialInternalEdgeToRef(B3
, C3
);
1784 RC
.switchTrivialInternalEdgeToRef(C2
, B3
);
1785 RC
.switchTrivialInternalEdgeToRef(B2
, C2
);
1786 RC
.switchTrivialInternalEdgeToRef(C1
, B2
);
1787 RC
.switchTrivialInternalEdgeToRef(B1
, C1
);
1789 // Check the initial post-order. We ensure this order with the extra edges
1790 // that are nuked above.
1791 ASSERT_EQ(8, RC
.size());
1792 EXPECT_EQ(&DC
, &RC
[0]);
1793 EXPECT_EQ(&C3C
, &RC
[1]);
1794 EXPECT_EQ(&B3C
, &RC
[2]);
1795 EXPECT_EQ(&C2C
, &RC
[3]);
1796 EXPECT_EQ(&B2C
, &RC
[4]);
1797 EXPECT_EQ(&C1C
, &RC
[5]);
1798 EXPECT_EQ(&B1C
, &RC
[6]);
1799 EXPECT_EQ(&AC
, &RC
[7]);
1801 // Switch C3 -> B1 to a call edge. This doesn't form any new cycles but does
1802 // require reordering the SCCs in the face of tricky internal node
1804 EXPECT_FALSE(RC
.switchInternalEdgeToCall(C3
, B1
));
1805 ASSERT_EQ(8, RC
.size());
1806 EXPECT_EQ(&DC
, &RC
[0]);
1807 EXPECT_EQ(&B3C
, &RC
[1]);
1808 EXPECT_EQ(&B2C
, &RC
[2]);
1809 EXPECT_EQ(&B1C
, &RC
[3]);
1810 EXPECT_EQ(&C3C
, &RC
[4]);
1811 EXPECT_EQ(&C2C
, &RC
[5]);
1812 EXPECT_EQ(&C1C
, &RC
[6]);
1813 EXPECT_EQ(&AC
, &RC
[7]);
1816 TEST(LazyCallGraphTest
, InternalRefEdgeToCallBothPartitionAndMerge
) {
1817 LLVMContext Context
;
1818 // Test for having a postorder where between the source and target are all
1819 // three kinds of other SCCs:
1820 // 1) One connected to the target only that have to be shifted below the
1822 // 2) One connected to the source only that have to be shifted below the
1824 // 3) One connected to both source and target that has to remain and get
1827 // To achieve this we construct a heavily connected graph to force
1828 // a particular post-order. Then we remove the forcing edges and connect
1831 // Diagram for the graph we want on the left and the graph we use to force
1832 // the ordering on the right. Edges ponit down or right.
1844 // And we form a cycle by connecting F to B.
1845 std::unique_ptr
<Module
> M
=
1846 parseAssembly(Context
, "define void @a() {\n"
1852 "define void @b() {\n"
1858 "define void @c() {\n"
1864 "define void @d() {\n"
1870 "define void @e() {\n"
1875 "define void @f() {\n"
1877 " store void()* @b, void()** undef\n"
1881 "define void @g() {\n"
1883 " store void()* @a, void()** undef\n"
1886 LazyCallGraph CG
= buildCG(*M
);
1888 // Force the graph to be fully expanded.
1890 auto I
= CG
.postorder_ref_scc_begin();
1891 LazyCallGraph::RefSCC
&RC
= *I
++;
1892 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
1894 LazyCallGraph::Node
&A
= *CG
.lookup(lookupFunction(*M
, "a"));
1895 LazyCallGraph::Node
&B
= *CG
.lookup(lookupFunction(*M
, "b"));
1896 LazyCallGraph::Node
&C
= *CG
.lookup(lookupFunction(*M
, "c"));
1897 LazyCallGraph::Node
&D
= *CG
.lookup(lookupFunction(*M
, "d"));
1898 LazyCallGraph::Node
&E
= *CG
.lookup(lookupFunction(*M
, "e"));
1899 LazyCallGraph::Node
&F
= *CG
.lookup(lookupFunction(*M
, "f"));
1900 LazyCallGraph::Node
&G
= *CG
.lookup(lookupFunction(*M
, "g"));
1901 LazyCallGraph::SCC
&AC
= *CG
.lookupSCC(A
);
1902 LazyCallGraph::SCC
&BC
= *CG
.lookupSCC(B
);
1903 LazyCallGraph::SCC
&CC
= *CG
.lookupSCC(C
);
1904 LazyCallGraph::SCC
&DC
= *CG
.lookupSCC(D
);
1905 LazyCallGraph::SCC
&EC
= *CG
.lookupSCC(E
);
1906 LazyCallGraph::SCC
&FC
= *CG
.lookupSCC(F
);
1907 LazyCallGraph::SCC
&GC
= *CG
.lookupSCC(G
);
1909 // Remove the extra edges that were used to force a particular post-order.
1910 RC
.switchTrivialInternalEdgeToRef(C
, D
);
1911 RC
.switchTrivialInternalEdgeToRef(D
, E
);
1913 // Check the initial post-order. We ensure this order with the extra edges
1914 // that are nuked above.
1915 ASSERT_EQ(7, RC
.size());
1916 EXPECT_EQ(&GC
, &RC
[0]);
1917 EXPECT_EQ(&FC
, &RC
[1]);
1918 EXPECT_EQ(&EC
, &RC
[2]);
1919 EXPECT_EQ(&DC
, &RC
[3]);
1920 EXPECT_EQ(&CC
, &RC
[4]);
1921 EXPECT_EQ(&BC
, &RC
[5]);
1922 EXPECT_EQ(&AC
, &RC
[6]);
1924 // Switch F -> B to a call edge. This merges B, D, and F into a single SCC,
1925 // and has to place the C and E SCCs on either side of it:
1935 EXPECT_TRUE(RC
.switchInternalEdgeToCall(
1936 F
, B
, [&](ArrayRef
<LazyCallGraph::SCC
*> MergedCs
) {
1937 ASSERT_EQ(2u, MergedCs
.size());
1938 EXPECT_EQ(&FC
, MergedCs
[0]);
1939 EXPECT_EQ(&DC
, MergedCs
[1]);
1941 EXPECT_EQ(3, BC
.size());
1943 // And make sure the postorder was updated.
1944 ASSERT_EQ(5, RC
.size());
1945 EXPECT_EQ(&GC
, &RC
[0]);
1946 EXPECT_EQ(&CC
, &RC
[1]);
1947 EXPECT_EQ(&BC
, &RC
[2]);
1948 EXPECT_EQ(&EC
, &RC
[3]);
1949 EXPECT_EQ(&AC
, &RC
[4]);
1952 // Test for IR containing constants using blockaddress constant expressions.
1953 // These are truly unique constructs: constant expressions with non-constant
1955 TEST(LazyCallGraphTest
, HandleBlockAddress
) {
1956 LLVMContext Context
;
1957 std::unique_ptr
<Module
> M
=
1958 parseAssembly(Context
, "define void @f() {\n"
1964 "define void @g(i8** %ptr) {\n"
1966 " store i8* blockaddress(@f, %bb), i8** %ptr\n"
1969 LazyCallGraph CG
= buildCG(*M
);
1972 auto I
= CG
.postorder_ref_scc_begin();
1973 LazyCallGraph::RefSCC
&FRC
= *I
++;
1974 LazyCallGraph::RefSCC
&GRC
= *I
++;
1975 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
1977 LazyCallGraph::Node
&F
= *CG
.lookup(lookupFunction(*M
, "f"));
1978 LazyCallGraph::Node
&G
= *CG
.lookup(lookupFunction(*M
, "g"));
1979 EXPECT_EQ(&FRC
, CG
.lookupRefSCC(F
));
1980 EXPECT_EQ(&GRC
, CG
.lookupRefSCC(G
));
1981 EXPECT_FALSE(GRC
.isParentOf(FRC
));
1982 EXPECT_FALSE(FRC
.isParentOf(GRC
));
1985 // Test that a blockaddress that refers to itself creates no new RefSCC
1986 // connections. https://bugs.llvm.org/show_bug.cgi?id=40722
1987 TEST(LazyCallGraphTest
, HandleBlockAddress2
) {
1988 LLVMContext Context
;
1989 std::unique_ptr
<Module
> M
=
1990 parseAssembly(Context
, "define void @f() {\n"
1993 "define void @g(i8** %ptr) {\n"
1995 " store i8* blockaddress(@g, %bb), i8** %ptr\n"
1998 LazyCallGraph CG
= buildCG(*M
);
2001 auto I
= CG
.postorder_ref_scc_begin();
2002 LazyCallGraph::RefSCC
&FRC
= *I
++;
2003 LazyCallGraph::RefSCC
&GRC
= *I
++;
2004 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2006 LazyCallGraph::Node
&F
= *CG
.lookup(lookupFunction(*M
, "f"));
2007 LazyCallGraph::Node
&G
= *CG
.lookup(lookupFunction(*M
, "g"));
2008 EXPECT_EQ(&FRC
, CG
.lookupRefSCC(F
));
2009 EXPECT_EQ(&GRC
, CG
.lookupRefSCC(G
));
2010 EXPECT_FALSE(GRC
.isParentOf(FRC
));
2011 EXPECT_FALSE(FRC
.isParentOf(GRC
));
2014 TEST(LazyCallGraphTest
, ReplaceNodeFunction
) {
2015 LLVMContext Context
;
2016 // A graph with several different kinds of edges pointing at a particular
2018 std::unique_ptr
<Module
> M
=
2019 parseAssembly(Context
,
2020 "define void @a(i8** %ptr) {\n"
2022 " store i8* bitcast (void(i8**)* @d to i8*), i8** %ptr\n"
2025 "define void @b(i8** %ptr) {\n"
2027 " store i8* bitcast (void(i8**)* @d to i8*), i8** %ptr\n"
2028 " store i8* bitcast (void(i8**)* @d to i8*), i8** %ptr\n"
2029 " call void @d(i8** %ptr)"
2032 "define void @c(i8** %ptr) {\n"
2034 " call void @d(i8** %ptr)"
2035 " call void @d(i8** %ptr)"
2036 " store i8* bitcast (void(i8**)* @d to i8*), i8** %ptr\n"
2039 "define void @d(i8** %ptr) {\n"
2041 " store i8* bitcast (void(i8**)* @b to i8*), i8** %ptr\n"
2042 " call void @c(i8** %ptr)"
2043 " call void @d(i8** %ptr)"
2044 " store i8* bitcast (void(i8**)* @d to i8*), i8** %ptr\n"
2047 LazyCallGraph CG
= buildCG(*M
);
2049 // Force the graph to be fully expanded.
2051 auto I
= CG
.postorder_ref_scc_begin();
2052 LazyCallGraph::RefSCC
&RC1
= *I
++;
2053 LazyCallGraph::RefSCC
&RC2
= *I
++;
2054 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2056 ASSERT_EQ(2, RC1
.size());
2057 LazyCallGraph::SCC
&C1
= RC1
[0];
2058 LazyCallGraph::SCC
&C2
= RC1
[1];
2060 LazyCallGraph::Node
&AN
= *CG
.lookup(lookupFunction(*M
, "a"));
2061 LazyCallGraph::Node
&BN
= *CG
.lookup(lookupFunction(*M
, "b"));
2062 LazyCallGraph::Node
&CN
= *CG
.lookup(lookupFunction(*M
, "c"));
2063 LazyCallGraph::Node
&DN
= *CG
.lookup(lookupFunction(*M
, "d"));
2064 EXPECT_EQ(&C1
, CG
.lookupSCC(DN
));
2065 EXPECT_EQ(&C1
, CG
.lookupSCC(CN
));
2066 EXPECT_EQ(&C2
, CG
.lookupSCC(BN
));
2067 EXPECT_EQ(&RC1
, CG
.lookupRefSCC(DN
));
2068 EXPECT_EQ(&RC1
, CG
.lookupRefSCC(CN
));
2069 EXPECT_EQ(&RC1
, CG
.lookupRefSCC(BN
));
2070 EXPECT_EQ(&RC2
, CG
.lookupRefSCC(AN
));
2072 // Now we need to build a new function 'e' with the same signature as 'd'.
2073 Function
&D
= DN
.getFunction();
2074 Function
&E
= *Function::Create(D
.getFunctionType(), D
.getLinkage(), "e");
2075 D
.getParent()->getFunctionList().insert(D
.getIterator(), &E
);
2077 // Change each use of 'd' to use 'e'. This is particularly easy as they have
2079 D
.replaceAllUsesWith(&E
);
2081 // Splice the body of the old function into the new one.
2082 E
.splice(E
.begin(), &D
);
2083 // And fix up the one argument.
2084 D
.arg_begin()->replaceAllUsesWith(&*E
.arg_begin());
2085 E
.arg_begin()->takeName(&*D
.arg_begin());
2087 // Now replace the function in the graph.
2088 RC1
.replaceNodeFunction(DN
, E
);
2090 EXPECT_EQ(&E
, &DN
.getFunction());
2091 EXPECT_EQ(&DN
, &(*CN
)[DN
].getNode());
2092 EXPECT_EQ(&DN
, &(*BN
)[DN
].getNode());
2095 TEST(LazyCallGraphTest
, RemoveFunctionWithSpuriousRef
) {
2096 LLVMContext Context
;
2097 // A graph with a couple of RefSCCs.
2098 std::unique_ptr
<Module
> M
=
2099 parseAssembly(Context
,
2100 "define void @a(i8** %ptr) {\n"
2102 " store i8* bitcast (void(i8**)* @d to i8*), i8** %ptr\n"
2105 "define void @b(i8** %ptr) {\n"
2107 " store i8* bitcast (void(i8**)* @c to i8*), i8** %ptr\n"
2110 "define void @c(i8** %ptr) {\n"
2112 " call void @d(i8** %ptr)"
2115 "define void @d(i8** %ptr) {\n"
2117 " call void @c(i8** %ptr)"
2118 " store i8* bitcast (void(i8**)* @b to i8*), i8** %ptr\n"
2121 "define void @dead() {\n"
2125 LazyCallGraph CG
= buildCG(*M
);
2127 // Insert spurious ref edges.
2128 LazyCallGraph::Node
&AN
= CG
.get(lookupFunction(*M
, "a"));
2129 LazyCallGraph::Node
&BN
= CG
.get(lookupFunction(*M
, "b"));
2130 LazyCallGraph::Node
&CN
= CG
.get(lookupFunction(*M
, "c"));
2131 LazyCallGraph::Node
&DN
= CG
.get(lookupFunction(*M
, "d"));
2132 LazyCallGraph::Node
&DeadN
= CG
.get(lookupFunction(*M
, "dead"));
2138 CG
.insertEdge(AN
, DeadN
, LazyCallGraph::Edge::Ref
);
2139 CG
.insertEdge(BN
, DeadN
, LazyCallGraph::Edge::Ref
);
2140 CG
.insertEdge(CN
, DeadN
, LazyCallGraph::Edge::Ref
);
2141 CG
.insertEdge(DN
, DeadN
, LazyCallGraph::Edge::Ref
);
2143 // Force the graph to be fully expanded.
2145 auto I
= CG
.postorder_ref_scc_begin();
2146 LazyCallGraph::RefSCC
&DeadRC
= *I
++;
2147 LazyCallGraph::RefSCC
&RC1
= *I
++;
2148 LazyCallGraph::RefSCC
&RC2
= *I
++;
2149 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2151 ASSERT_EQ(2, RC1
.size());
2152 LazyCallGraph::SCC
&C1
= RC1
[0];
2153 LazyCallGraph::SCC
&C2
= RC1
[1];
2155 EXPECT_EQ(&DeadRC
, CG
.lookupRefSCC(DeadN
));
2156 EXPECT_EQ(&C1
, CG
.lookupSCC(DN
));
2157 EXPECT_EQ(&C1
, CG
.lookupSCC(CN
));
2158 EXPECT_EQ(&C2
, CG
.lookupSCC(BN
));
2159 EXPECT_EQ(&RC1
, CG
.lookupRefSCC(DN
));
2160 EXPECT_EQ(&RC1
, CG
.lookupRefSCC(CN
));
2161 EXPECT_EQ(&RC1
, CG
.lookupRefSCC(BN
));
2162 EXPECT_EQ(&RC2
, CG
.lookupRefSCC(AN
));
2164 // Now delete 'dead'. There are no uses of this function but there are
2165 // spurious references.
2166 CG
.removeDeadFunction(DeadN
.getFunction());
2168 // The only observable change should be that the RefSCC is gone from the
2169 // postorder sequence.
2170 I
= CG
.postorder_ref_scc_begin();
2171 EXPECT_EQ(&RC1
, &*I
++);
2172 EXPECT_EQ(&RC2
, &*I
++);
2173 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2176 TEST(LazyCallGraphTest
, RemoveFunctionWithSpuriousRefRecursive
) {
2177 LLVMContext Context
;
2178 std::unique_ptr
<Module
> M
=
2179 parseAssembly(Context
, "define void @a(ptr %p) {\n"
2180 " store ptr @b, ptr %p\n"
2183 "define void @b(ptr %p) {\n"
2184 " store ptr @c, ptr %p\n"
2187 "define void @c(ptr %p) {\n"
2190 LazyCallGraph CG
= buildCG(*M
);
2192 LazyCallGraph::Node
&AN
= CG
.get(lookupFunction(*M
, "a"));
2193 LazyCallGraph::Node
&BN
= CG
.get(lookupFunction(*M
, "b"));
2194 LazyCallGraph::Node
&CN
= CG
.get(lookupFunction(*M
, "c"));
2198 // Insert spurious ref edge.
2199 CG
.insertEdge(CN
, AN
, LazyCallGraph::Edge::Ref
);
2201 // Force the graph to be fully expanded.
2203 auto I
= CG
.postorder_ref_scc_begin();
2204 LazyCallGraph::RefSCC
&RC
= *I
++;
2205 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2207 ASSERT_EQ(RC
.size(), 3);
2209 EXPECT_EQ(&RC
, CG
.lookupRefSCC(AN
));
2210 EXPECT_EQ(&RC
, CG
.lookupRefSCC(BN
));
2211 EXPECT_EQ(&RC
, CG
.lookupRefSCC(CN
));
2213 // Now delete 'a'. There are no uses of this function but there are
2214 // spurious references.
2215 CG
.removeDeadFunction(AN
.getFunction());
2217 // The only observable change should be that the RefSCC is gone from the
2218 // postorder sequence.
2219 I
= CG
.postorder_ref_scc_begin();
2220 EXPECT_EQ(CG
.lookupRefSCC(CN
), &*I
++);
2221 EXPECT_EQ(CG
.lookupRefSCC(BN
), &*I
++);
2222 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2225 TEST(LazyCallGraphTest
, RemoveFunctionWithSpuriousRefRecursive2
) {
2226 LLVMContext Context
;
2227 std::unique_ptr
<Module
> M
=
2228 parseAssembly(Context
, "define void @a(ptr %p) {\n"
2229 " store ptr @b, ptr %p\n"
2232 "define void @b(ptr %p) {\n"
2233 " store ptr @c, ptr %p\n"
2236 "define void @c(ptr %p) {\n"
2237 " store ptr @b, ptr %p\n"
2238 " store ptr @d, ptr %p\n"
2241 "define void @d(ptr %p) {\n"
2244 LazyCallGraph CG
= buildCG(*M
);
2246 LazyCallGraph::Node
&AN
= CG
.get(lookupFunction(*M
, "a"));
2247 LazyCallGraph::Node
&BN
= CG
.get(lookupFunction(*M
, "b"));
2248 LazyCallGraph::Node
&CN
= CG
.get(lookupFunction(*M
, "c"));
2249 LazyCallGraph::Node
&DN
= CG
.get(lookupFunction(*M
, "d"));
2254 // Insert spurious ref edge.
2255 CG
.insertEdge(DN
, AN
, LazyCallGraph::Edge::Ref
);
2257 // Force the graph to be fully expanded.
2259 auto I
= CG
.postorder_ref_scc_begin();
2260 LazyCallGraph::RefSCC
&RC
= *I
++;
2261 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2263 ASSERT_EQ(4, RC
.size());
2265 EXPECT_EQ(&RC
, CG
.lookupRefSCC(AN
));
2266 EXPECT_EQ(&RC
, CG
.lookupRefSCC(BN
));
2267 EXPECT_EQ(&RC
, CG
.lookupRefSCC(CN
));
2268 EXPECT_EQ(&RC
, CG
.lookupRefSCC(DN
));
2270 // Now delete 'a'. There are no uses of this function but there are
2271 // spurious references.
2272 CG
.removeDeadFunction(AN
.getFunction());
2274 // The only observable change should be that the RefSCC is gone from the
2275 // postorder sequence.
2276 I
= CG
.postorder_ref_scc_begin();
2277 EXPECT_EQ(CG
.lookupRefSCC(DN
), &*I
++);
2278 EXPECT_EQ(CG
.lookupRefSCC(CN
), &*I
);
2279 EXPECT_EQ(CG
.lookupRefSCC(BN
), &*I
++);
2280 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2283 TEST(LazyCallGraphTest
, RemoveFunctionWithSpuriousRefRecursive3
) {
2284 LLVMContext Context
;
2285 std::unique_ptr
<Module
> M
=
2286 parseAssembly(Context
, "define void @a(ptr %p) {\n"
2287 " store ptr @b, ptr %p\n"
2290 "define void @b(ptr %p) {\n"
2291 " store ptr @c, ptr %p\n"
2294 "define void @c(ptr %p) {\n"
2297 LazyCallGraph CG
= buildCG(*M
);
2299 LazyCallGraph::Node
&AN
= CG
.get(lookupFunction(*M
, "a"));
2300 LazyCallGraph::Node
&BN
= CG
.get(lookupFunction(*M
, "b"));
2301 LazyCallGraph::Node
&CN
= CG
.get(lookupFunction(*M
, "c"));
2305 // Insert spurious ref edges.
2306 CG
.insertEdge(CN
, AN
, LazyCallGraph::Edge::Ref
);
2307 CG
.insertEdge(BN
, AN
, LazyCallGraph::Edge::Ref
);
2309 // Force the graph to be fully expanded.
2311 auto I
= CG
.postorder_ref_scc_begin();
2312 LazyCallGraph::RefSCC
&RC
= *I
++;
2313 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2315 ASSERT_EQ(RC
.size(), 3);
2317 EXPECT_EQ(&RC
, CG
.lookupRefSCC(AN
));
2318 EXPECT_EQ(&RC
, CG
.lookupRefSCC(BN
));
2319 EXPECT_EQ(&RC
, CG
.lookupRefSCC(CN
));
2321 // Now delete 'a'. There are no uses of this function but there are
2322 // spurious references.
2323 CG
.removeDeadFunction(AN
.getFunction());
2325 // The only observable change should be that the RefSCC is gone from the
2326 // postorder sequence.
2327 I
= CG
.postorder_ref_scc_begin();
2328 EXPECT_EQ(CG
.lookupRefSCC(CN
), &*I
++);
2329 EXPECT_EQ(CG
.lookupRefSCC(BN
), &*I
++);
2330 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2333 TEST(LazyCallGraphTest
, AddSplitFunction1
) {
2334 LLVMContext Context
;
2335 std::unique_ptr
<Module
> M
= parseAssembly(Context
, "define void @f() {\n"
2338 LazyCallGraph CG
= buildCG(*M
);
2340 Function
&F
= lookupFunction(*M
, "f");
2341 LazyCallGraph::Node
&FN
= CG
.get(F
);
2343 // Force the graph to be fully expanded.
2345 auto I
= CG
.postorder_ref_scc_begin();
2346 LazyCallGraph::RefSCC
*ORC
= &*I
++;
2347 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2349 auto *G
= Function::Create(F
.getFunctionType(), F
.getLinkage(),
2350 F
.getAddressSpace(), "g", F
.getParent());
2351 BasicBlock
*GBB
= BasicBlock::Create(Context
, "", G
);
2352 (void)ReturnInst::Create(Context
, GBB
);
2354 // Create f -call-> g.
2355 (void)CallInst::Create(G
, {}, "", &*F
.getEntryBlock().begin());
2357 EXPECT_FALSE(verifyModule(*M
, &errs()));
2359 CG
.addSplitFunction(F
, *G
);
2361 LazyCallGraph::Node
*GN
= CG
.lookup(*G
);
2364 I
= CG
.postorder_ref_scc_begin();
2365 LazyCallGraph::RefSCC
*RC1
= &*I
++;
2366 EXPECT_EQ(RC1
, CG
.lookupRefSCC(*GN
));
2367 LazyCallGraph::RefSCC
*RC2
= &*I
++;
2368 EXPECT_EQ(RC2
, ORC
);
2369 EXPECT_EQ(RC2
, CG
.lookupRefSCC(FN
));
2370 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2373 TEST(LazyCallGraphTest
, AddSplitFunction2
) {
2374 LLVMContext Context
;
2375 std::unique_ptr
<Module
> M
= parseAssembly(Context
, "define void @f() {\n"
2378 LazyCallGraph CG
= buildCG(*M
);
2380 Function
&F
= lookupFunction(*M
, "f");
2381 LazyCallGraph::Node
&FN
= CG
.get(F
);
2383 // Force the graph to be fully expanded.
2385 auto I
= CG
.postorder_ref_scc_begin();
2386 LazyCallGraph::RefSCC
*ORC
= &*I
++;
2387 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2389 auto *G
= Function::Create(F
.getFunctionType(), F
.getLinkage(),
2390 F
.getAddressSpace(), "g", F
.getParent());
2391 BasicBlock
*GBB
= BasicBlock::Create(Context
, "", G
);
2392 (void)ReturnInst::Create(Context
, GBB
);
2394 // Create f -ref-> g.
2395 (void)CastInst::CreatePointerCast(G
, Type::getInt8PtrTy(Context
), "",
2396 &*F
.getEntryBlock().begin());
2398 EXPECT_FALSE(verifyModule(*M
, &errs()));
2400 CG
.addSplitFunction(F
, *G
);
2402 LazyCallGraph::Node
*GN
= CG
.lookup(*G
);
2405 I
= CG
.postorder_ref_scc_begin();
2406 LazyCallGraph::RefSCC
*RC1
= &*I
++;
2407 EXPECT_EQ(RC1
, CG
.lookupRefSCC(*GN
));
2408 LazyCallGraph::RefSCC
*RC2
= &*I
++;
2409 EXPECT_EQ(RC2
, ORC
);
2410 EXPECT_EQ(RC2
, CG
.lookupRefSCC(FN
));
2411 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2414 TEST(LazyCallGraphTest
, AddSplitFunction3
) {
2415 LLVMContext Context
;
2416 std::unique_ptr
<Module
> M
= parseAssembly(Context
, "define void @f() {\n"
2419 LazyCallGraph CG
= buildCG(*M
);
2421 Function
&F
= lookupFunction(*M
, "f");
2422 LazyCallGraph::Node
&FN
= CG
.get(F
);
2424 // Force the graph to be fully expanded.
2426 auto I
= CG
.postorder_ref_scc_begin();
2427 LazyCallGraph::RefSCC
*ORC
= &*I
++;
2428 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2430 auto *G
= Function::Create(F
.getFunctionType(), F
.getLinkage(),
2431 F
.getAddressSpace(), "g", F
.getParent());
2432 BasicBlock
*GBB
= BasicBlock::Create(Context
, "", G
);
2433 // Create g -ref-> f.
2434 (void)CastInst::CreatePointerCast(&F
, Type::getInt8PtrTy(Context
), "", GBB
);
2435 (void)ReturnInst::Create(Context
, GBB
);
2437 // Create f -call-> g.
2438 (void)CallInst::Create(G
, {}, "", &*F
.getEntryBlock().begin());
2440 EXPECT_FALSE(verifyModule(*M
, &errs()));
2442 CG
.addSplitFunction(F
, *G
);
2444 LazyCallGraph::Node
*GN
= CG
.lookup(*G
);
2447 I
= CG
.postorder_ref_scc_begin();
2448 LazyCallGraph::RefSCC
*RC
= &*I
++;
2449 EXPECT_EQ(RC
, CG
.lookupRefSCC(*GN
));
2451 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2453 EXPECT_EQ(2, RC
->size());
2454 EXPECT_EQ(CG
.lookupSCC(*GN
), &(*RC
)[0]);
2455 EXPECT_EQ(CG
.lookupSCC(FN
), &(*RC
)[1]);
2458 TEST(LazyCallGraphTest
, AddSplitFunction4
) {
2459 LLVMContext Context
;
2460 std::unique_ptr
<Module
> M
= parseAssembly(Context
, "define void @f() {\n"
2463 LazyCallGraph CG
= buildCG(*M
);
2465 Function
&F
= lookupFunction(*M
, "f");
2466 LazyCallGraph::Node
&FN
= CG
.get(F
);
2468 // Force the graph to be fully expanded.
2470 auto I
= CG
.postorder_ref_scc_begin();
2471 LazyCallGraph::RefSCC
*ORC
= &*I
++;
2472 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2474 auto *G
= Function::Create(F
.getFunctionType(), F
.getLinkage(),
2475 F
.getAddressSpace(), "g", F
.getParent());
2476 BasicBlock
*GBB
= BasicBlock::Create(Context
, "", G
);
2477 // Create g -ref-> f.
2478 (void)CastInst::CreatePointerCast(&F
, Type::getInt8PtrTy(Context
), "", GBB
);
2479 (void)ReturnInst::Create(Context
, GBB
);
2481 // Create f -ref-> g.
2482 (void)CastInst::CreatePointerCast(G
, Type::getInt8PtrTy(Context
), "",
2483 &*F
.getEntryBlock().begin());
2485 EXPECT_FALSE(verifyModule(*M
, &errs()));
2487 CG
.addSplitFunction(F
, *G
);
2489 LazyCallGraph::Node
*GN
= CG
.lookup(*G
);
2492 I
= CG
.postorder_ref_scc_begin();
2493 LazyCallGraph::RefSCC
*RC
= &*I
++;
2494 EXPECT_EQ(RC
, CG
.lookupRefSCC(*GN
));
2496 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2498 // Order doesn't matter for sibling SCCs.
2499 EXPECT_EQ(2, RC
->size());
2500 EXPECT_EQ(&CG
.lookupSCC(*GN
)->getOuterRefSCC(), RC
);
2501 EXPECT_EQ(&CG
.lookupSCC(FN
)->getOuterRefSCC(), RC
);
2504 TEST(LazyCallGraphTest
, AddSplitFunction5
) {
2505 LLVMContext Context
;
2506 std::unique_ptr
<Module
> M
= parseAssembly(Context
, "define void @f() {\n"
2509 LazyCallGraph CG
= buildCG(*M
);
2511 Function
&F
= lookupFunction(*M
, "f");
2512 LazyCallGraph::Node
&FN
= CG
.get(F
);
2514 // Force the graph to be fully expanded.
2516 auto I
= CG
.postorder_ref_scc_begin();
2517 LazyCallGraph::RefSCC
*ORC
= &*I
++;
2518 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2520 auto *G
= Function::Create(F
.getFunctionType(), F
.getLinkage(),
2521 F
.getAddressSpace(), "g", F
.getParent());
2522 BasicBlock
*GBB
= BasicBlock::Create(Context
, "", G
);
2523 // Create g -call-> f.
2524 (void)CallInst::Create(&F
, {}, "", GBB
);
2525 (void)ReturnInst::Create(Context
, GBB
);
2527 // Create f -ref-> g.
2528 (void)CastInst::CreatePointerCast(G
, Type::getInt8PtrTy(Context
), "",
2529 &*F
.getEntryBlock().begin());
2531 EXPECT_FALSE(verifyModule(*M
, &errs()));
2533 CG
.addSplitFunction(F
, *G
);
2535 LazyCallGraph::Node
*GN
= CG
.lookup(*G
);
2538 I
= CG
.postorder_ref_scc_begin();
2539 LazyCallGraph::RefSCC
*RC
= &*I
++;
2540 EXPECT_EQ(RC
, CG
.lookupRefSCC(*GN
));
2542 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2544 EXPECT_EQ(2, RC
->size());
2545 EXPECT_EQ(CG
.lookupSCC(FN
), &(*RC
)[0]);
2546 EXPECT_EQ(CG
.lookupSCC(*GN
), &(*RC
)[1]);
2549 TEST(LazyCallGraphTest
, AddSplitFunction6
) {
2550 LLVMContext Context
;
2551 std::unique_ptr
<Module
> M
= parseAssembly(Context
, "define void @f() {\n"
2554 LazyCallGraph CG
= buildCG(*M
);
2556 Function
&F
= lookupFunction(*M
, "f");
2557 LazyCallGraph::Node
&FN
= CG
.get(F
);
2559 // Force the graph to be fully expanded.
2561 auto I
= CG
.postorder_ref_scc_begin();
2562 LazyCallGraph::RefSCC
*ORC
= &*I
++;
2563 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2565 auto *G
= Function::Create(F
.getFunctionType(), F
.getLinkage(),
2566 F
.getAddressSpace(), "g", F
.getParent());
2567 BasicBlock
*GBB
= BasicBlock::Create(Context
, "", G
);
2568 // Create g -call-> f.
2569 (void)CallInst::Create(&F
, {}, "", GBB
);
2570 (void)ReturnInst::Create(Context
, GBB
);
2572 // Create f -call-> g.
2573 (void)CallInst::Create(G
, {}, "", &*F
.getEntryBlock().begin());
2575 EXPECT_FALSE(verifyModule(*M
, &errs()));
2577 CG
.addSplitFunction(F
, *G
);
2579 LazyCallGraph::Node
*GN
= CG
.lookup(*G
);
2582 I
= CG
.postorder_ref_scc_begin();
2583 LazyCallGraph::RefSCC
*RC
= &*I
++;
2584 EXPECT_EQ(RC
, CG
.lookupRefSCC(*GN
));
2586 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2588 EXPECT_EQ(1, RC
->size());
2589 EXPECT_EQ(CG
.lookupSCC(FN
), &(*RC
)[0]);
2590 EXPECT_EQ(CG
.lookupSCC(*GN
), &(*RC
)[0]);
2593 TEST(LazyCallGraphTest
, AddSplitFunction7
) {
2594 LLVMContext Context
;
2595 std::unique_ptr
<Module
> M
= parseAssembly(Context
, "define void @f() {\n"
2596 " call void @f2()\n"
2599 "define void @f2() {\n"
2603 LazyCallGraph CG
= buildCG(*M
);
2605 Function
&F
= lookupFunction(*M
, "f");
2606 LazyCallGraph::Node
&FN
= CG
.get(F
);
2607 Function
&F2
= lookupFunction(*M
, "f2");
2608 LazyCallGraph::Node
&F2N
= CG
.get(F2
);
2610 // Force the graph to be fully expanded.
2612 auto I
= CG
.postorder_ref_scc_begin();
2613 LazyCallGraph::RefSCC
*ORC
= &*I
++;
2614 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2616 auto *G
= Function::Create(F
.getFunctionType(), F
.getLinkage(),
2617 F
.getAddressSpace(), "g", F
.getParent());
2618 BasicBlock
*GBB
= BasicBlock::Create(Context
, "", G
);
2619 // Create g -call-> f2.
2620 (void)CallInst::Create(&F2
, {}, "", GBB
);
2621 (void)ReturnInst::Create(Context
, GBB
);
2623 // Create f -call-> g.
2624 (void)CallInst::Create(G
, {}, "", &*F
.getEntryBlock().begin());
2626 EXPECT_FALSE(verifyModule(*M
, &errs()));
2628 CG
.addSplitFunction(F
, *G
);
2630 LazyCallGraph::Node
*GN
= CG
.lookup(*G
);
2633 I
= CG
.postorder_ref_scc_begin();
2634 LazyCallGraph::RefSCC
*RC
= &*I
++;
2635 EXPECT_EQ(RC
, CG
.lookupRefSCC(*GN
));
2637 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2639 EXPECT_EQ(1, RC
->size());
2640 EXPECT_EQ(CG
.lookupSCC(FN
), &(*RC
)[0]);
2641 EXPECT_EQ(CG
.lookupSCC(F2N
), &(*RC
)[0]);
2642 EXPECT_EQ(CG
.lookupSCC(*GN
), &(*RC
)[0]);
2645 TEST(LazyCallGraphTest
, AddSplitFunction8
) {
2646 LLVMContext Context
;
2647 std::unique_ptr
<Module
> M
= parseAssembly(Context
, "define void @f() {\n"
2648 " call void @f2()\n"
2651 "define void @f2() {\n"
2655 LazyCallGraph CG
= buildCG(*M
);
2657 Function
&F
= lookupFunction(*M
, "f");
2658 LazyCallGraph::Node
&FN
= CG
.get(F
);
2659 Function
&F2
= lookupFunction(*M
, "f2");
2660 LazyCallGraph::Node
&F2N
= CG
.get(F2
);
2662 // Force the graph to be fully expanded.
2664 auto I
= CG
.postorder_ref_scc_begin();
2665 LazyCallGraph::RefSCC
*ORC
= &*I
++;
2666 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2668 auto *G
= Function::Create(F
.getFunctionType(), F
.getLinkage(),
2669 F
.getAddressSpace(), "g", F
.getParent());
2670 BasicBlock
*GBB
= BasicBlock::Create(Context
, "", G
);
2671 // Create g -call-> f2.
2672 (void)CallInst::Create(&F2
, {}, "", GBB
);
2673 (void)ReturnInst::Create(Context
, GBB
);
2675 // Create f -ref-> g.
2676 (void)CastInst::CreatePointerCast(G
, Type::getInt8PtrTy(Context
), "",
2677 &*F
.getEntryBlock().begin());
2679 EXPECT_FALSE(verifyModule(*M
, &errs()));
2681 CG
.addSplitFunction(F
, *G
);
2683 LazyCallGraph::Node
*GN
= CG
.lookup(*G
);
2686 I
= CG
.postorder_ref_scc_begin();
2687 LazyCallGraph::RefSCC
*RC
= &*I
++;
2688 EXPECT_EQ(RC
, CG
.lookupRefSCC(*GN
));
2690 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2692 EXPECT_EQ(2, RC
->size());
2693 EXPECT_EQ(CG
.lookupSCC(FN
), &(*RC
)[0]);
2694 EXPECT_EQ(CG
.lookupSCC(F2N
), &(*RC
)[0]);
2695 EXPECT_EQ(CG
.lookupSCC(*GN
), &(*RC
)[1]);
2698 TEST(LazyCallGraphTest
, AddSplitFunction9
) {
2699 LLVMContext Context
;
2700 std::unique_ptr
<Module
> M
= parseAssembly(Context
, "define void @f() {\n"
2701 " call void @f2()\n"
2704 "define void @f2() {\n"
2708 LazyCallGraph CG
= buildCG(*M
);
2710 Function
&F
= lookupFunction(*M
, "f");
2711 LazyCallGraph::Node
&FN
= CG
.get(F
);
2712 Function
&F2
= lookupFunction(*M
, "f2");
2713 LazyCallGraph::Node
&F2N
= CG
.get(F2
);
2715 // Force the graph to be fully expanded.
2717 auto I
= CG
.postorder_ref_scc_begin();
2718 LazyCallGraph::RefSCC
*ORC
= &*I
++;
2719 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2721 auto *G
= Function::Create(F
.getFunctionType(), F
.getLinkage(),
2722 F
.getAddressSpace(), "g", F
.getParent());
2723 BasicBlock
*GBB
= BasicBlock::Create(Context
, "", G
);
2724 // Create g -ref-> f2.
2725 (void)CastInst::CreatePointerCast(&F2
, Type::getInt8PtrTy(Context
), "", GBB
);
2726 (void)ReturnInst::Create(Context
, GBB
);
2728 // Create f -call-> g.
2729 (void)CallInst::Create(G
, {}, "", &*F
.getEntryBlock().begin());
2731 EXPECT_FALSE(verifyModule(*M
, &errs()));
2733 CG
.addSplitFunction(F
, *G
);
2735 LazyCallGraph::Node
*GN
= CG
.lookup(*G
);
2738 I
= CG
.postorder_ref_scc_begin();
2739 LazyCallGraph::RefSCC
*RC
= &*I
++;
2740 EXPECT_EQ(RC
, CG
.lookupRefSCC(*GN
));
2742 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2744 EXPECT_EQ(2, RC
->size());
2745 EXPECT_EQ(CG
.lookupSCC(*GN
), &(*RC
)[0]);
2746 EXPECT_EQ(CG
.lookupSCC(FN
), &(*RC
)[1]);
2747 EXPECT_EQ(CG
.lookupSCC(F2N
), &(*RC
)[1]);
2750 TEST(LazyCallGraphTest
, AddSplitFunctions1
) {
2751 LLVMContext Context
;
2752 std::unique_ptr
<Module
> M
= parseAssembly(Context
, "define void @f() {\n"
2755 LazyCallGraph CG
= buildCG(*M
);
2757 Function
&F
= lookupFunction(*M
, "f");
2758 LazyCallGraph::Node
&FN
= CG
.get(F
);
2760 // Force the graph to be fully expanded.
2762 auto I
= CG
.postorder_ref_scc_begin();
2763 LazyCallGraph::RefSCC
*ORC
= &*I
++;
2764 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2766 auto *G
= Function::Create(F
.getFunctionType(), F
.getLinkage(),
2767 F
.getAddressSpace(), "g", F
.getParent());
2768 BasicBlock
*GBB
= BasicBlock::Create(Context
, "", G
);
2769 (void)ReturnInst::Create(Context
, GBB
);
2771 // Create f -ref-> g.
2772 (void)CastInst::CreatePointerCast(G
, Type::getInt8PtrTy(Context
), "",
2773 &*F
.getEntryBlock().begin());
2775 EXPECT_FALSE(verifyModule(*M
, &errs()));
2777 CG
.addSplitRefRecursiveFunctions(F
, SmallVector
<Function
*, 1>({G
}));
2779 LazyCallGraph::Node
*GN
= CG
.lookup(*G
);
2782 I
= CG
.postorder_ref_scc_begin();
2783 LazyCallGraph::RefSCC
*RC1
= &*I
++;
2784 EXPECT_EQ(RC1
, CG
.lookupRefSCC(*GN
));
2785 LazyCallGraph::RefSCC
*RC2
= &*I
++;
2786 EXPECT_EQ(RC2
, ORC
);
2787 EXPECT_EQ(RC2
, CG
.lookupRefSCC(FN
));
2788 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2791 TEST(LazyCallGraphTest
, AddSplitFunctions2
) {
2792 LLVMContext Context
;
2793 std::unique_ptr
<Module
> M
= parseAssembly(Context
, "define void @f() {\n"
2796 LazyCallGraph CG
= buildCG(*M
);
2798 Function
&F
= lookupFunction(*M
, "f");
2799 LazyCallGraph::Node
&FN
= CG
.get(F
);
2801 // Force the graph to be fully expanded.
2803 auto I
= CG
.postorder_ref_scc_begin();
2804 LazyCallGraph::RefSCC
*ORC
= &*I
++;
2805 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2807 auto *G
= Function::Create(F
.getFunctionType(), F
.getLinkage(),
2808 F
.getAddressSpace(), "g", F
.getParent());
2809 BasicBlock
*GBB
= BasicBlock::Create(Context
, "", G
);
2810 // Create g -ref-> f.
2811 (void)CastInst::CreatePointerCast(&F
, Type::getInt8PtrTy(Context
), "", GBB
);
2812 (void)ReturnInst::Create(Context
, GBB
);
2814 // Create f -ref-> g.
2815 (void)CastInst::CreatePointerCast(G
, Type::getInt8PtrTy(Context
), "",
2816 &*F
.getEntryBlock().begin());
2818 EXPECT_FALSE(verifyModule(*M
, &errs()));
2820 CG
.addSplitRefRecursiveFunctions(F
, SmallVector
<Function
*, 1>({G
}));
2822 LazyCallGraph::Node
*GN
= CG
.lookup(*G
);
2825 I
= CG
.postorder_ref_scc_begin();
2826 LazyCallGraph::RefSCC
*RC
= &*I
++;
2827 EXPECT_EQ(RC
, CG
.lookupRefSCC(*GN
));
2829 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2831 // Order doesn't matter for sibling SCCs.
2832 EXPECT_EQ(2, RC
->size());
2833 EXPECT_EQ(&CG
.lookupSCC(*GN
)->getOuterRefSCC(), RC
);
2834 EXPECT_EQ(&CG
.lookupSCC(FN
)->getOuterRefSCC(), RC
);
2837 TEST(LazyCallGraphTest
, AddSplitFunctions3
) {
2838 LLVMContext Context
;
2839 std::unique_ptr
<Module
> M
= parseAssembly(Context
, "define void @f() {\n"
2842 LazyCallGraph CG
= buildCG(*M
);
2844 Function
&F
= lookupFunction(*M
, "f");
2845 LazyCallGraph::Node
&FN
= CG
.get(F
);
2847 // Force the graph to be fully expanded.
2849 auto I
= CG
.postorder_ref_scc_begin();
2850 LazyCallGraph::RefSCC
*ORC
= &*I
++;
2851 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2853 auto *G1
= Function::Create(F
.getFunctionType(), F
.getLinkage(),
2854 F
.getAddressSpace(), "g1", F
.getParent());
2855 auto *G2
= Function::Create(F
.getFunctionType(), F
.getLinkage(),
2856 F
.getAddressSpace(), "g2", F
.getParent());
2857 BasicBlock
*G1BB
= BasicBlock::Create(Context
, "", G1
);
2858 BasicBlock
*G2BB
= BasicBlock::Create(Context
, "", G2
);
2859 // Create g1 -ref-> g2 and g2 -ref-> g1.
2860 (void)CastInst::CreatePointerCast(G2
, Type::getInt8PtrTy(Context
), "", G1BB
);
2861 (void)CastInst::CreatePointerCast(G1
, Type::getInt8PtrTy(Context
), "", G2BB
);
2862 (void)ReturnInst::Create(Context
, G1BB
);
2863 (void)ReturnInst::Create(Context
, G2BB
);
2865 // Create f -ref-> g1 and f -ref-> g2.
2866 (void)CastInst::CreatePointerCast(G1
, Type::getInt8PtrTy(Context
), "",
2867 &*F
.getEntryBlock().begin());
2868 (void)CastInst::CreatePointerCast(G2
, Type::getInt8PtrTy(Context
), "",
2869 &*F
.getEntryBlock().begin());
2871 EXPECT_FALSE(verifyModule(*M
, &errs()));
2873 CG
.addSplitRefRecursiveFunctions(F
, SmallVector
<Function
*, 1>({G1
, G2
}));
2875 LazyCallGraph::Node
*G1N
= CG
.lookup(*G1
);
2877 LazyCallGraph::Node
*G2N
= CG
.lookup(*G2
);
2880 I
= CG
.postorder_ref_scc_begin();
2881 LazyCallGraph::RefSCC
*RC1
= &*I
++;
2882 EXPECT_EQ(2, RC1
->size());
2883 EXPECT_EQ(RC1
, CG
.lookupRefSCC(*G1N
));
2884 EXPECT_EQ(RC1
, CG
.lookupRefSCC(*G2N
));
2885 LazyCallGraph::RefSCC
*RC2
= &*I
++;
2886 EXPECT_EQ(RC2
, ORC
);
2887 EXPECT_EQ(RC2
, CG
.lookupRefSCC(FN
));
2888 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2891 TEST(LazyCallGraphTest
, AddSplitFunctions4
) {
2892 LLVMContext Context
;
2893 std::unique_ptr
<Module
> M
= parseAssembly(Context
, "define void @f() {\n"
2896 LazyCallGraph CG
= buildCG(*M
);
2898 Function
&F
= lookupFunction(*M
, "f");
2899 LazyCallGraph::Node
&FN
= CG
.get(F
);
2901 // Force the graph to be fully expanded.
2903 auto I
= CG
.postorder_ref_scc_begin();
2904 LazyCallGraph::RefSCC
*ORC
= &*I
++;
2905 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2907 auto *G1
= Function::Create(F
.getFunctionType(), F
.getLinkage(),
2908 F
.getAddressSpace(), "g1", F
.getParent());
2909 auto *G2
= Function::Create(F
.getFunctionType(), F
.getLinkage(),
2910 F
.getAddressSpace(), "g2", F
.getParent());
2911 BasicBlock
*G1BB
= BasicBlock::Create(Context
, "", G1
);
2912 BasicBlock
*G2BB
= BasicBlock::Create(Context
, "", G2
);
2913 // Create g1 -ref-> g2 and g2 -ref-> g1.
2914 (void)CastInst::CreatePointerCast(G2
, Type::getInt8PtrTy(Context
), "", G1BB
);
2915 (void)CastInst::CreatePointerCast(G1
, Type::getInt8PtrTy(Context
), "", G2BB
);
2916 // Create g2 -ref-> f.
2917 (void)CastInst::CreatePointerCast(&F
, Type::getInt8PtrTy(Context
), "", G2BB
);
2918 (void)ReturnInst::Create(Context
, G1BB
);
2919 (void)ReturnInst::Create(Context
, G2BB
);
2921 // Create f -ref-> g1 and f -ref-> g2.
2922 (void)CastInst::CreatePointerCast(G1
, Type::getInt8PtrTy(Context
), "",
2923 &*F
.getEntryBlock().begin());
2924 (void)CastInst::CreatePointerCast(G2
, Type::getInt8PtrTy(Context
), "",
2925 &*F
.getEntryBlock().begin());
2927 EXPECT_FALSE(verifyModule(*M
, &errs()));
2929 CG
.addSplitRefRecursiveFunctions(F
, SmallVector
<Function
*, 1>({G1
, G2
}));
2931 LazyCallGraph::Node
*G1N
= CG
.lookup(*G1
);
2933 LazyCallGraph::Node
*G2N
= CG
.lookup(*G2
);
2936 I
= CG
.postorder_ref_scc_begin();
2937 LazyCallGraph::RefSCC
*RC
= &*I
++;
2939 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2941 // Order doesn't matter for sibling SCCs.
2942 EXPECT_EQ(3, RC
->size());
2943 EXPECT_EQ(&CG
.lookupSCC(FN
)->getOuterRefSCC(), RC
);
2944 EXPECT_EQ(&CG
.lookupSCC(*G1N
)->getOuterRefSCC(), RC
);
2945 EXPECT_EQ(&CG
.lookupSCC(*G2N
)->getOuterRefSCC(), RC
);
2946 EXPECT_EQ(RC
, CG
.lookupRefSCC(*G1N
));
2947 EXPECT_EQ(RC
, CG
.lookupRefSCC(*G2N
));
2950 TEST(LazyCallGraphTest
, AddSplitFunctions5
) {
2951 LLVMContext Context
;
2952 std::unique_ptr
<Module
> M
=
2953 parseAssembly(Context
, "define void @f() {\n"
2954 " %1 = bitcast void ()* @f2 to i8*\n"
2957 "define void @f2() {\n"
2961 LazyCallGraph CG
= buildCG(*M
);
2963 Function
&F
= lookupFunction(*M
, "f");
2964 LazyCallGraph::Node
&FN
= CG
.get(F
);
2965 Function
&F2
= lookupFunction(*M
, "f2");
2966 LazyCallGraph::Node
&F2N
= CG
.get(F
);
2968 // Force the graph to be fully expanded.
2970 auto I
= CG
.postorder_ref_scc_begin();
2971 LazyCallGraph::RefSCC
*ORC
= &*I
++;
2972 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);
2974 auto *G1
= Function::Create(F
.getFunctionType(), F
.getLinkage(),
2975 F
.getAddressSpace(), "g1", F
.getParent());
2976 auto *G2
= Function::Create(F
.getFunctionType(), F
.getLinkage(),
2977 F
.getAddressSpace(), "g2", F
.getParent());
2978 BasicBlock
*G1BB
= BasicBlock::Create(Context
, "", G1
);
2979 BasicBlock
*G2BB
= BasicBlock::Create(Context
, "", G2
);
2980 // Create g1 -ref-> g2 and g2 -ref-> g1.
2981 (void)CastInst::CreatePointerCast(G2
, Type::getInt8PtrTy(Context
), "", G1BB
);
2982 (void)CastInst::CreatePointerCast(G1
, Type::getInt8PtrTy(Context
), "", G2BB
);
2983 // Create g2 -ref-> f2.
2984 (void)CastInst::CreatePointerCast(&F2
, Type::getInt8PtrTy(Context
), "", G2BB
);
2985 (void)ReturnInst::Create(Context
, G1BB
);
2986 (void)ReturnInst::Create(Context
, G2BB
);
2988 // Create f -ref-> g1 and f -ref-> g2.
2989 (void)CastInst::CreatePointerCast(G1
, Type::getInt8PtrTy(Context
), "",
2990 &*F
.getEntryBlock().begin());
2991 (void)CastInst::CreatePointerCast(G2
, Type::getInt8PtrTy(Context
), "",
2992 &*F
.getEntryBlock().begin());
2994 EXPECT_FALSE(verifyModule(*M
, &errs()));
2996 CG
.addSplitRefRecursiveFunctions(F
, SmallVector
<Function
*, 1>({G1
, G2
}));
2998 LazyCallGraph::Node
*G1N
= CG
.lookup(*G1
);
3000 LazyCallGraph::Node
*G2N
= CG
.lookup(*G2
);
3003 I
= CG
.postorder_ref_scc_begin();
3004 LazyCallGraph::RefSCC
*RC
= &*I
++;
3005 EXPECT_EQ(4, RC
->size());
3007 EXPECT_EQ(RC
, CG
.lookupRefSCC(*G1N
));
3008 EXPECT_EQ(RC
, CG
.lookupRefSCC(*G2N
));
3009 EXPECT_EQ(RC
, CG
.lookupRefSCC(FN
));
3010 EXPECT_EQ(RC
, CG
.lookupRefSCC(F2N
));
3011 EXPECT_EQ(CG
.postorder_ref_scc_end(), I
);