Skip to content

Commit

Permalink
[LCG] Add some basic methods for querying the parent/child relationships
Browse files Browse the repository at this point in the history
of SCCs in the SCC DAG. Exercise them in the big graph test case. These
will be especially useful for establishing invariants in insertion
logic.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@207749 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
chandlerc committed May 1, 2014
1 parent 217b586 commit b8f4625
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 0 deletions.
14 changes: 14 additions & 0 deletions include/llvm/Analysis/LazyCallGraph.h
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,20 @@ class LazyCallGraph {
return iterator_range<parent_iterator>(parent_begin(), parent_end());
}

/// \brief Test if this SCC is a parent of \a C.
bool isParentOf(const SCC &C) const { return C.isChildOf(*this); }

/// \brief Test if this SCC is an ancestor of \a C.
bool isAncestorOf(const SCC &C) const { return C.isDescendantOf(*this); }

/// \brief Test if this SCC is a child of \a C.
bool isChildOf(const SCC &C) const {
return ParentSCCs.count(const_cast<SCC *>(&C));
}

/// \brief Test if this SCC is a descendant of \a C.
bool isDescendantOf(const SCC &C) const;

///@{
/// \name Mutation API
///
Expand Down
15 changes: 15 additions & 0 deletions lib/Analysis/LazyCallGraph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,21 @@ void LazyCallGraph::SCC::insert(Node &N) {
G->SCCMap[&N] = this;
}

bool LazyCallGraph::SCC::isDescendantOf(const SCC &C) const {
// Walk up the parents of this SCC and verify that we eventually find C.
SmallVector<const SCC *, 4> AncestorWorklist;
AncestorWorklist.push_back(this);
do {
const SCC *AncestorC = AncestorWorklist.pop_back_val();
if (AncestorC->isChildOf(C))
return true;
for (const SCC *ParentC : AncestorC->ParentSCCs)
AncestorWorklist.push_back(ParentC);
} while (!AncestorWorklist.empty());

return false;
}

void LazyCallGraph::SCC::insertIntraSCCEdge(Node &CallerN, Node &CalleeN) {
// First insert it into the caller.
CallerN.insertEdgeInternal(CalleeN);
Expand Down
20 changes: 20 additions & 0 deletions unittests/Analysis/LazyCallGraphTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,10 @@ TEST(LazyCallGraphTest, BasicGraphFormation) {
EXPECT_EQ("d2", Nodes[1]);
EXPECT_EQ("d3", Nodes[2]);
Nodes.clear();
EXPECT_FALSE(D.isParentOf(D));
EXPECT_FALSE(D.isChildOf(D));
EXPECT_FALSE(D.isAncestorOf(D));
EXPECT_FALSE(D.isDescendantOf(D));

LazyCallGraph::SCC &C = *SCCI++;
for (LazyCallGraph::Node *N : C)
Expand All @@ -224,6 +228,10 @@ TEST(LazyCallGraphTest, BasicGraphFormation) {
EXPECT_EQ("c2", Nodes[1]);
EXPECT_EQ("c3", Nodes[2]);
Nodes.clear();
EXPECT_TRUE(C.isParentOf(D));
EXPECT_FALSE(C.isChildOf(D));
EXPECT_TRUE(C.isAncestorOf(D));
EXPECT_FALSE(C.isDescendantOf(D));

LazyCallGraph::SCC &B = *SCCI++;
for (LazyCallGraph::Node *N : B)
Expand All @@ -234,6 +242,12 @@ TEST(LazyCallGraphTest, BasicGraphFormation) {
EXPECT_EQ("b2", Nodes[1]);
EXPECT_EQ("b3", Nodes[2]);
Nodes.clear();
EXPECT_TRUE(B.isParentOf(D));
EXPECT_FALSE(B.isChildOf(D));
EXPECT_TRUE(B.isAncestorOf(D));
EXPECT_FALSE(B.isDescendantOf(D));
EXPECT_FALSE(B.isAncestorOf(C));
EXPECT_FALSE(C.isAncestorOf(B));

LazyCallGraph::SCC &A = *SCCI++;
for (LazyCallGraph::Node *N : A)
Expand All @@ -244,6 +258,12 @@ TEST(LazyCallGraphTest, BasicGraphFormation) {
EXPECT_EQ("a2", Nodes[1]);
EXPECT_EQ("a3", Nodes[2]);
Nodes.clear();
EXPECT_TRUE(A.isParentOf(B));
EXPECT_TRUE(A.isParentOf(C));
EXPECT_FALSE(A.isParentOf(D));
EXPECT_TRUE(A.isAncestorOf(B));
EXPECT_TRUE(A.isAncestorOf(C));
EXPECT_TRUE(A.isAncestorOf(D));

EXPECT_EQ(CG.postorder_scc_end(), SCCI);
}
Expand Down

0 comments on commit b8f4625

Please sign in to comment.