#ifndef LLVM_CODEGEN_MACHINEDOMINATORS_H
#define LLVM_CODEGEN_MACHINEDOMINATORS_H
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBundleIterator.h"
#include "llvm/Support/GenericDomTree.h"
#include "llvm/Support/GenericDomTreeConstruction.h"
#include <cassert>
#include <memory>
namespace llvm {
class AnalysisUsage;
class MachineFunction;
class Module;
class raw_ostream;
template <>
inline void DominatorTreeBase<MachineBasicBlock, false>::addRoot(
MachineBasicBlock *MBB) {
this->Roots.push_back(MBB);
}
extern template class DomTreeNodeBase<MachineBasicBlock>;
extern template class DominatorTreeBase<MachineBasicBlock, false>; extern template class DominatorTreeBase<MachineBasicBlock, true>;
using MachineDomTree = DomTreeBase<MachineBasicBlock>;
using MachineDomTreeNode = DomTreeNodeBase<MachineBasicBlock>;
class MachineDominatorTree : public MachineFunctionPass {
struct CriticalEdge {
MachineBasicBlock *FromBB;
MachineBasicBlock *ToBB;
MachineBasicBlock *NewBB;
};
mutable SmallVector<CriticalEdge, 32> CriticalEdgesToSplit;
mutable SmallSet<MachineBasicBlock *, 32> NewBBs;
std::unique_ptr<MachineDomTree> DT;
void applySplitCriticalEdges() const;
public:
static char ID;
MachineDominatorTree();
explicit MachineDominatorTree(MachineFunction &MF) : MachineFunctionPass(ID) {
calculate(MF);
}
MachineDomTree &getBase() {
if (!DT)
DT.reset(new MachineDomTree());
applySplitCriticalEdges();
return *DT;
}
void getAnalysisUsage(AnalysisUsage &AU) const override;
MachineBasicBlock *getRoot() const {
applySplitCriticalEdges();
return DT->getRoot();
}
MachineDomTreeNode *getRootNode() const {
applySplitCriticalEdges();
return DT->getRootNode();
}
bool runOnMachineFunction(MachineFunction &F) override;
void calculate(MachineFunction &F);
bool dominates(const MachineDomTreeNode *A,
const MachineDomTreeNode *B) const {
applySplitCriticalEdges();
return DT->dominates(A, B);
}
void getDescendants(MachineBasicBlock *A,
SmallVectorImpl<MachineBasicBlock *> &Result) {
applySplitCriticalEdges();
DT->getDescendants(A, Result);
}
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;
}
bool properlyDominates(const MachineDomTreeNode *A,
const MachineDomTreeNode *B) const {
applySplitCriticalEdges();
return DT->properlyDominates(A, B);
}
bool properlyDominates(const MachineBasicBlock *A,
const MachineBasicBlock *B) const {
applySplitCriticalEdges();
return DT->properlyDominates(A, B);
}
MachineBasicBlock *findNearestCommonDominator(MachineBasicBlock *A,
MachineBasicBlock *B) {
applySplitCriticalEdges();
return DT->findNearestCommonDominator(A, B);
}
MachineDomTreeNode *operator[](MachineBasicBlock *BB) const {
applySplitCriticalEdges();
return DT->getNode(BB);
}
MachineDomTreeNode *getNode(MachineBasicBlock *BB) const {
applySplitCriticalEdges();
return DT->getNode(BB);
}
MachineDomTreeNode *addNewBlock(MachineBasicBlock *BB,
MachineBasicBlock *DomBB) {
applySplitCriticalEdges();
return DT->addNewBlock(BB, DomBB);
}
void changeImmediateDominator(MachineBasicBlock *N,
MachineBasicBlock *NewIDom) {
applySplitCriticalEdges();
DT->changeImmediateDominator(N, NewIDom);
}
void changeImmediateDominator(MachineDomTreeNode *N,
MachineDomTreeNode *NewIDom) {
applySplitCriticalEdges();
DT->changeImmediateDominator(N, NewIDom);
}
void eraseNode(MachineBasicBlock *BB) {
applySplitCriticalEdges();
DT->eraseNode(BB);
}
void splitBlock(MachineBasicBlock* NewBB) {
applySplitCriticalEdges();
DT->splitBlock(NewBB);
}
bool isReachableFromEntry(const MachineBasicBlock *A) {
applySplitCriticalEdges();
return DT->isReachableFromEntry(A);
}
void releaseMemory() override;
void verifyAnalysis() const 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({FromBB, ToBB, NewBB});
}
};
template <class Node, class ChildIterator>
struct MachineDomTreeGraphTraitsBase {
using NodeRef = Node *;
using ChildIteratorType = ChildIterator;
static NodeRef getEntryNode(NodeRef N) { return N; }
static ChildIteratorType child_begin(NodeRef N) { return N->begin(); }
static ChildIteratorType child_end(NodeRef N) { return N->end(); }
};
template <class T> struct GraphTraits;
template <>
struct GraphTraits<MachineDomTreeNode *>
: public MachineDomTreeGraphTraitsBase<MachineDomTreeNode,
MachineDomTreeNode::const_iterator> {
};
template <>
struct GraphTraits<const MachineDomTreeNode *>
: public MachineDomTreeGraphTraitsBase<const MachineDomTreeNode,
MachineDomTreeNode::const_iterator> {
};
template <> struct GraphTraits<MachineDominatorTree*>
: public GraphTraits<MachineDomTreeNode *> {
static NodeRef getEntryNode(MachineDominatorTree *DT) {
return DT->getRootNode();
}
};
}
#endif