From: Anna Zaks Date: Thu, 22 Sep 2011 18:10:41 +0000 (+0000) Subject: ST->scanReachableSymbols() is creating a SubRegionMap (SRM) on every call since one... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5f625712f622f6e57de17b6f7eec242956b993ee;p=clang 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 --- 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 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 VisitedItems; + + VisitedItems visited; + const ProgramState *state; + SymbolVisitor &visitor; + llvm::OwningPtr 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, 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 VisitedItems; - - VisitedItems visited; - const ProgramState *state; - SymbolVisitor &visitor; - llvm::OwningPtr 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))