[cfe-commits] r46744 - in /cfe/trunk/Analysis: GRConstants.cpp ValueState.cpp ValueState.h

Ted Kremenek kremenek at apple.com
Mon Feb 4 23:17:49 PST 2008


Author: kremenek
Date: Tue Feb  5 01:17:49 2008
New Revision: 46744

URL: http://llvm.org/viewvc/llvm-project?rev=46744&view=rev
Log:
Overhauling of "ValueState" so that it represents its own functional data
structure that can contain several maps, not just one.

Modified:
    cfe/trunk/Analysis/GRConstants.cpp
    cfe/trunk/Analysis/ValueState.cpp
    cfe/trunk/Analysis/ValueState.h

Modified: cfe/trunk/Analysis/GRConstants.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Analysis/GRConstants.cpp?rev=46744&r1=46743&r2=46744&view=diff

==============================================================================
--- cfe/trunk/Analysis/GRConstants.cpp (original)
+++ cfe/trunk/Analysis/GRConstants.cpp Tue Feb  5 01:17:49 2008
@@ -874,17 +874,17 @@
 struct VISIBILITY_HIDDEN DOTGraphTraits<GRConstants::NodeTy*> :
   public DefaultDOTGraphTraits {
 
-  static void PrintKindLabel(std::ostream& Out, ValueKey::Kind kind) {
+  static void PrintKindLabel(std::ostream& Out, VarBindKey::Kind kind) {
     switch (kind) {
-      case ValueKey::IsSubExpr:  Out << "Sub-Expressions:\\l"; break;
-      case ValueKey::IsDecl:    Out << "Variables:\\l"; break;
-      case ValueKey::IsBlkExpr: Out << "Block-level Expressions:\\l"; break;
-      default: assert (false && "Unknown ValueKey type.");
+      case VarBindKey::IsSubExpr:  Out << "Sub-Expressions:\\l"; break;
+      case VarBindKey::IsDecl:    Out << "Variables:\\l"; break;
+      case VarBindKey::IsBlkExpr: Out << "Block-level Expressions:\\l"; break;
+      default: assert (false && "Unknown VarBindKey type.");
     }
   }
     
   static void PrintKind(std::ostream& Out, GRConstants::StateTy M,
-                        ValueKey::Kind kind, bool isFirstGroup = false) {
+                        VarBindKey::Kind kind, bool isFirstGroup = false) {
     bool isFirst = true;
     
     for (GRConstants::StateTy::iterator I=M.begin(), E=M.end();I!=E;++I) {        
@@ -968,11 +968,11 @@
       }
     }
     
-    Out << "\\|StateID: " << (void*) N->getState().getRoot() << "\\|";
+    Out << "\\|StateID: " << (void*) N->getState().getImpl() << "\\|";
     
-    PrintKind(Out, N->getState(), ValueKey::IsDecl, true);
-    PrintKind(Out, N->getState(), ValueKey::IsBlkExpr);
-    PrintKind(Out, N->getState(), ValueKey::IsSubExpr);
+    PrintKind(Out, N->getState(), VarBindKey::IsDecl, true);
+    PrintKind(Out, N->getState(), VarBindKey::IsBlkExpr);
+    PrintKind(Out, N->getState(), VarBindKey::IsSubExpr);
       
     Out << "\\l";
     return Out.str();

Modified: cfe/trunk/Analysis/ValueState.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Analysis/ValueState.cpp?rev=46744&r1=46743&r2=46744&view=diff

==============================================================================
--- cfe/trunk/Analysis/ValueState.cpp (original)
+++ cfe/trunk/Analysis/ValueState.cpp Tue Feb  5 01:17:49 2008
@@ -1,3 +1,16 @@
+//= ValueState.cpp - Path-Sens. "State" for tracking valuues -----*- C++ -*--=//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This files defines SymbolID, VarBindKey, and ValueState.
+//
+//===----------------------------------------------------------------------===//
+
 #include "ValueState.h"
 
 using namespace clang;
@@ -5,7 +18,9 @@
 RValue ValueStateManager::GetValue(const StateTy& St, const LValue& LV) {
   switch (LV.getSubKind()) {
     case LValueDeclKind: {
-      StateTy::TreeTy* T = St.SlimFind(cast<LValueDecl>(LV).getDecl()); 
+      StateTy::VariableBindingsTy::TreeTy* T =
+        St.getImpl()->VariableBindings.SlimFind(cast<LValueDecl>(LV).getDecl());
+      
       return T ? T->getValue().second : InvalidValue();
     }
     default:
@@ -71,7 +86,8 @@
     break;
   }
   
-  StateTy::TreeTy* T = St.SlimFind(S);
+  StateTy::VariableBindingsTy::TreeTy* T =
+    St.getImpl()->VariableBindings.SlimFind(S);
   
   if (T) {
     if (hasVal) *hasVal = true;
@@ -100,7 +116,7 @@
                             const RValue& V) {
   
   assert (S);
-  return V.isValid() ? Factory.Add(St, ValueKey(S, isBlkExpr), V) : St;
+  return V.isValid() ? Add(St, VarBindKey(S, isBlkExpr), V) : St;
 }
 
 ValueStateManager::StateTy
@@ -108,8 +124,8 @@
   
   switch (LV.getSubKind()) {
     case LValueDeclKind:        
-      return V.isValid() ? Factory.Add(St, cast<LValueDecl>(LV).getDecl(), V)
-      : Factory.Remove(St, cast<LValueDecl>(LV).getDecl());
+      return V.isValid() ? Add(St, cast<LValueDecl>(LV).getDecl(), V)
+                         : Remove(St, cast<LValueDecl>(LV).getDecl());
       
     default:
       assert ("SetValue for given LValue type not yet implemented.");
@@ -117,7 +133,52 @@
   }
 }
 
-ValueStateManager::StateTy ValueStateManager::Remove(StateTy St, ValueKey K) {
-  return Factory.Remove(St, K);
+ValueStateManager::StateTy
+ValueStateManager::Remove(StateTy St, VarBindKey K) {
+
+  // Create a new state with the old binding removed.
+  ValueStateImpl NewStateImpl = *St.getImpl();
+  NewStateImpl.VariableBindings =
+    VBFactory.Remove(NewStateImpl.VariableBindings, K);
+
+  // Get the persistent copy.
+  return getPersistentState(NewStateImpl);
 }
+
+ValueStateManager::StateTy
+ValueStateManager::Add(StateTy St, VarBindKey K, const RValue& V) {
+  
+  // Create a new state with the old binding removed.
+  ValueStateImpl NewStateImpl = *St.getImpl();
+  NewStateImpl.VariableBindings =
+    VBFactory.Add(NewStateImpl.VariableBindings, K, V);
   
+  // Get the persistent copy.
+  return getPersistentState(NewStateImpl);
+}
+
+
+ValueStateManager::StateTy
+ValueStateManager::getInitialState() {
+
+  // Create a state with empty variable bindings.
+  ValueStateImpl StateImpl(VBFactory.GetEmptyMap());
+  
+  return getPersistentState(StateImpl);
+}
+
+ValueStateManager::StateTy
+ValueStateManager::getPersistentState(const ValueStateImpl &State) {
+  
+  llvm::FoldingSetNodeID ID;
+  State.Profile(ID);  
+  void* InsertPos;  
+  
+  if (ValueStateImpl* I = StateSet.FindNodeOrInsertPos(ID, InsertPos))
+    return I;
+  
+  ValueStateImpl* I = (ValueStateImpl*) Alloc.Allocate<ValueState>();
+  new (I) ValueStateImpl(State);  
+  StateSet.InsertNode(I, InsertPos);
+  return I;
+}

Modified: cfe/trunk/Analysis/ValueState.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Analysis/ValueState.h?rev=46744&r1=46743&r2=46744&view=diff

==============================================================================
--- cfe/trunk/Analysis/ValueState.h (original)
+++ cfe/trunk/Analysis/ValueState.h Tue Feb  5 01:17:49 2008
@@ -7,7 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 //
-//  This files defines SymbolID, ValueKey, and ValueState.
+//  This files defines SymbolID, VarBindKey, and ValueState.
 //
 //===----------------------------------------------------------------------===//
 
@@ -39,11 +39,11 @@
 
 namespace clang {  
 
-/// ValueKey - A variant smart pointer that wraps either a ValueDecl* or a
+/// VarBindKey - A variant smart pointer that wraps either a ValueDecl* or a
 ///  Stmt*.  Use cast<> or dyn_cast<> to get actual pointer type
-class ValueKey {
+class VarBindKey {
   uintptr_t Raw;  
-  void operator=(const ValueKey& RHS); // Do not implement.
+  void operator=(const VarBindKey& RHS); // Do not implement.
   
 public:
   enum  Kind { IsSubExpr=0x0, IsBlkExpr=0x1, IsDecl=0x2, // L-Value Bindings.
@@ -64,17 +64,17 @@
     return Raw >> 2;
   }
   
-  ValueKey(const ValueDecl* VD)
+  VarBindKey(const ValueDecl* VD)
   : Raw(reinterpret_cast<uintptr_t>(VD) | IsDecl) {
     assert(VD && "ValueDecl cannot be NULL.");
   }
   
-  ValueKey(Stmt* S, bool isBlkExpr = false) 
+  VarBindKey(Stmt* S, bool isBlkExpr = false) 
   : Raw(reinterpret_cast<uintptr_t>(S) | (isBlkExpr ? IsBlkExpr : IsSubExpr)){
     assert(S && "Tracked statement cannot be NULL.");
   }
   
-  ValueKey(SymbolID V)
+  VarBindKey(SymbolID V)
   : Raw((V << 2) | IsSymbol) {}  
   
   bool isSymbol()  const { return getKind() == IsSymbol; }
@@ -92,16 +92,16 @@
       ID.AddPointer(getPtr());
   }
   
-  inline bool operator==(const ValueKey& X) const {
+  inline bool operator==(const VarBindKey& X) const {
     return isSymbol() ? getSymbolID() == X.getSymbolID()
     : getPtr() == X.getPtr();
   }
   
-  inline bool operator!=(const ValueKey& X) const {
+  inline bool operator!=(const VarBindKey& X) const {
     return !operator==(X);
   }
   
-  inline bool operator<(const ValueKey& X) const { 
+  inline bool operator<(const VarBindKey& X) const { 
     if (isSymbol())
       return X.isSymbol() ? getSymbolID() < X.getSymbolID() : false;
     
@@ -113,40 +113,97 @@
 // ValueState - An ImmutableMap type Stmt*/Decl*/Symbols to RValues.
 //===----------------------------------------------------------------------===//
 
-typedef llvm::ImmutableMap<ValueKey,RValue> ValueState;
+namespace vstate {
+  typedef llvm::ImmutableMap<VarBindKey,RValue> VariableBindingsTy;  
+}
+  
+struct ValueStateImpl : public llvm::FoldingSetNode {
+  vstate::VariableBindingsTy VariableBindings;
+  
+  ValueStateImpl(vstate::VariableBindingsTy VB)
+    : VariableBindings(VB) {}
+  
+  ValueStateImpl(const ValueStateImpl& RHS)
+    : llvm::FoldingSetNode(), VariableBindings(RHS.VariableBindings) {} 
+    
+  
+  static void Profile(llvm::FoldingSetNodeID& ID, const ValueStateImpl& V) {
+    V.VariableBindings.Profile(ID);
+  }
+  
+  void Profile(llvm::FoldingSetNodeID& ID) const {
+    Profile(ID, *this);
+  }
+  
+};
+  
+class ValueState : public llvm::FoldingSetNode {
+  ValueStateImpl* Data;
+public:
+  typedef vstate::VariableBindingsTy VariableBindingsTy;
+  typedef VariableBindingsTy::iterator iterator;
+  
 
-template<>
-struct GRTrait<ValueState> {
-  static inline void* toPtr(ValueState M) {
-    return reinterpret_cast<void*>(M.getRoot());
+  
+  iterator begin() { return Data->VariableBindings.begin(); }
+  iterator end() { return Data->VariableBindings.end(); }
+  
+  bool operator==(const ValueState& RHS) const {
+    return Data == RHS.Data;
+  }
+  
+  static void Profile(llvm::FoldingSetNodeID& ID, const ValueState& V) {
+    ID.AddPointer(V.getImpl());
+  }
+  
+  void Profile(llvm::FoldingSetNodeID& ID) const {
+    Profile(ID, *this);
+  }
+    
+  ValueState(ValueStateImpl* D) : Data(D) {}
+  ValueState() : Data(0) {}
+  
+  void operator=(ValueStateImpl* D) {
+    Data = D;
+  }
+  
+  ValueStateImpl* getImpl() const { return Data; }
+};  
+  
+template<> struct GRTrait<ValueState> {
+  static inline void* toPtr(ValueState St) {
+    return reinterpret_cast<void*>(St.getImpl());
   }  
-  static inline ValueState toState(void* P) {
-    return ValueState(static_cast<ValueState::TreeTy*>(P));
+  static inline ValueState toState(void* P) {    
+    return ValueState(static_cast<ValueStateImpl*>(P));
   }
 };
-  
+    
   
 class ValueStateManager {
 public:
   typedef ValueState StateTy;
 
 private:
-  typedef ValueState::Factory FactoryTy;
-  FactoryTy Factory;
+  ValueState::VariableBindingsTy::Factory VBFactory;
+  llvm::FoldingSet<ValueStateImpl> StateSet;
 
   /// ValueMgr - Object that manages the data for all created RValues.
   ValueManager ValMgr;
-  
+
   /// SymMgr - Object that manages the symbol information.
   SymbolManager SymMgr;
+
+  /// Alloc - A BumpPtrAllocator to allocate states.
+  llvm::BumpPtrAllocator& Alloc;
+
+  StateTy getPersistentState(const ValueState& St);
   
 public:  
-  ValueStateManager(ASTContext& Ctx, llvm::BumpPtrAllocator& Alloc) 
-    : ValMgr(Ctx, Alloc) {}
+  ValueStateManager(ASTContext& Ctx, llvm::BumpPtrAllocator& alloc) 
+    : ValMgr(Ctx, alloc), Alloc(alloc) {}
   
-  StateTy getInitialState() {
-    return Factory.GetEmptyMap();
-  }
+  StateTy getInitialState();
         
   ValueManager& getValueManager() { return ValMgr; }
   SymbolManager& getSymbolManager() { return SymMgr; }
@@ -158,40 +215,41 @@
   RValue GetValue(const StateTy& St, const LValue& LV);
     
   LValue GetLValue(const StateTy& St, Stmt* S);
-  
-  StateTy Remove(StateTy St, ValueKey K);
-  
+
+  StateTy Add(StateTy St, VarBindKey K, const RValue& V);
+  StateTy Remove(StateTy St, VarBindKey K);
+  StateTy getPersistentState(const ValueStateImpl& Impl);
 };
   
 } // end clang namespace
 
 //==------------------------------------------------------------------------==//
-// Casting machinery to get cast<> and dyn_cast<> working with ValueKey.
+// Casting machinery to get cast<> and dyn_cast<> working with VarBindKey.
 //==------------------------------------------------------------------------==//
 
 namespace llvm {
   
   template<> inline bool
-  isa<clang::ValueDecl,clang::ValueKey>(const clang::ValueKey& V) {
-    return V.getKind() == clang::ValueKey::IsDecl;
+  isa<clang::ValueDecl,clang::VarBindKey>(const clang::VarBindKey& V) {
+    return V.getKind() == clang::VarBindKey::IsDecl;
   }
   
   template<> inline bool
-  isa<clang::Stmt,clang::ValueKey>(const clang::ValueKey& V) {
-    return ((unsigned) V.getKind()) < clang::ValueKey::IsDecl;
+  isa<clang::Stmt,clang::VarBindKey>(const clang::VarBindKey& V) {
+    return ((unsigned) V.getKind()) < clang::VarBindKey::IsDecl;
   }
   
-  template<> struct cast_retty_impl<clang::ValueDecl,clang::ValueKey> {
+  template<> struct cast_retty_impl<clang::ValueDecl,clang::VarBindKey> {
     typedef const clang::ValueDecl* ret_type;
   };
   
-  template<> struct cast_retty_impl<clang::Stmt,clang::ValueKey> {
+  template<> struct cast_retty_impl<clang::Stmt,clang::VarBindKey> {
     typedef const clang::Stmt* ret_type;
   };
   
-  template<> struct simplify_type<clang::ValueKey> {
+  template<> struct simplify_type<clang::VarBindKey> {
     typedef void* SimpleType;
-    static inline SimpleType getSimplifiedValue(const clang::ValueKey &V) {
+    static inline SimpleType getSimplifiedValue(const clang::VarBindKey &V) {
       return V.getPtr();
     }
   };





More information about the cfe-commits mailing list