summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorChandler Carruth <chandlerc@gmail.com>2017-08-05 06:24:09 +0000
committerChandler Carruth <chandlerc@gmail.com>2017-08-05 06:24:09 +0000
commit38bd6b50ef500c2bf166593712443c609a3356ba (patch)
treef0591c7df6cad0da7f172adbe71bd655a8c99f6c /llvm/lib
parentc718b8e7c35d0677a68ecdfd8d575b58205a970f (diff)
downloadbcm5719-llvm-38bd6b50ef500c2bf166593712443c609a3356ba.tar.gz
bcm5719-llvm-38bd6b50ef500c2bf166593712443c609a3356ba.zip
[LCG] Re-implement the basic isParentOf, isAncestorOf, isChildOf, and
isDescendantOf methods on RefSCCs in terms of the forward edges rather than the parent sets. This is technically slower, but probably not interestingly slower, and all of these routines were already so expensive that they're guarded behind both !NDEBUG and EXPENSIVE_CHECKS. This removes another non-critical usage of parent sets. I've also added some comments to try and help clarify to any potential users the costs of these routines. They're mostly useful for debugging, asserts, or other queries. llvm-svn: 310170
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Analysis/LazyCallGraph.cpp47
1 files changed, 37 insertions, 10 deletions
diff --git a/llvm/lib/Analysis/LazyCallGraph.cpp b/llvm/lib/Analysis/LazyCallGraph.cpp
index 6c55a3f0406..4bdfbdaab9f 100644
--- a/llvm/lib/Analysis/LazyCallGraph.cpp
+++ b/llvm/lib/Analysis/LazyCallGraph.cpp
@@ -334,17 +334,44 @@ void LazyCallGraph::RefSCC::verify() {
}
#endif
-bool LazyCallGraph::RefSCC::isDescendantOf(const RefSCC &C) const {
- // Walk up the parents of this SCC and verify that we eventually find C.
- SmallVector<const RefSCC *, 4> AncestorWorklist;
- AncestorWorklist.push_back(this);
+bool LazyCallGraph::RefSCC::isParentOf(const RefSCC &RC) const {
+ if (&RC == this)
+ return false;
+
+ // Search all edges to see if this is a parent.
+ for (SCC &C : *this)
+ for (Node &N : C)
+ for (Edge &E : *N)
+ if (G->lookupRefSCC(E.getNode()) == &RC)
+ return true;
+
+ return false;
+}
+
+bool LazyCallGraph::RefSCC::isAncestorOf(const RefSCC &RC) const {
+ if (&RC == this)
+ return false;
+
+ // For each descendant of this RefSCC, see if one of its children is the
+ // argument. If not, add that descendant to the worklist and continue
+ // searching.
+ SmallVector<const RefSCC *, 4> Worklist;
+ SmallPtrSet<const RefSCC *, 4> Visited;
+ Worklist.push_back(this);
+ Visited.insert(this);
do {
- const RefSCC *AncestorC = AncestorWorklist.pop_back_val();
- if (AncestorC->isChildOf(C))
- return true;
- for (const RefSCC *ParentC : AncestorC->Parents)
- AncestorWorklist.push_back(ParentC);
- } while (!AncestorWorklist.empty());
+ const RefSCC &DescendantRC = *Worklist.pop_back_val();
+ for (SCC &C : DescendantRC)
+ for (Node &N : C)
+ for (Edge &E : *N) {
+ auto *ChildRC = G->lookupRefSCC(E.getNode());
+ if (ChildRC == &RC)
+ return true;
+ if (!ChildRC || !Visited.insert(ChildRC).second)
+ continue;
+ Worklist.push_back(ChildRC);
+ }
+ } while (!Worklist.empty());
return false;
}
OpenPOWER on IntegriCloud