[cfe-commits] r145858 - in /cfe/trunk: include/clang/Analysis/Analyses/Dominators.h include/clang/Analysis/CFG.h lib/Analysis/CFG.cpp lib/Analysis/CMakeLists.txt lib/Analysis/Dominators.cpp lib/StaticAnalyzer/Checkers/DebugCheckers.cpp

Anna Zaks ganna at apple.com
Mon Dec 5 13:33:11 PST 2011


Author: zaks
Date: Mon Dec  5 15:33:11 2011
New Revision: 145858

URL: http://llvm.org/viewvc/llvm-project?rev=145858&view=rev
Log:
[analyzer] Rely on LLVM Dominators in Clang dominator computation.

(Previously, Clang used it's implementation of dominators.)

The patch is contributed by Guoping Long!

Removed:
    cfe/trunk/lib/Analysis/Dominators.cpp
Modified:
    cfe/trunk/include/clang/Analysis/Analyses/Dominators.h
    cfe/trunk/include/clang/Analysis/CFG.h
    cfe/trunk/lib/Analysis/CFG.cpp
    cfe/trunk/lib/Analysis/CMakeLists.txt
    cfe/trunk/lib/StaticAnalyzer/Checkers/DebugCheckers.cpp

Modified: cfe/trunk/include/clang/Analysis/Analyses/Dominators.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/Analyses/Dominators.h?rev=145858&r1=145857&r2=145858&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/Analyses/Dominators.h (original)
+++ cfe/trunk/include/clang/Analysis/Analyses/Dominators.h Mon Dec  5 15:33:11 2011
@@ -1,4 +1,4 @@
-//==- Dominators.h - Construct the Dominance Tree Given CFG -----*- C++ --*-==//
+//==- Dominators.h - Implementation of dominators tree for Clang CFG C++ -*-==//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -7,74 +7,205 @@
 //
 //===----------------------------------------------------------------------===//
 //
-// This file implements a simple, fast dominance algorithm for source-level
-// CFGs.
+// This file implements the dominators tree functionality for Clang CFGs.
 //
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_DOMINATORS_H
 #define LLVM_CLANG_DOMINATORS_H
 
-#include "clang/Analysis/CFG.h"
 #include "clang/Analysis/AnalysisContext.h"
-#include "llvm/ADT/DenseMap.h"
+
+#include "llvm/Module.h"
+#include "llvm/ADT/GraphTraits.h"
+#include "clang/Analysis/CFG.h"
+#include "llvm/Analysis/Dominators.h"
+#include "llvm/Analysis/DominatorInternals.h"
 
 namespace clang {
 
-class CFG;
 class CFGBlock;
+typedef llvm::DomTreeNodeBase<CFGBlock> DomTreeNode;
 
+/// \brief Concrete subclass of DominatorTreeBase for Clang
+/// This class implements the dominators tree functionality given a Clang CFG.
+///
 class DominatorTree : public ManagedAnalysis {
-  typedef llvm::DenseMap<const CFGBlock *, CFGBlock*> CFGBlockMapTy;
-
 public:
-  DominatorTree(AnalysisDeclContext &ac)
-      : AC(ac) {}
+  llvm::DominatorTreeBase<CFGBlock>* DT;
 
-  virtual ~DominatorTree();
+  DominatorTree() {
+    DT = new llvm::DominatorTreeBase<CFGBlock>(false);
+  }
 
-  /// Return the immediate dominator node given a CFGBlock.
-  /// For entry block, the dominator is itself.
-  /// This is the same as using operator[] on this class.
-  CFGBlock *getNode(const CFGBlock *B) const;
+  ~DominatorTree() {
+    delete DT;
+  }
+
+  llvm::DominatorTreeBase<CFGBlock>& getBase() { return *DT; }
+
+  /// \brief This method returns the root CFGBlock of the dominators tree.
+  ///
+  inline CFGBlock *getRoot() const {
+    return DT->getRoot();
+  }
+
+  /// \brief This method returns the root DomTreeNode, which is the wrapper
+  /// for CFGBlock.
+  inline DomTreeNode *getRootNode() const {
+    return DT->getRootNode();
+  }
+
+  /// \brief This method compares two dominator trees.
+  /// The method returns false if the other dominator tree matches this
+  /// dominator tree, otherwise returns true.
+  ///
+  inline bool compare(DominatorTree &Other) const {
+    DomTreeNode *R = getRootNode();
+    DomTreeNode *OtherR = Other.getRootNode();
+
+    if (!R || !OtherR || R->getBlock() != OtherR->getBlock())
+      return true;
+
+    if (DT->compare(Other.getBase()))
+      return true;
+
+    return false;
+  }
+
+  /// \brief This method builds the dominator tree for a given CFG
+  /// The CFG information is passed via AnalysisDeclContext
+  ///
+  void buildDominatorTree(AnalysisDeclContext &AC) {
+    cfg = AC.getCFG();
+    DT->recalculate(*cfg);
+  }
 
-  /// This returns the Entry Block for the given CFG
-  CFGBlock *getRootNode() { return RootNode; }
-  const CFGBlock *getRootNode() const { return RootNode; }
+  /// \brief This method dumps immediate dominators for each block,
+  /// mainly used for debug purposes.
+  ///
+  void dump() {
+    llvm::errs() << "Immediate dominance tree (Node#,IDom#):\n";
+    for (CFG::const_iterator I = cfg->begin(),
+        E = cfg->end(); I != E; ++I) {
+      if(DT->getNode(*I)->getIDom())
+        llvm::errs() << "(" << (*I)->getBlockID()
+                     << ","
+                     << DT->getNode(*I)->getIDom()->getBlock()->getBlockID()
+                     << ")\n";
+      else llvm::errs() << "(" << (*I)->getBlockID()
+                        << "," << (*I)->getBlockID() << ")\n";
+    }
+  }
+
+  /// \brief This method tests if one CFGBlock dominates the other.
+  /// The method return true if A dominates B, false otherwise.
+  /// Note a block always dominates itself.
+  ///
+  inline bool dominates(const CFGBlock* A, const CFGBlock* B) const {
+    return DT->dominates(A, B);
+  }
 
-  /// Returns true iff A dominates B and A != B.
-  /// Note that this is not a constant time operation.
-  bool properlyDominates(const CFGBlock *A, const CFGBlock *B) const;
+  /// \brief This method tests if one CFGBlock properly dominates the other.
+  /// The method return true if A properly dominates B, false otherwise.
+  ///
+  bool properlyDominates(const CFGBlock*A, const CFGBlock*B) const {
+    return DT->properlyDominates(A, B);
+  }
 
-  /// Returns true iff A dominates B.
-  bool dominates(const CFGBlock *A, const CFGBlock *B) const;
+  /// \brief This method finds the nearest common dominator CFG block
+  /// for CFG block A and B. If there is no such block then return NULL.
+  ///
+  inline CFGBlock *findNearestCommonDominator(CFGBlock *A, CFGBlock *B) {
+    return DT->findNearestCommonDominator(A, B);
+  }
+
+  inline const CFGBlock *findNearestCommonDominator(const CFGBlock *A,
+                                                      const CFGBlock *B) {
+    return DT->findNearestCommonDominator(A, B);
+  }
 
-  /// Find nearest common dominator for blocks A and B.
-  /// Common dominator always exists, ex: entry block.
-  const CFGBlock *findNearestCommonDominator(const CFGBlock *A,
-                                       const CFGBlock *B) const;
+  /// \brief This method is used to update the dominator
+  /// tree information when a node's immediate dominator changes.
+  ///
+  inline void changeImmediateDominator(CFGBlock *N, CFGBlock *NewIDom) {
+    DT->changeImmediateDominator(N, NewIDom);
+  }
 
-  /// Constructs immediate dominator tree for a given CFG based on the algorithm
-  /// described in this paper:
+  /// \brief This method tests if the given CFGBlock can be reachable from root.
+  /// Returns true if reachable, false otherwise.
   ///
-  ///  A Simple, Fast Dominance Algorithm
-  ///  Keith D. Cooper, Timothy J. Harvey and Ken Kennedy
-  ///  Software-Practice and Expreience, 2001;4:1-10.
+  bool isReachableFromEntry(const CFGBlock *A) {
+    return DT->isReachableFromEntry(A);
+  }
+
+  /// \brief This method releases the memory held by the dominator tree.
   ///
-  /// This implementation is simple and runs faster in practice than the classis
-  /// Lengauer-Tarjan algorithm. For detailed discussions, refer to the paper.
-  void BuildDominatorTree();
+  virtual void releaseMemory() {
+    DT->releaseMemory();
+  }
 
-  /// Dump the immediate dominance tree
-  void dump();
+  /// \brief This method converts the dominator tree to human readable form.
+  ///
+  virtual void print(raw_ostream &OS, const llvm::Module* M= 0) const {
+    DT->print(OS);
+  }
 
 private:
-  AnalysisDeclContext &AC;
-  CFGBlock *RootNode;
-  CFGBlockMapTy IDoms;
+  CFG *cfg;
 };
 
+void WriteAsOperand(raw_ostream &OS, const CFGBlock *BB,
+                          bool t) {
+  OS << "BB#" << BB->getBlockID();
+}
+
 } // end namespace clang
 
-#endif
+//===-------------------------------------
+/// DominatorTree GraphTraits specialization so the DominatorTree can be
+/// iterable by generic graph iterators.
+///
+namespace llvm {
+template <> struct GraphTraits< ::clang::DomTreeNode* > {
+  typedef ::clang::DomTreeNode NodeType;
+  typedef NodeType::iterator  ChildIteratorType;
+
+  static NodeType *getEntryNode(NodeType *N) {
+    return N;
+  }
+  static inline ChildIteratorType child_begin(NodeType *N) {
+    return N->begin();
+  }
+  static inline ChildIteratorType child_end(NodeType *N) {
+    return N->end();
+  }
+
+  typedef df_iterator< ::clang::DomTreeNode* > nodes_iterator;
+
+  static nodes_iterator nodes_begin(::clang::DomTreeNode *N) {
+    return df_begin(getEntryNode(N));
+  }
+
+  static nodes_iterator nodes_end(::clang::DomTreeNode *N) {
+    return df_end(getEntryNode(N));
+  }
+};
 
+template <> struct GraphTraits< ::clang::DominatorTree* >
+  : public GraphTraits< ::clang::DomTreeNode* > {
+  static NodeType *getEntryNode(::clang::DominatorTree *DT) {
+    return DT->getRootNode();
+  }
+
+  static nodes_iterator nodes_begin(::clang::DominatorTree *N) {
+    return df_begin(getEntryNode(N));
+  }
+
+  static nodes_iterator nodes_end(::clang::DominatorTree *N) {
+    return df_end(getEntryNode(N));
+  }
+};
+} // end namespace llvm
+
+#endif

Modified: cfe/trunk/include/clang/Analysis/CFG.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/CFG.h?rev=145858&r1=145857&r2=145858&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/CFG.h (original)
+++ cfe/trunk/include/clang/Analysis/CFG.h Mon Dec  5 15:33:11 2011
@@ -344,10 +344,14 @@
   /// storage if the memory usage of CFGBlock becomes an issue.
   unsigned HasNoReturnElement : 1;
 
+  /// Parent - The parent CFG that owns this CFGBlock.
+  CFG *Parent;
+
 public:
-  explicit CFGBlock(unsigned blockid, BumpVectorContext &C)
-    : Elements(C), Label(NULL), Terminator(NULL), LoopTarget(NULL),
-      BlockID(blockid), Preds(C, 1), Succs(C, 1), HasNoReturnElement(false) {}
+  explicit CFGBlock(unsigned blockid, BumpVectorContext &C, CFG *parent)
+    : Elements(C), Label(NULL), Terminator(NULL), LoopTarget(NULL), 
+      BlockID(blockid), Preds(C, 1), Succs(C, 1), HasNoReturnElement(false),
+      Parent(parent) {}
   ~CFGBlock() {}
 
   // Statement iterators
@@ -489,6 +493,8 @@
 
   unsigned getBlockID() const { return BlockID; }
 
+  CFG *getParent() const { return Parent; }
+
   void dump(const CFG *cfg, const LangOptions &LO) const;
   void print(raw_ostream &OS, const CFG* cfg, const LangOptions &LO) const;
   void printTerminator(raw_ostream &OS, const LangOptions &LO) const;
@@ -583,6 +589,55 @@
       ,AddImplicitDtors(false) {}
   };
 
+  /// \brief Provides a custom implementation of the iterator class to have the
+  /// same interface as Function::iterator - iterator returns CFGBlock
+  /// (not a pointer to CFGBlock).
+  class graph_iterator {
+  public:
+    typedef const CFGBlock                  value_type;
+    typedef value_type&                     reference;
+    typedef value_type*                     pointer;
+    typedef BumpVector<CFGBlock*>::iterator ImplTy;
+
+    graph_iterator(const ImplTy &i) : I(i) {}
+
+    bool operator==(const graph_iterator &X) const { return I == X.I; }
+    bool operator!=(const graph_iterator &X) const { return I != X.I; }
+
+    reference operator*()    const { return **I; }
+    pointer operator->()     const { return  *I; }
+    operator CFGBlock* ()          { return  *I; }
+
+    graph_iterator &operator++() { ++I; return *this; }
+    graph_iterator &operator--() { --I; return *this; }
+
+  private:
+    ImplTy I;
+  };
+
+  class const_graph_iterator {
+  public:
+    typedef const CFGBlock                  value_type;
+    typedef value_type&                     reference;
+    typedef value_type*                     pointer;
+    typedef BumpVector<CFGBlock*>::const_iterator ImplTy;
+
+    const_graph_iterator(const ImplTy &i) : I(i) {}
+
+    bool operator==(const const_graph_iterator &X) const { return I == X.I; }
+    bool operator!=(const const_graph_iterator &X) const { return I != X.I; }
+
+    reference operator*() const { return **I; }
+    pointer operator->()  const { return  *I; }
+    operator CFGBlock* () const { return  *I; }
+
+    const_graph_iterator &operator++() { ++I; return *this; }
+    const_graph_iterator &operator--() { --I; return *this; }
+
+  private:
+    ImplTy I;
+  };
+
   /// buildCFG - Builds a CFG from an AST.  The responsibility to free the
   ///   constructed CFG belongs to the caller.
   static CFG* buildCFG(const Decl *D, Stmt *AST, ASTContext *C,
@@ -619,6 +674,15 @@
   const_iterator            begin()       const    { return Blocks.begin(); }
   const_iterator            end()         const    { return Blocks.end(); }
 
+  graph_iterator nodes_begin() { return graph_iterator(Blocks.begin()); }
+  graph_iterator nodes_end() { return graph_iterator(Blocks.end()); }
+  const_graph_iterator nodes_begin() const {
+    return const_graph_iterator(Blocks.begin());
+  }
+  const_graph_iterator nodes_end() const {
+    return const_graph_iterator(Blocks.end());
+  }
+
   reverse_iterator          rbegin()               { return Blocks.rbegin(); }
   reverse_iterator          rend()                 { return Blocks.rend(); }
   const_reverse_iterator    rbegin()      const    { return Blocks.rbegin(); }
@@ -681,6 +745,11 @@
   /// start at 0).
   unsigned getNumBlockIDs() const { return NumBlockIDs; }
 
+  /// size - Return the total number of CFGBlocks within the CFG
+  /// This is simply a renaming of the getNumBlockIDs(). This is necessary 
+  /// because the dominator implementation needs such an interface.
+  unsigned size() const { return NumBlockIDs; }
+
   //===--------------------------------------------------------------------===//
   // CFG Debugging: Pretty-Printing and Visualization.
   //===--------------------------------------------------------------------===//
@@ -781,6 +850,20 @@
   { return N->succ_end(); }
 };
 
+template <> struct GraphTraits<Inverse< ::clang::CFGBlock*> > {
+  typedef ::clang::CFGBlock NodeType;
+  typedef ::clang::CFGBlock::const_pred_iterator ChildIteratorType;
+
+  static NodeType *getEntryNode(Inverse< ::clang::CFGBlock*> G)
+  { return G.Graph; }
+
+  static inline ChildIteratorType child_begin(NodeType* N)
+  { return N->pred_begin(); }
+
+  static inline ChildIteratorType child_end(NodeType* N)
+  { return N->pred_end(); }
+};
+
 template <> struct GraphTraits<Inverse<const ::clang::CFGBlock*> > {
   typedef const ::clang::CFGBlock NodeType;
   typedef ::clang::CFGBlock::const_pred_iterator ChildIteratorType;
@@ -800,37 +883,55 @@
 template <> struct GraphTraits< ::clang::CFG* >
     : public GraphTraits< ::clang::CFGBlock *>  {
 
-  typedef ::clang::CFG::iterator nodes_iterator;
+  typedef ::clang::CFG::graph_iterator nodes_iterator;
 
-  static NodeType *getEntryNode(::clang::CFG* F) { return &F->getEntry(); }
-  static nodes_iterator nodes_begin(::clang::CFG* F) { return F->begin(); }
-  static nodes_iterator nodes_end(::clang::CFG* F) { return F->end(); }
+  static NodeType     *getEntryNode(::clang::CFG* F) { return &F->getEntry(); }
+  static nodes_iterator nodes_begin(::clang::CFG* F) { return F->nodes_begin();}
+  static nodes_iterator   nodes_end(::clang::CFG* F) { return F->nodes_end(); }
+  static unsigned              size(::clang::CFG* F) { return F->size(); }
 };
 
 template <> struct GraphTraits<const ::clang::CFG* >
     : public GraphTraits<const ::clang::CFGBlock *>  {
 
-  typedef ::clang::CFG::const_iterator nodes_iterator;
+  typedef ::clang::CFG::const_graph_iterator nodes_iterator;
 
   static NodeType *getEntryNode( const ::clang::CFG* F) {
     return &F->getEntry();
   }
   static nodes_iterator nodes_begin( const ::clang::CFG* F) {
-    return F->begin();
+    return F->nodes_begin();
   }
   static nodes_iterator nodes_end( const ::clang::CFG* F) {
-    return F->end();
+    return F->nodes_end();
+  }
+  static unsigned size(const ::clang::CFG* F) {
+    return F->size();
   }
 };
 
+template <> struct GraphTraits<Inverse< ::clang::CFG*> >
+  : public GraphTraits<Inverse< ::clang::CFGBlock*> > {
+
+  typedef ::clang::CFG::graph_iterator nodes_iterator;
+
+  static NodeType *getEntryNode( ::clang::CFG* F) { return &F->getExit(); }
+  static nodes_iterator nodes_begin( ::clang::CFG* F) {return F->nodes_begin();}
+  static nodes_iterator nodes_end( ::clang::CFG* F) { return F->nodes_end(); }
+};
+
 template <> struct GraphTraits<Inverse<const ::clang::CFG*> >
   : public GraphTraits<Inverse<const ::clang::CFGBlock*> > {
 
-  typedef ::clang::CFG::const_iterator nodes_iterator;
+  typedef ::clang::CFG::const_graph_iterator nodes_iterator;
 
   static NodeType *getEntryNode(const ::clang::CFG* F) { return &F->getExit(); }
-  static nodes_iterator nodes_begin(const ::clang::CFG* F) { return F->begin();}
-  static nodes_iterator nodes_end(const ::clang::CFG* F) { return F->end(); }
+  static nodes_iterator nodes_begin(const ::clang::CFG* F) {
+    return F->nodes_begin();
+  }
+  static nodes_iterator nodes_end(const ::clang::CFG* F) {
+    return F->nodes_end();
+  }
 };
 } // end llvm namespace
 #endif

Modified: cfe/trunk/lib/Analysis/CFG.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CFG.cpp?rev=145858&r1=145857&r2=145858&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/CFG.cpp (original)
+++ cfe/trunk/lib/Analysis/CFG.cpp Mon Dec  5 15:33:11 2011
@@ -3039,7 +3039,7 @@
 
   // Create the block.
   CFGBlock *Mem = getAllocator().Allocate<CFGBlock>();
-  new (Mem) CFGBlock(NumBlockIDs++, BlkBVC);
+  new (Mem) CFGBlock(NumBlockIDs++, BlkBVC, this);
   Blocks.push_back(Mem, BlkBVC);
 
   // If this is the first block, set it as the Entry and Exit.

Modified: cfe/trunk/lib/Analysis/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CMakeLists.txt?rev=145858&r1=145857&r2=145858&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/CMakeLists.txt (original)
+++ cfe/trunk/lib/Analysis/CMakeLists.txt Mon Dec  5 15:33:11 2011
@@ -6,7 +6,6 @@
   CFGReachabilityAnalysis.cpp
   CFGStmtMap.cpp
   CocoaConventions.cpp
-  Dominators.cpp
   FormatString.cpp
   LiveVariables.cpp
   PostOrderCFGView.cpp

Removed: cfe/trunk/lib/Analysis/Dominators.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/Dominators.cpp?rev=145857&view=auto
==============================================================================
--- cfe/trunk/lib/Analysis/Dominators.cpp (original)
+++ cfe/trunk/lib/Analysis/Dominators.cpp (removed)
@@ -1,160 +0,0 @@
-//==- Dominators.cpp - Construct the Dominance Tree Given CFG ----*- 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 a simple, fast dominance algorithm for source-level CFGs.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Analysis/Analyses/Dominators.h"
-#include "clang/Analysis/CFG.h"
-#include "clang/Analysis/AnalysisContext.h"
-#include "clang/Analysis/Analyses/PostOrderCFGView.h"
-
-using namespace clang;
-
-DominatorTree::~DominatorTree() {
-  IDoms.clear();
-  RootNode = 0;
-}
-
-CFGBlock * DominatorTree::getNode(const CFGBlock *B) const {
-  CFGBlockMapTy::const_iterator I = IDoms.find(B);
-  return I != IDoms.end() ? I->second : 0; 
-}
-
-bool DominatorTree::properlyDominates(const CFGBlock *A, 
-                                      const CFGBlock *B) const {
-  if (0 == A || 0 == B || A == B)
-    return false;
-
-  // The EntryBlock dominates every other block.
-  if (A == RootNode)
-    return true;
-
-  // Note: The dominator of the EntryBlock is itself.
-  CFGBlock *IDom = getNode(B);
-  while (IDom != A && IDom != RootNode)
-    IDom = getNode(IDom);
-
-  return IDom != RootNode;
-}
-
-bool DominatorTree::dominates(const CFGBlock *A,
-                              const CFGBlock *B) const {
-  if (A == B)
-    return true;
-
-  return properlyDominates(A, B);
-}
-
-const CFGBlock * DominatorTree::findNearestCommonDominator
-      (const CFGBlock *A, const CFGBlock *B) const {
-  //If A dominates B, then A is the nearest common dominator
-  if (dominates(A, B))
-    return A;
-
-  //If B dominates A, then B is the nearest common dominator
-  if (dominates(B, A))
-    return B;
-
-  //Collect all A's dominators
-  llvm::SmallPtrSet<CFGBlock *, 16> ADoms;
-  ADoms.insert(RootNode);
-  CFGBlock *ADom = getNode(A);
-  while (ADom != RootNode) {
-    ADoms.insert(ADom);
-    ADom = getNode(ADom);
-  }  
-
-  //Check all B's dominators against ADoms
-  CFGBlock *BDom = getNode(B);
-  while (BDom != RootNode){
-    if (ADoms.count(BDom) != 0)
-      return BDom;
-
-    BDom = getNode(BDom);
-  }
-
-  //The RootNode dominates every other node
-  return RootNode;
-}
-
-/// Constructs immediate dominator tree for a given CFG based on the algorithm
-/// described in this paper:
-///
-///  A Simple, Fast Dominance Algorithm
-///  Keith D. Cooper, Timothy J. Harvey and Ken Kennedy
-///  Software-Practice and Expreience, 2001;4:1-10.
-///
-/// This implementation is simple and runs faster in practice than the classis
-/// Lengauer-Tarjan algorithm. For detailed discussions, refer to the paper. 
-void DominatorTree::BuildDominatorTree() {
-  CFG *cfg = AC.getCFG();
-  CFGBlock *EntryBlk = &cfg->getEntry();
-
-  //Sort all CFGBlocks in reverse order
-  PostOrderCFGView *rpocfg = AC.getAnalysis<PostOrderCFGView>();
-
-  //Set the root of the dominance tree
-  RootNode = EntryBlk;
-  
-  //Compute the immediate dominator for each CFGBlock
-  IDoms[EntryBlk] = EntryBlk;
-  bool changed = true;
-  while (changed){
-    changed = false;
-
-    for (PostOrderCFGView::iterator I = rpocfg->begin(),
-        E = rpocfg->end(); I != E; ++I){
-      if (EntryBlk == *I)
-        continue;
-      if (const CFGBlock *B = *I) {
-        //Compute immediate dominance information for CFGBlock B
-        CFGBlock *IDom = 0;
-        for (CFGBlock::const_pred_iterator J = B->pred_begin(),
-            K = B->pred_end(); J != K; ++J)
-          if( CFGBlock *P = *J) {
-            if (IDoms.find(P) == IDoms.end())
-              continue;
-            if (!IDom)
-              IDom = P;
-            else {
-              //intersect IDom and P
-              CFGBlock *B1 = IDom, *B2 = P;
-              while (B1 != B2) {
-                while ((rpocfg->getComparator())(B2,B1))
-                  B1 = IDoms[B1];
-                while ((rpocfg->getComparator())(B1,B2))
-                  B2 = IDoms[B2];
-              }
-              IDom = B1;
-            }
-          }
-        if (IDoms[B] != IDom) {
-          IDoms[B] = IDom;
-          changed = true;
-        } 
-      }
-    }
-  }//while
-}
-
-void DominatorTree::dump() {
-  CFG *cfg = AC.getCFG();
-
-  llvm::errs() << "Immediate dominance tree (Node#,IDom#):\n";
-  for (CFG::const_iterator I = cfg->begin(),
-      E = cfg->end(); I != E; ++I) {
-    assert(IDoms[(*I)] && 
-       "Failed to find the immediate dominator for all CFG blocks.");
-    llvm::errs() << "(" << (*I)->getBlockID()
-                 << "," << IDoms[(*I)]->getBlockID() << ")\n";
-  }
-}
-

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/DebugCheckers.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/DebugCheckers.cpp?rev=145858&r1=145857&r2=145858&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/DebugCheckers.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/DebugCheckers.cpp Mon Dec  5 15:33:11 2011
@@ -30,8 +30,8 @@
   void checkASTCodeBody(const Decl *D, AnalysisManager& mgr,
                         BugReporter &BR) const {
     if (AnalysisDeclContext *AC = mgr.getAnalysisDeclContext(D)) {
-      DominatorTree dom(*AC);
-      dom.BuildDominatorTree();
+      DominatorTree dom;
+      dom.buildDominatorTree(*AC);
       dom.dump();
     }
   }





More information about the cfe-commits mailing list