//===- llvm/Analysis/Dominators.h - Dominator Info Calculation --*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the DominatorTree class, which provides fast and efficient
// dominance queries.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_DOMINATORS_H
#define LLVM_ANALYSIS_DOMINATORS_H
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/ADT/GraphTraits.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/IR/Function.h"
#include "llvm/Pass.h"
#include "llvm/Support/CFG.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
namespace llvm {
//===----------------------------------------------------------------------===//
/// DominatorBase - Base class that other, more interesting dominator analyses
/// inherit from.
///
template <class NodeT>
class DominatorBase {
protected:
std::vector<NodeT*> Roots;
const bool IsPostDominators;
inline explicit DominatorBase(bool isPostDom) :
Roots(), IsPostDominators(isPostDom) {}
public:
/// getRoots - Return the root blocks of the current CFG. This may include
/// multiple blocks if we are computing post dominators. For forward
/// dominators, this will always be a single block (the entry node).
///
inline const std::vector<NodeT*> &getRoots() const { return Roots; }
/// isPostDominator - Returns true if analysis based of postdoms
///
bool isPostDominator() const { return IsPostDominators; }
};
//===----------------------------------------------------------------------===//
// DomTreeNode - Dominator Tree Node
template<class NodeT> class DominatorTreeBase;
struct PostDominatorTree;
class MachineBasicBlock;
template <class NodeT>
class DomTreeNodeBase {
NodeT *TheBB;
DomTreeNodeBase<NodeT> *IDom;
std::vector<DomTreeNodeBase<NodeT> *> Children;
int DFSNumIn, DFSNumOut;
template<class N> friend class DominatorTreeBase;
friend struct PostDominatorTree;
public:
typedef typename std::vector<DomTreeNodeBase<NodeT> *>::iterator iterator;
typedef typename std::vector<DomTreeNodeBase<NodeT> *>::const_iterator
const_iterator;
iterator begin() { return Children.begin(); }
iterator end() { return Children.end(); }
const_iterator begin() const { return Children.begin(); }
const_iterator end() const { return Children.end(); }
NodeT *getBlock() const { return TheBB; }
DomTreeNodeBase<NodeT> *getIDom() const { return IDom; }
const std::vector<DomTreeNodeBase<NodeT>*> &getChildren() const {
return Children;
}
DomTreeNodeBase(NodeT *BB, DomTreeNodeBase<NodeT> *iDom)
: TheBB(BB), IDom(iDom), DFSNumIn(-1), DFSNumOut(-1) { }
DomTreeNodeBase<NodeT> *addChild(DomTreeNodeBase<NodeT> *C) {
Children.push_back(C);
return C;
}
size_t getNumChildren() const {
return Children.size();
}
void clearAllChildren() {
Children.clear();
}
bool compare(const DomTreeNodeBase<NodeT> *Other) const {
if (getNumChildren() != Other->getNumChildren())
return true;
SmallPtrSet<const NodeT *, 4> OtherChildren;
for (const_iterator I = Other->begin(), E = Other->end(); I != E; ++I) {
const NodeT *Nd = (*I)->getBlock();
OtherChildren.insert(Nd);
}
for (const_iterator I = begin(), E = end(); I != E; ++I) {
const NodeT *N = (*I)->getBlock();
if (OtherChildren.count(N) == 0)
return true;
}
return false;
}
void setIDom(DomTreeNodeBase<NodeT> *NewIDom) {
assert(IDom && "No immediate dominator?");
if (IDom != NewIDom) {
typename std::vector<DomTreeNodeBase<NodeT>*>::iterator I =
std::find(IDom->Children.begin(), IDom->Children.end(), this);
assert(I != IDom->Children.end() &&
"Not in immediate dominator children set!");
// I am no longer your child...
IDom->Children.erase(I);
// Switch to new dominator
IDom = NewIDom;
IDom->Children.push_back(this);
}
}
/// getDFSNumIn/getDFSNumOut - These are an internal implementation detail, do
/// not call them.
unsigned getDFSNumIn() const { return DFSNumIn; }
unsigned getDFSNumOut() const { return DFSNumOut; }
private:
// Return true if this node is dominated by other. Use this only if DFS info
// is valid.
bool DominatedBy(const DomTreeNodeBase<NodeT> *other) const {