mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-22 10:29:35 +00:00
trees into the Support library. These are all expressed in terms of the generic GraphTraits and CFG, with no reliance on any concrete IR types. Putting them in support clarifies that and makes the fact that the static analyzer in Clang uses them much more sane. When moving the Dominators.h file into the IR library I claimed that this was the right home for it but not something I planned to work on. Oops. So why am I doing this? It happens to be one step toward breaking the requirement that IR verification can only be performed from inside of a pass context, which completely blocks the implementation of verification for the new pass manager infrastructure. Fixing it will also allow removing the concept of the "preverify" step (WTF???) and allow the verifier to cleanly flag functions which fail verification in a way that precludes even computing dominance information. Currently, that results in a fatal error even when you ask the verifier to not fatally error. It's awesome like that. The yak shaving will continue... git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@199095 91177308-0d34-0410-b5e6-96231b3b80d8
206 lines
6.8 KiB
C++
206 lines
6.8 KiB
C++
//=- llvm/CodeGen/MachineDominators.h - Machine Dom 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 classes mirroring those in llvm/Analysis/Dominators.h,
|
|
// but for target-specific code rather than target-independent IR.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef LLVM_CODEGEN_MACHINEDOMINATORS_H
|
|
#define LLVM_CODEGEN_MACHINEDOMINATORS_H
|
|
|
|
#include "llvm/CodeGen/MachineBasicBlock.h"
|
|
#include "llvm/CodeGen/MachineFunction.h"
|
|
#include "llvm/CodeGen/MachineFunctionPass.h"
|
|
#include "llvm/Support/GenericDomTreeConstruction.h"
|
|
#include "llvm/Support/GenericDomTree.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;
|
|
|
|
//===-------------------------------------
|
|
/// DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to
|
|
/// compute a normal dominator tree.
|
|
///
|
|
class MachineDominatorTree : public MachineFunctionPass {
|
|
public:
|
|
static char ID; // Pass ID, replacement for typeid
|
|
DominatorTreeBase<MachineBasicBlock>* DT;
|
|
|
|
MachineDominatorTree();
|
|
|
|
~MachineDominatorTree();
|
|
|
|
DominatorTreeBase<MachineBasicBlock>& getBase() { return *DT; }
|
|
|
|
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
|
|
|
|
/// 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<MachineBasicBlock*> &getRoots() const {
|
|
return DT->getRoots();
|
|
}
|
|
|
|
inline MachineBasicBlock *getRoot() const {
|
|
return DT->getRoot();
|
|
}
|
|
|
|
inline MachineDomTreeNode *getRootNode() const {
|
|
return DT->getRootNode();
|
|
}
|
|
|
|
virtual bool runOnMachineFunction(MachineFunction &F);
|
|
|
|
inline bool dominates(const MachineDomTreeNode* A,
|
|
const MachineDomTreeNode* B) const {
|
|
return DT->dominates(A, B);
|
|
}
|
|
|
|
inline bool dominates(const MachineBasicBlock* A,
|
|
const MachineBasicBlock* B) const {
|
|
return DT->dominates(A, B);
|
|
}
|
|
|
|
// dominates - Return true if A dominates B. This performs the
|
|
// special checks necessary if A and B are in the same basic block.
|
|
bool dominates(const MachineInstr *A, const MachineInstr *B) const {
|
|
const MachineBasicBlock *BBA = A->getParent(), *BBB = B->getParent();
|
|
if (BBA != BBB) return DT->dominates(BBA, BBB);
|
|
|
|
// Loop through the basic block until we find A or B.
|
|
MachineBasicBlock::const_iterator I = BBA->begin();
|
|
for (; &*I != A && &*I != B; ++I)
|
|
/*empty*/ ;
|
|
|
|
//if(!DT.IsPostDominators) {
|
|
// A dominates B if it is found first in the basic block.
|
|
return &*I == A;
|
|
//} else {
|
|
// // A post-dominates B if B is found first in the basic block.
|
|
// return &*I == B;
|
|
//}
|
|
}
|
|
|
|
inline bool properlyDominates(const MachineDomTreeNode* A,
|
|
const MachineDomTreeNode* B) const {
|
|
return DT->properlyDominates(A, B);
|
|
}
|
|
|
|
inline bool properlyDominates(const MachineBasicBlock* A,
|
|
const MachineBasicBlock* B) const {
|
|
return DT->properlyDominates(A, B);
|
|
}
|
|
|
|
/// findNearestCommonDominator - Find nearest common dominator basic block
|
|
/// for basic block A and B. If there is no such block then return NULL.
|
|
inline MachineBasicBlock *findNearestCommonDominator(MachineBasicBlock *A,
|
|
MachineBasicBlock *B) {
|
|
return DT->findNearestCommonDominator(A, B);
|
|
}
|
|
|
|
inline MachineDomTreeNode *operator[](MachineBasicBlock *BB) const {
|
|
return DT->getNode(BB);
|
|
}
|
|
|
|
/// getNode - return the (Post)DominatorTree node for the specified basic
|
|
/// block. This is the same as using operator[] on this class.
|
|
///
|
|
inline MachineDomTreeNode *getNode(MachineBasicBlock *BB) const {
|
|
return DT->getNode(BB);
|
|
}
|
|
|
|
/// addNewBlock - Add a new node to the dominator tree information. This
|
|
/// creates a new node as a child of DomBB dominator node,linking it into
|
|
/// the children list of the immediate dominator.
|
|
inline MachineDomTreeNode *addNewBlock(MachineBasicBlock *BB,
|
|
MachineBasicBlock *DomBB) {
|
|
return DT->addNewBlock(BB, DomBB);
|
|
}
|
|
|
|
/// changeImmediateDominator - This method is used to update the dominator
|
|
/// tree information when a node's immediate dominator changes.
|
|
///
|
|
inline void changeImmediateDominator(MachineBasicBlock *N,
|
|
MachineBasicBlock* NewIDom) {
|
|
DT->changeImmediateDominator(N, NewIDom);
|
|
}
|
|
|
|
inline void changeImmediateDominator(MachineDomTreeNode *N,
|
|
MachineDomTreeNode* NewIDom) {
|
|
DT->changeImmediateDominator(N, NewIDom);
|
|
}
|
|
|
|
/// eraseNode - Removes a node from the dominator tree. Block must not
|
|
/// dominate any other blocks. Removes node from its immediate dominator's
|
|
/// children list. Deletes dominator node associated with basic block BB.
|
|
inline void eraseNode(MachineBasicBlock *BB) {
|
|
DT->eraseNode(BB);
|
|
}
|
|
|
|
/// splitBlock - BB is split and now it has one successor. Update dominator
|
|
/// tree to reflect this change.
|
|
inline void splitBlock(MachineBasicBlock* NewBB) {
|
|
DT->splitBlock(NewBB);
|
|
}
|
|
|
|
/// isReachableFromEntry - Return true if A is dominated by the entry
|
|
/// block of the function containing it.
|
|
bool isReachableFromEntry(const MachineBasicBlock *A) {
|
|
return DT->isReachableFromEntry(A);
|
|
}
|
|
|
|
virtual void releaseMemory();
|
|
|
|
virtual void print(raw_ostream &OS, const Module*) const;
|
|
};
|
|
|
|
//===-------------------------------------
|
|
/// DominatorTree GraphTraits specialization so the DominatorTree can be
|
|
/// iterable by generic graph iterators.
|
|
///
|
|
|
|
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
|