summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorJordan Rose <jordan_rose@apple.com>2013-02-15 00:32:06 +0000
committerJordan Rose <jordan_rose@apple.com>2013-02-15 00:32:06 +0000
commit44d877a8c75db5126fe1fd5a8b6797efd46e107a (patch)
tree0a3f944d78605bef9f9b8dec3d95162912b68d00 /clang/lib
parent8628bc59e0e64725fdc7ffe1294583ad8ad3700e (diff)
downloadbcm5719-llvm-44d877a8c75db5126fe1fd5a8b6797efd46e107a.tar.gz
bcm5719-llvm-44d877a8c75db5126fe1fd5a8b6797efd46e107a.zip
[analyzer] Use collectSubRegionKeys to make removeDeadBindings faster.
Previously, whenever we had a LazyCompoundVal, we crawled through the entire store snapshot looking for bindings within the LCV's region. Now, we just ask for the subregion bindings of the lazy region and only visit those. This is an optimization (so no test case), but it may allow us to clean up more dead bindings than we were previously. llvm-svn: 175230
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/StaticAnalyzer/Core/RegionStore.cpp52
1 files changed, 33 insertions, 19 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp
index 7b1d72b3f20..76abf238f26 100644
--- a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp
+++ b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp
@@ -713,10 +713,16 @@ static bool isCompatibleWithFields(BindingKey K, const FieldVector &Fields) {
Fields.begin() - Delta);
}
+/// Collects all keys in \p Cluster that may refer to bindings within \p Top.
+///
+/// The \p IncludeAllDefaultBindings parameter specifies whether to include
+/// default bindings that may extend beyond \p Top itself, e.g. if \p Top is
+/// an aggregate within a larger aggregate with a default binding.
static void collectSubRegionKeys(SmallVectorImpl<BindingKey> &Keys,
SValBuilder &SVB,
const ClusterBindings &Cluster,
- const SubRegion *Top, BindingKey TopKey) {
+ const SubRegion *Top, BindingKey TopKey,
+ bool IncludeAllDefaultBindings) {
FieldVector FieldsInSymbolicSubregions;
if (TopKey.hasSymbolicOffset()) {
getSymbolicOffsetFields(TopKey, FieldsInSymbolicSubregions);
@@ -758,7 +764,7 @@ static void collectSubRegionKeys(SmallVectorImpl<BindingKey> &Keys,
// we're invalidating.
// FIXME: This is probably incorrect; consider invalidating an outer
// struct whose first field is bound to a LazyCompoundVal.
- if (NextKey.isDirect())
+ if (IncludeAllDefaultBindings || NextKey.isDirect())
Keys.push_back(NextKey);
}
@@ -768,7 +774,7 @@ static void collectSubRegionKeys(SmallVectorImpl<BindingKey> &Keys,
// Case 3: The next key is symbolic and we just changed something within
// its concrete region. We don't know if the binding is still valid, so
// we'll be conservative and remove it.
- if (NextKey.isDirect())
+ if (IncludeAllDefaultBindings || NextKey.isDirect())
if (isCompatibleWithFields(NextKey, FieldsInSymbolicSubregions))
Keys.push_back(NextKey);
} else if (const SubRegion *BaseSR = dyn_cast<SubRegion>(Base)) {
@@ -782,6 +788,16 @@ static void collectSubRegionKeys(SmallVectorImpl<BindingKey> &Keys,
}
}
+static void collectSubRegionKeys(SmallVectorImpl<BindingKey> &Keys,
+ SValBuilder &SVB,
+ const ClusterBindings &Cluster,
+ const SubRegion *Top,
+ bool IncludeAllDefaultBindings) {
+ collectSubRegionKeys(Keys, SVB, Cluster, Top,
+ BindingKey::Make(Top, BindingKey::Default),
+ IncludeAllDefaultBindings);
+}
+
RegionBindingsRef
RegionStoreManager::removeSubRegionBindings(RegionBindingsConstRef B,
const SubRegion *Top) {
@@ -797,7 +813,8 @@ RegionStoreManager::removeSubRegionBindings(RegionBindingsConstRef B,
return B;
SmallVector<BindingKey, 32> Keys;
- collectSubRegionKeys(Keys, svalBuilder, *Cluster, Top, TopKey);
+ collectSubRegionKeys(Keys, svalBuilder, *Cluster, Top, TopKey,
+ /*IncludeAllDefaultBindings=*/false);
ClusterBindingsRef Result(*Cluster, CBFactory);
for (SmallVectorImpl<BindingKey>::const_iterator I = Keys.begin(),
@@ -1974,23 +1991,20 @@ void removeDeadBindingsWorker::VisitBinding(SVal V) {
if (const nonloc::LazyCompoundVal *LCS =
dyn_cast<nonloc::LazyCompoundVal>(&V)) {
- const MemRegion *LazyR = LCS->getRegion();
+ const SubRegion *LazyR = LCS->getRegion();
RegionBindingsRef B = RM.getRegionBindings(LCS->getStore());
- // 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());
- }
- }
+ 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));
}
return;
OpenPOWER on IntegriCloud