mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-21 21:11:36 +00:00
Rework dominator and post dominator information so that we do not have to
unify all exit nodes of a function to compute post-dominance information. This does not work with functions that have both unwind and return nodes, because we cannot unify these blocks. The new implementation is better anyway. :) llvm-svn: 8459
This commit is contained in:
parent
0d124f6067
commit
e7c33c0f65
@ -32,12 +32,15 @@ template <typename GraphType> struct GraphTraits;
|
||||
//
|
||||
class DominatorBase : public FunctionPass {
|
||||
protected:
|
||||
BasicBlock *Root;
|
||||
std::vector<BasicBlock*> Roots;
|
||||
const bool IsPostDominators;
|
||||
|
||||
inline DominatorBase(bool isPostDom) : Root(0), IsPostDominators(isPostDom) {}
|
||||
inline DominatorBase(bool isPostDom) : Roots(), IsPostDominators(isPostDom) {}
|
||||
public:
|
||||
inline BasicBlock *getRoot() const { return Root; }
|
||||
// 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<BasicBlock*> &getRoots() const { return Roots; }
|
||||
|
||||
// Returns true if analysis based of postdoms
|
||||
bool isPostDominator() const { return IsPostDominators; }
|
||||
@ -144,6 +147,11 @@ struct DominatorSet : public DominatorSetBase {
|
||||
/// obviously really slow, so it should be avoided if at all possible.
|
||||
void recalculate();
|
||||
|
||||
BasicBlock *getRoot() const {
|
||||
assert(Roots.size() == 1 && "Should always have entry node!");
|
||||
return Roots[0];
|
||||
}
|
||||
|
||||
// getAnalysisUsage - This simply provides a dominator set
|
||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
AU.setPreservesAll();
|
||||
@ -219,10 +227,15 @@ public:
|
||||
struct ImmediateDominators : public ImmediateDominatorsBase {
|
||||
ImmediateDominators() : ImmediateDominatorsBase(false) {}
|
||||
|
||||
BasicBlock *getRoot() const {
|
||||
assert(Roots.size() == 1 && "Should always have entry node!");
|
||||
return Roots[0];
|
||||
}
|
||||
|
||||
virtual bool runOnFunction(Function &F) {
|
||||
IDoms.clear(); // Reset from the last time we were run...
|
||||
DominatorSet &DS = getAnalysis<DominatorSet>();
|
||||
Root = DS.getRoot();
|
||||
Roots = DS.getRoots();
|
||||
calcIDoms(DS);
|
||||
return false;
|
||||
}
|
||||
@ -247,6 +260,8 @@ protected:
|
||||
std::map<BasicBlock*, Node*> Nodes;
|
||||
void reset();
|
||||
typedef std::map<BasicBlock*, Node*> NodeMapType;
|
||||
|
||||
Node *RootNode;
|
||||
public:
|
||||
class Node2 {
|
||||
friend class DominatorTree;
|
||||
@ -303,7 +318,18 @@ public:
|
||||
return getNode(BB);
|
||||
}
|
||||
|
||||
//===--------------------------------------------------------------------===// // API to update (Post)DominatorTree information based on modifications to
|
||||
// getRootNode - This returns the entry node for the CFG of the function. If
|
||||
// this tree represents the post-dominance relations for a function, however,
|
||||
// this root may be a node with the block == NULL. This is the case when
|
||||
// there are multiple exit nodes from a particular function. Consumers of
|
||||
// post-dominance information must be capable of dealing with this
|
||||
// possibility.
|
||||
//
|
||||
Node *getRootNode() { return RootNode; }
|
||||
const Node *getRootNode() const { return RootNode; }
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// API to update (Post)DominatorTree information based on modifications to
|
||||
// the CFG...
|
||||
|
||||
/// createNewNode - Add a new node to the dominator tree information. This
|
||||
@ -336,10 +362,15 @@ public:
|
||||
struct DominatorTree : public DominatorTreeBase {
|
||||
DominatorTree() : DominatorTreeBase(false) {}
|
||||
|
||||
BasicBlock *getRoot() const {
|
||||
assert(Roots.size() == 1 && "Should always have entry node!");
|
||||
return Roots[0];
|
||||
}
|
||||
|
||||
virtual bool runOnFunction(Function &F) {
|
||||
reset(); // Reset from the last time we were run...
|
||||
DominatorSet &DS = getAnalysis<DominatorSet>();
|
||||
Root = DS.getRoot();
|
||||
Roots = DS.getRoots();
|
||||
calculate(DS);
|
||||
return false;
|
||||
}
|
||||
@ -374,7 +405,7 @@ template <> struct GraphTraits<DominatorTree::Node*> {
|
||||
template <> struct GraphTraits<DominatorTree*>
|
||||
: public GraphTraits<DominatorTree::Node*> {
|
||||
static NodeType *getEntryNode(DominatorTree *DT) {
|
||||
return DT->getNode(DT->getRoot());
|
||||
return DT->getRootNode();
|
||||
}
|
||||
};
|
||||
|
||||
@ -431,11 +462,17 @@ public:
|
||||
struct DominanceFrontier : public DominanceFrontierBase {
|
||||
DominanceFrontier() : DominanceFrontierBase(false) {}
|
||||
|
||||
BasicBlock *getRoot() const {
|
||||
assert(Roots.size() == 1 && "Should always have entry node!");
|
||||
return Roots[0];
|
||||
}
|
||||
|
||||
virtual bool runOnFunction(Function &) {
|
||||
Frontiers.clear();
|
||||
DominatorTree &DT = getAnalysis<DominatorTree>();
|
||||
Root = DT.getRoot();
|
||||
calculate(DT, DT[Root]);
|
||||
Roots = DT.getRoots();
|
||||
assert(Roots.size() == 1 && "Only one entry block for forward domfronts!");
|
||||
calculate(DT, DT[Roots[0]]);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -10,19 +10,23 @@
|
||||
#include "llvm/Analysis/Dominators.h"
|
||||
|
||||
|
||||
//===-------------------------------------
|
||||
// DominatorSet Class - Concrete subclass of DominatorSetBase that is used to
|
||||
// compute the post-dominator set.
|
||||
//
|
||||
/// PostDominatorSet Class - Concrete subclass of DominatorSetBase that is used
|
||||
/// to compute the post-dominator set. Because there can be multiple exit nodes
|
||||
/// in an LLVM function, we calculate post dominators with a special null block
|
||||
/// which is the virtual exit node that the real exit nodes all virtually branch
|
||||
/// to. Clients should be prepared to see an entry in the dominator sets with a
|
||||
/// null BasicBlock*.
|
||||
///
|
||||
struct PostDominatorSet : public DominatorSetBase {
|
||||
PostDominatorSet() : DominatorSetBase(true) {}
|
||||
|
||||
virtual bool runOnFunction(Function &F);
|
||||
|
||||
// getAnalysisUsage - This obviously provides a dominator set, but it also
|
||||
// uses the UnifyFunctionExitNode pass if building post-dominators
|
||||
// getAnalysisUsage - This pass does not modify the function at all.
|
||||
//
|
||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
|
||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
AU.setPreservesAll();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -37,7 +41,7 @@ struct ImmediatePostDominators : public ImmediateDominatorsBase {
|
||||
virtual bool runOnFunction(Function &F) {
|
||||
IDoms.clear(); // Reset from the last time we were run...
|
||||
PostDominatorSet &DS = getAnalysis<PostDominatorSet>();
|
||||
Root = DS.getRoot();
|
||||
Roots = DS.getRoots();
|
||||
calcIDoms(DS);
|
||||
return false;
|
||||
}
|
||||
@ -59,7 +63,7 @@ struct PostDominatorTree : public DominatorTreeBase {
|
||||
virtual bool runOnFunction(Function &F) {
|
||||
reset(); // Reset from the last time we were run...
|
||||
PostDominatorSet &DS = getAnalysis<PostDominatorSet>();
|
||||
Root = DS.getRoot();
|
||||
Roots = DS.getRoots();
|
||||
calculate(DS);
|
||||
return false;
|
||||
}
|
||||
@ -83,8 +87,8 @@ struct PostDominanceFrontier : public DominanceFrontierBase {
|
||||
virtual bool runOnFunction(Function &) {
|
||||
Frontiers.clear();
|
||||
PostDominatorTree &DT = getAnalysis<PostDominatorTree>();
|
||||
Root = DT.getRoot();
|
||||
calculate(DT, DT[Root]);
|
||||
Roots = DT.getRoots();
|
||||
calculate(DT, DT.getRootNode());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user