[cfe-commits] r53726 - in /cfe/trunk: include/clang/Analysis/PathSensitive/Store.h include/clang/Analysis/PathSensitive/ValueState.h lib/Analysis/BasicStore.cpp lib/Analysis/ValueState.cpp
Ted Kremenek
kremenek at apple.com
Thu Jul 17 11:38:48 PDT 2008
Author: kremenek
Date: Thu Jul 17 13:38:48 2008
New Revision: 53726
URL: http://llvm.org/viewvc/llvm-project?rev=53726&view=rev
Log:
Moved RemoveDeadBindings logic for the contents of 'Store' to a virtual RemoveDeadBindings method in StoreManager.
Modified:
cfe/trunk/include/clang/Analysis/PathSensitive/Store.h
cfe/trunk/include/clang/Analysis/PathSensitive/ValueState.h
cfe/trunk/lib/Analysis/BasicStore.cpp
cfe/trunk/lib/Analysis/ValueState.cpp
Modified: cfe/trunk/include/clang/Analysis/PathSensitive/Store.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/Store.h?rev=53726&r1=53725&r2=53726&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/Store.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/Store.h Thu Jul 17 13:38:48 2008
@@ -15,18 +15,33 @@
#define LLVM_CLANG_ANALYSIS_STORE_H
#include "clang/Analysis/PathSensitive/RValues.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/DenseSet.h"
+#include <vector>
namespace clang {
typedef const void* Store;
+class LiveVariables;
+class Stmt;
class StoreManager {
public:
+ typedef llvm::SmallSet<SymbolID, 20> LiveSymbolsTy;
+ typedef llvm::DenseSet<SymbolID> DeadSymbolsTy;
+ typedef std::vector<ValueDecl*> DeclRootsTy;
+
virtual ~StoreManager() {}
- virtual RVal GetRVal(Store St, LVal LV, QualType T) = 0;
+ virtual RVal GetRVal(Store St, LVal LV, QualType T = QualType()) = 0;
virtual Store SetRVal(Store St, LVal LV, RVal V) = 0;
virtual Store Remove(Store St, LVal LV) = 0;
virtual Store getInitialStore() = 0;
+
+ virtual Store RemoveDeadBindings(Store store, Stmt* Loc,
+ const LiveVariables& Live,
+ DeclRootsTy& DRoots, LiveSymbolsTy& LSymbols,
+ DeadSymbolsTy& DSymbols) = 0;
};
} // end clang namespace
Modified: cfe/trunk/include/clang/Analysis/PathSensitive/ValueState.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/ValueState.h?rev=53726&r1=53725&r2=53726&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/ValueState.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/ValueState.h Thu Jul 17 13:38:48 2008
@@ -31,7 +31,6 @@
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/ImmutableMap.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Compiler.h"
@@ -57,7 +56,7 @@
typedef llvm::ImmutableSet<llvm::APSInt*> IntSetTy;
typedef llvm::ImmutableMap<SymbolID,IntSetTy> ConstNotEqTy;
typedef llvm::ImmutableMap<SymbolID,const llvm::APSInt*> ConstEqTy;
-
+
private:
void operator=(const ValueState& R) const;
@@ -128,6 +127,7 @@
// Iterators.
+
// FIXME: We'll be removing the VarBindings iterator very soon. Right now
// it assumes that Store is a VarBindingsTy.
typedef llvm::ImmutableMap<VarDecl*,RVal> VarBindingsTy;
@@ -140,6 +140,7 @@
VarBindingsTy B(static_cast<const VarBindingsTy::TreeTy*>(St));
return B.end();
}
+
typedef Environment::seb_iterator seb_iterator;
seb_iterator seb_begin() const { return Env.seb_begin(); }
@@ -184,6 +185,7 @@
class ValueStateManager {
+
private:
EnvironmentManager EnvMgr;
llvm::OwningPtr<StoreManager> StMgr;
@@ -204,6 +206,10 @@
/// Alloc - A BumpPtrAllocator to allocate states.
llvm::BumpPtrAllocator& Alloc;
+ /// DRoots - A vector to hold of worklist used by RemoveDeadSymbols.
+ /// This vector is persistent because it is reused over and over.
+ StoreManager::DeclRootsTy DRoots;
+
private:
Environment RemoveBlkExpr(const Environment& Env, Expr* E) {
@@ -232,11 +238,11 @@
BasicValueFactory& getBasicValueFactory() { return BasicVals; }
SymbolManager& getSymbolManager() { return SymMgr; }
- typedef llvm::DenseSet<SymbolID> DeadSymbolsTy;
+ typedef StoreManager::DeadSymbolsTy DeadSymbolsTy;
const ValueState* RemoveDeadBindings(const ValueState* St, Stmt* Loc,
const LiveVariables& Liveness,
- DeadSymbolsTy& DeadSymbols);
+ DeadSymbolsTy& DeadSyms);
const ValueState* RemoveSubExprBindings(const ValueState* St) {
ValueState NewSt = *St;
Modified: cfe/trunk/lib/Analysis/BasicStore.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/BasicStore.cpp?rev=53726&r1=53725&r2=53726&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/BasicStore.cpp (original)
+++ cfe/trunk/lib/Analysis/BasicStore.cpp Thu Jul 17 13:38:48 2008
@@ -11,6 +11,7 @@
//
//===----------------------------------------------------------------------===//
+#include "clang/Analysis/Analyses/LiveVariables.h"
#include "clang/Analysis/PathSensitive/BasicStore.h"
#include "llvm/ADT/ImmutableMap.h"
#include "llvm/Support/Compiler.h"
@@ -34,6 +35,15 @@
virtual Store getInitialStore() {
return VBFactory.GetEmptyMap().getRoot();
}
+
+ virtual Store RemoveDeadBindings(Store store, Stmt* Loc,
+ const LiveVariables& Live,
+ DeclRootsTy& DRoots, LiveSymbolsTy& LSymbols,
+ DeadSymbolsTy& DSymbols);
+
+ static inline VarBindingsTy GetVarBindings(Store store) {
+ return VarBindingsTy(static_cast<const VarBindingsTy::TreeTy*>(store));
+ }
};
} // end anonymous namespace
@@ -108,34 +118,85 @@
return UnknownVal();
}
-Store BasicStoreManager::SetRVal(Store St, LVal LV, RVal V) {
-
- VarBindingsTy B(static_cast<const VarBindingsTy::TreeTy*>(St));
-
- switch (LV.getSubKind()) {
-
- case lval::DeclValKind:
+Store BasicStoreManager::SetRVal(Store store, LVal LV, RVal V) {
+ switch (LV.getSubKind()) {
+ case lval::DeclValKind: {
+ VarBindingsTy B = GetVarBindings(store);
return V.isUnknown()
? VBFactory.Remove(B,cast<lval::DeclVal>(LV).getDecl()).getRoot()
: VBFactory.Add(B, cast<lval::DeclVal>(LV).getDecl(), V).getRoot();
-
+ }
default:
assert ("SetRVal for given LVal type not yet implemented.");
- return St;
+ return store;
}
}
-Store BasicStoreManager::Remove(Store St, LVal LV) {
-
- VarBindingsTy B(static_cast<const VarBindingsTy::TreeTy*>(St));
-
+Store BasicStoreManager::Remove(Store store, LVal LV) {
switch (LV.getSubKind()) {
-
- case lval::DeclValKind:
+ case lval::DeclValKind: {
+ VarBindingsTy B = GetVarBindings(store);
return VBFactory.Remove(B,cast<lval::DeclVal>(LV).getDecl()).getRoot();
-
+ }
default:
assert ("Remove for given LVal type not yet implemented.");
- return St;
+ return store;
}
}
+
+Store BasicStoreManager::RemoveDeadBindings(Store store,
+ Stmt* Loc,
+ const LiveVariables& Liveness,
+ DeclRootsTy& DRoots,
+ LiveSymbolsTy& LSymbols,
+ DeadSymbolsTy& DSymbols) {
+
+ VarBindingsTy B = GetVarBindings(store);
+ typedef RVal::symbol_iterator symbol_iterator;
+
+ // Iterate over the variable bindings.
+ for (VarBindingsTy::iterator I=B.begin(), E=B.end(); I!=E ; ++I)
+ if (Liveness.isLive(Loc, I.getKey())) {
+ DRoots.push_back(I.getKey());
+ RVal X = I.getData();
+
+ for (symbol_iterator SI=X.symbol_begin(), SE=X.symbol_end(); SI!=SE; ++SI)
+ LSymbols.insert(*SI);
+ }
+
+ // Scan for live variables and live symbols.
+ llvm::SmallPtrSet<ValueDecl*, 10> Marked;
+
+ while (!DRoots.empty()) {
+ ValueDecl* V = DRoots.back();
+ DRoots.pop_back();
+
+ if (Marked.count(V))
+ continue;
+
+ Marked.insert(V);
+
+ RVal X = GetRVal(store, lval::DeclVal(cast<VarDecl>(V)), QualType());
+
+ for (symbol_iterator SI=X.symbol_begin(), SE=X.symbol_end(); SI!=SE; ++SI)
+ LSymbols.insert(*SI);
+
+ if (!isa<lval::DeclVal>(X))
+ continue;
+
+ const lval::DeclVal& LVD = cast<lval::DeclVal>(X);
+ DRoots.push_back(LVD.getDecl());
+ }
+
+ // Remove dead variable bindings.
+ for (VarBindingsTy::iterator I=B.begin(), E=B.end(); I!=E ; ++I)
+ if (!Marked.count(I.getKey())) {
+ store = Remove(store, lval::DeclVal(I.getKey()));
+ RVal X = I.getData();
+
+ for (symbol_iterator SI=X.symbol_begin(), SE=X.symbol_end(); SI!=SE; ++SI)
+ if (!LSymbols.count(*SI)) DSymbols.insert(*SI);
+ }
+
+ return store;
+}
Modified: cfe/trunk/lib/Analysis/ValueState.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/ValueState.cpp?rev=53726&r1=53725&r2=53726&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/ValueState.cpp (original)
+++ cfe/trunk/lib/Analysis/ValueState.cpp Thu Jul 17 13:38:48 2008
@@ -33,20 +33,21 @@
const ValueState*
ValueStateManager::RemoveDeadBindings(const ValueState* St, Stmt* Loc,
const LiveVariables& Liveness,
- DeadSymbolsTy& DeadSymbols) {
+ DeadSymbolsTy& DSymbols) {
// This code essentially performs a "mark-and-sweep" of the VariableBindings.
// The roots are any Block-level exprs and Decls that our liveness algorithm
// tells us are live. We then see what Decls they may reference, and keep
// those around. This code more than likely can be made faster, and the
// frequency of which this method is called should be experimented with
- // for optimum performance.
-
- llvm::SmallVector<ValueDecl*, 10> WList;
- llvm::SmallPtrSet<ValueDecl*, 10> Marked;
- llvm::SmallSet<SymbolID, 20> MarkedSymbols;
+ // for optimum performance.
+ DRoots.clear();
+ StoreManager::LiveSymbolsTy LSymbols;
ValueState NewSt = *St;
+
+ // FIXME: Put this in environment.
+ // Clean up the environment.
// Drop bindings for subexpressions.
NewSt.Env = EnvMgr.RemoveSubExprBindings(NewSt.Env);
@@ -62,12 +63,12 @@
if (isa<lval::DeclVal>(X)) {
lval::DeclVal LV = cast<lval::DeclVal>(X);
- WList.push_back(LV.getDecl());
+ DRoots.push_back(LV.getDecl());
}
for (RVal::symbol_iterator SI = X.symbol_begin(), SE = X.symbol_end();
SI != SE; ++SI) {
- MarkedSymbols.insert(*SI);
+ LSymbols.insert(*SI);
}
}
else {
@@ -80,69 +81,18 @@
}
}
- // Iterate over the variable bindings.
-
- for (ValueState::vb_iterator I = St->vb_begin(), E = St->vb_end(); I!=E ; ++I)
- if (Liveness.isLive(Loc, I.getKey())) {
- WList.push_back(I.getKey());
-
- RVal X = I.getData();
-
- for (RVal::symbol_iterator SI = X.symbol_begin(), SE = X.symbol_end();
- SI != SE; ++SI) {
- MarkedSymbols.insert(*SI);
- }
- }
-
- // Perform the mark-and-sweep.
-
- while (!WList.empty()) {
-
- ValueDecl* V = WList.back();
- WList.pop_back();
-
- if (Marked.count(V))
- continue;
-
- Marked.insert(V);
-
- RVal X = GetRVal(St, lval::DeclVal(cast<VarDecl>(V)));
-
- for (RVal::symbol_iterator SI = X.symbol_begin(), SE = X.symbol_end();
- SI != SE; ++SI) {
- MarkedSymbols.insert(*SI);
- }
-
- if (!isa<lval::DeclVal>(X))
- continue;
-
- const lval::DeclVal& LVD = cast<lval::DeclVal>(X);
- WList.push_back(LVD.getDecl());
- }
-
- // Remove dead variable bindings.
+ // Clean up the store.
+ DSymbols.clear();
+ NewSt.St = StMgr->RemoveDeadBindings(St->getStore(), Loc, Liveness, DRoots,
+ LSymbols, DSymbols);
- DeadSymbols.clear();
-
- for (ValueState::vb_iterator I = St->vb_begin(), E = St->vb_end(); I!=E ; ++I)
- if (!Marked.count(I.getKey())) {
- NewSt.St = StMgr->Remove(NewSt.St, lval::DeclVal(I.getKey()));
-
- RVal X = I.getData();
-
- for (RVal::symbol_iterator SI = X.symbol_begin(), SE = X.symbol_end();
- SI != SE; ++SI)
- if (!MarkedSymbols.count(*SI)) DeadSymbols.insert(*SI);
- }
-
- // Remove dead symbols.
-
+ // Remove the dead symbols from the symbol tracker.
for (ValueState::ce_iterator I = St->ce_begin(), E=St->ce_end(); I!=E; ++I) {
SymbolID sym = I.getKey();
- if (!MarkedSymbols.count(sym)) {
- DeadSymbols.insert(sym);
+ if (!LSymbols.count(sym)) {
+ DSymbols.insert(sym);
NewSt.ConstEq = CEFactory.Remove(NewSt.ConstEq, sym);
}
}
@@ -151,8 +101,8 @@
SymbolID sym = I.getKey();
- if (!MarkedSymbols.count(sym)) {
- DeadSymbols.insert(sym);
+ if (!LSymbols.count(sym)) {
+ DSymbols.insert(sym);
NewSt.ConstNotEq = CNEFactory.Remove(NewSt.ConstNotEq, sym);
}
}
More information about the cfe-commits
mailing list