diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Analysis/BasicStore.cpp | 95 | ||||
-rw-r--r-- | lib/Analysis/ValueState.cpp | 86 |
2 files changed, 96 insertions, 85 deletions
diff --git a/lib/Analysis/BasicStore.cpp b/lib/Analysis/BasicStore.cpp index 38c1db70f1..64a230975f 100644 --- a/lib/Analysis/BasicStore.cpp +++ b/lib/Analysis/BasicStore.cpp @@ -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 @@ public: 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 @@ RVal BasicStoreManager::GetRVal(Store St, LVal LV, QualType T) { 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; +} diff --git a/lib/Analysis/ValueState.cpp b/lib/Analysis/ValueState.cpp index 72ff498adb..ca78faf349 100644 --- a/lib/Analysis/ValueState.cpp +++ b/lib/Analysis/ValueState.cpp @@ -33,20 +33,21 @@ const llvm::APSInt* ValueState::getSymVal(SymbolID sym) const { 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 @@ ValueStateManager::RemoveDeadBindings(const ValueState* St, Stmt* Loc, 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 @@ ValueStateManager::RemoveDeadBindings(const ValueState* St, Stmt* Loc, } } - // 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 @@ ValueStateManager::RemoveDeadBindings(const ValueState* St, Stmt* Loc, 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); } } |