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.

llvm-svn: 140323
This commit is contained in:
Anna Zaks 2011-09-22 18:10:41 +00:00
parent f04ee930a0
commit 9db35a8750
3 changed files with 43 additions and 35 deletions

View File

@ -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

View File

@ -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;
}

View File

@ -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))