MachineDominators.h [plain text]
#ifndef LLVM_CODEGEN_MACHINEDOMINATORS_H
#define LLVM_CODEGEN_MACHINEDOMINATORS_H
#include "llvm/ADT/SmallSet.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/Support/GenericDomTree.h"
#include "llvm/Support/GenericDomTreeConstruction.h"
namespace llvm {
template<>
inline void DominatorTreeBase<MachineBasicBlock>::addRoot(MachineBasicBlock* MBB) {
this->Roots.push_back(MBB);
}
EXTERN_TEMPLATE_INSTANTIATION(class DomTreeNodeBase<MachineBasicBlock>);
EXTERN_TEMPLATE_INSTANTIATION(class DominatorTreeBase<MachineBasicBlock>);
typedef DomTreeNodeBase<MachineBasicBlock> MachineDomTreeNode;
class MachineDominatorTree : public MachineFunctionPass {
struct CriticalEdge {
MachineBasicBlock *FromBB;
MachineBasicBlock *ToBB;
MachineBasicBlock *NewBB;
CriticalEdge(MachineBasicBlock *FromBB, MachineBasicBlock *ToBB,
MachineBasicBlock *NewBB)
: FromBB(FromBB), ToBB(ToBB), NewBB(NewBB) {}
};
mutable SmallVector<CriticalEdge, 32> CriticalEdgesToSplit;
mutable SmallSet<MachineBasicBlock *, 32> NewBBs;
void applySplitCriticalEdges() const {
if (CriticalEdgesToSplit.empty())
return;
SmallVector<bool, 32> IsNewIDom;
IsNewIDom.resize(CriticalEdgesToSplit.size());
size_t Idx = 0;
for (CriticalEdge &Edge : CriticalEdgesToSplit) {
MachineBasicBlock *Succ = Edge.ToBB;
MachineDomTreeNode *SucccDTNode = DT->getNode(Succ);
IsNewIDom[Idx] = true;
for (MachineBasicBlock *PredBB : Succ->predecessors()) {
if (PredBB == Edge.NewBB)
continue;
if (NewBBs.count(PredBB)) {
assert(PredBB->pred_size() == 1 && "A basic block resulting from a "
"critical edge split has more "
"than one predecessor!");
PredBB = *PredBB->pred_begin();
}
if (!DT->dominates(SucccDTNode, DT->getNode(PredBB))) {
IsNewIDom[Idx] = false;
break;
}
}
++Idx;
}
Idx = 0;
for (CriticalEdge &Edge : CriticalEdgesToSplit) {
MachineDomTreeNode *NewDTNode = DT->addNewBlock(Edge.NewBB, Edge.FromBB);
MachineDomTreeNode *SucccDTNode = DT->getNode(Edge.ToBB);
if (IsNewIDom[Idx])
DT->changeImmediateDominator(SucccDTNode, NewDTNode);
++Idx;
}
NewBBs.clear();
CriticalEdgesToSplit.clear();
}
public:
static char ID; DominatorTreeBase<MachineBasicBlock>* DT;
MachineDominatorTree();
~MachineDominatorTree();
DominatorTreeBase<MachineBasicBlock> &getBase() {
applySplitCriticalEdges();
return *DT;
}
void getAnalysisUsage(AnalysisUsage &AU) const override;
inline const std::vector<MachineBasicBlock*> &getRoots() const {
applySplitCriticalEdges();
return DT->getRoots();
}
inline MachineBasicBlock *getRoot() const {
applySplitCriticalEdges();
return DT->getRoot();
}
inline MachineDomTreeNode *getRootNode() const {
applySplitCriticalEdges();
return DT->getRootNode();
}
bool runOnMachineFunction(MachineFunction &F) override;
inline bool dominates(const MachineDomTreeNode* A,
const MachineDomTreeNode* B) const {
applySplitCriticalEdges();
return DT->dominates(A, B);
}
inline bool dominates(const MachineBasicBlock* A,
const MachineBasicBlock* B) const {
applySplitCriticalEdges();
return DT->dominates(A, B);
}
bool dominates(const MachineInstr *A, const MachineInstr *B) const {
applySplitCriticalEdges();
const MachineBasicBlock *BBA = A->getParent(), *BBB = B->getParent();
if (BBA != BBB) return DT->dominates(BBA, BBB);
MachineBasicBlock::const_iterator I = BBA->begin();
for (; &*I != A && &*I != B; ++I)
;
return &*I == A;
}
inline bool properlyDominates(const MachineDomTreeNode* A,
const MachineDomTreeNode* B) const {
applySplitCriticalEdges();
return DT->properlyDominates(A, B);
}
inline bool properlyDominates(const MachineBasicBlock* A,
const MachineBasicBlock* B) const {
applySplitCriticalEdges();
return DT->properlyDominates(A, B);
}
inline MachineBasicBlock *findNearestCommonDominator(MachineBasicBlock *A,
MachineBasicBlock *B) {
applySplitCriticalEdges();
return DT->findNearestCommonDominator(A, B);
}
inline MachineDomTreeNode *operator[](MachineBasicBlock *BB) const {
applySplitCriticalEdges();
return DT->getNode(BB);
}
inline MachineDomTreeNode *getNode(MachineBasicBlock *BB) const {
applySplitCriticalEdges();
return DT->getNode(BB);
}
inline MachineDomTreeNode *addNewBlock(MachineBasicBlock *BB,
MachineBasicBlock *DomBB) {
applySplitCriticalEdges();
return DT->addNewBlock(BB, DomBB);
}
inline void changeImmediateDominator(MachineBasicBlock *N,
MachineBasicBlock* NewIDom) {
applySplitCriticalEdges();
DT->changeImmediateDominator(N, NewIDom);
}
inline void changeImmediateDominator(MachineDomTreeNode *N,
MachineDomTreeNode* NewIDom) {
applySplitCriticalEdges();
DT->changeImmediateDominator(N, NewIDom);
}
inline void eraseNode(MachineBasicBlock *BB) {
applySplitCriticalEdges();
DT->eraseNode(BB);
}
inline void splitBlock(MachineBasicBlock* NewBB) {
applySplitCriticalEdges();
DT->splitBlock(NewBB);
}
bool isReachableFromEntry(const MachineBasicBlock *A) {
applySplitCriticalEdges();
return DT->isReachableFromEntry(A);
}
void releaseMemory() override;
void print(raw_ostream &OS, const Module*) const override;
void recordSplitCriticalEdge(MachineBasicBlock *FromBB,
MachineBasicBlock *ToBB,
MachineBasicBlock *NewBB) {
bool Inserted = NewBBs.insert(NewBB).second;
(void)Inserted;
assert(Inserted &&
"A basic block inserted via edge splitting cannot appear twice");
CriticalEdgesToSplit.push_back(CriticalEdge(FromBB, ToBB, NewBB));
}
};
template<class T> struct GraphTraits;
template <> struct GraphTraits<MachineDomTreeNode *> {
typedef MachineDomTreeNode 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();
}
};
template <> struct GraphTraits<MachineDominatorTree*>
: public GraphTraits<MachineDomTreeNode *> {
static NodeType *getEntryNode(MachineDominatorTree *DT) {
return DT->getRootNode();
}
};
}
#endif