aboutsummaryrefslogtreecommitdiff
path: root/Analysis/ValueState.cpp
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2008-02-08 19:17:19 +0000
committerTed Kremenek <kremenek@apple.com>2008-02-08 19:17:19 +0000
commitb87d9096d0bbce83fd5f79f2346dc49d1046e092 (patch)
treea634115cc92bb0fa631dbd07b7840ac11e481a97 /Analysis/ValueState.cpp
parent071679dcace879f3ec861b7b2fb1ce44f4717538 (diff)
Moved implementation of "RemoveDeadBindings" from the main
GRConstants logic to ValueStateManager. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@46888 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'Analysis/ValueState.cpp')
-rw-r--r--Analysis/ValueState.cpp71
1 files changed, 71 insertions, 0 deletions
diff --git a/Analysis/ValueState.cpp b/Analysis/ValueState.cpp
index d191623dd8..55451a959e 100644
--- a/Analysis/ValueState.cpp
+++ b/Analysis/ValueState.cpp
@@ -31,6 +31,77 @@ const llvm::APSInt* ValueState::getSymVal(SymbolID sym) const {
return T ? T->getValue().second : NULL;
}
+ValueState
+ValueStateManager::RemoveDeadBindings(ValueState St, Stmt* Loc,
+ const LiveVariables& Liveness) {
+
+ // 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;
+
+ for (StateTy::vb_iterator I = St.begin(), E = St.end(); I!=E ; ++I) {
+
+ // Remove old bindings for subexpressions.
+ if (I.getKey().isSubExpr()) {
+ St = Remove(St, I.getKey());
+ continue;
+ }
+
+ if (I.getKey().isBlkExpr()) {
+ if (Liveness.isLive(Loc, cast<Stmt>(I.getKey()))) {
+ if (isa<lval::DeclVal>(I.getData())) {
+ lval::DeclVal LV = cast<lval::DeclVal>(I.getData());
+ WList.push_back(LV.getDecl());
+ }
+ }
+ else
+ St = Remove(St, I.getKey());
+
+ continue;
+ }
+
+ assert (I.getKey().isDecl());
+
+ if (VarDecl* V = dyn_cast<VarDecl>(cast<ValueDecl>(I.getKey())))
+ if (Liveness.isLive(Loc, V))
+ WList.push_back(V);
+ }
+
+ llvm::SmallPtrSet<ValueDecl*, 10> Marked;
+
+ while (!WList.empty()) {
+ ValueDecl* V = WList.back();
+ WList.pop_back();
+
+ if (Marked.count(V))
+ continue;
+
+ Marked.insert(V);
+
+ if (V->getType()->isPointerType()) {
+ const LValue& LV = cast<LValue>(GetValue(St, lval::DeclVal(V)));
+
+ if (!isa<lval::DeclVal>(LV))
+ continue;
+
+ const lval::DeclVal& LVD = cast<lval::DeclVal>(LV);
+ WList.push_back(LVD.getDecl());
+ }
+ }
+
+ for (StateTy::vb_iterator I = St.begin(), E = St.end(); I!=E ; ++I)
+ if (I.getKey().isDecl())
+ if (VarDecl* V = dyn_cast<VarDecl>(cast<ValueDecl>(I.getKey())))
+ if (!Marked.count(V))
+ St = Remove(St, V);
+
+ return St;
+}
RValue ValueStateManager::GetValue(const StateTy& St, const LValue& LV,