[dom] The formatting of the generic domtree has bitrotted over the years

significantly. Clean it up with the help of clang-format.

I've touched this up by hand in a couple of places that weren't quite
right (IMO). I think most of these actually have bugs open about
already.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225938 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chandler Carruth 2015-01-14 03:56:00 +00:00
parent 3abe6ea44a
commit 35854cb40b

View File

@ -31,71 +31,65 @@ namespace llvm {
/// \brief Base class that other, more interesting dominator analyses /// \brief Base class that other, more interesting dominator analyses
/// inherit from. /// inherit from.
template <class NodeT> template <class NodeT> class DominatorBase {
class DominatorBase {
protected: protected:
std::vector<NodeT*> Roots; std::vector<NodeT *> Roots;
const bool IsPostDominators; const bool IsPostDominators;
inline explicit DominatorBase(bool isPostDom) : inline explicit DominatorBase(bool isPostDom)
Roots(), IsPostDominators(isPostDom) {} : Roots(), IsPostDominators(isPostDom) {}
public:
public:
/// getRoots - Return the root blocks of the current CFG. This may include /// getRoots - Return the root blocks of the current CFG. This may include
/// multiple blocks if we are computing post dominators. For forward /// multiple blocks if we are computing post dominators. For forward
/// dominators, this will always be a single block (the entry node). /// dominators, this will always be a single block (the entry node).
/// ///
inline const std::vector<NodeT*> &getRoots() const { return Roots; } inline const std::vector<NodeT *> &getRoots() const { return Roots; }
/// isPostDominator - Returns true if analysis based of postdoms /// isPostDominator - Returns true if analysis based of postdoms
/// ///
bool isPostDominator() const { return IsPostDominators; } bool isPostDominator() const { return IsPostDominators; }
}; };
template <class NodeT> class DominatorTreeBase;
template<class NodeT> class DominatorTreeBase;
struct PostDominatorTree; struct PostDominatorTree;
/// \brief Base class for the actual dominator tree node. /// \brief Base class for the actual dominator tree node.
template <class NodeT> template <class NodeT> class DomTreeNodeBase {
class DomTreeNodeBase {
NodeT *TheBB; NodeT *TheBB;
DomTreeNodeBase<NodeT> *IDom; DomTreeNodeBase<NodeT> *IDom;
std::vector<DomTreeNodeBase<NodeT> *> Children; std::vector<DomTreeNodeBase<NodeT> *> Children;
mutable int DFSNumIn, DFSNumOut; mutable int DFSNumIn, DFSNumOut;
template<class N> friend class DominatorTreeBase; template <class N> friend class DominatorTreeBase;
friend struct PostDominatorTree; friend struct PostDominatorTree;
public: public:
typedef typename std::vector<DomTreeNodeBase<NodeT> *>::iterator iterator; typedef typename std::vector<DomTreeNodeBase<NodeT> *>::iterator iterator;
typedef typename std::vector<DomTreeNodeBase<NodeT> *>::const_iterator typedef typename std::vector<DomTreeNodeBase<NodeT> *>::const_iterator
const_iterator; const_iterator;
iterator begin() { return Children.begin(); } iterator begin() { return Children.begin(); }
iterator end() { return Children.end(); } iterator end() { return Children.end(); }
const_iterator begin() const { return Children.begin(); } const_iterator begin() const { return Children.begin(); }
const_iterator end() const { return Children.end(); } const_iterator end() const { return Children.end(); }
NodeT *getBlock() const { return TheBB; } NodeT *getBlock() const { return TheBB; }
DomTreeNodeBase<NodeT> *getIDom() const { return IDom; } DomTreeNodeBase<NodeT> *getIDom() const { return IDom; }
const std::vector<DomTreeNodeBase<NodeT>*> &getChildren() const { const std::vector<DomTreeNodeBase<NodeT> *> &getChildren() const {
return Children; return Children;
} }
DomTreeNodeBase(NodeT *BB, DomTreeNodeBase<NodeT> *iDom) DomTreeNodeBase(NodeT *BB, DomTreeNodeBase<NodeT> *iDom)
: TheBB(BB), IDom(iDom), DFSNumIn(-1), DFSNumOut(-1) { } : TheBB(BB), IDom(iDom), DFSNumIn(-1), DFSNumOut(-1) {}
DomTreeNodeBase<NodeT> *addChild(DomTreeNodeBase<NodeT> *C) { DomTreeNodeBase<NodeT> *addChild(DomTreeNodeBase<NodeT> *C) {
Children.push_back(C); Children.push_back(C);
return C; return C;
} }
size_t getNumChildren() const { size_t getNumChildren() const { return Children.size(); }
return Children.size();
}
void clearAllChildren() { void clearAllChildren() { Children.clear(); }
Children.clear();
}
bool compare(const DomTreeNodeBase<NodeT> *Other) const { bool compare(const DomTreeNodeBase<NodeT> *Other) const {
if (getNumChildren() != Other->getNumChildren()) if (getNumChildren() != Other->getNumChildren())
@ -118,8 +112,8 @@ public:
void setIDom(DomTreeNodeBase<NodeT> *NewIDom) { void setIDom(DomTreeNodeBase<NodeT> *NewIDom) {
assert(IDom && "No immediate dominator?"); assert(IDom && "No immediate dominator?");
if (IDom != NewIDom) { if (IDom != NewIDom) {
typename std::vector<DomTreeNodeBase<NodeT>*>::iterator I = typename std::vector<DomTreeNodeBase<NodeT> *>::iterator I =
std::find(IDom->Children.begin(), IDom->Children.end(), this); std::find(IDom->Children.begin(), IDom->Children.end(), this);
assert(I != IDom->Children.end() && assert(I != IDom->Children.end() &&
"Not in immediate dominator children set!"); "Not in immediate dominator children set!");
// I am no longer your child... // I am no longer your child...
@ -135,16 +129,17 @@ public:
/// not call them. /// not call them.
unsigned getDFSNumIn() const { return DFSNumIn; } unsigned getDFSNumIn() const { return DFSNumIn; }
unsigned getDFSNumOut() const { return DFSNumOut; } unsigned getDFSNumOut() const { return DFSNumOut; }
private: private:
// Return true if this node is dominated by other. Use this only if DFS info // Return true if this node is dominated by other. Use this only if DFS info
// is valid. // is valid.
bool DominatedBy(const DomTreeNodeBase<NodeT> *other) const { bool DominatedBy(const DomTreeNodeBase<NodeT> *other) const {
return this->DFSNumIn >= other->DFSNumIn && return this->DFSNumIn >= other->DFSNumIn &&
this->DFSNumOut <= other->DFSNumOut; this->DFSNumOut <= other->DFSNumOut;
} }
}; };
template<class NodeT> template <class NodeT>
inline raw_ostream &operator<<(raw_ostream &o, inline raw_ostream &operator<<(raw_ostream &o,
const DomTreeNodeBase<NodeT> *Node) { const DomTreeNodeBase<NodeT> *Node) {
if (Node->getBlock()) if (Node->getBlock())
@ -157,26 +152,26 @@ inline raw_ostream &operator<<(raw_ostream &o,
return o << "\n"; return o << "\n";
} }
template<class NodeT> template <class NodeT>
inline void PrintDomTree(const DomTreeNodeBase<NodeT> *N, raw_ostream &o, inline void PrintDomTree(const DomTreeNodeBase<NodeT> *N, raw_ostream &o,
unsigned Lev) { unsigned Lev) {
o.indent(2*Lev) << "[" << Lev << "] " << N; o.indent(2 * Lev) << "[" << Lev << "] " << N;
for (typename DomTreeNodeBase<NodeT>::const_iterator I = N->begin(), for (typename DomTreeNodeBase<NodeT>::const_iterator I = N->begin(),
E = N->end(); I != E; ++I) E = N->end();
PrintDomTree<NodeT>(*I, o, Lev+1); I != E; ++I)
PrintDomTree<NodeT>(*I, o, Lev + 1);
} }
// The calculate routine is provided in a separate header but referenced here. // The calculate routine is provided in a separate header but referenced here.
template<class FuncT, class N> template <class FuncT, class N>
void Calculate(DominatorTreeBase<typename GraphTraits<N>::NodeType>& DT, void Calculate(DominatorTreeBase<typename GraphTraits<N>::NodeType> &DT,
FuncT& F); FuncT &F);
/// \brief Core dominator tree base class. /// \brief Core dominator tree base class.
/// ///
/// This class is a generic template over graph nodes. It is instantiated for /// This class is a generic template over graph nodes. It is instantiated for
/// various graphs in the LLVM IR or in the code generator. /// various graphs in the LLVM IR or in the code generator.
template<class NodeT> template <class NodeT> class DominatorTreeBase : public DominatorBase<NodeT> {
class DominatorTreeBase : public DominatorBase<NodeT> {
bool dominatedBySlowTreeWalk(const DomTreeNodeBase<NodeT> *A, bool dominatedBySlowTreeWalk(const DomTreeNodeBase<NodeT> *A,
const DomTreeNodeBase<NodeT> *B) const { const DomTreeNodeBase<NodeT> *B) const {
assert(A != B); assert(A != B);
@ -185,12 +180,12 @@ class DominatorTreeBase : public DominatorBase<NodeT> {
const DomTreeNodeBase<NodeT> *IDom; const DomTreeNodeBase<NodeT> *IDom;
while ((IDom = B->getIDom()) != nullptr && IDom != A && IDom != B) while ((IDom = B->getIDom()) != nullptr && IDom != A && IDom != B)
B = IDom; // Walk up the tree B = IDom; // Walk up the tree
return IDom != nullptr; return IDom != nullptr;
} }
protected: protected:
typedef DenseMap<NodeT*, DomTreeNodeBase<NodeT>*> DomTreeNodeMapType; typedef DenseMap<NodeT *, DomTreeNodeBase<NodeT> *> DomTreeNodeMapType;
DomTreeNodeMapType DomTreeNodes; DomTreeNodeMapType DomTreeNodes;
DomTreeNodeBase<NodeT> *RootNode; DomTreeNodeBase<NodeT> *RootNode;
@ -206,17 +201,18 @@ protected:
InfoRec() : DFSNum(0), Parent(0), Semi(0), Label(nullptr) {} InfoRec() : DFSNum(0), Parent(0), Semi(0), Label(nullptr) {}
}; };
DenseMap<NodeT*, NodeT*> IDoms; DenseMap<NodeT *, NodeT *> IDoms;
// Vertex - Map the DFS number to the NodeT* // Vertex - Map the DFS number to the NodeT*
std::vector<NodeT*> Vertex; std::vector<NodeT *> Vertex;
// Info - Collection of information used during the computation of idoms. // Info - Collection of information used during the computation of idoms.
DenseMap<NodeT*, InfoRec> Info; DenseMap<NodeT *, InfoRec> Info;
void reset() { void reset() {
for (typename DomTreeNodeMapType::iterator I = this->DomTreeNodes.begin(), for (typename DomTreeNodeMapType::iterator I = this->DomTreeNodes.begin(),
E = DomTreeNodes.end(); I != E; ++I) E = DomTreeNodes.end();
I != E; ++I)
delete I->second; delete I->second;
DomTreeNodes.clear(); DomTreeNodes.clear();
IDoms.clear(); IDoms.clear();
@ -227,27 +223,29 @@ protected:
// NewBB is split and now it has one successor. Update dominator tree to // NewBB is split and now it has one successor. Update dominator tree to
// reflect this change. // reflect this change.
template<class N, class GraphT> template <class N, class GraphT>
void Split(DominatorTreeBase<typename GraphT::NodeType>& DT, void Split(DominatorTreeBase<typename GraphT::NodeType> &DT,
typename GraphT::NodeType* NewBB) { typename GraphT::NodeType *NewBB) {
assert(std::distance(GraphT::child_begin(NewBB), assert(std::distance(GraphT::child_begin(NewBB),
GraphT::child_end(NewBB)) == 1 && GraphT::child_end(NewBB)) == 1 &&
"NewBB should have a single successor!"); "NewBB should have a single successor!");
typename GraphT::NodeType* NewBBSucc = *GraphT::child_begin(NewBB); typename GraphT::NodeType *NewBBSucc = *GraphT::child_begin(NewBB);
std::vector<typename GraphT::NodeType*> PredBlocks; std::vector<typename GraphT::NodeType *> PredBlocks;
typedef GraphTraits<Inverse<N> > InvTraits; typedef GraphTraits<Inverse<N>> InvTraits;
for (typename InvTraits::ChildIteratorType PI = for (typename InvTraits::ChildIteratorType
InvTraits::child_begin(NewBB), PI = InvTraits::child_begin(NewBB),
PE = InvTraits::child_end(NewBB); PI != PE; ++PI) PE = InvTraits::child_end(NewBB);
PI != PE; ++PI)
PredBlocks.push_back(*PI); PredBlocks.push_back(*PI);
assert(!PredBlocks.empty() && "No predblocks?"); assert(!PredBlocks.empty() && "No predblocks?");
bool NewBBDominatesNewBBSucc = true; bool NewBBDominatesNewBBSucc = true;
for (typename InvTraits::ChildIteratorType PI = for (typename InvTraits::ChildIteratorType
InvTraits::child_begin(NewBBSucc), PI = InvTraits::child_begin(NewBBSucc),
E = InvTraits::child_end(NewBBSucc); PI != E; ++PI) { E = InvTraits::child_end(NewBBSucc);
PI != E; ++PI) {
typename InvTraits::NodeType *ND = *PI; typename InvTraits::NodeType *ND = *PI;
if (ND != NewBB && !DT.dominates(NewBBSucc, ND) && if (ND != NewBB && !DT.dominates(NewBBSucc, ND) &&
DT.isReachableFromEntry(ND)) { DT.isReachableFromEntry(ND)) {
@ -290,7 +288,7 @@ protected:
public: public:
explicit DominatorTreeBase(bool isPostDom) explicit DominatorTreeBase(bool isPostDom)
: DominatorBase<NodeT>(isPostDom), DFSInfoValid(false), SlowQueries(0) {} : DominatorBase<NodeT>(isPostDom), DFSInfoValid(false), SlowQueries(0) {}
virtual ~DominatorTreeBase() { reset(); } virtual ~DominatorTreeBase() { reset(); }
/// compare - Return false if the other dominator tree base matches this /// compare - Return false if the other dominator tree base matches this
@ -302,15 +300,17 @@ public:
return true; return true;
for (typename DomTreeNodeMapType::const_iterator for (typename DomTreeNodeMapType::const_iterator
I = this->DomTreeNodes.begin(), I = this->DomTreeNodes.begin(),
E = this->DomTreeNodes.end(); I != E; ++I) { E = this->DomTreeNodes.end();
I != E; ++I) {
NodeT *BB = I->first; NodeT *BB = I->first;
typename DomTreeNodeMapType::const_iterator OI = OtherDomTreeNodes.find(BB); typename DomTreeNodeMapType::const_iterator OI =
OtherDomTreeNodes.find(BB);
if (OI == OtherDomTreeNodes.end()) if (OI == OtherDomTreeNodes.end())
return true; return true;
DomTreeNodeBase<NodeT>* MyNd = I->second; DomTreeNodeBase<NodeT> *MyNd = I->second;
DomTreeNodeBase<NodeT>* OtherNd = OI->second; DomTreeNodeBase<NodeT> *OtherNd = OI->second;
if (MyNd->compare(OtherNd)) if (MyNd->compare(OtherNd))
return true; return true;
@ -374,7 +374,7 @@ public:
/// isReachableFromEntry - Return true if A is dominated by the entry /// isReachableFromEntry - Return true if A is dominated by the entry
/// block of the function containing it. /// block of the function containing it.
bool isReachableFromEntry(const NodeT* A) const { bool isReachableFromEntry(const NodeT *A) const {
assert(!this->isPostDominator() && assert(!this->isPostDominator() &&
"This is not implemented for post dominators"); "This is not implemented for post dominators");
return isReachableFromEntry(getNode(const_cast<NodeT *>(A))); return isReachableFromEntry(getNode(const_cast<NodeT *>(A)));
@ -471,7 +471,7 @@ public:
} }
// Collect NodeA dominators set. // Collect NodeA dominators set.
SmallPtrSet<DomTreeNodeBase<NodeT>*, 16> NodeADoms; SmallPtrSet<DomTreeNodeBase<NodeT> *, 16> NodeADoms;
NodeADoms.insert(NodeA); NodeADoms.insert(NodeA);
DomTreeNodeBase<NodeT> *IDomA = NodeA->getIDom(); DomTreeNodeBase<NodeT> *IDomA = NodeA->getIDom();
while (IDomA) { while (IDomA) {
@ -511,7 +511,7 @@ public:
assert(IDomNode && "Not immediate dominator specified for block!"); assert(IDomNode && "Not immediate dominator specified for block!");
DFSInfoValid = false; DFSInfoValid = false;
return DomTreeNodes[BB] = return DomTreeNodes[BB] =
IDomNode->addChild(new DomTreeNodeBase<NodeT>(BB, IDomNode)); IDomNode->addChild(new DomTreeNodeBase<NodeT>(BB, IDomNode));
} }
/// changeImmediateDominator - This method is used to update the dominator /// changeImmediateDominator - This method is used to update the dominator
@ -536,11 +536,11 @@ public:
assert(Node && "Removing node that isn't in dominator tree."); assert(Node && "Removing node that isn't in dominator tree.");
assert(Node->getChildren().empty() && "Node is not a leaf node."); assert(Node->getChildren().empty() && "Node is not a leaf node.");
// Remove node from immediate dominator's children list. // Remove node from immediate dominator's children list.
DomTreeNodeBase<NodeT> *IDom = Node->getIDom(); DomTreeNodeBase<NodeT> *IDom = Node->getIDom();
if (IDom) { if (IDom) {
typename std::vector<DomTreeNodeBase<NodeT>*>::iterator I = typename std::vector<DomTreeNodeBase<NodeT> *>::iterator I =
std::find(IDom->Children.begin(), IDom->Children.end(), Node); std::find(IDom->Children.begin(), IDom->Children.end(), Node);
assert(I != IDom->Children.end() && assert(I != IDom->Children.end() &&
"Not in immediate dominator children set!"); "Not in immediate dominator children set!");
// I am no longer your child... // I am no longer your child...
@ -561,11 +561,12 @@ public:
/// splitBlock - BB is split and now it has one successor. Update dominator /// splitBlock - BB is split and now it has one successor. Update dominator
/// tree to reflect this change. /// tree to reflect this change.
void splitBlock(NodeT* NewBB) { void splitBlock(NodeT *NewBB) {
if (this->IsPostDominators) if (this->IsPostDominators)
this->Split<Inverse<NodeT*>, GraphTraits<Inverse<NodeT*> > >(*this, NewBB); this->Split<Inverse<NodeT *>, GraphTraits<Inverse<NodeT *>>>(*this,
NewBB);
else else
this->Split<NodeT*, GraphTraits<NodeT*> >(*this, NewBB); this->Split<NodeT *, GraphTraits<NodeT *>>(*this, NewBB);
} }
/// print - Convert to human readable form /// print - Convert to human readable form
@ -586,28 +587,27 @@ public:
} }
protected: protected:
template<class GraphT> template <class GraphT>
friend typename GraphT::NodeType* Eval( friend typename GraphT::NodeType *
DominatorTreeBase<typename GraphT::NodeType>& DT, Eval(DominatorTreeBase<typename GraphT::NodeType> &DT,
typename GraphT::NodeType* V, typename GraphT::NodeType *V, unsigned LastLinked);
unsigned LastLinked);
template<class GraphT> template <class GraphT>
friend unsigned DFSPass(DominatorTreeBase<typename GraphT::NodeType>& DT, friend unsigned DFSPass(DominatorTreeBase<typename GraphT::NodeType> &DT,
typename GraphT::NodeType* V, typename GraphT::NodeType *V, unsigned N);
unsigned N);
template<class FuncT, class N> template <class FuncT, class N>
friend void Calculate(DominatorTreeBase<typename GraphTraits<N>::NodeType>& DT, friend void
FuncT& F); Calculate(DominatorTreeBase<typename GraphTraits<N>::NodeType> &DT, FuncT &F);
/// updateDFSNumbers - Assign In and Out numbers to the nodes while walking /// updateDFSNumbers - Assign In and Out numbers to the nodes while walking
/// dominator tree in dfs order. /// dominator tree in dfs order.
void updateDFSNumbers() const { void updateDFSNumbers() const {
unsigned DFSNum = 0; unsigned DFSNum = 0;
SmallVector<std::pair<const DomTreeNodeBase<NodeT>*, SmallVector<std::pair<const DomTreeNodeBase<NodeT> *,
typename DomTreeNodeBase<NodeT>::const_iterator>, 32> WorkStack; typename DomTreeNodeBase<NodeT>::const_iterator>,
32> WorkStack;
const DomTreeNodeBase<NodeT> *ThisRoot = getRootNode(); const DomTreeNodeBase<NodeT> *ThisRoot = getRootNode();
@ -624,7 +624,7 @@ protected:
while (!WorkStack.empty()) { while (!WorkStack.empty()) {
const DomTreeNodeBase<NodeT> *Node = WorkStack.back().first; const DomTreeNodeBase<NodeT> *Node = WorkStack.back().first;
typename DomTreeNodeBase<NodeT>::const_iterator ChildIt = typename DomTreeNodeBase<NodeT>::const_iterator ChildIt =
WorkStack.back().second; WorkStack.back().second;
// If we visited all of the children of this node, "recurse" back up the // If we visited all of the children of this node, "recurse" back up the
// stack setting the DFOutNum. // stack setting the DFOutNum.
@ -662,19 +662,14 @@ protected:
return this->DomTreeNodes[BB] = IDomNode->addChild(C); return this->DomTreeNodes[BB] = IDomNode->addChild(C);
} }
inline NodeT *getIDom(NodeT *BB) const { inline NodeT *getIDom(NodeT *BB) const { return IDoms.lookup(BB); }
return IDoms.lookup(BB);
}
inline void addRoot(NodeT* BB) { inline void addRoot(NodeT *BB) { this->Roots.push_back(BB); }
this->Roots.push_back(BB);
}
public: public:
/// recalculate - compute a dominator tree for the given function /// recalculate - compute a dominator tree for the given function
template<class FT> template <class FT> void recalculate(FT &F) {
void recalculate(FT& F) { typedef GraphTraits<FT *> TraitsTy;
typedef GraphTraits<FT*> TraitsTy;
reset(); reset();
this->Vertex.push_back(nullptr); this->Vertex.push_back(nullptr);
@ -685,27 +680,29 @@ public:
this->IDoms[entry] = nullptr; this->IDoms[entry] = nullptr;
this->DomTreeNodes[entry] = nullptr; this->DomTreeNodes[entry] = nullptr;
Calculate<FT, NodeT*>(*this, F); Calculate<FT, NodeT *>(*this, F);
} else { } else {
// Initialize the roots list // Initialize the roots list
for (typename TraitsTy::nodes_iterator I = TraitsTy::nodes_begin(&F), for (typename TraitsTy::nodes_iterator I = TraitsTy::nodes_begin(&F),
E = TraitsTy::nodes_end(&F); I != E; ++I) { E = TraitsTy::nodes_end(&F);
I != E; ++I) {
if (TraitsTy::child_begin(I) == TraitsTy::child_end(I)) if (TraitsTy::child_begin(I) == TraitsTy::child_end(I))
addRoot(I); addRoot(I);
// Prepopulate maps so that we don't get iterator invalidation issues later. // Prepopulate maps so that we don't get iterator invalidation issues
// later.
this->IDoms[I] = nullptr; this->IDoms[I] = nullptr;
this->DomTreeNodes[I] = nullptr; this->DomTreeNodes[I] = nullptr;
} }
Calculate<FT, Inverse<NodeT*> >(*this, F); Calculate<FT, Inverse<NodeT *>>(*this, F);
} }
} }
}; };
// These two functions are declared out of line as a workaround for building // These two functions are declared out of line as a workaround for building
// with old (< r147295) versions of clang because of pr11642. // with old (< r147295) versions of clang because of pr11642.
template<class NodeT> template <class NodeT>
bool DominatorTreeBase<NodeT>::dominates(const NodeT *A, const NodeT *B) const { bool DominatorTreeBase<NodeT>::dominates(const NodeT *A, const NodeT *B) const {
if (A == B) if (A == B)
return true; return true;
@ -716,9 +713,9 @@ bool DominatorTreeBase<NodeT>::dominates(const NodeT *A, const NodeT *B) const {
return dominates(getNode(const_cast<NodeT *>(A)), return dominates(getNode(const_cast<NodeT *>(A)),
getNode(const_cast<NodeT *>(B))); getNode(const_cast<NodeT *>(B)));
} }
template<class NodeT> template <class NodeT>
bool bool DominatorTreeBase<NodeT>::properlyDominates(const NodeT *A,
DominatorTreeBase<NodeT>::properlyDominates(const NodeT *A, const NodeT *B) const { const NodeT *B) const {
if (A == B) if (A == B)
return false; return false;