|
@@ -349,7 +349,6 @@ private:
|
|
/// regions.
|
|
/// regions.
|
|
void populateWorkList(invalidateRegionsWorker &W,
|
|
void populateWorkList(invalidateRegionsWorker &W,
|
|
ArrayRef<SVal> Values,
|
|
ArrayRef<SVal> Values,
|
|
- bool IsArrayOfConstRegions,
|
|
|
|
InvalidatedRegions *TopLevelRegions);
|
|
InvalidatedRegions *TopLevelRegions);
|
|
|
|
|
|
public:
|
|
public:
|
|
@@ -395,15 +394,13 @@ public:
|
|
|
|
|
|
StoreRef invalidateRegions(Store store,
|
|
StoreRef invalidateRegions(Store store,
|
|
ArrayRef<SVal> Values,
|
|
ArrayRef<SVal> Values,
|
|
- ArrayRef<SVal> ConstValues,
|
|
|
|
const Expr *E, unsigned Count,
|
|
const Expr *E, unsigned Count,
|
|
const LocationContext *LCtx,
|
|
const LocationContext *LCtx,
|
|
const CallEvent *Call,
|
|
const CallEvent *Call,
|
|
InvalidatedSymbols &IS,
|
|
InvalidatedSymbols &IS,
|
|
- InvalidatedSymbols &ConstIS,
|
|
|
|
|
|
+ RegionAndSymbolInvalidationTraits &ITraits,
|
|
InvalidatedRegions *Invalidated,
|
|
InvalidatedRegions *Invalidated,
|
|
- InvalidatedRegions *InvalidatedTopLevel,
|
|
|
|
- InvalidatedRegions *InvalidatedTopLevelConst);
|
|
|
|
|
|
+ InvalidatedRegions *InvalidatedTopLevel);
|
|
|
|
|
|
bool scanReachableSymbols(Store S, const MemRegion *R,
|
|
bool scanReachableSymbols(Store S, const MemRegion *R,
|
|
ScanReachableSymbols &Callbacks);
|
|
ScanReachableSymbols &Callbacks);
|
|
@@ -648,7 +645,7 @@ template <typename DERIVED>
|
|
class ClusterAnalysis {
|
|
class ClusterAnalysis {
|
|
protected:
|
|
protected:
|
|
typedef llvm::DenseMap<const MemRegion *, const ClusterBindings *> ClusterMap;
|
|
typedef llvm::DenseMap<const MemRegion *, const ClusterBindings *> ClusterMap;
|
|
- typedef llvm::PointerIntPair<const MemRegion *, 1, bool> WorkListElement;
|
|
|
|
|
|
+ typedef const MemRegion * WorkListElement;
|
|
typedef SmallVector<WorkListElement, 10> WorkList;
|
|
typedef SmallVector<WorkListElement, 10> WorkList;
|
|
|
|
|
|
llvm::SmallPtrSet<const ClusterBindings *, 16> Visited;
|
|
llvm::SmallPtrSet<const ClusterBindings *, 16> Visited;
|
|
@@ -720,18 +717,17 @@ public:
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
|
|
- bool AddToWorkList(const MemRegion *R, bool Flag = false) {
|
|
|
|
|
|
+ bool AddToWorkList(const MemRegion *R) {
|
|
const MemRegion *BaseR = R->getBaseRegion();
|
|
const MemRegion *BaseR = R->getBaseRegion();
|
|
- return AddToWorkList(WorkListElement(BaseR, Flag), getCluster(BaseR));
|
|
|
|
|
|
+ return AddToWorkList(WorkListElement(BaseR), getCluster(BaseR));
|
|
}
|
|
}
|
|
|
|
|
|
void RunWorkList() {
|
|
void RunWorkList() {
|
|
while (!WL.empty()) {
|
|
while (!WL.empty()) {
|
|
WorkListElement E = WL.pop_back_val();
|
|
WorkListElement E = WL.pop_back_val();
|
|
- const MemRegion *BaseR = E.getPointer();
|
|
|
|
|
|
+ const MemRegion *BaseR = E;
|
|
|
|
|
|
- static_cast<DERIVED*>(this)->VisitCluster(BaseR, getCluster(BaseR),
|
|
|
|
- E.getInt());
|
|
|
|
|
|
+ static_cast<DERIVED*>(this)->VisitCluster(BaseR, getCluster(BaseR));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -951,7 +947,7 @@ class invalidateRegionsWorker : public ClusterAnalysis<invalidateRegionsWorker>
|
|
unsigned Count;
|
|
unsigned Count;
|
|
const LocationContext *LCtx;
|
|
const LocationContext *LCtx;
|
|
InvalidatedSymbols &IS;
|
|
InvalidatedSymbols &IS;
|
|
- InvalidatedSymbols &ConstIS;
|
|
|
|
|
|
+ RegionAndSymbolInvalidationTraits &ITraits;
|
|
StoreManager::InvalidatedRegions *Regions;
|
|
StoreManager::InvalidatedRegions *Regions;
|
|
public:
|
|
public:
|
|
invalidateRegionsWorker(RegionStoreManager &rm,
|
|
invalidateRegionsWorker(RegionStoreManager &rm,
|
|
@@ -960,16 +956,15 @@ public:
|
|
const Expr *ex, unsigned count,
|
|
const Expr *ex, unsigned count,
|
|
const LocationContext *lctx,
|
|
const LocationContext *lctx,
|
|
InvalidatedSymbols &is,
|
|
InvalidatedSymbols &is,
|
|
- InvalidatedSymbols &inConstIS,
|
|
|
|
|
|
+ RegionAndSymbolInvalidationTraits &ITraitsIn,
|
|
StoreManager::InvalidatedRegions *r,
|
|
StoreManager::InvalidatedRegions *r,
|
|
GlobalsFilterKind GFK)
|
|
GlobalsFilterKind GFK)
|
|
: ClusterAnalysis<invalidateRegionsWorker>(rm, stateMgr, b, GFK),
|
|
: ClusterAnalysis<invalidateRegionsWorker>(rm, stateMgr, b, GFK),
|
|
- Ex(ex), Count(count), LCtx(lctx), IS(is), ConstIS(inConstIS), Regions(r){}
|
|
|
|
|
|
+ Ex(ex), Count(count), LCtx(lctx), IS(is), ITraits(ITraitsIn), Regions(r){}
|
|
|
|
|
|
/// \param IsConst Specifies if the region we are invalidating is constant.
|
|
/// \param IsConst Specifies if the region we are invalidating is constant.
|
|
/// If it is, we invalidate all subregions, but not the base region itself.
|
|
/// If it is, we invalidate all subregions, but not the base region itself.
|
|
- void VisitCluster(const MemRegion *baseR, const ClusterBindings *C,
|
|
|
|
- bool IsConst);
|
|
|
|
|
|
+ void VisitCluster(const MemRegion *baseR, const ClusterBindings *C);
|
|
void VisitBinding(SVal V);
|
|
void VisitBinding(SVal V);
|
|
};
|
|
};
|
|
}
|
|
}
|
|
@@ -1000,14 +995,18 @@ void invalidateRegionsWorker::VisitBinding(SVal V) {
|
|
}
|
|
}
|
|
|
|
|
|
void invalidateRegionsWorker::VisitCluster(const MemRegion *baseR,
|
|
void invalidateRegionsWorker::VisitCluster(const MemRegion *baseR,
|
|
- const ClusterBindings *C,
|
|
|
|
- bool IsConst) {
|
|
|
|
|
|
+ const ClusterBindings *C) {
|
|
|
|
+
|
|
|
|
+ bool PreserveRegionsContents =
|
|
|
|
+ ITraits.hasTrait(baseR,
|
|
|
|
+ RegionAndSymbolInvalidationTraits::TK_PreserveContents);
|
|
|
|
+
|
|
if (C) {
|
|
if (C) {
|
|
for (ClusterBindings::iterator I = C->begin(), E = C->end(); I != E; ++I)
|
|
for (ClusterBindings::iterator I = C->begin(), E = C->end(); I != E; ++I)
|
|
VisitBinding(I.getData());
|
|
VisitBinding(I.getData());
|
|
|
|
|
|
- // Invalidate the contents of a non-const base region.
|
|
|
|
- if (!IsConst)
|
|
|
|
|
|
+ // Invalidate regions contents.
|
|
|
|
+ if (!PreserveRegionsContents)
|
|
B = B.remove(baseR);
|
|
B = B.remove(baseR);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1039,18 +1038,11 @@ void invalidateRegionsWorker::VisitCluster(const MemRegion *baseR,
|
|
}
|
|
}
|
|
|
|
|
|
// Symbolic region?
|
|
// Symbolic region?
|
|
- if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(baseR)) {
|
|
|
|
- SymbolRef RegionSym = SR->getSymbol();
|
|
|
|
-
|
|
|
|
- // Mark that symbol touched by the invalidation.
|
|
|
|
- if (IsConst)
|
|
|
|
- ConstIS.insert(RegionSym);
|
|
|
|
- else
|
|
|
|
- IS.insert(RegionSym);
|
|
|
|
- }
|
|
|
|
|
|
+ if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(baseR))
|
|
|
|
+ IS.insert(SR->getSymbol());
|
|
|
|
|
|
- // Nothing else should be done for a const region.
|
|
|
|
- if (IsConst)
|
|
|
|
|
|
+ // Nothing else should be done in the case when we preserve regions context.
|
|
|
|
+ if (PreserveRegionsContents)
|
|
return;
|
|
return;
|
|
|
|
|
|
// Otherwise, we have a normal data region. Record that we touched the region.
|
|
// Otherwise, we have a normal data region. Record that we touched the region.
|
|
@@ -1059,7 +1051,7 @@ void invalidateRegionsWorker::VisitCluster(const MemRegion *baseR,
|
|
|
|
|
|
if (isa<AllocaRegion>(baseR) || isa<SymbolicRegion>(baseR)) {
|
|
if (isa<AllocaRegion>(baseR) || isa<SymbolicRegion>(baseR)) {
|
|
// Invalidate the region by setting its default value to
|
|
// Invalidate the region by setting its default value to
|
|
- // conjured symbol. The type of the symbol is irrelavant.
|
|
|
|
|
|
+ // conjured symbol. The type of the symbol is irrelevant.
|
|
DefinedOrUnknownSVal V =
|
|
DefinedOrUnknownSVal V =
|
|
svalBuilder.conjureSymbolVal(baseR, Ex, LCtx, Ctx.IntTy, Count);
|
|
svalBuilder.conjureSymbolVal(baseR, Ex, LCtx, Ctx.IntTy, Count);
|
|
B = B.addBinding(baseR, BindingKey::Default, V);
|
|
B = B.addBinding(baseR, BindingKey::Default, V);
|
|
@@ -1081,7 +1073,7 @@ void invalidateRegionsWorker::VisitCluster(const MemRegion *baseR,
|
|
|
|
|
|
if (T->isStructureOrClassType()) {
|
|
if (T->isStructureOrClassType()) {
|
|
// Invalidate the region by setting its default value to
|
|
// Invalidate the region by setting its default value to
|
|
- // conjured symbol. The type of the symbol is irrelavant.
|
|
|
|
|
|
+ // conjured symbol. The type of the symbol is irrelevant.
|
|
DefinedOrUnknownSVal V = svalBuilder.conjureSymbolVal(baseR, Ex, LCtx,
|
|
DefinedOrUnknownSVal V = svalBuilder.conjureSymbolVal(baseR, Ex, LCtx,
|
|
Ctx.IntTy, Count);
|
|
Ctx.IntTy, Count);
|
|
B = B.addBinding(baseR, BindingKey::Default, V);
|
|
B = B.addBinding(baseR, BindingKey::Default, V);
|
|
@@ -1130,7 +1122,6 @@ RegionStoreManager::invalidateGlobalRegion(MemRegion::Kind K,
|
|
|
|
|
|
void RegionStoreManager::populateWorkList(invalidateRegionsWorker &W,
|
|
void RegionStoreManager::populateWorkList(invalidateRegionsWorker &W,
|
|
ArrayRef<SVal> Values,
|
|
ArrayRef<SVal> Values,
|
|
- bool IsArrayOfConstRegions,
|
|
|
|
InvalidatedRegions *TopLevelRegions) {
|
|
InvalidatedRegions *TopLevelRegions) {
|
|
for (ArrayRef<SVal>::iterator I = Values.begin(),
|
|
for (ArrayRef<SVal>::iterator I = Values.begin(),
|
|
E = Values.end(); I != E; ++I) {
|
|
E = Values.end(); I != E; ++I) {
|
|
@@ -1145,7 +1136,7 @@ void RegionStoreManager::populateWorkList(invalidateRegionsWorker &W,
|
|
// Note: the last argument is false here because these are
|
|
// Note: the last argument is false here because these are
|
|
// non-top-level regions.
|
|
// non-top-level regions.
|
|
if (const MemRegion *R = (*I).getAsRegion())
|
|
if (const MemRegion *R = (*I).getAsRegion())
|
|
- W.AddToWorkList(R, /*IsConst=*/ false);
|
|
|
|
|
|
+ W.AddToWorkList(R);
|
|
}
|
|
}
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
@@ -1153,7 +1144,7 @@ void RegionStoreManager::populateWorkList(invalidateRegionsWorker &W,
|
|
if (const MemRegion *R = V.getAsRegion()) {
|
|
if (const MemRegion *R = V.getAsRegion()) {
|
|
if (TopLevelRegions)
|
|
if (TopLevelRegions)
|
|
TopLevelRegions->push_back(R);
|
|
TopLevelRegions->push_back(R);
|
|
- W.AddToWorkList(R, /*IsConst=*/ IsArrayOfConstRegions);
|
|
|
|
|
|
+ W.AddToWorkList(R);
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -1161,16 +1152,14 @@ void RegionStoreManager::populateWorkList(invalidateRegionsWorker &W,
|
|
|
|
|
|
StoreRef
|
|
StoreRef
|
|
RegionStoreManager::invalidateRegions(Store store,
|
|
RegionStoreManager::invalidateRegions(Store store,
|
|
- ArrayRef<SVal> Values,
|
|
|
|
- ArrayRef<SVal> ConstValues,
|
|
|
|
- const Expr *Ex, unsigned Count,
|
|
|
|
- const LocationContext *LCtx,
|
|
|
|
- const CallEvent *Call,
|
|
|
|
- InvalidatedSymbols &IS,
|
|
|
|
- InvalidatedSymbols &ConstIS,
|
|
|
|
- InvalidatedRegions *TopLevelRegions,
|
|
|
|
- InvalidatedRegions *TopLevelConstRegions,
|
|
|
|
- InvalidatedRegions *Invalidated) {
|
|
|
|
|
|
+ ArrayRef<SVal> Values,
|
|
|
|
+ const Expr *Ex, unsigned Count,
|
|
|
|
+ const LocationContext *LCtx,
|
|
|
|
+ const CallEvent *Call,
|
|
|
|
+ InvalidatedSymbols &IS,
|
|
|
|
+ RegionAndSymbolInvalidationTraits &ITraits,
|
|
|
|
+ InvalidatedRegions *TopLevelRegions,
|
|
|
|
+ InvalidatedRegions *Invalidated) {
|
|
GlobalsFilterKind GlobalsFilter;
|
|
GlobalsFilterKind GlobalsFilter;
|
|
if (Call) {
|
|
if (Call) {
|
|
if (Call->isInSystemHeader())
|
|
if (Call->isInSystemHeader())
|
|
@@ -1182,17 +1171,14 @@ RegionStoreManager::invalidateRegions(Store store,
|
|
}
|
|
}
|
|
|
|
|
|
RegionBindingsRef B = getRegionBindings(store);
|
|
RegionBindingsRef B = getRegionBindings(store);
|
|
- invalidateRegionsWorker W(*this, StateMgr, B, Ex, Count, LCtx, IS, ConstIS,
|
|
|
|
|
|
+ invalidateRegionsWorker W(*this, StateMgr, B, Ex, Count, LCtx, IS, ITraits,
|
|
Invalidated, GlobalsFilter);
|
|
Invalidated, GlobalsFilter);
|
|
|
|
|
|
// Scan the bindings and generate the clusters.
|
|
// Scan the bindings and generate the clusters.
|
|
W.GenerateClusters();
|
|
W.GenerateClusters();
|
|
|
|
|
|
// Add the regions to the worklist.
|
|
// Add the regions to the worklist.
|
|
- populateWorkList(W, Values, /*IsArrayOfConstRegions*/ false,
|
|
|
|
- TopLevelRegions);
|
|
|
|
- populateWorkList(W, ConstValues, /*IsArrayOfConstRegions*/ true,
|
|
|
|
- TopLevelConstRegions);
|
|
|
|
|
|
+ populateWorkList(W, Values, TopLevelRegions);
|
|
|
|
|
|
W.RunWorkList();
|
|
W.RunWorkList();
|
|
|
|
|