mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-14 11:32:34 +00:00
Add a first attempt at dominator information for MBB's. Use with caution: this has been tested to compile. It has not yet been confirmed to generate correct analysis.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@43438 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
0569187653
commit
08895f8866
@ -105,7 +105,7 @@ public:
|
|||||||
void setIDom(DomTreeNodeBase<NodeT> *NewIDom) {
|
void setIDom(DomTreeNodeBase<NodeT> *NewIDom) {
|
||||||
assert(IDom && "No immediate dominator?");
|
assert(IDom && "No immediate dominator?");
|
||||||
if (IDom != NewIDom) {
|
if (IDom != NewIDom) {
|
||||||
std::vector<DomTreeNodeBase<BasicBlock>*>::iterator I =
|
typename std::vector<DomTreeNodeBase<NodeT>*>::iterator I =
|
||||||
std::find(IDom->Children.begin(), IDom->Children.end(), this);
|
std::find(IDom->Children.begin(), IDom->Children.end(), this);
|
||||||
assert(I != IDom->Children.end() &&
|
assert(I != IDom->Children.end() &&
|
||||||
"Not in immediate dominator children set!");
|
"Not in immediate dominator children set!");
|
||||||
@ -267,7 +267,7 @@ protected:
|
|||||||
|
|
||||||
// Find NewBB's immediate dominator and create new dominator tree node for
|
// Find NewBB's immediate dominator and create new dominator tree node for
|
||||||
// NewBB.
|
// NewBB.
|
||||||
BasicBlock *NewBBIDom = 0;
|
NodeT *NewBBIDom = 0;
|
||||||
unsigned i = 0;
|
unsigned i = 0;
|
||||||
for (i = 0; i < PredBlocks.size(); ++i)
|
for (i = 0; i < PredBlocks.size(); ++i)
|
||||||
if (DT.isReachableFromEntry(PredBlocks[i])) {
|
if (DT.isReachableFromEntry(PredBlocks[i])) {
|
||||||
@ -282,12 +282,12 @@ protected:
|
|||||||
assert(NewBBIDom && "No immediate dominator found??");
|
assert(NewBBIDom && "No immediate dominator found??");
|
||||||
|
|
||||||
// Create the new dominator tree node... and set the idom of NewBB.
|
// Create the new dominator tree node... and set the idom of NewBB.
|
||||||
DomTreeNode *NewBBNode = DT.addNewBlock(NewBB, NewBBIDom);
|
DomTreeNodeBase<NodeT> *NewBBNode = DT.addNewBlock(NewBB, NewBBIDom);
|
||||||
|
|
||||||
// If NewBB strictly dominates other blocks, then it is now the immediate
|
// If NewBB strictly dominates other blocks, then it is now the immediate
|
||||||
// dominator of NewBBSucc. Update the dominator tree as appropriate.
|
// dominator of NewBBSucc. Update the dominator tree as appropriate.
|
||||||
if (NewBBDominatesNewBBSucc) {
|
if (NewBBDominatesNewBBSucc) {
|
||||||
DomTreeNode *NewBBSuccNode = DT.getNode(NewBBSucc);
|
DomTreeNodeBase<NodeT> *NewBBSuccNode = DT.getNode(NewBBSucc);
|
||||||
DT.changeImmediateDominator(NewBBSuccNode, NewBBNode);
|
DT.changeImmediateDominator(NewBBSuccNode, NewBBNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -348,7 +348,7 @@ public:
|
|||||||
const bool isReachableFromEntry(NodeT* A) {
|
const bool isReachableFromEntry(NodeT* A) {
|
||||||
assert (!this->isPostDominator()
|
assert (!this->isPostDominator()
|
||||||
&& "This is not implemented for post dominators");
|
&& "This is not implemented for post dominators");
|
||||||
return dominates(&A->getParent()->getEntryBlock(), A);
|
return dominates(&A->getParent()->front(), A);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// dominates - Returns true iff A dominates B. Note that this is not a
|
/// dominates - Returns true iff A dominates B. Note that this is not a
|
||||||
@ -398,7 +398,7 @@ public:
|
|||||||
&& "Two blocks are not in same function");
|
&& "Two blocks are not in same function");
|
||||||
|
|
||||||
// If either A or B is a entry block then it is nearest common dominator.
|
// If either A or B is a entry block then it is nearest common dominator.
|
||||||
NodeT &Entry = A->getParent()->getEntryBlock();
|
NodeT &Entry = A->getParent()->front();
|
||||||
if (A == &Entry || B == &Entry)
|
if (A == &Entry || B == &Entry)
|
||||||
return &Entry;
|
return &Entry;
|
||||||
|
|
||||||
@ -447,7 +447,7 @@ public:
|
|||||||
assert(IDomNode && "Not immediate dominator specified for block!");
|
assert(IDomNode && "Not immediate dominator specified for block!");
|
||||||
DFSInfoValid = false;
|
DFSInfoValid = false;
|
||||||
return DomTreeNodes[BB] =
|
return DomTreeNodes[BB] =
|
||||||
IDomNode->addChild(new DomTreeNode(BB, IDomNode));
|
IDomNode->addChild(new DomTreeNodeBase<NodeT>(BB, IDomNode));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// changeImmediateDominator - This method is used to update the dominator
|
/// changeImmediateDominator - This method is used to update the dominator
|
||||||
|
170
include/llvm/CodeGen/MachineDominators.h
Normal file
170
include/llvm/CodeGen/MachineDominators.h
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
//=- llvm/CodeGen/MachineDominators.h - Machine Dom Calculation --*- C++ -*-==//
|
||||||
|
//
|
||||||
|
// The LLVM Compiler Infrastructure
|
||||||
|
//
|
||||||
|
// This file was developed by Owen Anderson and 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/MachineFunctionPass.h"
|
||||||
|
#include "llvm/CodeGen/MachineBasicBlock.h"
|
||||||
|
#include "llvm/CodeGen/MachineFunction.h"
|
||||||
|
#include "llvm/CodeGen/MachineInstr.h"
|
||||||
|
#include "llvm/Analysis/Dominators.h"
|
||||||
|
#include "llvm/Analysis/DominatorInternals.h"
|
||||||
|
|
||||||
|
namespace llvm {
|
||||||
|
|
||||||
|
void WriteAsOperand(std::ostream &, const MachineBasicBlock*, bool t) { }
|
||||||
|
|
||||||
|
//===-------------------------------------
|
||||||
|
/// 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() : MachineFunctionPass(intptr_t(&ID)) {
|
||||||
|
DT = new DominatorTreeBase<MachineBasicBlock>(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
~MachineDominatorTree() {
|
||||||
|
DT->releaseMemory();
|
||||||
|
delete DT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 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 runOnFunction(Function &F);
|
||||||
|
|
||||||
|
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
|
||||||
|
AU.setPreservesAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool dominates(MachineDomTreeNode* A, MachineDomTreeNode* B) const {
|
||||||
|
return DT->dominates(A, B);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool dominates(MachineBasicBlock* A, 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(MachineInstr *A, MachineInstr *B) 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::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,
|
||||||
|
MachineDomTreeNode* B) const {
|
||||||
|
return DT->properlyDominates(A, B);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool properlyDominates(MachineBasicBlock* A,
|
||||||
|
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
|
||||||
|
/// domiante 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
virtual void releaseMemory() {
|
||||||
|
DT->releaseMemory();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void print(std::ostream &OS, const Module* M= 0) const {
|
||||||
|
DT->print(OS, M);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user