[cfe-commits] r124214 - in /cfe/trunk: include/clang/StaticAnalyzer/PathSensitive/ExplodedGraph.h include/clang/StaticAnalyzer/PathSensitive/GRState.h lib/StaticAnalyzer/Checkers/ExprEngine.cpp lib/StaticAnalyzer/GRState.cpp

Ted Kremenek kremenek at apple.com
Tue Jan 25 11:13:54 PST 2011


Author: kremenek
Date: Tue Jan 25 13:13:54 2011
New Revision: 124214

URL: http://llvm.org/viewvc/llvm-project?rev=124214&view=rev
Log:
Recycle memory for GRStates that are never referenced
by ExplodedNodes.  This leads to about a 4-8%
reduction in memory footprint when analyzing
functions in sqlite3.

Modified:
    cfe/trunk/include/clang/StaticAnalyzer/PathSensitive/ExplodedGraph.h
    cfe/trunk/include/clang/StaticAnalyzer/PathSensitive/GRState.h
    cfe/trunk/lib/StaticAnalyzer/Checkers/ExprEngine.cpp
    cfe/trunk/lib/StaticAnalyzer/GRState.cpp

Modified: cfe/trunk/include/clang/StaticAnalyzer/PathSensitive/ExplodedGraph.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/PathSensitive/ExplodedGraph.h?rev=124214&r1=124213&r2=124214&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/PathSensitive/ExplodedGraph.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/PathSensitive/ExplodedGraph.h Tue Jan 25 13:13:54 2011
@@ -31,6 +31,7 @@
 #include "llvm/ADT/DepthFirstIterator.h"
 #include "llvm/Support/Casting.h"
 #include "clang/Analysis/Support/BumpVector.h"
+#include "clang/StaticAnalyzer/PathSensitive/GRState.h"
 
 namespace clang {
 
@@ -38,7 +39,6 @@
 
 namespace ento {
 
-class GRState;
 class ExplodedGraph;
 
 //===----------------------------------------------------------------------===//
@@ -115,7 +115,9 @@
 public:
 
   explicit ExplodedNode(const ProgramPoint& loc, const GRState* state)
-    : Location(loc), State(state) {}
+    : Location(loc), State(state) {
+    const_cast<GRState*>(State)->setReferencedByExplodedNode();
+  }
 
   /// getLocation - Returns the edge associated with the given node.
   ProgramPoint getLocation() const { return Location; }

Modified: cfe/trunk/include/clang/StaticAnalyzer/PathSensitive/GRState.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/PathSensitive/GRState.h?rev=124214&r1=124213&r2=124214&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/PathSensitive/GRState.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/PathSensitive/GRState.h Tue Jan 25 13:13:54 2011
@@ -18,6 +18,7 @@
 #include "clang/StaticAnalyzer/PathSensitive/Environment.h"
 #include "clang/StaticAnalyzer/PathSensitive/Store.h"
 #include "clang/StaticAnalyzer/PathSensitive/SValBuilder.h"
+#include "llvm/ADT/PointerIntPair.h"
 #include "llvm/ADT/FoldingSet.h"
 #include "llvm/ADT/ImmutableMap.h"
 #include "llvm/Support/Casting.h"
@@ -78,7 +79,7 @@
 
   friend class GRStateManager;
 
-  GRStateManager *StateMgr;
+  llvm::PointerIntPair<GRStateManager *, 1, bool> stateMgr;
   Environment Env;           // Maps a Stmt to its current SVal.
   Store St;                  // Maps a location to its current value.
   GenericDataMap   GDM;      // Custom data stored by a client of this class.
@@ -92,7 +93,7 @@
   /// This ctor is used when creating the first GRState object.
   GRState(GRStateManager *mgr, const Environment& env,
           Store st, GenericDataMap gdm)
-    : StateMgr(mgr),
+    : stateMgr(mgr, false),
       Env(env),
       St(st),
       GDM(gdm) {}
@@ -101,14 +102,23 @@
   ///  in FoldingSetNode will also get copied.
   GRState(const GRState& RHS)
     : llvm::FoldingSetNode(),
-      StateMgr(RHS.StateMgr),
+      stateMgr(RHS.stateMgr.getPointer(), false),
       Env(RHS.Env),
       St(RHS.St),
       GDM(RHS.GDM) {}
 
-  /// getStateManager - Return the GRStateManager associated with this state.
+  /// Return the GRStateManager associated with this state.
   GRStateManager &getStateManager() const {
-    return *StateMgr;
+    return *stateMgr.getPointer();
+  }
+
+  /// Return true if this state is referenced by a persistent ExplodedNode.
+  bool referencedByExplodedNode() const {
+    return stateMgr.getInt();
+  }
+  
+  void setReferencedByExplodedNode() {
+    stateMgr.setInt(true);
   }
 
   /// getEnvironment - Return the environment associated with this state.
@@ -428,9 +438,16 @@
   /// Object that manages the data for all created SVals.
   llvm::OwningPtr<SValBuilder> svalBuilder;
 
-  /// Alloc - A BumpPtrAllocator to allocate states.
+  /// A BumpPtrAllocator to allocate states.
   llvm::BumpPtrAllocator &Alloc;
 
+  /// A vector of recently allocated GRStates that can potentially be
+  /// reused.
+  std::vector<GRState *> recentlyAllocatedStates;
+  
+  /// A vector of GRStates that we can reuse.
+  std::vector<GRState *> freeStates;
+
 public:
   GRStateManager(ASTContext& Ctx,
                  StoreManagerCreator CreateStoreManager,
@@ -509,6 +526,10 @@
   }
 
   const GRState* getPersistentState(GRState& Impl);
+  
+  /// Periodically called by ExprEngine to recycle GRStates that were
+  /// created but never used for creating an ExplodedNode.
+  void recycleUnusedStates();
 
   //==---------------------------------------------------------------------==//
   // Generic Data Map methods.

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/ExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/ExprEngine.cpp?rev=124214&r1=124213&r2=124214&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/ExprEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/ExprEngine.cpp Tue Jan 25 13:13:54 2011
@@ -574,6 +574,9 @@
 }
 
 void ExprEngine::ProcessStmt(const CFGStmt S, StmtNodeBuilder& builder) {
+  // Recycle any unused states in the GRStateManager.
+  StateMgr.recycleUnusedStates();
+  
   currentStmt = S.getStmt();
   PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
                                 currentStmt->getLocStart(),

Modified: cfe/trunk/lib/StaticAnalyzer/GRState.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/GRState.cpp?rev=124214&r1=124213&r2=124214&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/GRState.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/GRState.cpp Tue Jan 25 13:13:54 2011
@@ -285,6 +285,18 @@
   return getPersistentState(State);
 }
 
+void GRStateManager::recycleUnusedStates() {
+  for (std::vector<GRState*>::iterator i = recentlyAllocatedStates.begin(),
+       e = recentlyAllocatedStates.end(); i != e; ++i) {
+    GRState *state = *i;
+    if (state->referencedByExplodedNode())
+      continue;
+    StateSet.RemoveNode(state);
+    freeStates.push_back(state);
+  }
+  recentlyAllocatedStates.clear();
+}
+
 const GRState* GRStateManager::getPersistentState(GRState& State) {
 
   llvm::FoldingSetNodeID ID;
@@ -294,10 +306,18 @@
   if (GRState* I = StateSet.FindNodeOrInsertPos(ID, InsertPos))
     return I;
 
-  GRState* I = (GRState*) Alloc.Allocate<GRState>();
-  new (I) GRState(State);
-  StateSet.InsertNode(I, InsertPos);
-  return I;
+  GRState *newState = 0;
+  if (!freeStates.empty()) {
+    newState = freeStates.back();
+    freeStates.pop_back();    
+  }
+  else {
+    newState = (GRState*) Alloc.Allocate<GRState>();
+  }
+  new (newState) GRState(State);
+  StateSet.InsertNode(newState, InsertPos);
+  recentlyAllocatedStates.push_back(newState);
+  return newState;
 }
 
 const GRState* GRState::makeWithStore(Store store) const {





More information about the cfe-commits mailing list