};
typedef const SymbolData* SymbolRef;
+typedef llvm::SmallVector<SymbolRef, 1> SymbolRefSmallVectorTy;
/// A symbol representing the value of a MemRegion.
class SymbolRegionValue : public SymbolData {
class SymbolManager {
typedef llvm::FoldingSet<SymExpr> DataSetTy;
+ typedef llvm::DenseMap<SymbolRef, SymbolRefSmallVectorTy> SymbolDependTy;
DataSetTy DataSet;
+ /// Stores the extra dependencies between symbols: the data should be kept
+ /// alive as long as the key is live.
+ SymbolDependTy SymbolDependencies;
unsigned SymbolCounter;
llvm::BumpPtrAllocator& BPAlloc;
BasicValueFactory &BV;
return SE->getType(Ctx);
}
+ /// \brief Add artificial symbol dependency.
+ ///
+ /// The dependent symbol should stay alive as long as the primary is alive.
+ void addSymbolDependency(const SymbolRef Primary, const SymbolRef Dependent);
+
+ /// \brief Drop all user-added dependencies on the primary symbol.
+ void removeSymbolDependencies(const SymbolRef Primary);
+
+ const SymbolRefSmallVectorTy *getDependentSymbols(const SymbolRef Primary);
+
ASTContext &getContext() { return Ctx; }
BasicValueFactory &getBasicVals() { return BV; }
};
/// \brief Set to the value of the symbolic store after
/// StoreManager::removeDeadBindings has been called.
void setReapedStore(StoreRef st) { reapedStore = st; }
+
+private:
+ /// Mark the symbols dependent on the input symbol as live.
+ void markDependentsLive(SymbolRef sym);
};
class SymbolVisitor {
return false;
}
+void SymbolManager::addSymbolDependency(const SymbolRef Primary,
+ const SymbolRef Dependent) {
+ SymbolDependencies[Primary].push_back(Dependent);
+}
+
+void SymbolManager::removeSymbolDependencies(const SymbolRef Primary) {
+ SymbolDependencies.erase(Primary);
+}
+
+const SymbolRefSmallVectorTy *SymbolManager::getDependentSymbols(
+ const SymbolRef Primary) {
+ SymbolDependTy::const_iterator I = SymbolDependencies.find(Primary);
+ if (I == SymbolDependencies.end())
+ return 0;
+ return &I->second;
+}
+
+void SymbolReaper::markDependentsLive(SymbolRef sym) {
+ if (const SymbolRefSmallVectorTy *Deps = SymMgr.getDependentSymbols(sym)) {
+ for (SymbolRefSmallVectorTy::const_iterator I = Deps->begin(),
+ E = Deps->end(); I != E; ++I) {
+ markLive(*I);
+ }
+ }
+}
+
void SymbolReaper::markLive(SymbolRef sym) {
TheLiving.insert(sym);
TheDead.erase(sym);
+ markDependentsLive(sym);
}
void SymbolReaper::markLive(const MemRegion *region) {
}
bool SymbolReaper::isLive(SymbolRef sym) {
- if (TheLiving.count(sym))
+ if (TheLiving.count(sym)) {
+ markDependentsLive(sym);
return true;
+ }
if (const SymbolDerived *derived = dyn_cast<SymbolDerived>(sym)) {
if (isLive(derived->getParentSymbol())) {