summaryrefslogtreecommitdiffstats
path: root/llvm/unittests/Analysis/LazyCallGraphTest.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/unittests/Analysis/LazyCallGraphTest.cpp')
-rw-r--r--llvm/unittests/Analysis/LazyCallGraphTest.cpp494
1 files changed, 251 insertions, 243 deletions
diff --git a/llvm/unittests/Analysis/LazyCallGraphTest.cpp b/llvm/unittests/Analysis/LazyCallGraphTest.cpp
index 457c07dc308..224a9458cc8 100644
--- a/llvm/unittests/Analysis/LazyCallGraphTest.cpp
+++ b/llvm/unittests/Analysis/LazyCallGraphTest.cpp
@@ -21,10 +21,10 @@ using namespace llvm;
namespace {
-std::unique_ptr<Module> parseAssembly(const char *Assembly) {
+std::unique_ptr<Module> parseAssembly(LLVMContext &Context,
+ const char *Assembly) {
SMDiagnostic Error;
- std::unique_ptr<Module> M =
- parseAssemblyString(Assembly, Error, getGlobalContext());
+ std::unique_ptr<Module> M = parseAssemblyString(Assembly, Error, Context);
std::string ErrMsg;
raw_string_ostream OS(ErrMsg);
@@ -121,7 +121,8 @@ static const char DiamondOfTriangles[] =
"}\n";
TEST(LazyCallGraphTest, BasicGraphFormation) {
- std::unique_ptr<Module> M = parseAssembly(DiamondOfTriangles);
+ LLVMContext Context;
+ std::unique_ptr<Module> M = parseAssembly(Context, DiamondOfTriangles);
LazyCallGraph CG(*M);
// The order of the entry nodes should be stable w.r.t. the source order of
@@ -280,21 +281,21 @@ static Function &lookupFunction(Module &M, StringRef Name) {
}
TEST(LazyCallGraphTest, BasicGraphMutation) {
- std::unique_ptr<Module> M = parseAssembly(
- "define void @a() {\n"
- "entry:\n"
- " call void @b()\n"
- " call void @c()\n"
- " ret void\n"
- "}\n"
- "define void @b() {\n"
- "entry:\n"
- " ret void\n"
- "}\n"
- "define void @c() {\n"
- "entry:\n"
- " ret void\n"
- "}\n");
+ LLVMContext Context;
+ std::unique_ptr<Module> M = parseAssembly(Context, "define void @a() {\n"
+ "entry:\n"
+ " call void @b()\n"
+ " call void @c()\n"
+ " ret void\n"
+ "}\n"
+ "define void @b() {\n"
+ "entry:\n"
+ " ret void\n"
+ "}\n"
+ "define void @c() {\n"
+ "entry:\n"
+ " ret void\n"
+ "}\n");
LazyCallGraph CG(*M);
LazyCallGraph::Node &A = CG.get(lookupFunction(*M, "a"));
@@ -328,7 +329,8 @@ TEST(LazyCallGraphTest, BasicGraphMutation) {
}
TEST(LazyCallGraphTest, InnerSCCFormation) {
- std::unique_ptr<Module> M = parseAssembly(DiamondOfTriangles);
+ LLVMContext Context;
+ std::unique_ptr<Module> M = parseAssembly(Context, DiamondOfTriangles);
LazyCallGraph CG(*M);
// Now mutate the graph to connect every node into a single RefSCC to ensure
@@ -391,37 +393,37 @@ TEST(LazyCallGraphTest, InnerSCCFormation) {
}
TEST(LazyCallGraphTest, MultiArmSCC) {
+ LLVMContext Context;
// Two interlocking cycles. The really useful thing about this SCC is that it
// will require Tarjan's DFS to backtrack and finish processing all of the
// children of each node in the SCC. Since this involves call edges, both
// Tarjan implementations will have to successfully navigate the structure.
- std::unique_ptr<Module> M = parseAssembly(
- "define void @f1() {\n"
- "entry:\n"
- " call void @f2()\n"
- " call void @f4()\n"
- " ret void\n"
- "}\n"
- "define void @f2() {\n"
- "entry:\n"
- " call void @f3()\n"
- " ret void\n"
- "}\n"
- "define void @f3() {\n"
- "entry:\n"
- " call void @f1()\n"
- " ret void\n"
- "}\n"
- "define void @f4() {\n"
- "entry:\n"
- " call void @f5()\n"
- " ret void\n"
- "}\n"
- "define void @f5() {\n"
- "entry:\n"
- " call void @f1()\n"
- " ret void\n"
- "}\n");
+ std::unique_ptr<Module> M = parseAssembly(Context, "define void @f1() {\n"
+ "entry:\n"
+ " call void @f2()\n"
+ " call void @f4()\n"
+ " ret void\n"
+ "}\n"
+ "define void @f2() {\n"
+ "entry:\n"
+ " call void @f3()\n"
+ " ret void\n"
+ "}\n"
+ "define void @f3() {\n"
+ "entry:\n"
+ " call void @f1()\n"
+ " ret void\n"
+ "}\n"
+ "define void @f4() {\n"
+ "entry:\n"
+ " call void @f5()\n"
+ " ret void\n"
+ "}\n"
+ "define void @f5() {\n"
+ "entry:\n"
+ " call void @f1()\n"
+ " ret void\n"
+ "}\n");
LazyCallGraph CG(*M);
// Force the graph to be fully expanded.
@@ -451,27 +453,27 @@ TEST(LazyCallGraphTest, MultiArmSCC) {
}
TEST(LazyCallGraphTest, OutgoingEdgeMutation) {
- std::unique_ptr<Module> M = parseAssembly(
- "define void @a() {\n"
- "entry:\n"
- " call void @b()\n"
- " call void @c()\n"
- " ret void\n"
- "}\n"
- "define void @b() {\n"
- "entry:\n"
- " call void @d()\n"
- " ret void\n"
- "}\n"
- "define void @c() {\n"
- "entry:\n"
- " call void @d()\n"
- " ret void\n"
- "}\n"
- "define void @d() {\n"
- "entry:\n"
- " ret void\n"
- "}\n");
+ LLVMContext Context;
+ std::unique_ptr<Module> M = parseAssembly(Context, "define void @a() {\n"
+ "entry:\n"
+ " call void @b()\n"
+ " call void @c()\n"
+ " ret void\n"
+ "}\n"
+ "define void @b() {\n"
+ "entry:\n"
+ " call void @d()\n"
+ " ret void\n"
+ "}\n"
+ "define void @c() {\n"
+ "entry:\n"
+ " call void @d()\n"
+ " ret void\n"
+ "}\n"
+ "define void @d() {\n"
+ "entry:\n"
+ " ret void\n"
+ "}\n");
LazyCallGraph CG(*M);
// Force the graph to be fully expanded.
@@ -575,6 +577,7 @@ TEST(LazyCallGraphTest, OutgoingEdgeMutation) {
}
TEST(LazyCallGraphTest, IncomingEdgeInsertion) {
+ LLVMContext Context;
// We want to ensure we can add edges even across complex diamond graphs, so
// we use the diamond of triangles graph defined above. The ascii diagram is
// repeated here for easy reference.
@@ -591,7 +594,7 @@ TEST(LazyCallGraphTest, IncomingEdgeInsertion) {
// / \ |
// a3--a2 |
//
- std::unique_ptr<Module> M = parseAssembly(DiamondOfTriangles);
+ std::unique_ptr<Module> M = parseAssembly(Context, DiamondOfTriangles);
LazyCallGraph CG(*M);
// Force the graph to be fully expanded.
@@ -668,9 +671,10 @@ TEST(LazyCallGraphTest, IncomingEdgeInsertion) {
}
TEST(LazyCallGraphTest, IncomingEdgeInsertionMidTraversal) {
+ LLVMContext Context;
// This is the same fundamental test as the previous, but we perform it
// having only partially walked the RefSCCs of the graph.
- std::unique_ptr<Module> M = parseAssembly(DiamondOfTriangles);
+ std::unique_ptr<Module> M = parseAssembly(Context, DiamondOfTriangles);
LazyCallGraph CG(*M);
// Walk the RefSCCs until we find the one containing 'c1'.
@@ -744,22 +748,22 @@ TEST(LazyCallGraphTest, IncomingEdgeInsertionMidTraversal) {
}
TEST(LazyCallGraphTest, InternalEdgeMutation) {
- std::unique_ptr<Module> M = parseAssembly(
- "define void @a() {\n"
- "entry:\n"
- " call void @b()\n"
- " ret void\n"
- "}\n"
- "define void @b() {\n"
- "entry:\n"
- " call void @c()\n"
- " ret void\n"
- "}\n"
- "define void @c() {\n"
- "entry:\n"
- " call void @a()\n"
- " ret void\n"
- "}\n");
+ LLVMContext Context;
+ std::unique_ptr<Module> M = parseAssembly(Context, "define void @a() {\n"
+ "entry:\n"
+ " call void @b()\n"
+ " ret void\n"
+ "}\n"
+ "define void @b() {\n"
+ "entry:\n"
+ " call void @c()\n"
+ " ret void\n"
+ "}\n"
+ "define void @c() {\n"
+ "entry:\n"
+ " call void @a()\n"
+ " ret void\n"
+ "}\n");
LazyCallGraph CG(*M);
// Force the graph to be fully expanded.
@@ -824,29 +828,30 @@ TEST(LazyCallGraphTest, InternalEdgeMutation) {
}
TEST(LazyCallGraphTest, InternalEdgeRemoval) {
+ LLVMContext Context;
// A nice fully connected (including self-edges) RefSCC.
std::unique_ptr<Module> M = parseAssembly(
- "define void @a(i8** %ptr) {\n"
- "entry:\n"
- " store i8* bitcast (void(i8**)* @a to i8*), i8** %ptr\n"
- " store i8* bitcast (void(i8**)* @b to i8*), i8** %ptr\n"
- " store i8* bitcast (void(i8**)* @c to i8*), i8** %ptr\n"
- " ret void\n"
- "}\n"
- "define void @b(i8** %ptr) {\n"
- "entry:\n"
- " store i8* bitcast (void(i8**)* @a to i8*), i8** %ptr\n"
- " store i8* bitcast (void(i8**)* @b to i8*), i8** %ptr\n"
- " store i8* bitcast (void(i8**)* @c to i8*), i8** %ptr\n"
- " ret void\n"
- "}\n"
- "define void @c(i8** %ptr) {\n"
- "entry:\n"
- " store i8* bitcast (void(i8**)* @a to i8*), i8** %ptr\n"
- " store i8* bitcast (void(i8**)* @b to i8*), i8** %ptr\n"
- " store i8* bitcast (void(i8**)* @c to i8*), i8** %ptr\n"
- " ret void\n"
- "}\n");
+ Context, "define void @a(i8** %ptr) {\n"
+ "entry:\n"
+ " store i8* bitcast (void(i8**)* @a to i8*), i8** %ptr\n"
+ " store i8* bitcast (void(i8**)* @b to i8*), i8** %ptr\n"
+ " store i8* bitcast (void(i8**)* @c to i8*), i8** %ptr\n"
+ " ret void\n"
+ "}\n"
+ "define void @b(i8** %ptr) {\n"
+ "entry:\n"
+ " store i8* bitcast (void(i8**)* @a to i8*), i8** %ptr\n"
+ " store i8* bitcast (void(i8**)* @b to i8*), i8** %ptr\n"
+ " store i8* bitcast (void(i8**)* @c to i8*), i8** %ptr\n"
+ " ret void\n"
+ "}\n"
+ "define void @c(i8** %ptr) {\n"
+ "entry:\n"
+ " store i8* bitcast (void(i8**)* @a to i8*), i8** %ptr\n"
+ " store i8* bitcast (void(i8**)* @b to i8*), i8** %ptr\n"
+ " store i8* bitcast (void(i8**)* @c to i8*), i8** %ptr\n"
+ " ret void\n"
+ "}\n");
LazyCallGraph CG(*M);
// Force the graph to be fully expanded.
@@ -882,29 +887,29 @@ TEST(LazyCallGraphTest, InternalEdgeRemoval) {
}
TEST(LazyCallGraphTest, InternalCallEdgeToRef) {
+ LLVMContext Context;
// A nice fully connected (including self-edges) SCC (and RefSCC)
- std::unique_ptr<Module> M = parseAssembly(
- "define void @a() {\n"
- "entry:\n"
- " call void @a()\n"
- " call void @b()\n"
- " call void @c()\n"
- " ret void\n"
- "}\n"
- "define void @b() {\n"
- "entry:\n"
- " call void @a()\n"
- " call void @b()\n"
- " call void @c()\n"
- " ret void\n"
- "}\n"
- "define void @c() {\n"
- "entry:\n"
- " call void @a()\n"
- " call void @b()\n"
- " call void @c()\n"
- " ret void\n"
- "}\n");
+ std::unique_ptr<Module> M = parseAssembly(Context, "define void @a() {\n"
+ "entry:\n"
+ " call void @a()\n"
+ " call void @b()\n"
+ " call void @c()\n"
+ " ret void\n"
+ "}\n"
+ "define void @b() {\n"
+ "entry:\n"
+ " call void @a()\n"
+ " call void @b()\n"
+ " call void @c()\n"
+ " ret void\n"
+ "}\n"
+ "define void @c() {\n"
+ "entry:\n"
+ " call void @a()\n"
+ " call void @b()\n"
+ " call void @c()\n"
+ " ret void\n"
+ "}\n");
LazyCallGraph CG(*M);
// Force the graph to be fully expanded.
@@ -964,33 +969,34 @@ TEST(LazyCallGraphTest, InternalCallEdgeToRef) {
}
TEST(LazyCallGraphTest, InternalRefEdgeToCall) {
+ LLVMContext Context;
// Basic tests for making a ref edge a call. This hits the basics of the
// process only.
- std::unique_ptr<Module> M = parseAssembly(
- "define void @a() {\n"
- "entry:\n"
- " call void @b()\n"
- " call void @c()\n"
- " store void()* @d, void()** undef\n"
- " ret void\n"
- "}\n"
- "define void @b() {\n"
- "entry:\n"
- " store void()* @c, void()** undef\n"
- " call void @d()\n"
- " ret void\n"
- "}\n"
- "define void @c() {\n"
- "entry:\n"
- " store void()* @b, void()** undef\n"
- " call void @d()\n"
- " ret void\n"
- "}\n"
- "define void @d() {\n"
- "entry:\n"
- " store void()* @a, void()** undef\n"
- " ret void\n"
- "}\n");
+ std::unique_ptr<Module> M =
+ parseAssembly(Context, "define void @a() {\n"
+ "entry:\n"
+ " call void @b()\n"
+ " call void @c()\n"
+ " store void()* @d, void()** undef\n"
+ " ret void\n"
+ "}\n"
+ "define void @b() {\n"
+ "entry:\n"
+ " store void()* @c, void()** undef\n"
+ " call void @d()\n"
+ " ret void\n"
+ "}\n"
+ "define void @c() {\n"
+ "entry:\n"
+ " store void()* @b, void()** undef\n"
+ " call void @d()\n"
+ " ret void\n"
+ "}\n"
+ "define void @d() {\n"
+ "entry:\n"
+ " store void()* @a, void()** undef\n"
+ " ret void\n"
+ "}\n");
LazyCallGraph CG(*M);
// Force the graph to be fully expanded.
@@ -1049,59 +1055,60 @@ TEST(LazyCallGraphTest, InternalRefEdgeToCall) {
}
TEST(LazyCallGraphTest, InternalRefEdgeToCallNoCycleInterleaved) {
+ LLVMContext Context;
// Test for having a post-order prior to changing a ref edge to a call edge
// with SCCs connecting to the source and connecting to the target, but not
// connecting to both, interleaved between the source and target. This
// ensures we correctly partition the range rather than simply moving one or
// the other.
- std::unique_ptr<Module> M = parseAssembly(
- "define void @a() {\n"
- "entry:\n"
- " call void @b1()\n"
- " call void @c1()\n"
- " ret void\n"
- "}\n"
- "define void @b1() {\n"
- "entry:\n"
- " call void @c1()\n"
- " call void @b2()\n"
- " ret void\n"
- "}\n"
- "define void @c1() {\n"
- "entry:\n"
- " call void @b2()\n"
- " call void @c2()\n"
- " ret void\n"
- "}\n"
- "define void @b2() {\n"
- "entry:\n"
- " call void @c2()\n"
- " call void @b3()\n"
- " ret void\n"
- "}\n"
- "define void @c2() {\n"
- "entry:\n"
- " call void @b3()\n"
- " call void @c3()\n"
- " ret void\n"
- "}\n"
- "define void @b3() {\n"
- "entry:\n"
- " call void @c3()\n"
- " call void @d()\n"
- " ret void\n"
- "}\n"
- "define void @c3() {\n"
- "entry:\n"
- " store void()* @b1, void()** undef\n"
- " call void @d()\n"
- " ret void\n"
- "}\n"
- "define void @d() {\n"
- "entry:\n"
- " store void()* @a, void()** undef\n"
- " ret void\n"
- "}\n");
+ std::unique_ptr<Module> M =
+ parseAssembly(Context, "define void @a() {\n"
+ "entry:\n"
+ " call void @b1()\n"
+ " call void @c1()\n"
+ " ret void\n"
+ "}\n"
+ "define void @b1() {\n"
+ "entry:\n"
+ " call void @c1()\n"
+ " call void @b2()\n"
+ " ret void\n"
+ "}\n"
+ "define void @c1() {\n"
+ "entry:\n"
+ " call void @b2()\n"
+ " call void @c2()\n"
+ " ret void\n"
+ "}\n"
+ "define void @b2() {\n"
+ "entry:\n"
+ " call void @c2()\n"
+ " call void @b3()\n"
+ " ret void\n"
+ "}\n"
+ "define void @c2() {\n"
+ "entry:\n"
+ " call void @b3()\n"
+ " call void @c3()\n"
+ " ret void\n"
+ "}\n"
+ "define void @b3() {\n"
+ "entry:\n"
+ " call void @c3()\n"
+ " call void @d()\n"
+ " ret void\n"
+ "}\n"
+ "define void @c3() {\n"
+ "entry:\n"
+ " store void()* @b1, void()** undef\n"
+ " call void @d()\n"
+ " ret void\n"
+ "}\n"
+ "define void @d() {\n"
+ "entry:\n"
+ " store void()* @a, void()** undef\n"
+ " ret void\n"
+ "}\n");
LazyCallGraph CG(*M);
// Force the graph to be fully expanded.
@@ -1163,6 +1170,7 @@ TEST(LazyCallGraphTest, InternalRefEdgeToCallNoCycleInterleaved) {
}
TEST(LazyCallGraphTest, InternalRefEdgeToCallBothPartitionAndMerge) {
+ LLVMContext Context;
// Test for having a postorder where between the source and target are all
// three kinds of other SCCs:
// 1) One connected to the target only that have to be shifted below the
@@ -1190,47 +1198,47 @@ TEST(LazyCallGraphTest, InternalRefEdgeToCallBothPartitionAndMerge) {
// G | G |
//
// And we form a cycle by connecting F to B.
- std::unique_ptr<Module> M = parseAssembly(
- "define void @a() {\n"
- "entry:\n"
- " call void @b()\n"
- " call void @e()\n"
- " ret void\n"
- "}\n"
- "define void @b() {\n"
- "entry:\n"
- " call void @c()\n"
- " call void @d()\n"
- " ret void\n"
- "}\n"
- "define void @c() {\n"
- "entry:\n"
- " call void @d()\n"
- " call void @g()\n"
- " ret void\n"
- "}\n"
- "define void @d() {\n"
- "entry:\n"
- " call void @e()\n"
- " call void @f()\n"
- " ret void\n"
- "}\n"
- "define void @e() {\n"
- "entry:\n"
- " call void @f()\n"
- " ret void\n"
- "}\n"
- "define void @f() {\n"
- "entry:\n"
- " store void()* @b, void()** undef\n"
- " call void @g()\n"
- " ret void\n"
- "}\n"
- "define void @g() {\n"
- "entry:\n"
- " store void()* @a, void()** undef\n"
- " ret void\n"
- "}\n");
+ std::unique_ptr<Module> M =
+ parseAssembly(Context, "define void @a() {\n"
+ "entry:\n"
+ " call void @b()\n"
+ " call void @e()\n"
+ " ret void\n"
+ "}\n"
+ "define void @b() {\n"
+ "entry:\n"
+ " call void @c()\n"
+ " call void @d()\n"
+ " ret void\n"
+ "}\n"
+ "define void @c() {\n"
+ "entry:\n"
+ " call void @d()\n"
+ " call void @g()\n"
+ " ret void\n"
+ "}\n"
+ "define void @d() {\n"
+ "entry:\n"
+ " call void @e()\n"
+ " call void @f()\n"
+ " ret void\n"
+ "}\n"
+ "define void @e() {\n"
+ "entry:\n"
+ " call void @f()\n"
+ " ret void\n"
+ "}\n"
+ "define void @f() {\n"
+ "entry:\n"
+ " store void()* @b, void()** undef\n"
+ " call void @g()\n"
+ " ret void\n"
+ "}\n"
+ "define void @g() {\n"
+ "entry:\n"
+ " store void()* @a, void()** undef\n"
+ " ret void\n"
+ "}\n");
LazyCallGraph CG(*M);
// Force the graph to be fully expanded.
OpenPOWER on IntegriCloud