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
diff --git a/Analysis/ValueState.cpp b/Analysis/ValueState.cpp
index d191623..55451a9 100644
--- a/Analysis/ValueState.cpp
+++ b/Analysis/ValueState.cpp
@@ -31,6 +31,77 @@
   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,