summaryrefslogtreecommitdiffstats
path: root/clang/lib/StaticAnalyzer/Core/ProgramState.cpp
diff options
context:
space:
mode:
authorPavel Labath <labath@google.com>2013-08-19 15:23:34 +0000
committerPavel Labath <labath@google.com>2013-08-19 15:23:34 +0000
commit71bb9879974ae39d1a8fc0d349c00049571a72d2 (patch)
treee29e9cd85bac16fa26a040800959cfc1d354af83 /clang/lib/StaticAnalyzer/Core/ProgramState.cpp
parent4a9df8a768823ba74279596da0fabdada25f6de6 (diff)
downloadbcm5719-llvm-71bb9879974ae39d1a8fc0d349c00049571a72d2.tar.gz
bcm5719-llvm-71bb9879974ae39d1a8fc0d349c00049571a72d2.zip
[analyzer] Fix inefficiency in dead symbol removal
Summary: ScanReachableSymbols uses a "visited" set to avoid scanning the same object twice. However, it did not use the optimization for LazyCompoundVal objects, which resulted in exponential complexity for long chains of temporary objects. Adding this resulted in a decrease of analysis time from >3h to 3 seconds for some files. Reviewers: jordan_rose CC: cfe-commits Differential Revision: http://llvm-reviews.chandlerc.com/D1398 llvm-svn: 188677
Diffstat (limited to 'clang/lib/StaticAnalyzer/Core/ProgramState.cpp')
-rw-r--r--clang/lib/StaticAnalyzer/Core/ProgramState.cpp36
1 files changed, 19 insertions, 17 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/ProgramState.cpp b/clang/lib/StaticAnalyzer/Core/ProgramState.cpp
index 653b69bf486..fbd3fc526d3 100644
--- a/clang/lib/StaticAnalyzer/Core/ProgramState.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ProgramState.cpp
@@ -526,6 +526,19 @@ ProgramStateRef ProgramStateManager::removeGDM(ProgramStateRef state, void *Key)
return getPersistentState(NewState);
}
+bool ScanReachableSymbols::scan(nonloc::LazyCompoundVal val) {
+ bool wasVisited = !visited.insert(val.getCVData()).second;
+ if (wasVisited)
+ return true;
+
+ StoreManager &StoreMgr = state->getStateManager().getStoreManager();
+ // FIXME: We don't really want to use getBaseRegion() here because pointer
+ // arithmetic doesn't apply, but scanReachableSymbols only accepts base
+ // regions right now.
+ const MemRegion *R = val.getRegion()->getBaseRegion();
+ return StoreMgr.scanReachableSymbols(val.getStore(), R, *this);
+}
+
bool ScanReachableSymbols::scan(nonloc::CompoundVal val) {
for (nonloc::CompoundVal::iterator I=val.begin(), E=val.end(); I!=E; ++I)
if (!scan(*I))
@@ -535,10 +548,9 @@ bool ScanReachableSymbols::scan(nonloc::CompoundVal val) {
}
bool ScanReachableSymbols::scan(const SymExpr *sym) {
- unsigned &isVisited = visited[sym];
- if (isVisited)
+ bool wasVisited = !visited.insert(sym).second;
+ if (wasVisited)
return true;
- isVisited = 1;
if (!visitor.VisitSymbol(sym))
return false;
@@ -570,16 +582,8 @@ bool ScanReachableSymbols::scan(SVal val) {
return scan(X->getRegion());
if (Optional<nonloc::LazyCompoundVal> X =
- val.getAs<nonloc::LazyCompoundVal>()) {
- StoreManager &StoreMgr = state->getStateManager().getStoreManager();
- // FIXME: We don't really want to use getBaseRegion() here because pointer
- // arithmetic doesn't apply, but scanReachableSymbols only accepts base
- // regions right now.
- if (!StoreMgr.scanReachableSymbols(X->getStore(),
- X->getRegion()->getBaseRegion(),
- *this))
- return false;
- }
+ val.getAs<nonloc::LazyCompoundVal>())
+ return scan(*X);
if (Optional<nonloc::LocAsInteger> X = val.getAs<nonloc::LocAsInteger>())
return scan(X->getLoc());
@@ -600,11 +604,9 @@ bool ScanReachableSymbols::scan(const MemRegion *R) {
if (isa<MemSpaceRegion>(R))
return true;
- unsigned &isVisited = visited[R];
- if (isVisited)
+ bool wasVisited = !visited.insert(R).second;
+ if (wasVisited)
return true;
- isVisited = 1;
-
if (!visitor.VisitMemRegion(R))
return false;
OpenPOWER on IntegriCloud