r175233 - [analyzer] Cache the bindings accessible through a LazyCompoundVal.
Jordan Rose
jordan_rose at apple.com
Thu Feb 14 16:32:12 PST 2013
Author: jrose
Date: Thu Feb 14 18:32:12 2013
New Revision: 175233
URL: http://llvm.org/viewvc/llvm-project?rev=175233&view=rev
Log:
[analyzer] Cache the bindings accessible through a LazyCompoundVal.
This means we don't have to recompute them all later for every
removeDeadSymbols check.
Modified:
cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp
Modified: cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp?rev=175233&r1=175232&r2=175233&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp Thu Feb 14 18:32:12 2013
@@ -323,6 +323,13 @@ public:
RegionBindings::Factory RBFactory;
mutable ClusterBindings::Factory CBFactory;
+ typedef std::vector<SVal> SValListTy;
+private:
+ typedef llvm::DenseMap<const LazyCompoundValData *,
+ SValListTy> LazyBindingsMapTy;
+ LazyBindingsMapTy LazyBindingsMap;
+
+public:
RegionStoreManager(ProgramStateManager& mgr, const RegionStoreFeatures &f)
: StoreManager(mgr), Features(f),
RBFactory(mgr.getAllocator()), CBFactory(mgr.getAllocator()) {}
@@ -495,6 +502,14 @@ public: // Part of public interface to c
getLazyBinding(RegionBindingsConstRef B, const MemRegion *R,
const MemRegion *originalRegion);
+ /// Returns the cached set of interesting SVals contained within a lazy
+ /// binding.
+ ///
+ /// The precise value of "interesting" is determined for the purposes of
+ /// RegionStore's internal analysis. It must always contain all regions and
+ /// symbols, but may omit constants and other kinds of SVal.
+ const SValListTy &getInterestingValues(nonloc::LazyCompoundVal LCV);
+
//===------------------------------------------------------------------===//
// State pruning.
//===------------------------------------------------------------------===//
@@ -878,23 +893,12 @@ void invalidateRegionsWorker::VisitBindi
if (const nonloc::LazyCompoundVal *LCS =
dyn_cast<nonloc::LazyCompoundVal>(&V)) {
- const MemRegion *LazyR = LCS->getRegion();
- RegionBindingsRef B = RM.getRegionBindings(LCS->getStore());
+ const RegionStoreManager::SValListTy &Vals = RM.getInterestingValues(*LCS);
- // FIXME: This should not have to walk all bindings in the old store.
- for (RegionBindingsRef::iterator RI = B.begin(), RE = B.end(); RI != RE; ++RI){
- const ClusterBindings &Cluster = RI.getData();
- for (ClusterBindings::iterator CI = Cluster.begin(), CE = Cluster.end();
- CI != CE; ++CI) {
- BindingKey K = CI.getKey();
- if (const SubRegion *BaseR = dyn_cast<SubRegion>(K.getRegion())) {
- if (BaseR == LazyR)
- VisitBinding(CI.getData());
- else if (K.hasSymbolicOffset() && BaseR->isSubRegionOf(LazyR))
- VisitBinding(CI.getData());
- }
- }
- }
+ for (RegionStoreManager::SValListTy::const_iterator I = Vals.begin(),
+ E = Vals.end();
+ I != E; ++I)
+ VisitBinding(*I);
return;
}
@@ -1595,6 +1599,49 @@ SVal RegionStoreManager::getBindingForLa
return svalBuilder.getRegionValueSymbolVal(R);
}
+const RegionStoreManager::SValListTy &
+RegionStoreManager::getInterestingValues(nonloc::LazyCompoundVal LCV) {
+ // First, check the cache.
+ LazyBindingsMapTy::iterator I = LazyBindingsMap.find(LCV.getCVData());
+ if (I != LazyBindingsMap.end())
+ return I->second;
+
+ // If we don't have a list of values cached, start constructing it.
+ SValListTy &List = LazyBindingsMap[LCV.getCVData()];
+
+ const SubRegion *LazyR = LCV.getRegion();
+ RegionBindingsRef B = getRegionBindings(LCV.getStore());
+
+ // If this region had /no/ bindings at the time, there are no interesting
+ // values to return.
+ const ClusterBindings *Cluster = B.lookup(LazyR->getBaseRegion());
+ if (!Cluster)
+ return List;
+
+ SmallVector<BindingKey, 32> Keys;
+ collectSubRegionKeys(Keys, svalBuilder, *Cluster, LazyR,
+ /*IncludeAllDefaultBindings=*/true);
+ for (SmallVectorImpl<BindingKey>::const_iterator I = Keys.begin(),
+ E = Keys.end();
+ I != E; ++I) {
+ SVal V = *Cluster->lookup(*I);
+ if (V.isUnknownOrUndef() || V.isConstant())
+ continue;
+
+ const nonloc::LazyCompoundVal *InnerLCV =
+ dyn_cast<nonloc::LazyCompoundVal>(&V);
+ if (InnerLCV) {
+ const SValListTy &InnerList = getInterestingValues(*InnerLCV);
+ List.insert(List.end(), InnerList.begin(), InnerList.end());
+ continue;
+ }
+
+ List.push_back(V);
+ }
+
+ return List;
+}
+
NonLoc RegionStoreManager::createLazyBinding(RegionBindingsConstRef B,
const TypedValueRegion *R) {
// If we already have a lazy binding, and it's for the whole structure,
@@ -1991,21 +2038,12 @@ void removeDeadBindingsWorker::VisitBind
if (const nonloc::LazyCompoundVal *LCS =
dyn_cast<nonloc::LazyCompoundVal>(&V)) {
- const SubRegion *LazyR = LCS->getRegion();
- RegionBindingsRef B = RM.getRegionBindings(LCS->getStore());
+ const RegionStoreManager::SValListTy &Vals = RM.getInterestingValues(*LCS);
- const ClusterBindings *Cluster = B.lookup(LazyR->getBaseRegion());
- if (!Cluster)
- return;
-
- SmallVector<BindingKey, 32> Keys;
- collectSubRegionKeys(Keys, svalBuilder, *Cluster, LazyR,
- /*IncludeAllDefaultBindings=*/true);
- for (SmallVectorImpl<BindingKey>::const_iterator I = Keys.begin(),
- E = Keys.end();
- I != E; ++I) {
- VisitBinding(*Cluster->lookup(*I));
- }
+ for (RegionStoreManager::SValListTy::const_iterator I = Vals.begin(),
+ E = Vals.end();
+ I != E; ++I)
+ VisitBinding(*I);
return;
}
More information about the cfe-commits
mailing list