diff options
author | Anna Zaks <ganna@apple.com> | 2011-09-22 18:10:41 +0000 |
---|---|---|
committer | Anna Zaks <ganna@apple.com> | 2011-09-22 18:10:41 +0000 |
commit | 5f625712f622f6e57de17b6f7eec242956b993ee (patch) | |
tree | 27472f5b34834e40e70bb4b1899c162209de1636 | |
parent | d8e0fe617af3c9fb60a680ecb2ff765b71ef3c1d (diff) |
ST->scanReachableSymbols() is creating a SubRegionMap (SRM) on every call since one SRM is created in each ScanReachableSymbols instance. Creating the object just once and calling only scan inside the loop gives ~ 14% speed up of the StaticAnalyzer run (Release+Asserts).
Pull out the declaration of the ScanReachableSymbols so that it can be used directly. Document ProgramState::scanReachableSymbols() methods.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@140323 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h | 43 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/Environment.cpp | 6 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/ProgramState.cpp | 29 |
3 files changed, 43 insertions, 35 deletions
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h index c83792ce64..edae06e68c 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h @@ -56,6 +56,7 @@ template <typename T> struct ProgramStateTrait { class ProgramStateManager; +/// \class ProgramState /// ProgramState - This class encapsulates: /// /// 1. A mapping from expressions to values (Environment) @@ -179,10 +180,7 @@ public: DefinedOrUnknownSVal upperBound, bool assumption) const; - //==---------------------------------------------------------------------==// - // Utility methods for getting regions. - //==---------------------------------------------------------------------==// - + /// Utility method for getting regions. const VarRegion* getRegion(const VarDecl *D, const LocationContext *LC) const; //==---------------------------------------------------------------------==// @@ -262,11 +260,22 @@ public: SVal getSValAsScalarOrLoc(const MemRegion *R) const; + /// \brief Visits the symbols reachable from the given SVal using the provided + /// SymbolVisitor. + /// + /// This is a convenience API. Consider using ScanReachableSymbols class + /// directly when making multiple scans on the same state with the same + /// visitor to avoid repeated initialization cost. + /// \sa ScanReachableSymbols bool scanReachableSymbols(SVal val, SymbolVisitor& visitor) const; + /// \brief Visits the symbols reachable from the SVals in the given range + /// using the provided SymbolVisitor. bool scanReachableSymbols(const SVal *I, const SVal *E, SymbolVisitor &visitor) const; + /// \brief Visits the symbols reachable from the regions in the given + /// MemRegions range using the provided SymbolVisitor. bool scanReachableSymbols(const MemRegion * const *I, const MemRegion * const *E, SymbolVisitor &visitor) const; @@ -772,6 +781,32 @@ CB ProgramState::scanReachableSymbols(const MemRegion * const *beg, return cb; } +/// \class ScanReachableSymbols +/// A Utility class that allows to visit the reachable symbols using a custom +/// SymbolVisitor. +class ScanReachableSymbols : public SubRegionMap::Visitor { + typedef llvm::DenseMap<const void*, unsigned> VisitedItems; + + VisitedItems visited; + const ProgramState *state; + SymbolVisitor &visitor; + llvm::OwningPtr<SubRegionMap> SRM; +public: + + ScanReachableSymbols(const ProgramState *st, SymbolVisitor& v) + : state(st), visitor(v) {} + + bool scan(nonloc::CompoundVal val); + bool scan(SVal val); + bool scan(const MemRegion *R); + bool scan(const SymExpr *sym); + + // From SubRegionMap::Visitor. + bool Visit(const MemRegion* Parent, const MemRegion* SubRegion) { + return scan(SubRegion); + } +}; + } // end GR namespace } // end clang namespace diff --git a/lib/StaticAnalyzer/Core/Environment.cpp b/lib/StaticAnalyzer/Core/Environment.cpp index 2d37e53cee..0ca1168631 100644 --- a/lib/StaticAnalyzer/Core/Environment.cpp +++ b/lib/StaticAnalyzer/Core/Environment.cpp @@ -156,6 +156,9 @@ EnvironmentManager::removeDeadBindings(Environment Env, SmallVector<std::pair<const Stmt*, SVal>, 10> deferredLocations; + MarkLiveCallback CB(SymReaper); + ScanReachableSymbols RSScaner(ST, CB); + // Iterate over the block-expr bindings. for (Environment::iterator I = Env.begin(), E = Env.end(); I != E; ++I) { @@ -183,8 +186,7 @@ EnvironmentManager::removeDeadBindings(Environment Env, } // Mark all symbols in the block expr's value live. - MarkLiveCallback cb(SymReaper); - ST->scanReachableSymbols(X, cb); + RSScaner.scan(X); continue; } diff --git a/lib/StaticAnalyzer/Core/ProgramState.cpp b/lib/StaticAnalyzer/Core/ProgramState.cpp index 6a03a3e8cc..73788cc42e 100644 --- a/lib/StaticAnalyzer/Core/ProgramState.cpp +++ b/lib/StaticAnalyzer/Core/ProgramState.cpp @@ -513,35 +513,6 @@ const ProgramState *ProgramStateManager::removeGDM(const ProgramState *state, vo return getPersistentState(NewState); } -//===----------------------------------------------------------------------===// -// Utility. -//===----------------------------------------------------------------------===// - -namespace { -class ScanReachableSymbols : public SubRegionMap::Visitor { - typedef llvm::DenseMap<const void*, unsigned> VisitedItems; - - VisitedItems visited; - const ProgramState *state; - SymbolVisitor &visitor; - llvm::OwningPtr<SubRegionMap> SRM; -public: - - ScanReachableSymbols(const ProgramState *st, SymbolVisitor& v) - : state(st), visitor(v) {} - - bool scan(nonloc::CompoundVal val); - bool scan(SVal val); - bool scan(const MemRegion *R); - bool scan(const SymExpr *sym); - - // From SubRegionMap::Visitor. - bool Visit(const MemRegion* Parent, const MemRegion* SubRegion) { - return scan(SubRegion); - } -}; -} - bool ScanReachableSymbols::scan(nonloc::CompoundVal val) { for (nonloc::CompoundVal::iterator I=val.begin(), E=val.end(); I!=E; ++I) if (!scan(*I)) |