[llvm] 0deef2e - Re-land "Add LazyCallGraph API to add function to RefSCC"
Brian Gesiak via llvm-commits
llvm-commits at lists.llvm.org
Mon Feb 17 13:59:39 PST 2020
Author: Brian Gesiak
Date: 2020-02-17T16:59:25-05:00
New Revision: 0deef2e164e1db5e262fb14906c97b01b74a24dd
URL: https://github.com/llvm/llvm-project/commit/0deef2e164e1db5e262fb14906c97b01b74a24dd
DIFF: https://github.com/llvm/llvm-project/commit/0deef2e164e1db5e262fb14906c97b01b74a24dd.diff
LOG: Re-land "Add LazyCallGraph API to add function to RefSCC"
This re-commits https://reviews.llvm.org/D70927, which I reverted in
https://reviews.llvm.org/rG28213680b2a7d1fdeea16aa3f3a368879472c72a due
to a buildbot error:
http://lab.llvm.org:8011/builders/clang-cmake-x86_64-avx2-linux/builds/13251
I no longer include a test case that appears to crash when built with the
buildbot's compiler, GCC 5.4.0.
Added:
Modified:
llvm/include/llvm/Analysis/LazyCallGraph.h
llvm/lib/Analysis/LazyCallGraph.cpp
llvm/unittests/Analysis/LazyCallGraphTest.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/Analysis/LazyCallGraph.h b/llvm/include/llvm/Analysis/LazyCallGraph.h
index c0fbadb73dcf..ea63b837ba70 100644
--- a/llvm/include/llvm/Analysis/LazyCallGraph.h
+++ b/llvm/include/llvm/Analysis/LazyCallGraph.h
@@ -1061,6 +1061,10 @@ class LazyCallGraph {
/// Introduce a node for the function \p NewF in the SCC \p C.
void addNewFunctionIntoSCC(Function &NewF, SCC &C);
+ /// Introduce a node for the function \p NewF, as a single node in a
+ /// new SCC, in the RefSCC \p RC.
+ void addNewFunctionIntoRefSCC(Function &NewF, RefSCC &RC);
+
///@}
///@{
@@ -1167,6 +1171,13 @@ class LazyCallGraph {
/// Helper to update pointers back to the graph object during moves.
void updateGraphPtrs();
+ /// Helper to insert a new function, add it to the NodeMap, and populate its
+ /// node.
+ Node &createNode(Function &F);
+
+ /// Helper to add the given Node \p N to the SCCMap, mapped to the SCC \p C.
+ void addNodeToSCC(SCC &C, Node &N);
+
/// Allocates an SCC and constructs it using the graph allocator.
///
/// The arguments are forwarded to the constructor.
diff --git a/llvm/lib/Analysis/LazyCallGraph.cpp b/llvm/lib/Analysis/LazyCallGraph.cpp
index cdf1d55f5ba2..0d647cba7092 100644
--- a/llvm/lib/Analysis/LazyCallGraph.cpp
+++ b/llvm/lib/Analysis/LazyCallGraph.cpp
@@ -1567,12 +1567,17 @@ void LazyCallGraph::removeDeadFunction(Function &F) {
}
void LazyCallGraph::addNewFunctionIntoSCC(Function &NewF, SCC &C) {
- Node &CGNode = get(NewF);
- CGNode.DFSNumber = CGNode.LowLink = -1;
- CGNode.populate();
- C.Nodes.push_back(&CGNode);
- SCCMap[&CGNode] = &C;
- NodeMap[&NewF] = &CGNode;
+ addNodeToSCC(C, createNode(NewF));
+}
+
+void LazyCallGraph::addNewFunctionIntoRefSCC(Function &NewF, RefSCC &RC) {
+ Node &N = createNode(NewF);
+
+ auto *C = createSCC(RC, SmallVector<Node *, 1>());
+ addNodeToSCC(*C, N);
+
+ RC.SCCIndices[C] = RC.SCCIndices.size();
+ RC.SCCs.push_back(C);
}
LazyCallGraph::Node &LazyCallGraph::insertInto(Function &F, Node *&MappedN) {
@@ -1589,6 +1594,21 @@ void LazyCallGraph::updateGraphPtrs() {
RC->G = this;
}
+LazyCallGraph::Node &LazyCallGraph::createNode(Function &F) {
+ assert(!lookup(F) && "node already exists");
+
+ Node &N = get(F);
+ NodeMap[&F] = &N;
+ N.DFSNumber = N.LowLink = -1;
+ N.populate();
+ return N;
+}
+
+void LazyCallGraph::addNodeToSCC(LazyCallGraph::SCC &C, Node &N) {
+ C.Nodes.push_back(&N);
+ SCCMap[&N] = &C;
+}
+
template <typename RootsT, typename GetBeginT, typename GetEndT,
typename GetNodeT, typename FormSCCCallbackT>
void LazyCallGraph::buildGenericSCCs(RootsT &&Roots, GetBeginT &&GetBegin,
diff --git a/llvm/unittests/Analysis/LazyCallGraphTest.cpp b/llvm/unittests/Analysis/LazyCallGraphTest.cpp
index 3be463646878..a507367518a7 100644
--- a/llvm/unittests/Analysis/LazyCallGraphTest.cpp
+++ b/llvm/unittests/Analysis/LazyCallGraphTest.cpp
@@ -2210,4 +2210,46 @@ TEST(LazyCallGraphTest, RemoveFunctionWithSpurriousRef) {
EXPECT_EQ(&RC2, &*I++);
EXPECT_EQ(CG.postorder_ref_scc_end(), I);
}
+
+TEST(LazyCallGraphTest, AddNewFunctionIntoRefSCC) {
+ LLVMContext Context;
+ // Build and populate a graph composed of a single, self-referential node.
+ std::unique_ptr<Module> M = parseAssembly(Context, "define void @f() {\n"
+ "entry:\n"
+ " call void @f()\n"
+ " ret void\n"
+ "}\n");
+ LazyCallGraph CG = buildCG(*M);
+ CG.buildRefSCCs();
+
+ // At this point 'f' is in the call graph.
+ auto &F = lookupFunction(*M, "f");
+ LazyCallGraph::Node *FN = CG.lookup(F);
+ EXPECT_NE(FN, nullptr);
+
+ // And it has an SCC, of course.
+ auto *FSCC = CG.lookupSCC(*FN);
+ EXPECT_NE(FSCC, nullptr);
+
+ // Now, create a new function 'g'.
+ auto *G = Function::Create(F.getFunctionType(), F.getLinkage(),
+ F.getAddressSpace(), "g", F.getParent());
+ BasicBlock::Create(F.getParent()->getContext(), "entry", G);
+
+ // Instruct the LazyCallGraph to create a new node for 'g', within the same
+ // RefSCC as 'f', but in a separate SCC.
+ CG.addNewFunctionIntoRefSCC(*G, FSCC->getOuterRefSCC());
+
+ // 'g' should now be in the call graph.
+ LazyCallGraph::Node *GN = CG.lookup(*G);
+ EXPECT_NE(GN, nullptr);
+ // 'g' should have an SCC, composed of the singular node 'g'.
+ // ('f' should not be included in the 'g' SCC.)
+ LazyCallGraph::SCC *GSCC = CG.lookupSCC(*GN);
+ EXPECT_NE(GSCC, nullptr);
+ EXPECT_EQ(GSCC->size(), 1);
+ EXPECT_NE(GSCC, FSCC);
+ // 'g' and 'f' should be part of the same RefSCC.
+ EXPECT_EQ(&GSCC->getOuterRefSCC(), &FSCC->getOuterRefSCC());
+}
}
More information about the llvm-commits
mailing list