[cfe-commits] r61106 - in /cfe/trunk: include/clang/Analysis/PathSensitive/GRCoreEngine.h include/clang/Analysis/PathSensitive/GRWorkList.h lib/Analysis/GRCoreEngine.cpp

Ted Kremenek kremenek at apple.com
Tue Dec 16 14:13:34 PST 2008


Author: kremenek
Date: Tue Dec 16 16:13:33 2008
New Revision: 61106

URL: http://llvm.org/viewvc/llvm-project?rev=61106&view=rev
Log:
Add new GRWorkList class that uses two queues:
- one queue (FIFO) to queue up nodes at block entrances
- another queue (LIFO) to queue up other nodes
- The idea is to explore basic blocks to completion, but to do a BFS exploration of blocks.

Modified:
    cfe/trunk/include/clang/Analysis/PathSensitive/GRCoreEngine.h
    cfe/trunk/include/clang/Analysis/PathSensitive/GRWorkList.h
    cfe/trunk/lib/Analysis/GRCoreEngine.cpp

Modified: cfe/trunk/include/clang/Analysis/PathSensitive/GRCoreEngine.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/GRCoreEngine.h?rev=61106&r1=61105&r2=61106&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/GRCoreEngine.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/GRCoreEngine.h Tue Dec 16 16:13:33 2008
@@ -613,7 +613,8 @@
   /// Construct a GRCoreEngine object to analyze the provided CFG using
   ///  a DFS exploration of the exploded graph.
   GRCoreEngine(CFG& cfg, Decl& cd, ASTContext& ctx, SubEngineTy& subengine)
-    : GRCoreEngineImpl(new GraphTy(cfg, cd, ctx), GRWorkList::MakeDFS()),
+    : GRCoreEngineImpl(new GraphTy(cfg, cd, ctx),
+                       GRWorkList::MakeBFSBlockDFSContents()),
       SubEngine(subengine) {}
   
   /// Construct a GRCoreEngine object to analyze the provided CFG and to

Modified: cfe/trunk/include/clang/Analysis/PathSensitive/GRWorkList.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/GRWorkList.h?rev=61106&r1=61105&r2=61106&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/GRWorkList.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/GRWorkList.h Tue Dec 16 16:13:33 2008
@@ -69,6 +69,7 @@
   GRBlockCounter getBlockCounter() const { return CurrentCounter; }
   
   static GRWorkList* MakeDFS(); 
+  static GRWorkList* MakeBFSBlockDFSContents();
 };
 } // end clang namespace  
 #endif

Modified: cfe/trunk/lib/Analysis/GRCoreEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/GRCoreEngine.cpp?rev=61106&r1=61105&r2=61106&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/GRCoreEngine.cpp (original)
+++ cfe/trunk/lib/Analysis/GRCoreEngine.cpp Tue Dec 16 16:13:33 2008
@@ -18,11 +18,16 @@
 #include "llvm/Support/Casting.h"
 #include "llvm/ADT/DenseMap.h"
 #include <vector>
+#include <queue>
 
 using llvm::cast;
 using llvm::isa;
 using namespace clang;
 
+//===----------------------------------------------------------------------===//
+// Worklist classes for exploration of reachable states.
+//===----------------------------------------------------------------------===//
+
 namespace {
   class VISIBILITY_HIDDEN DFS : public GRWorkList {
   llvm::SmallVector<GRWorkListUnit,20> Stack;
@@ -50,6 +55,48 @@
 
 GRWorkList* GRWorkList::MakeDFS() { return new DFS(); }
 
+namespace {
+  class VISIBILITY_HIDDEN BFSBlockDFSContents : public GRWorkList {
+    std::queue<GRWorkListUnit> Queue;
+    llvm::SmallVector<GRWorkListUnit,20> Stack;
+  public:
+    virtual bool hasWork() const {
+      return !Queue.empty() || !Stack.empty();
+    }
+    
+    virtual void Enqueue(const GRWorkListUnit& U) {
+      if (isa<BlockEntrance>(U.getNode()->getLocation()))
+        Queue.push(U);
+      else
+        Stack.push_back(U);
+    }
+    
+    virtual GRWorkListUnit Dequeue() {
+      // Process all basic blocks to completion.
+      if (!Stack.empty()) {
+        const GRWorkListUnit& U = Stack.back();
+        Stack.pop_back(); // This technically "invalidates" U, but we are fine.
+        return U;
+      }
+      
+      assert(!Queue.empty());
+      // Don't use const reference.  The subsequent pop_back() might make it
+      // unsafe.
+      GRWorkListUnit U = Queue.front(); 
+      Queue.pop();
+      return U;      
+    }
+  };
+} // end anonymous namespace
+
+GRWorkList* GRWorkList::MakeBFSBlockDFSContents() {
+  return new BFSBlockDFSContents();
+}
+
+//===----------------------------------------------------------------------===//
+// Core analysis engine.
+//===----------------------------------------------------------------------===//
+
 /// ExecuteWorkList - Run the worklist algorithm for a maximum number of steps.
 bool GRCoreEngineImpl::ExecuteWorkList(unsigned Steps) {
   
@@ -90,8 +137,7 @@
     
     // Dispatch on the location type.
     switch (Node->getLocation().getKind()) {
-      default:
-        assert (isa<BlockEdge>(Node->getLocation()));
+      case ProgramPoint::BlockEdgeKind:
         HandleBlockEdge(cast<BlockEdge>(Node->getLocation()), Node);
         break;
         
@@ -102,9 +148,9 @@
       case ProgramPoint::BlockExitKind:
         assert (false && "BlockExit location never occur in forward analysis.");
         break;
-      
-      case ProgramPoint::PostLoadKind:
-      case ProgramPoint::PostStmtKind:
+
+      default:
+        assert(isa<PostStmt>(Node->getLocation()));
         HandlePostStmt(cast<PostStmt>(Node->getLocation()), WU.getBlock(),
                        WU.getIndex(), Node);
         break;        
@@ -332,6 +378,18 @@
       
     case ProgramPoint::PostLoadKind:
       return PostLoad(S);
+
+    case ProgramPoint::PostUndefLocationCheckFailedKind:
+      return PostUndefLocationCheckFailed(S);
+
+    case ProgramPoint::PostLocationChecksSucceedKind:
+      return PostLocationChecksSucceed(S);
+      
+    case ProgramPoint::PostOutOfBoundsCheckFailedKind:
+      return PostOutOfBoundsCheckFailed(S);
+      
+    case ProgramPoint::PostNullCheckFailedKind:
+      return PostNullCheckFailed(S);
       
     case ProgramPoint::PostStoreKind:
       return PostStore(S);





More information about the cfe-commits mailing list