mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-23 14:25:07 +00:00
Templatify DominanceFrontier.
Theoretically this should now work for MachineBasicBlocks. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@212885 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -23,168 +23,186 @@
|
|||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
/// DominanceFrontierBase - Common base class for computing forward and inverse
|
/// DominanceFrontierBase - Common base class for computing forward and inverse
|
||||||
/// dominance frontiers for a function.
|
/// dominance frontiers for a function.
|
||||||
///
|
///
|
||||||
class DominanceFrontierBase : public FunctionPass {
|
template <class BlockT>
|
||||||
|
class DominanceFrontierBase {
|
||||||
public:
|
public:
|
||||||
typedef std::set<BasicBlock*> DomSetType; // Dom set for a bb
|
typedef std::set<BlockT *> DomSetType; // Dom set for a bb
|
||||||
typedef std::map<BasicBlock*, DomSetType> DomSetMapType; // Dom set map
|
typedef std::map<BlockT *, DomSetType> DomSetMapType; // Dom set map
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
typedef GraphTraits<BlockT *> BlockTraits;
|
||||||
|
|
||||||
DomSetMapType Frontiers;
|
DomSetMapType Frontiers;
|
||||||
std::vector<BasicBlock*> Roots;
|
std::vector<BlockT *> Roots;
|
||||||
const bool IsPostDominators;
|
const bool IsPostDominators;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DominanceFrontierBase(char &ID, bool isPostDom)
|
DominanceFrontierBase(bool isPostDom) : IsPostDominators(isPostDom) {}
|
||||||
: FunctionPass(ID), IsPostDominators(isPostDom) {}
|
|
||||||
|
|
||||||
/// getRoots - Return the root blocks of the current CFG. This may include
|
/// getRoots - Return the root blocks of the current CFG. This may include
|
||||||
/// multiple blocks if we are computing post dominators. For forward
|
/// multiple blocks if we are computing post dominators. For forward
|
||||||
/// dominators, this will always be a single block (the entry node).
|
/// dominators, this will always be a single block (the entry node).
|
||||||
///
|
///
|
||||||
inline const std::vector<BasicBlock*> &getRoots() const { return Roots; }
|
inline const std::vector<BlockT *> &getRoots() const {
|
||||||
|
return Roots;
|
||||||
|
}
|
||||||
|
|
||||||
|
BlockT *getRoot() const {
|
||||||
|
assert(Roots.size() == 1 && "Should always have entry node!");
|
||||||
|
return Roots[0];
|
||||||
|
}
|
||||||
|
|
||||||
/// isPostDominator - Returns true if analysis based of postdoms
|
/// isPostDominator - Returns true if analysis based of postdoms
|
||||||
///
|
///
|
||||||
bool isPostDominator() const { return IsPostDominators; }
|
bool isPostDominator() const {
|
||||||
|
return IsPostDominators;
|
||||||
|
}
|
||||||
|
|
||||||
void releaseMemory() override { Frontiers.clear(); }
|
void releaseMemory() {
|
||||||
|
Frontiers.clear();
|
||||||
|
}
|
||||||
|
|
||||||
// Accessor interface:
|
// Accessor interface:
|
||||||
typedef DomSetMapType::iterator iterator;
|
typedef typename DomSetMapType::iterator iterator;
|
||||||
typedef DomSetMapType::const_iterator const_iterator;
|
typedef typename DomSetMapType::const_iterator const_iterator;
|
||||||
iterator begin() { return Frontiers.begin(); }
|
iterator begin() { return Frontiers.begin(); }
|
||||||
const_iterator begin() const { return Frontiers.begin(); }
|
const_iterator begin() const { return Frontiers.begin(); }
|
||||||
iterator end() { return Frontiers.end(); }
|
iterator end() { return Frontiers.end(); }
|
||||||
const_iterator end() const { return Frontiers.end(); }
|
const_iterator end() const { return Frontiers.end(); }
|
||||||
iterator find(BasicBlock *B) { return Frontiers.find(B); }
|
iterator find(BlockT *B) { return Frontiers.find(B); }
|
||||||
const_iterator find(BasicBlock *B) const { return Frontiers.find(B); }
|
const_iterator find(BlockT *B) const { return Frontiers.find(B); }
|
||||||
|
|
||||||
iterator addBasicBlock(BasicBlock *BB, const DomSetType &frontier) {
|
iterator addBasicBlock(BlockT *BB, const DomSetType &frontier) {
|
||||||
assert(find(BB) == end() && "Block already in DominanceFrontier!");
|
assert(find(BB) == end() && "Block already in DominanceFrontier!");
|
||||||
return Frontiers.insert(std::make_pair(BB, frontier)).first;
|
return Frontiers.insert(std::make_pair(BB, frontier)).first;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// removeBlock - Remove basic block BB's frontier.
|
/// removeBlock - Remove basic block BB's frontier.
|
||||||
void removeBlock(BasicBlock *BB) {
|
void removeBlock(BlockT *BB);
|
||||||
assert(find(BB) != end() && "Block is not in DominanceFrontier!");
|
|
||||||
for (iterator I = begin(), E = end(); I != E; ++I)
|
|
||||||
I->second.erase(BB);
|
|
||||||
Frontiers.erase(BB);
|
|
||||||
}
|
|
||||||
|
|
||||||
void addToFrontier(iterator I, BasicBlock *Node) {
|
void addToFrontier(iterator I, BlockT *Node);
|
||||||
assert(I != end() && "BB is not in DominanceFrontier!");
|
|
||||||
I->second.insert(Node);
|
|
||||||
}
|
|
||||||
|
|
||||||
void removeFromFrontier(iterator I, BasicBlock *Node) {
|
void removeFromFrontier(iterator I, BlockT *Node);
|
||||||
assert(I != end() && "BB is not in DominanceFrontier!");
|
|
||||||
assert(I->second.count(Node) && "Node is not in DominanceFrontier of BB");
|
|
||||||
I->second.erase(Node);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// compareDomSet - Return false if two domsets match. Otherwise
|
/// compareDomSet - Return false if two domsets match. Otherwise
|
||||||
/// return true;
|
/// return true;
|
||||||
bool compareDomSet(DomSetType &DS1, const DomSetType &DS2) const {
|
bool compareDomSet(DomSetType &DS1, const DomSetType &DS2) const;
|
||||||
std::set<BasicBlock *> tmpSet;
|
|
||||||
for (DomSetType::const_iterator I = DS2.begin(),
|
|
||||||
E = DS2.end(); I != E; ++I)
|
|
||||||
tmpSet.insert(*I);
|
|
||||||
|
|
||||||
for (DomSetType::const_iterator I = DS1.begin(),
|
|
||||||
E = DS1.end(); I != E; ) {
|
|
||||||
BasicBlock *Node = *I++;
|
|
||||||
|
|
||||||
if (tmpSet.erase(Node) == 0)
|
|
||||||
// Node is in DS1 but not in DS2.
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!tmpSet.empty())
|
|
||||||
// There are nodes that are in DS2 but not in DS1.
|
|
||||||
return true;
|
|
||||||
|
|
||||||
// DS1 and DS2 matches.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// compare - Return true if the other dominance frontier base matches
|
/// compare - Return true if the other dominance frontier base matches
|
||||||
/// this dominance frontier base. Otherwise return false.
|
/// this dominance frontier base. Otherwise return false.
|
||||||
bool compare(DominanceFrontierBase &Other) const {
|
bool compare(DominanceFrontierBase<BlockT> &Other) const;
|
||||||
DomSetMapType tmpFrontiers;
|
|
||||||
for (DomSetMapType::const_iterator I = Other.begin(),
|
|
||||||
E = Other.end(); I != E; ++I)
|
|
||||||
tmpFrontiers.insert(std::make_pair(I->first, I->second));
|
|
||||||
|
|
||||||
for (DomSetMapType::iterator I = tmpFrontiers.begin(),
|
|
||||||
E = tmpFrontiers.end(); I != E; ) {
|
|
||||||
BasicBlock *Node = I->first;
|
|
||||||
const_iterator DFI = find(Node);
|
|
||||||
if (DFI == end())
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if (compareDomSet(I->second, DFI->second))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
++I;
|
|
||||||
tmpFrontiers.erase(Node);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!tmpFrontiers.empty())
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// print - Convert to human readable form
|
/// print - Convert to human readable form
|
||||||
///
|
///
|
||||||
void print(raw_ostream &OS, const Module* = nullptr) const override;
|
void print(raw_ostream &OS) const;
|
||||||
|
|
||||||
/// dump - Dump the dominance frontier to dbgs().
|
/// dump - Dump the dominance frontier to dbgs().
|
||||||
void dump() const;
|
void dump() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//===-------------------------------------
|
//===-------------------------------------
|
||||||
/// DominanceFrontier Class - Concrete subclass of DominanceFrontierBase that is
|
/// DominanceFrontier Class - Concrete subclass of DominanceFrontierBase that is
|
||||||
/// used to compute a forward dominator frontiers.
|
/// used to compute a forward dominator frontiers.
|
||||||
///
|
///
|
||||||
class DominanceFrontier : public DominanceFrontierBase {
|
template <class BlockT>
|
||||||
virtual void anchor();
|
class ForwardDominanceFrontierBase : public DominanceFrontierBase<BlockT> {
|
||||||
|
private:
|
||||||
|
typedef GraphTraits<BlockT *> BlockTraits;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static char ID; // Pass ID, replacement for typeid
|
typedef DominatorTreeBase<BlockT> DomTreeT;
|
||||||
DominanceFrontier() :
|
typedef DomTreeNodeBase<BlockT> DomTreeNodeT;
|
||||||
DominanceFrontierBase(ID, false) {
|
typedef typename DominanceFrontierBase<BlockT>::DomSetType DomSetType;
|
||||||
initializeDominanceFrontierPass(*PassRegistry::getPassRegistry());
|
|
||||||
}
|
|
||||||
|
|
||||||
BasicBlock *getRoot() const {
|
ForwardDominanceFrontierBase() : DominanceFrontierBase<BlockT>(false) {}
|
||||||
assert(Roots.size() == 1 && "Should always have entry node!");
|
|
||||||
return Roots[0];
|
void analyze(DomTreeT &DT) {
|
||||||
|
this->Roots = DT.getRoots();
|
||||||
|
assert(this->Roots.size() == 1 &&
|
||||||
|
"Only one entry block for forward domfronts!");
|
||||||
|
calculate(DT, DT[this->Roots[0]]);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool runOnFunction(Function &) override {
|
const DomSetType &calculate(const DomTreeT &DT, const DomTreeNodeT *Node);
|
||||||
Frontiers.clear();
|
|
||||||
DominatorTree &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
|
|
||||||
Roots = DT.getRoots();
|
|
||||||
assert(Roots.size() == 1 && "Only one entry block for forward domfronts!");
|
|
||||||
calculate(DT, DT[Roots[0]]);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
|
||||||
AU.setPreservesAll();
|
|
||||||
AU.addRequired<DominatorTreeWrapperPass>();
|
|
||||||
}
|
|
||||||
|
|
||||||
const DomSetType &calculate(const DominatorTree &DT,
|
|
||||||
const DomTreeNode *Node);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class DominanceFrontier : public FunctionPass {
|
||||||
|
ForwardDominanceFrontierBase<BasicBlock> Base;
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef DominatorTreeBase<BasicBlock> DomTreeT;
|
||||||
|
typedef DomTreeNodeBase<BasicBlock> DomTreeNodeT;
|
||||||
|
typedef typename DominanceFrontierBase<BasicBlock>::DomSetType DomSetType;
|
||||||
|
typedef DominanceFrontierBase<BasicBlock>::iterator iterator;
|
||||||
|
typedef DominanceFrontierBase<BasicBlock>::const_iterator const_iterator;
|
||||||
|
|
||||||
|
static char ID; // Pass ID, replacement for typeid
|
||||||
|
|
||||||
|
DominanceFrontier();
|
||||||
|
|
||||||
|
ForwardDominanceFrontierBase<BasicBlock> &getBase() { return Base; }
|
||||||
|
|
||||||
|
inline const std::vector<BasicBlock *> &getRoots() const {
|
||||||
|
return Base.getRoots();
|
||||||
|
}
|
||||||
|
|
||||||
|
BasicBlock *getRoot() const { return Base.getRoot(); }
|
||||||
|
|
||||||
|
bool isPostDominator() const { return Base.isPostDominator(); }
|
||||||
|
|
||||||
|
iterator begin() { return Base.begin(); }
|
||||||
|
|
||||||
|
const_iterator begin() const { return Base.begin(); }
|
||||||
|
|
||||||
|
iterator end() { return Base.end(); }
|
||||||
|
|
||||||
|
const_iterator end() const { return Base.end(); }
|
||||||
|
|
||||||
|
iterator find(BasicBlock *B) { return Base.find(B); }
|
||||||
|
|
||||||
|
const_iterator find(BasicBlock *B) const { return Base.find(B); }
|
||||||
|
|
||||||
|
iterator addBasicBlock(BasicBlock *BB, const DomSetType &frontier) {
|
||||||
|
return Base.addBasicBlock(BB, frontier);
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeBlock(BasicBlock *BB) { return Base.removeBlock(BB); }
|
||||||
|
|
||||||
|
void addToFrontier(iterator I, BasicBlock *Node) {
|
||||||
|
return Base.addToFrontier(I, Node);
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeFromFrontier(iterator I, BasicBlock *Node) {
|
||||||
|
return Base.removeFromFrontier(I, Node);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool compareDomSet(DomSetType &DS1, const DomSetType &DS2) const {
|
||||||
|
return Base.compareDomSet(DS1, DS2);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool compare(DominanceFrontierBase<BasicBlock> &Other) const {
|
||||||
|
return Base.compare(Other);
|
||||||
|
}
|
||||||
|
|
||||||
|
void releaseMemory() override;
|
||||||
|
|
||||||
|
bool runOnFunction(Function &) override;
|
||||||
|
|
||||||
|
void getAnalysisUsage(AnalysisUsage &AU) const override;
|
||||||
|
|
||||||
|
void print(raw_ostream &OS, const Module * = nullptr) const override;
|
||||||
|
|
||||||
|
void dump() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
EXTERN_TEMPLATE_INSTANTIATION(class DominanceFrontierBase<BasicBlock>);
|
||||||
|
EXTERN_TEMPLATE_INSTANTIATION(class ForwardDominanceFrontierBase<BasicBlock>);
|
||||||
|
|
||||||
} // End llvm namespace
|
} // End llvm namespace
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
220
include/llvm/Analysis/DominanceFrontierImpl.h
Normal file
220
include/llvm/Analysis/DominanceFrontierImpl.h
Normal file
@@ -0,0 +1,220 @@
|
|||||||
|
//===- llvm/Analysis/DominanceFrontier.h - Dominator Frontiers --*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// The LLVM Compiler Infrastructure
|
||||||
|
//
|
||||||
|
// This file is distributed under the University of Illinois Open Source
|
||||||
|
// License. See LICENSE.TXT for details.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// This is the generic implementation of the DominanceFrontier class, which
|
||||||
|
// calculate and holds the dominance frontier for a function for.
|
||||||
|
//
|
||||||
|
// This should be considered deprecated, don't add any more uses of this data
|
||||||
|
// structure.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef LLVM_ANALYSIS_DOMINANCEFRONTIER_IMPL_H
|
||||||
|
#define LLVM_ANALYSIS_DOMINANCEFRONTIER_IMPL_H
|
||||||
|
|
||||||
|
#include "llvm/ADT/SmallPtrSet.h"
|
||||||
|
#include "llvm/Support/Debug.h"
|
||||||
|
|
||||||
|
namespace llvm {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
template <class BlockT>
|
||||||
|
class DFCalculateWorkObject {
|
||||||
|
public:
|
||||||
|
typedef DomTreeNodeBase<BlockT> DomTreeNodeT;
|
||||||
|
|
||||||
|
DFCalculateWorkObject(BlockT *B, BlockT *P, const DomTreeNodeT *N,
|
||||||
|
const DomTreeNodeT *PN)
|
||||||
|
: currentBB(B), parentBB(P), Node(N), parentNode(PN) {}
|
||||||
|
BlockT *currentBB;
|
||||||
|
BlockT *parentBB;
|
||||||
|
const DomTreeNodeT *Node;
|
||||||
|
const DomTreeNodeT *parentNode;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class BlockT>
|
||||||
|
void DominanceFrontierBase<BlockT>::removeBlock(BlockT *BB) {
|
||||||
|
assert(find(BB) != end() && "Block is not in DominanceFrontier!");
|
||||||
|
for (iterator I = begin(), E = end(); I != E; ++I)
|
||||||
|
I->second.erase(BB);
|
||||||
|
Frontiers.erase(BB);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class BlockT>
|
||||||
|
void DominanceFrontierBase<BlockT>::removeFromFrontier(iterator I,
|
||||||
|
BlockT *Node) {
|
||||||
|
assert(I != end() && "BB is not in DominanceFrontier!");
|
||||||
|
assert(I->second.count(Node) && "Node is not in DominanceFrontier of BB");
|
||||||
|
I->second.erase(Node);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class BlockT>
|
||||||
|
bool DominanceFrontierBase<BlockT>::compareDomSet(DomSetType &DS1,
|
||||||
|
const DomSetType &DS2) const {
|
||||||
|
std::set<BlockT *> tmpSet;
|
||||||
|
for (BlockT *BB : DS2)
|
||||||
|
tmpSet.insert(BB);
|
||||||
|
|
||||||
|
for (typename DomSetType::const_iterator I = DS1.begin(), E = DS1.end();
|
||||||
|
I != E;) {
|
||||||
|
BlockT *Node = *I++;
|
||||||
|
|
||||||
|
if (tmpSet.erase(Node) == 0)
|
||||||
|
// Node is in DS1 but tnot in DS2.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!tmpSet.empty()) {
|
||||||
|
// There are nodes that are in DS2 but not in DS1.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// DS1 and DS2 matches.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class BlockT>
|
||||||
|
bool DominanceFrontierBase<BlockT>::compare(
|
||||||
|
DominanceFrontierBase<BlockT> &Other) const {
|
||||||
|
DomSetMapType tmpFrontiers;
|
||||||
|
for (typename DomSetMapType::const_iterator I = Other.begin(),
|
||||||
|
E = Other.end();
|
||||||
|
I != E; ++I)
|
||||||
|
tmpFrontiers.insert(std::make_pair(I->first, I->second));
|
||||||
|
|
||||||
|
for (typename DomSetMapType::iterator I = tmpFrontiers.begin(),
|
||||||
|
E = tmpFrontiers.end();
|
||||||
|
I != E;) {
|
||||||
|
BlockT *Node = I->first;
|
||||||
|
const_iterator DFI = find(Node);
|
||||||
|
if (DFI == end())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (compareDomSet(I->second, DFI->second))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
++I;
|
||||||
|
tmpFrontiers.erase(Node);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!tmpFrontiers.empty())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class BlockT>
|
||||||
|
void DominanceFrontierBase<BlockT>::print(raw_ostream &OS) const {
|
||||||
|
for (const_iterator I = begin(), E = end(); I != E; ++I) {
|
||||||
|
OS << " DomFrontier for BB ";
|
||||||
|
if (I->first)
|
||||||
|
I->first->printAsOperand(OS, false);
|
||||||
|
else
|
||||||
|
OS << " <<exit node>>";
|
||||||
|
OS << " is:\t";
|
||||||
|
|
||||||
|
const std::set<BlockT *> &BBs = I->second;
|
||||||
|
|
||||||
|
for (const BlockT *BB : BBs) {
|
||||||
|
OS << ' ';
|
||||||
|
if (BB)
|
||||||
|
BB->printAsOperand(OS, false);
|
||||||
|
else
|
||||||
|
OS << "<<exit node>>";
|
||||||
|
}
|
||||||
|
OS << '\n';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
|
||||||
|
template <class BlockT>
|
||||||
|
void DominanceFrontierBase<BlockT>::dump() const {
|
||||||
|
print(dbgs());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template <class BlockT>
|
||||||
|
const typename ForwardDominanceFrontierBase<BlockT>::DomSetType &
|
||||||
|
ForwardDominanceFrontierBase<BlockT>::calculate(const DomTreeT &DT,
|
||||||
|
const DomTreeNodeT *Node) {
|
||||||
|
BlockT *BB = Node->getBlock();
|
||||||
|
DomSetType *Result = nullptr;
|
||||||
|
|
||||||
|
std::vector<DFCalculateWorkObject<BlockT>> workList;
|
||||||
|
SmallPtrSet<BlockT *, 32> visited;
|
||||||
|
|
||||||
|
workList.push_back(DFCalculateWorkObject<BlockT>(BB, nullptr, Node, nullptr));
|
||||||
|
do {
|
||||||
|
DFCalculateWorkObject<BlockT> *currentW = &workList.back();
|
||||||
|
assert(currentW && "Missing work object.");
|
||||||
|
|
||||||
|
BlockT *currentBB = currentW->currentBB;
|
||||||
|
BlockT *parentBB = currentW->parentBB;
|
||||||
|
const DomTreeNodeT *currentNode = currentW->Node;
|
||||||
|
const DomTreeNodeT *parentNode = currentW->parentNode;
|
||||||
|
assert(currentBB && "Invalid work object. Missing current Basic Block");
|
||||||
|
assert(currentNode && "Invalid work object. Missing current Node");
|
||||||
|
DomSetType &S = this->Frontiers[currentBB];
|
||||||
|
|
||||||
|
// Visit each block only once.
|
||||||
|
if (visited.count(currentBB) == 0) {
|
||||||
|
visited.insert(currentBB);
|
||||||
|
|
||||||
|
// Loop over CFG successors to calculate DFlocal[currentNode]
|
||||||
|
for (auto SI = BlockTraits::child_begin(currentBB),
|
||||||
|
SE = BlockTraits::child_end(currentBB);
|
||||||
|
SI != SE; ++SI) {
|
||||||
|
// Does Node immediately dominate this successor?
|
||||||
|
if (DT[*SI]->getIDom() != currentNode)
|
||||||
|
S.insert(*SI);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// At this point, S is DFlocal. Now we union in DFup's of our children...
|
||||||
|
// Loop through and visit the nodes that Node immediately dominates (Node's
|
||||||
|
// children in the IDomTree)
|
||||||
|
bool visitChild = false;
|
||||||
|
for (typename DomTreeNodeT::const_iterator NI = currentNode->begin(),
|
||||||
|
NE = currentNode->end();
|
||||||
|
NI != NE; ++NI) {
|
||||||
|
DomTreeNodeT *IDominee = *NI;
|
||||||
|
BlockT *childBB = IDominee->getBlock();
|
||||||
|
if (visited.count(childBB) == 0) {
|
||||||
|
workList.push_back(DFCalculateWorkObject<BlockT>(
|
||||||
|
childBB, currentBB, IDominee, currentNode));
|
||||||
|
visitChild = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If all children are visited or there is any child then pop this block
|
||||||
|
// from the workList.
|
||||||
|
if (!visitChild) {
|
||||||
|
if (!parentBB) {
|
||||||
|
Result = &S;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
typename DomSetType::const_iterator CDFI = S.begin(), CDFE = S.end();
|
||||||
|
DomSetType &parentSet = this->Frontiers[parentBB];
|
||||||
|
for (; CDFI != CDFE; ++CDFI) {
|
||||||
|
if (!DT.properlyDominates(parentNode, DT[*CDFI]))
|
||||||
|
parentSet.insert(*CDFI);
|
||||||
|
}
|
||||||
|
workList.pop_back();
|
||||||
|
}
|
||||||
|
|
||||||
|
} while (!workList.empty());
|
||||||
|
|
||||||
|
return *Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // End llvm namespace
|
||||||
|
|
||||||
|
#endif
|
109
include/llvm/CodeGen/MachineDominanceFrontier.h
Normal file
109
include/llvm/CodeGen/MachineDominanceFrontier.h
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
//===- llvm/CodeGen/MachineDominanceFrontier.h ------------------*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// The LLVM Compiler Infrastructure
|
||||||
|
//
|
||||||
|
// This file is distributed under the University of Illinois Open Source
|
||||||
|
// License. See LICENSE.TXT for details.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef LLVM_CODEGEN_MACHINEDOMINANCEFRONTIER_H
|
||||||
|
#define LLVM_CODEGEN_MACHINEDOMINANCEFRONTIER_H
|
||||||
|
|
||||||
|
#include "llvm/Analysis/DominanceFrontier.h"
|
||||||
|
#include "llvm/CodeGen/MachineBasicBlock.h"
|
||||||
|
#include "llvm/CodeGen/MachineFunctionPass.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace llvm {
|
||||||
|
|
||||||
|
class MachineDominanceFrontier : public MachineFunctionPass {
|
||||||
|
ForwardDominanceFrontierBase<MachineBasicBlock> Base;
|
||||||
|
public:
|
||||||
|
typedef DominatorTreeBase<MachineBasicBlock> DomTreeT;
|
||||||
|
typedef DomTreeNodeBase<MachineBasicBlock> DomTreeNodeT;
|
||||||
|
typedef typename DominanceFrontierBase<MachineBasicBlock>::DomSetType DomSetType;
|
||||||
|
typedef DominanceFrontierBase<MachineBasicBlock>::iterator iterator;
|
||||||
|
typedef DominanceFrontierBase<MachineBasicBlock>::const_iterator const_iterator;
|
||||||
|
|
||||||
|
void operator=(const MachineDominanceFrontier &) LLVM_DELETED_FUNCTION;
|
||||||
|
MachineDominanceFrontier(const MachineDominanceFrontier &) LLVM_DELETED_FUNCTION;
|
||||||
|
|
||||||
|
static char ID;
|
||||||
|
|
||||||
|
MachineDominanceFrontier();
|
||||||
|
|
||||||
|
DominanceFrontierBase<MachineBasicBlock> &getBase() {
|
||||||
|
return Base;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const std::vector<MachineBasicBlock*> &getRoots() const {
|
||||||
|
return Base.getRoots();
|
||||||
|
}
|
||||||
|
|
||||||
|
MachineBasicBlock *getRoot() const {
|
||||||
|
return Base.getRoot();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isPostDominator() const {
|
||||||
|
return Base.isPostDominator();
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator begin() {
|
||||||
|
return Base.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
const_iterator begin() const {
|
||||||
|
return Base.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator end() {
|
||||||
|
return Base.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
const_iterator end() const {
|
||||||
|
return Base.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator find(MachineBasicBlock *B) {
|
||||||
|
return Base.find(B);
|
||||||
|
}
|
||||||
|
|
||||||
|
const_iterator find(MachineBasicBlock *B) const {
|
||||||
|
return Base.find(B);
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator addBasicBlock(MachineBasicBlock *BB, const DomSetType &frontier) {
|
||||||
|
return Base.addBasicBlock(BB, frontier);
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeBlock(MachineBasicBlock *BB) {
|
||||||
|
return Base.removeBlock(BB);
|
||||||
|
}
|
||||||
|
|
||||||
|
void addToFrontier(iterator I, MachineBasicBlock *Node) {
|
||||||
|
return Base.addToFrontier(I, Node);
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeFromFrontier(iterator I, MachineBasicBlock *Node) {
|
||||||
|
return Base.removeFromFrontier(I, Node);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool compareDomSet(DomSetType &DS1, const DomSetType &DS2) const {
|
||||||
|
return Base.compareDomSet(DS1, DS2);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool compare(DominanceFrontierBase<MachineBasicBlock> &Other) const {
|
||||||
|
return Base.compare(Other);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool runOnMachineFunction(MachineFunction &F) override;
|
||||||
|
|
||||||
|
void releaseMemory() override;
|
||||||
|
|
||||||
|
void getAnalysisUsage(AnalysisUsage &AU) const override;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@@ -381,6 +381,9 @@ namespace llvm {
|
|||||||
/// MachineDominators - This pass is a machine dominators analysis pass.
|
/// MachineDominators - This pass is a machine dominators analysis pass.
|
||||||
extern char &MachineDominatorsID;
|
extern char &MachineDominatorsID;
|
||||||
|
|
||||||
|
/// MachineDominanaceFrontier - This pass is a machine dominators analysis pass.
|
||||||
|
extern char &MachineDominanceFrontierID;
|
||||||
|
|
||||||
/// EdgeBundles analysis - Bundle machine CFG edges.
|
/// EdgeBundles analysis - Bundle machine CFG edges.
|
||||||
extern char &EdgeBundlesID;
|
extern char &EdgeBundlesID;
|
||||||
|
|
||||||
|
@@ -184,6 +184,7 @@ void initializeMachineBlockPlacementStatsPass(PassRegistry&);
|
|||||||
void initializeMachineBranchProbabilityInfoPass(PassRegistry&);
|
void initializeMachineBranchProbabilityInfoPass(PassRegistry&);
|
||||||
void initializeMachineCSEPass(PassRegistry&);
|
void initializeMachineCSEPass(PassRegistry&);
|
||||||
void initializeMachineDominatorTreePass(PassRegistry&);
|
void initializeMachineDominatorTreePass(PassRegistry&);
|
||||||
|
void initializeMachineDominanceFrontierPass(PassRegistry&);
|
||||||
void initializeMachinePostDominatorTreePass(PassRegistry&);
|
void initializeMachinePostDominatorTreePass(PassRegistry&);
|
||||||
void initializeMachineLICMPass(PassRegistry&);
|
void initializeMachineLICMPass(PassRegistry&);
|
||||||
void initializeMachineLoopInfoPass(PassRegistry&);
|
void initializeMachineLoopInfoPass(PassRegistry&);
|
||||||
|
@@ -8,133 +8,50 @@
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "llvm/Analysis/DominanceFrontier.h"
|
#include "llvm/Analysis/DominanceFrontier.h"
|
||||||
#include "llvm/ADT/SmallPtrSet.h"
|
#include "llvm/Analysis/DominanceFrontierImpl.h"
|
||||||
#include "llvm/Support/Debug.h"
|
|
||||||
#include "llvm/Support/raw_ostream.h"
|
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
|
namespace llvm {
|
||||||
|
template class DominanceFrontierBase<BasicBlock>;
|
||||||
|
template class ForwardDominanceFrontierBase<BasicBlock>;
|
||||||
|
}
|
||||||
|
|
||||||
char DominanceFrontier::ID = 0;
|
char DominanceFrontier::ID = 0;
|
||||||
|
|
||||||
INITIALIZE_PASS_BEGIN(DominanceFrontier, "domfrontier",
|
INITIALIZE_PASS_BEGIN(DominanceFrontier, "domfrontier",
|
||||||
"Dominance Frontier Construction", true, true)
|
"Dominance Frontier Construction", true, true)
|
||||||
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
|
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
|
||||||
INITIALIZE_PASS_END(DominanceFrontier, "domfrontier",
|
INITIALIZE_PASS_END(DominanceFrontier, "domfrontier",
|
||||||
"Dominance Frontier Construction", true, true)
|
"Dominance Frontier Construction", true, true)
|
||||||
|
|
||||||
namespace {
|
DominanceFrontier::DominanceFrontier()
|
||||||
class DFCalculateWorkObject {
|
: FunctionPass(ID),
|
||||||
public:
|
Base() {
|
||||||
DFCalculateWorkObject(BasicBlock *B, BasicBlock *P,
|
initializeDominanceFrontierPass(*PassRegistry::getPassRegistry());
|
||||||
const DomTreeNode *N,
|
|
||||||
const DomTreeNode *PN)
|
|
||||||
: currentBB(B), parentBB(P), Node(N), parentNode(PN) {}
|
|
||||||
BasicBlock *currentBB;
|
|
||||||
BasicBlock *parentBB;
|
|
||||||
const DomTreeNode *Node;
|
|
||||||
const DomTreeNode *parentNode;
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DominanceFrontier::anchor() { }
|
void DominanceFrontier::releaseMemory() {
|
||||||
|
Base.releaseMemory();
|
||||||
const DominanceFrontier::DomSetType &
|
|
||||||
DominanceFrontier::calculate(const DominatorTree &DT,
|
|
||||||
const DomTreeNode *Node) {
|
|
||||||
BasicBlock *BB = Node->getBlock();
|
|
||||||
DomSetType *Result = nullptr;
|
|
||||||
|
|
||||||
std::vector<DFCalculateWorkObject> workList;
|
|
||||||
SmallPtrSet<BasicBlock *, 32> visited;
|
|
||||||
|
|
||||||
workList.push_back(DFCalculateWorkObject(BB, nullptr, Node, nullptr));
|
|
||||||
do {
|
|
||||||
DFCalculateWorkObject *currentW = &workList.back();
|
|
||||||
assert (currentW && "Missing work object.");
|
|
||||||
|
|
||||||
BasicBlock *currentBB = currentW->currentBB;
|
|
||||||
BasicBlock *parentBB = currentW->parentBB;
|
|
||||||
const DomTreeNode *currentNode = currentW->Node;
|
|
||||||
const DomTreeNode *parentNode = currentW->parentNode;
|
|
||||||
assert (currentBB && "Invalid work object. Missing current Basic Block");
|
|
||||||
assert (currentNode && "Invalid work object. Missing current Node");
|
|
||||||
DomSetType &S = Frontiers[currentBB];
|
|
||||||
|
|
||||||
// Visit each block only once.
|
|
||||||
if (visited.count(currentBB) == 0) {
|
|
||||||
visited.insert(currentBB);
|
|
||||||
|
|
||||||
// Loop over CFG successors to calculate DFlocal[currentNode]
|
|
||||||
for (succ_iterator SI = succ_begin(currentBB), SE = succ_end(currentBB);
|
|
||||||
SI != SE; ++SI) {
|
|
||||||
// Does Node immediately dominate this successor?
|
|
||||||
if (DT[*SI]->getIDom() != currentNode)
|
|
||||||
S.insert(*SI);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// At this point, S is DFlocal. Now we union in DFup's of our children...
|
|
||||||
// Loop through and visit the nodes that Node immediately dominates (Node's
|
|
||||||
// children in the IDomTree)
|
|
||||||
bool visitChild = false;
|
|
||||||
for (DomTreeNode::const_iterator NI = currentNode->begin(),
|
|
||||||
NE = currentNode->end(); NI != NE; ++NI) {
|
|
||||||
DomTreeNode *IDominee = *NI;
|
|
||||||
BasicBlock *childBB = IDominee->getBlock();
|
|
||||||
if (visited.count(childBB) == 0) {
|
|
||||||
workList.push_back(DFCalculateWorkObject(childBB, currentBB,
|
|
||||||
IDominee, currentNode));
|
|
||||||
visitChild = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If all children are visited or there is any child then pop this block
|
|
||||||
// from the workList.
|
|
||||||
if (!visitChild) {
|
|
||||||
|
|
||||||
if (!parentBB) {
|
|
||||||
Result = &S;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
DomSetType::const_iterator CDFI = S.begin(), CDFE = S.end();
|
|
||||||
DomSetType &parentSet = Frontiers[parentBB];
|
|
||||||
for (; CDFI != CDFE; ++CDFI) {
|
|
||||||
if (!DT.properlyDominates(parentNode, DT[*CDFI]))
|
|
||||||
parentSet.insert(*CDFI);
|
|
||||||
}
|
|
||||||
workList.pop_back();
|
|
||||||
}
|
|
||||||
|
|
||||||
} while (!workList.empty());
|
|
||||||
|
|
||||||
return *Result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DominanceFrontierBase::print(raw_ostream &OS, const Module* ) const {
|
bool DominanceFrontier::runOnFunction(Function &) {
|
||||||
for (const_iterator I = begin(), E = end(); I != E; ++I) {
|
releaseMemory();
|
||||||
OS << " DomFrontier for BB ";
|
Base.analyze(getAnalysis<DominatorTreeWrapperPass>().getDomTree());
|
||||||
if (I->first)
|
return false;
|
||||||
I->first->printAsOperand(OS, false);
|
}
|
||||||
else
|
|
||||||
OS << " <<exit node>>";
|
void DominanceFrontier::getAnalysisUsage(AnalysisUsage &AU) const {
|
||||||
OS << " is:\t";
|
AU.setPreservesAll();
|
||||||
|
AU.addRequired<DominatorTreeWrapperPass>();
|
||||||
const std::set<BasicBlock*> &BBs = I->second;
|
}
|
||||||
|
|
||||||
for (std::set<BasicBlock*>::const_iterator I = BBs.begin(), E = BBs.end();
|
void DominanceFrontier::print(raw_ostream &OS, const Module *) const {
|
||||||
I != E; ++I) {
|
Base.print(OS);
|
||||||
OS << ' ';
|
|
||||||
if (*I)
|
|
||||||
(*I)->printAsOperand(OS, false);
|
|
||||||
else
|
|
||||||
OS << "<<exit node>>";
|
|
||||||
}
|
|
||||||
OS << "\n";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
|
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
|
||||||
void DominanceFrontierBase::dump() const {
|
void DominanceFrontier::dump() const {
|
||||||
print(dbgs());
|
print(dbgs());
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@@ -51,6 +51,7 @@ add_llvm_library(LLVMCodeGen
|
|||||||
MachineCodeEmitter.cpp
|
MachineCodeEmitter.cpp
|
||||||
MachineCopyPropagation.cpp
|
MachineCopyPropagation.cpp
|
||||||
MachineDominators.cpp
|
MachineDominators.cpp
|
||||||
|
MachineDominanceFrontier.cpp
|
||||||
MachineFunction.cpp
|
MachineFunction.cpp
|
||||||
MachineFunctionAnalysis.cpp
|
MachineFunctionAnalysis.cpp
|
||||||
MachineFunctionPass.cpp
|
MachineFunctionPass.cpp
|
||||||
|
54
lib/CodeGen/MachineDominanceFrontier.cpp
Normal file
54
lib/CodeGen/MachineDominanceFrontier.cpp
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
//===- MachineDominanceFrontier.cpp ---------------------------------------===//
|
||||||
|
//
|
||||||
|
// The LLVM Compiler Infrastructure
|
||||||
|
//
|
||||||
|
// This file is distributed under the University of Illinois Open Source
|
||||||
|
// License. See LICENSE.TXT for details.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#include "llvm/CodeGen/MachineDominanceFrontier.h"
|
||||||
|
#include "llvm/CodeGen/MachineDominators.h"
|
||||||
|
#include "llvm/Analysis/DominanceFrontierImpl.h"
|
||||||
|
#include "llvm/CodeGen/Passes.h"
|
||||||
|
|
||||||
|
|
||||||
|
using namespace llvm;
|
||||||
|
|
||||||
|
namespace llvm {
|
||||||
|
template class DominanceFrontierBase<MachineBasicBlock>;
|
||||||
|
template class ForwardDominanceFrontierBase<MachineBasicBlock>;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char MachineDominanceFrontier::ID = 0;
|
||||||
|
|
||||||
|
INITIALIZE_PASS_BEGIN(MachineDominanceFrontier, "machine-domfrontier",
|
||||||
|
"Machine Dominance Frontier Construction", true, true)
|
||||||
|
INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
|
||||||
|
INITIALIZE_PASS_END(MachineDominanceFrontier, "machine-domfrontier",
|
||||||
|
"Machine Dominance Frontier Construction", true, true)
|
||||||
|
|
||||||
|
MachineDominanceFrontier::MachineDominanceFrontier()
|
||||||
|
: MachineFunctionPass(ID),
|
||||||
|
Base() {
|
||||||
|
initializeMachineDominanceFrontierPass(*PassRegistry::getPassRegistry());
|
||||||
|
}
|
||||||
|
|
||||||
|
char &llvm::MachineDominanceFrontierID = MachineDominanceFrontier::ID;
|
||||||
|
|
||||||
|
bool MachineDominanceFrontier::runOnMachineFunction(MachineFunction &) {
|
||||||
|
releaseMemory();
|
||||||
|
Base.analyze(getAnalysis<MachineDominatorTree>().getBase());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MachineDominanceFrontier::releaseMemory() {
|
||||||
|
Base.releaseMemory();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MachineDominanceFrontier::getAnalysisUsage(AnalysisUsage &AU) const {
|
||||||
|
AU.setPreservesAll();
|
||||||
|
AU.addRequired<MachineDominatorTree>();
|
||||||
|
MachineFunctionPass::getAnalysisUsage(AU);
|
||||||
|
}
|
Reference in New Issue
Block a user