forked from OSchip/llvm-project
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:
parent
f04ee930a0
commit
9db35a8750
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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))
|
||||
|
|
Loading…
Reference in New Issue