[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