[cfe-commits] r142713 - in /cfe/trunk: include/clang/Analysis/Analyses/PostOrderCFGView.h lib/Analysis/CMakeLists.txt lib/Analysis/LiveVariables.cpp lib/Analysis/PostOrderCFGView.cpp

Ted Kremenek kremenek at apple.com
Fri Oct 21 19:14:23 PDT 2011


Author: kremenek
Date: Fri Oct 21 21:14:23 2011
New Revision: 142713

URL: http://llvm.org/viewvc/llvm-project?rev=142713&view=rev
Log:
Pull TopologicallySortedCFG out of LiveVariables into its own analysis: PostOrderCFGView.

Added:
    cfe/trunk/include/clang/Analysis/Analyses/PostOrderCFGView.h
    cfe/trunk/lib/Analysis/PostOrderCFGView.cpp
Modified:
    cfe/trunk/lib/Analysis/CMakeLists.txt
    cfe/trunk/lib/Analysis/LiveVariables.cpp

Added: cfe/trunk/include/clang/Analysis/Analyses/PostOrderCFGView.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/Analyses/PostOrderCFGView.h?rev=142713&view=auto
==============================================================================
--- cfe/trunk/include/clang/Analysis/Analyses/PostOrderCFGView.h (added)
+++ cfe/trunk/include/clang/Analysis/Analyses/PostOrderCFGView.h Fri Oct 21 21:14:23 2011
@@ -0,0 +1,102 @@
+//===- PostOrderCFGView.h - Post order view of CFG blocks ---------*- C++ --*-//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements post order view of the blocks in a CFG.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_POSTORDER_CFGVIEW
+#define LLVM_CLANG_POSTORDER_CFGVIEW
+
+#include <vector>
+//#include <algorithm>
+
+#include "llvm/ADT/PostOrderIterator.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/BitVector.h"
+
+#include "clang/Analysis/AnalysisContext.h"
+#include "clang/Analysis/CFG.h"
+
+namespace clang {
+    
+class PostOrderCFGView : public ManagedAnalysis {
+  class CFGBlockSet {
+    llvm::BitVector VisitedBlockIDs;
+  public:
+    // po_iterator requires this iterator, but the only interface needed is the
+    // value_type typedef.
+    struct iterator { typedef const CFGBlock *value_type; };
+
+    CFGBlockSet() {}
+    CFGBlockSet(const CFG *G) : VisitedBlockIDs(G->getNumBlockIDs(), false) {}
+
+    /// \brief Set the bit associated with a particular CFGBlock.
+    /// This is the important method for the SetType template parameter.
+    bool insert(const CFGBlock *Block) {
+      // Note that insert() is called by po_iterator, which doesn't check to make
+      // sure that Block is non-null.  Moreover, the CFGBlock iterator will
+      // occasionally hand out null pointers for pruned edges, so we catch those
+      // here.
+      if (Block == 0)
+        return false;  // if an edge is trivially false.
+      if (VisitedBlockIDs.test(Block->getBlockID()))
+        return false;
+      VisitedBlockIDs.set(Block->getBlockID());
+      return true;
+    }
+
+    /// \brief Check if the bit for a CFGBlock has been already set.
+    /// This method is for tracking visited blocks in the main threadsafety loop.
+    /// Block must not be null.
+    bool alreadySet(const CFGBlock *Block) {
+      return VisitedBlockIDs.test(Block->getBlockID());
+    }
+  };
+
+  typedef llvm::po_iterator<const CFG*, CFGBlockSet, true>  po_iterator;  
+  std::vector<const CFGBlock*> Blocks;
+  
+  typedef llvm::DenseMap<const CFGBlock *, unsigned> BlockOrderTy;
+  BlockOrderTy BlockOrder;
+  
+public:
+  typedef std::vector<const CFGBlock*>::reverse_iterator iterator;
+  
+  PostOrderCFGView(const CFG *cfg);
+  
+  iterator begin() { return Blocks.rbegin(); }
+  iterator end()   { return Blocks.rend(); }
+  
+  bool empty() { return begin() == end(); }
+  
+  struct BlockOrderCompare;
+  friend struct BlockOrderCompare;
+
+  struct BlockOrderCompare {
+    const PostOrderCFGView &POV;
+  public:
+    BlockOrderCompare(const PostOrderCFGView &pov) : POV(pov) {}
+    bool operator()(const CFGBlock *b1, const CFGBlock *b2) const;  
+  };
+  
+  BlockOrderCompare getComparator() const {
+    return BlockOrderCompare(*this);
+  }
+
+  // Used by AnalyisContext to construct this object.
+  static const void *getTag();
+
+  static PostOrderCFGView *create(AnalysisContext &analysisContext);
+};
+  
+} // end clang namespace
+
+#endif
+

Modified: cfe/trunk/lib/Analysis/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CMakeLists.txt?rev=142713&r1=142712&r2=142713&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/CMakeLists.txt (original)
+++ cfe/trunk/lib/Analysis/CMakeLists.txt Fri Oct 21 21:14:23 2011
@@ -8,6 +8,7 @@
   CocoaConventions.cpp
   FormatString.cpp
   LiveVariables.cpp
+  PostOrderCFGView.cpp
   PrintfFormatString.cpp
   ProgramPoint.cpp
   PseudoConstantAnalysis.cpp

Modified: cfe/trunk/lib/Analysis/LiveVariables.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/LiveVariables.cpp?rev=142713&r1=142712&r2=142713&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/LiveVariables.cpp (original)
+++ cfe/trunk/lib/Analysis/LiveVariables.cpp Fri Oct 21 21:14:23 2011
@@ -1,4 +1,6 @@
 #include "clang/Analysis/Analyses/LiveVariables.h"
+#include "clang/Analysis/Analyses/PostOrderCFGView.h"
+
 #include "clang/AST/Stmt.h"
 #include "clang/Analysis/CFG.h"
 #include "clang/Analysis/AnalysisContext.h"
@@ -15,113 +17,14 @@
 
 namespace {
 
-// FIXME: This is copy-pasted from ThreadSafety.c.  I wanted a patch that
-// contained working code before refactoring the implementation of both
-// files.
-class CFGBlockSet {
-  llvm::BitVector VisitedBlockIDs;
-  
-public:
-  // po_iterator requires this iterator, but the only interface needed is the
-  // value_type typedef.
-  struct iterator {
-    typedef const CFGBlock *value_type;
-  };
-  
-  CFGBlockSet() {}
-  CFGBlockSet(const CFG *G) : VisitedBlockIDs(G->getNumBlockIDs(), false) {}
-  
-  /// \brief Set the bit associated with a particular CFGBlock.
-  /// This is the important method for the SetType template parameter.
-  bool insert(const CFGBlock *Block) {
-    // Note that insert() is called by po_iterator, which doesn't check to make
-    // sure that Block is non-null.  Moreover, the CFGBlock iterator will
-    // occasionally hand out null pointers for pruned edges, so we catch those
-    // here.
-    if (Block == 0)
-      return false;  // if an edge is trivially false.
-    if (VisitedBlockIDs.test(Block->getBlockID()))
-      return false;
-    VisitedBlockIDs.set(Block->getBlockID());
-    return true;
-  }
-  
-  /// \brief Check if the bit for a CFGBlock has been already set.
-  /// This method is for tracking visited blocks in the main threadsafety loop.
-  /// Block must not be null.
-  bool alreadySet(const CFGBlock *Block) {
-    return VisitedBlockIDs.test(Block->getBlockID());
-  }
-};
-
-/// \brief We create a helper class which we use to iterate through CFGBlocks in
-/// the topological order.
-class TopologicallySortedCFG {
-  typedef llvm::po_iterator<const CFG*, CFGBlockSet, true>  po_iterator;
-  
-  std::vector<const CFGBlock*> Blocks;
-  
-  typedef llvm::DenseMap<const CFGBlock *, unsigned> BlockOrderTy;
-  BlockOrderTy BlockOrder;
-  
-  
-public:
-  typedef std::vector<const CFGBlock*>::reverse_iterator iterator;
-  
-  TopologicallySortedCFG(const CFG *CFGraph) {
-    Blocks.reserve(CFGraph->getNumBlockIDs());
-    CFGBlockSet BSet(CFGraph);
-    
-    for (po_iterator I = po_iterator::begin(CFGraph, BSet),
-         E = po_iterator::end(CFGraph, BSet); I != E; ++I) {
-      BlockOrder[*I] = Blocks.size() + 1;
-      Blocks.push_back(*I);      
-    }
-  }
-  
-  iterator begin() {
-    return Blocks.rbegin();
-  }
-  
-  iterator end() {
-    return Blocks.rend();
-  }
-  
-  bool empty() {
-    return begin() == end();
-  }
-  
-  struct BlockOrderCompare;
-  friend struct BlockOrderCompare;
-
-  struct BlockOrderCompare {
-    const TopologicallySortedCFG &TSC;
-  public:
-    BlockOrderCompare(const TopologicallySortedCFG &tsc) : TSC(tsc) {}
-    
-    bool operator()(const CFGBlock *b1, const CFGBlock *b2) const {
-      TopologicallySortedCFG::BlockOrderTy::const_iterator b1It = TSC.BlockOrder.find(b1);
-      TopologicallySortedCFG::BlockOrderTy::const_iterator b2It = TSC.BlockOrder.find(b2);
-      
-      unsigned b1V = (b1It == TSC.BlockOrder.end()) ? 0 : b1It->second;
-      unsigned b2V = (b2It == TSC.BlockOrder.end()) ? 0 : b2It->second;
-      return b1V > b2V;
-    }  
-  };
-  
-  BlockOrderCompare getComparator() const {
-    return BlockOrderCompare(*this);
-  }
-};
-
 class DataflowWorklist {
   SmallVector<const CFGBlock *, 20> worklist;
   llvm::BitVector enqueuedBlocks;
-  TopologicallySortedCFG TSC;
+  PostOrderCFGView *POV;
 public:
-  DataflowWorklist(const CFG &cfg)
+  DataflowWorklist(const CFG &cfg, AnalysisContext &Ctx)
     : enqueuedBlocks(cfg.getNumBlockIDs()),
-      TSC(&cfg) {}
+      POV(Ctx.getAnalysis<PostOrderCFGView>()) {}
   
   void enqueueBlock(const CFGBlock *block);
   void enqueueSuccessors(const CFGBlock *block);
@@ -168,10 +71,9 @@
 }
 
 void DataflowWorklist::sortWorklist() {
-  std::sort(worklist.begin(), worklist.end(), TSC.getComparator());
+  std::sort(worklist.begin(), worklist.end(), POV->getComparator());
 }
 
-
 const CFGBlock *DataflowWorklist::dequeue() {
   if (worklist.empty())
     return 0;
@@ -557,7 +459,7 @@
 
   // Construct the dataflow worklist.  Enqueue the exit block as the
   // start of the analysis.
-  DataflowWorklist worklist(*cfg);
+  DataflowWorklist worklist(*cfg, AC);
   llvm::BitVector everAnalyzedBlock(cfg->getNumBlockIDs());
 
   // FIXME: we should enqueue using post order.

Added: cfe/trunk/lib/Analysis/PostOrderCFGView.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/PostOrderCFGView.cpp?rev=142713&view=auto
==============================================================================
--- cfe/trunk/lib/Analysis/PostOrderCFGView.cpp (added)
+++ cfe/trunk/lib/Analysis/PostOrderCFGView.cpp Fri Oct 21 21:14:23 2011
@@ -0,0 +1,47 @@
+//===- PostOrderCFGView.cpp - Post order view of CFG blocks -------*- C++ --*-//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements post order view of the blocks in a CFG.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Analysis/Analyses/PostOrderCFGView.h"
+
+using namespace clang;
+
+PostOrderCFGView::PostOrderCFGView(const CFG *cfg) {
+  Blocks.reserve(cfg->getNumBlockIDs());
+  CFGBlockSet BSet(cfg);
+    
+  for (po_iterator I = po_iterator::begin(cfg, BSet),
+                   E = po_iterator::end(cfg, BSet); I != E; ++I) {
+    BlockOrder[*I] = Blocks.size() + 1;
+    Blocks.push_back(*I);      
+  }
+}
+
+PostOrderCFGView *PostOrderCFGView::create(AnalysisContext &ctx) {
+  const CFG *cfg = ctx.getCFG();
+  if (!cfg)
+    return 0;
+  return new PostOrderCFGView(cfg);
+}
+
+const void *PostOrderCFGView::getTag() { static int x; return &x; }
+
+bool PostOrderCFGView::BlockOrderCompare::operator()(const CFGBlock *b1,
+                                                     const CFGBlock *b2) const {
+  PostOrderCFGView::BlockOrderTy::const_iterator b1It = POV.BlockOrder.find(b1);
+  PostOrderCFGView::BlockOrderTy::const_iterator b2It = POV.BlockOrder.find(b2);
+    
+  unsigned b1V = (b1It == POV.BlockOrder.end()) ? 0 : b1It->second;
+  unsigned b2V = (b2It == POV.BlockOrder.end()) ? 0 : b2It->second;
+  return b1V > b2V;
+}
+





More information about the cfe-commits mailing list