summaryrefslogtreecommitdiffstats
path: root/clang/lib/Analysis/ExplodedGraph.cpp
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2008-04-16 15:51:26 +0000
committerTed Kremenek <kremenek@apple.com>2008-04-16 15:51:26 +0000
commit08e562d3c841b813d8adf4b99e3ed8d52c14619d (patch)
treea91edc34136e58ba729a9b76a5012e64814c55b6 /clang/lib/Analysis/ExplodedGraph.cpp
parent522dc99164ae477b384aa6ca6080885832302163 (diff)
downloadbcm5719-llvm-08e562d3c841b813d8adf4b99e3ed8d52c14619d.tar.gz
bcm5719-llvm-08e562d3c841b813d8adf4b99e3ed8d52c14619d.zip
In ExplodedGraphImpl::Trim, prioritize for paths that don't span loops by using
two worklists: for nodes whose locations are block edges with loop terminators and another for nodes with all other locations. We only dequeue from the loop worklist when the other is empty. Exploration of the graph is still in reverse-BFS. llvm-svn: 49791
Diffstat (limited to 'clang/lib/Analysis/ExplodedGraph.cpp')
-rw-r--r--clang/lib/Analysis/ExplodedGraph.cpp39
1 files changed, 34 insertions, 5 deletions
diff --git a/clang/lib/Analysis/ExplodedGraph.cpp b/clang/lib/Analysis/ExplodedGraph.cpp
index 2ba46d77d63..3788551be00 100644
--- a/clang/lib/Analysis/ExplodedGraph.cpp
+++ b/clang/lib/Analysis/ExplodedGraph.cpp
@@ -13,6 +13,7 @@
//===----------------------------------------------------------------------===//
#include "clang/Analysis/PathSensitive/ExplodedGraph.h"
+#include "clang/AST/Stmt.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
@@ -103,18 +104,30 @@ ExplodedGraphImpl* ExplodedGraphImpl::Trim(ExplodedNodeImpl** BeginSources,
// Enqueue the source nodes to the first worklist.
std::list<std::pair<ExplodedNodeImpl*, ExplodedNodeImpl*> > WL1;
+ std::list<std::pair<ExplodedNodeImpl*, ExplodedNodeImpl*> > WL1_Loops;
for (ExplodedNodeImpl** I = BeginSources; I != EndSources; ++I)
WL1.push_back(std::make_pair(*I, *I));
// Process the worklist.
- while (!WL1.empty()) {
+ while (! (WL1.empty() && WL1_Loops.empty())) {
- ExplodedNodeImpl* N = WL1.back().first;
- ExplodedNodeImpl* Src = WL1.back().second;
+ ExplodedNodeImpl *N, *Src;
+
+ // Only dequeue from the "loops" worklist if WL1 has no items.
+ // Thus we prioritize for paths that don't span loop boundaries.
- WL1.pop_back();
+ if (WL1.empty()) {
+ N = WL1_Loops.back().first;
+ Src = WL1_Loops.back().second;
+ WL1_Loops.pop_back();
+ }
+ else {
+ N = WL1.back().first;
+ Src = WL1.back().second;
+ WL1.pop_back();
+ }
if (Pass1.find(N) != Pass1.end())
continue;
@@ -152,8 +165,24 @@ ExplodedGraphImpl* ExplodedGraphImpl::Trim(ExplodedNodeImpl** BeginSources,
if (VisitPreds)
for (ExplodedNodeImpl** I=N->Preds.begin(), **E=N->Preds.end();
- I!=E; ++I)
+ I!=E; ++I) {
+
+ ProgramPoint P = Src->getLocation();
+
+ if (const BlockEdge *BE = dyn_cast<BlockEdge>(&P))
+ if (Stmt* T = BE->getSrc()->getTerminator())
+ switch (T->getStmtClass()) {
+ default: break;
+ case Stmt::ForStmtClass:
+ case Stmt::WhileStmtClass:
+ case Stmt::DoStmtClass:
+ WL1_Loops.push_front(std::make_pair(*I, Src));
+ continue;
+
+ }
+
WL1.push_front(std::make_pair(*I, Src));
+ }
}
}
OpenPOWER on IntegriCloud