[PM] Fix the const-correctness of the generic DominatorTreeBase to

support notionally const queries even though they may trigger DFS
numbering updates.

The updating of DFS numbers and tracking of slow queries do not mutate
the observable state of the domtree. They should be const to
differentiate them from the APIs which mutate the tree directly to do
incremental updates.

This will make it possible in a world where the DominatorTree is not
a pass but merely the result of running a pass to derive DominatorTree
from the base class as it was originally designed, removing a huge
duplication of API in DominatorTree.

llvm-svn: 199101
This commit is contained in:
Chandler Carruth 2014-01-13 11:58:34 +00:00
parent 2192505190
commit db9120a037
1 changed files with 16 additions and 16 deletions

View File

@ -65,7 +65,7 @@ class DomTreeNodeBase {
NodeT *TheBB; NodeT *TheBB;
DomTreeNodeBase<NodeT> *IDom; DomTreeNodeBase<NodeT> *IDom;
std::vector<DomTreeNodeBase<NodeT> *> Children; std::vector<DomTreeNodeBase<NodeT> *> Children;
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;
@ -197,8 +197,8 @@ protected:
DomTreeNodeMapType DomTreeNodes; DomTreeNodeMapType DomTreeNodes;
DomTreeNodeBase<NodeT> *RootNode; DomTreeNodeBase<NodeT> *RootNode;
bool DFSInfoValid; mutable bool DFSInfoValid;
unsigned int SlowQueries; mutable unsigned int SlowQueries;
// Information record used during immediate dominators computation. // Information record used during immediate dominators computation.
struct InfoRec { struct InfoRec {
unsigned DFSNum; unsigned DFSNum;
@ -361,7 +361,7 @@ public:
/// Note that this is not a constant time operation! /// Note that this is not a constant time operation!
/// ///
bool properlyDominates(const DomTreeNodeBase<NodeT> *A, bool properlyDominates(const DomTreeNodeBase<NodeT> *A,
const DomTreeNodeBase<NodeT> *B) { const DomTreeNodeBase<NodeT> *B) const {
if (A == 0 || B == 0) if (A == 0 || B == 0)
return false; return false;
if (A == B) if (A == B)
@ -369,7 +369,7 @@ public:
return dominates(A, B); return dominates(A, B);
} }
bool properlyDominates(const NodeT *A, const NodeT *B); bool properlyDominates(const NodeT *A, const NodeT *B) const;
/// 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.
@ -387,7 +387,7 @@ public:
/// constant time operation! /// constant time operation!
/// ///
inline bool dominates(const DomTreeNodeBase<NodeT> *A, inline bool dominates(const DomTreeNodeBase<NodeT> *A,
const DomTreeNodeBase<NodeT> *B) { const DomTreeNodeBase<NodeT> *B) const {
// A node trivially dominates itself. // A node trivially dominates itself.
if (B == A) if (B == A)
return true; return true;
@ -422,7 +422,7 @@ public:
return dominatedBySlowTreeWalk(A, B); return dominatedBySlowTreeWalk(A, B);
} }
bool dominates(const NodeT *A, const NodeT *B); bool dominates(const NodeT *A, const NodeT *B) const;
NodeT *getRoot() const { NodeT *getRoot() const {
assert(this->Roots.size() == 1 && "Should always have entry node!"); assert(this->Roots.size() == 1 && "Should always have entry node!");
@ -587,13 +587,13 @@ protected:
/// 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() { void updateDFSNumbers() const {
unsigned DFSNum = 0; unsigned DFSNum = 0;
SmallVector<std::pair<DomTreeNodeBase<NodeT>*, SmallVector<std::pair<const DomTreeNodeBase<NodeT>*,
typename DomTreeNodeBase<NodeT>::iterator>, 32> WorkStack; typename DomTreeNodeBase<NodeT>::const_iterator>, 32> WorkStack;
DomTreeNodeBase<NodeT> *ThisRoot = getRootNode(); const DomTreeNodeBase<NodeT> *ThisRoot = getRootNode();
if (!ThisRoot) if (!ThisRoot)
return; return;
@ -606,8 +606,8 @@ protected:
ThisRoot->DFSNumIn = DFSNum++; ThisRoot->DFSNumIn = DFSNum++;
while (!WorkStack.empty()) { while (!WorkStack.empty()) {
DomTreeNodeBase<NodeT> *Node = WorkStack.back().first; const DomTreeNodeBase<NodeT> *Node = WorkStack.back().first;
typename DomTreeNodeBase<NodeT>::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
@ -617,7 +617,7 @@ protected:
WorkStack.pop_back(); WorkStack.pop_back();
} else { } else {
// Otherwise, recursively visit this child. // Otherwise, recursively visit this child.
DomTreeNodeBase<NodeT> *Child = *ChildIt; const DomTreeNodeBase<NodeT> *Child = *ChildIt;
++WorkStack.back().second; ++WorkStack.back().second;
WorkStack.push_back(std::make_pair(Child, Child->begin())); WorkStack.push_back(std::make_pair(Child, Child->begin()));
@ -690,7 +690,7 @@ public:
// 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) { bool DominatorTreeBase<NodeT>::dominates(const NodeT *A, const NodeT *B) const {
if (A == B) if (A == B)
return true; return true;
@ -702,7 +702,7 @@ bool DominatorTreeBase<NodeT>::dominates(const NodeT *A, const NodeT *B) {
} }
template<class NodeT> template<class NodeT>
bool bool
DominatorTreeBase<NodeT>::properlyDominates(const NodeT *A, const NodeT *B) { DominatorTreeBase<NodeT>::properlyDominates(const NodeT *A, const NodeT *B) const {
if (A == B) if (A == B)
return false; return false;