mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 12:41:49 +01:00
[Dominators] Make IsPostDominator a template parameter
Summary: DominatorTreeBase used to have IsPostDominators (bool) member to indicate if the tree is a dominator or a postdominator tree. This made it possible to switch between the two 'modes' at runtime, but it isn't used in practice anywhere. This patch makes IsPostDominator a template argument. This way, it is easier to switch between different algorithms at compile-time based on this argument and design external utilities around it. It also makes it impossible to incidentally assign a postdominator tree to a dominator tree (and vice versa), and to further simplify template code in GenericDominatorTreeConstruction. Reviewers: dberlin, sanjoy, davide, grosser Reviewed By: dberlin Subscribers: mzolotukhin, llvm-commits Differential Revision: https://reviews.llvm.org/D35315 llvm-svn: 308040
This commit is contained in:
parent
18d2353dc7
commit
aa78fc4f6e
@ -29,9 +29,9 @@ namespace llvm {
|
||||
/// DominanceFrontierBase - Common base class for computing forward and inverse
|
||||
/// dominance frontiers for a function.
|
||||
///
|
||||
template <class BlockT>
|
||||
template <class BlockT, bool IsPostDom>
|
||||
class DominanceFrontierBase {
|
||||
public:
|
||||
public:
|
||||
typedef std::set<BlockT *> DomSetType; // Dom set for a bb
|
||||
typedef std::map<BlockT *, DomSetType> DomSetMapType; // Dom set map
|
||||
|
||||
@ -40,10 +40,10 @@ protected:
|
||||
|
||||
DomSetMapType Frontiers;
|
||||
std::vector<BlockT *> Roots;
|
||||
const bool IsPostDominators;
|
||||
static constexpr bool IsPostDominators = IsPostDom;
|
||||
|
||||
public:
|
||||
DominanceFrontierBase(bool isPostDom) : IsPostDominators(isPostDom) {}
|
||||
public:
|
||||
DominanceFrontierBase() = default;
|
||||
|
||||
/// getRoots - Return the root blocks of the current CFG. This may include
|
||||
/// multiple blocks if we are computing post dominators. For forward
|
||||
@ -96,7 +96,7 @@ public:
|
||||
|
||||
/// compare - Return true if the other dominance frontier base matches
|
||||
/// this dominance frontier base. Otherwise return false.
|
||||
bool compare(DominanceFrontierBase<BlockT> &Other) const;
|
||||
bool compare(DominanceFrontierBase &Other) const;
|
||||
|
||||
/// print - Convert to human readable form
|
||||
///
|
||||
@ -113,22 +113,21 @@ public:
|
||||
/// used to compute a forward dominator frontiers.
|
||||
///
|
||||
template <class BlockT>
|
||||
class ForwardDominanceFrontierBase : public DominanceFrontierBase<BlockT> {
|
||||
private:
|
||||
class ForwardDominanceFrontierBase
|
||||
: public DominanceFrontierBase<BlockT, false> {
|
||||
private:
|
||||
typedef GraphTraits<BlockT *> BlockTraits;
|
||||
|
||||
public:
|
||||
typedef DominatorTreeBase<BlockT> DomTreeT;
|
||||
typedef DomTreeNodeBase<BlockT> DomTreeNodeT;
|
||||
typedef typename DominanceFrontierBase<BlockT>::DomSetType DomSetType;
|
||||
typedef DomTreeBase<BlockT> DomTreeT;
|
||||
typedef DomTreeNodeBase<BlockT> DomTreeNodeT;
|
||||
typedef typename DominanceFrontierBase<BlockT, false>::DomSetType DomSetType;
|
||||
|
||||
ForwardDominanceFrontierBase() : DominanceFrontierBase<BlockT>(false) {}
|
||||
|
||||
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]]);
|
||||
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]]);
|
||||
}
|
||||
|
||||
const DomSetType &calculate(const DomTreeT &DT, const DomTreeNodeT *Node);
|
||||
@ -136,15 +135,16 @@ public:
|
||||
|
||||
class DominanceFrontier : public ForwardDominanceFrontierBase<BasicBlock> {
|
||||
public:
|
||||
typedef DominatorTreeBase<BasicBlock> DomTreeT;
|
||||
typedef DomTreeNodeBase<BasicBlock> DomTreeNodeT;
|
||||
typedef DominanceFrontierBase<BasicBlock>::DomSetType DomSetType;
|
||||
typedef DominanceFrontierBase<BasicBlock>::iterator iterator;
|
||||
typedef DominanceFrontierBase<BasicBlock>::const_iterator const_iterator;
|
||||
typedef DomTreeBase<BasicBlock> DomTreeT;
|
||||
typedef DomTreeNodeBase<BasicBlock> DomTreeNodeT;
|
||||
typedef DominanceFrontierBase<BasicBlock, false>::DomSetType DomSetType;
|
||||
typedef DominanceFrontierBase<BasicBlock, false>::iterator iterator;
|
||||
typedef DominanceFrontierBase<BasicBlock, false>::const_iterator
|
||||
const_iterator;
|
||||
|
||||
/// Handle invalidation explicitly.
|
||||
bool invalidate(Function &F, const PreservedAnalyses &PA,
|
||||
FunctionAnalysisManager::Invalidator &);
|
||||
/// Handle invalidation explicitly.
|
||||
bool invalidate(Function &F, const PreservedAnalyses &PA,
|
||||
FunctionAnalysisManager::Invalidator &);
|
||||
};
|
||||
|
||||
class DominanceFrontierWrapperPass : public FunctionPass {
|
||||
@ -168,7 +168,8 @@ public:
|
||||
void dump() const;
|
||||
};
|
||||
|
||||
extern template class DominanceFrontierBase<BasicBlock>;
|
||||
extern template class DominanceFrontierBase<BasicBlock, false>;
|
||||
extern template class DominanceFrontierBase<BasicBlock, true>;
|
||||
extern template class ForwardDominanceFrontierBase<BasicBlock>;
|
||||
|
||||
/// \brief Analysis pass which computes a \c DominanceFrontier.
|
||||
|
@ -39,33 +39,33 @@ public:
|
||||
const DomTreeNodeT *parentNode;
|
||||
};
|
||||
|
||||
template <class BlockT>
|
||||
void DominanceFrontierBase<BlockT>::removeBlock(BlockT *BB) {
|
||||
template <class BlockT, bool IsPostDom>
|
||||
void DominanceFrontierBase<BlockT, IsPostDom>::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>::addToFrontier(iterator I,
|
||||
BlockT *Node) {
|
||||
template <class BlockT, bool IsPostDom>
|
||||
void DominanceFrontierBase<BlockT, IsPostDom>::addToFrontier(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>
|
||||
void DominanceFrontierBase<BlockT>::removeFromFrontier(iterator I,
|
||||
BlockT *Node) {
|
||||
template <class BlockT, bool IsPostDom>
|
||||
void DominanceFrontierBase<BlockT, IsPostDom>::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 {
|
||||
template <class BlockT, bool IsPostDom>
|
||||
bool DominanceFrontierBase<BlockT, IsPostDom>::compareDomSet(
|
||||
DomSetType &DS1, const DomSetType &DS2) const {
|
||||
std::set<BlockT *> tmpSet;
|
||||
for (BlockT *BB : DS2)
|
||||
tmpSet.insert(BB);
|
||||
@ -88,9 +88,9 @@ bool DominanceFrontierBase<BlockT>::compareDomSet(DomSetType &DS1,
|
||||
return false;
|
||||
}
|
||||
|
||||
template <class BlockT>
|
||||
bool DominanceFrontierBase<BlockT>::compare(
|
||||
DominanceFrontierBase<BlockT> &Other) const {
|
||||
template <class BlockT, bool IsPostDom>
|
||||
bool DominanceFrontierBase<BlockT, IsPostDom>::compare(
|
||||
DominanceFrontierBase<BlockT, IsPostDom> &Other) const {
|
||||
DomSetMapType tmpFrontiers;
|
||||
for (typename DomSetMapType::const_iterator I = Other.begin(),
|
||||
E = Other.end();
|
||||
@ -118,8 +118,8 @@ bool DominanceFrontierBase<BlockT>::compare(
|
||||
return false;
|
||||
}
|
||||
|
||||
template <class BlockT>
|
||||
void DominanceFrontierBase<BlockT>::print(raw_ostream &OS) const {
|
||||
template <class BlockT, bool IsPostDom>
|
||||
void DominanceFrontierBase<BlockT, IsPostDom>::print(raw_ostream &OS) const {
|
||||
for (const_iterator I = begin(), E = end(); I != E; ++I) {
|
||||
OS << " DomFrontier for BB ";
|
||||
if (I->first)
|
||||
@ -142,8 +142,8 @@ void DominanceFrontierBase<BlockT>::print(raw_ostream &OS) const {
|
||||
}
|
||||
|
||||
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
|
||||
template <class BlockT>
|
||||
void DominanceFrontierBase<BlockT>::dump() const {
|
||||
template <class BlockT, bool IsPostDom>
|
||||
void DominanceFrontierBase<BlockT, IsPostDom>::dump() const {
|
||||
print(dbgs());
|
||||
}
|
||||
#endif
|
||||
|
@ -42,11 +42,11 @@ namespace llvm {
|
||||
/// By default, liveness is not used to prune the IDF computation.
|
||||
/// The template parameters should be either BasicBlock* or Inverse<BasicBlock
|
||||
/// *>, depending on if you want the forward or reverse IDF.
|
||||
template <class NodeTy>
|
||||
template <class NodeTy, bool IsPostDom>
|
||||
class IDFCalculator {
|
||||
|
||||
public:
|
||||
IDFCalculator(DominatorTreeBase<BasicBlock> &DT) : DT(DT), useLiveIn(false) {}
|
||||
public:
|
||||
IDFCalculator(DominatorTreeBase<BasicBlock, IsPostDom> &DT)
|
||||
: DT(DT), useLiveIn(false) {}
|
||||
|
||||
/// \brief Give the IDF calculator the set of blocks in which the value is
|
||||
/// defined. This is equivalent to the set of starting blocks it should be
|
||||
@ -84,12 +84,12 @@ public:
|
||||
void calculate(SmallVectorImpl<BasicBlock *> &IDFBlocks);
|
||||
|
||||
private:
|
||||
DominatorTreeBase<BasicBlock> &DT;
|
||||
bool useLiveIn;
|
||||
const SmallPtrSetImpl<BasicBlock *> *LiveInBlocks;
|
||||
const SmallPtrSetImpl<BasicBlock *> *DefBlocks;
|
||||
DominatorTreeBase<BasicBlock, IsPostDom> &DT;
|
||||
bool useLiveIn;
|
||||
const SmallPtrSetImpl<BasicBlock *> *LiveInBlocks;
|
||||
const SmallPtrSetImpl<BasicBlock *> *DefBlocks;
|
||||
};
|
||||
typedef IDFCalculator<BasicBlock *> ForwardIDFCalculator;
|
||||
typedef IDFCalculator<Inverse<BasicBlock *>> ReverseIDFCalculator;
|
||||
typedef IDFCalculator<BasicBlock *, false> ForwardIDFCalculator;
|
||||
typedef IDFCalculator<Inverse<BasicBlock *>, true> ReverseIDFCalculator;
|
||||
}
|
||||
#endif
|
||||
|
@ -56,7 +56,8 @@ class Loop;
|
||||
class MDNode;
|
||||
class PHINode;
|
||||
class raw_ostream;
|
||||
template<class N> class DominatorTreeBase;
|
||||
template <class N, bool IsPostDom>
|
||||
class DominatorTreeBase;
|
||||
template<class N, class M> class LoopInfoBase;
|
||||
template<class N, class M> class LoopBase;
|
||||
|
||||
@ -663,12 +664,12 @@ public:
|
||||
}
|
||||
|
||||
/// Create the loop forest using a stable algorithm.
|
||||
void analyze(const DominatorTreeBase<BlockT> &DomTree);
|
||||
void analyze(const DominatorTreeBase<BlockT, false> &DomTree);
|
||||
|
||||
// Debugging
|
||||
void print(raw_ostream &OS) const;
|
||||
|
||||
void verify(const DominatorTreeBase<BlockT> &DomTree) const;
|
||||
void verify(const DominatorTreeBase<BlockT, false> &DomTree) const;
|
||||
};
|
||||
|
||||
// Implementation in LoopInfoImpl.h
|
||||
@ -683,7 +684,7 @@ class LoopInfo : public LoopInfoBase<BasicBlock, Loop> {
|
||||
LoopInfo(const LoopInfo &) = delete;
|
||||
public:
|
||||
LoopInfo() {}
|
||||
explicit LoopInfo(const DominatorTreeBase<BasicBlock> &DomTree);
|
||||
explicit LoopInfo(const DominatorTreeBase<BasicBlock, false> &DomTree);
|
||||
|
||||
LoopInfo(LoopInfo &&Arg) : BaseT(std::move(static_cast<BaseT &>(Arg))) {}
|
||||
LoopInfo &operator=(LoopInfo &&RHS) {
|
||||
|
@ -340,10 +340,10 @@ void LoopBase<BlockT, LoopT>::print(raw_ostream &OS, unsigned Depth,
|
||||
/// Discover a subloop with the specified backedges such that: All blocks within
|
||||
/// this loop are mapped to this loop or a subloop. And all subloops within this
|
||||
/// loop have their parent loop set to this loop or a subloop.
|
||||
template<class BlockT, class LoopT>
|
||||
static void discoverAndMapSubloop(LoopT *L, ArrayRef<BlockT*> Backedges,
|
||||
LoopInfoBase<BlockT, LoopT> *LI,
|
||||
const DominatorTreeBase<BlockT> &DomTree) {
|
||||
template <class BlockT, class LoopT>
|
||||
static void discoverAndMapSubloop(
|
||||
LoopT *L, ArrayRef<BlockT *> Backedges, LoopInfoBase<BlockT, LoopT> *LI,
|
||||
const DomTreeBase<BlockT> &DomTree) {
|
||||
typedef GraphTraits<Inverse<BlockT*> > InvBlockTraits;
|
||||
|
||||
unsigned NumBlocks = 0;
|
||||
@ -462,10 +462,9 @@ void PopulateLoopsDFS<BlockT, LoopT>::insertIntoLoop(BlockT *Block) {
|
||||
///
|
||||
/// The Block vectors are inclusive, so step 3 requires loop-depth number of
|
||||
/// insertions per block.
|
||||
template<class BlockT, class LoopT>
|
||||
void LoopInfoBase<BlockT, LoopT>::
|
||||
analyze(const DominatorTreeBase<BlockT> &DomTree) {
|
||||
|
||||
template <class BlockT, class LoopT>
|
||||
void LoopInfoBase<BlockT, LoopT>::analyze(
|
||||
const DomTreeBase<BlockT> &DomTree) {
|
||||
// Postorder traversal of the dominator tree.
|
||||
const DomTreeNodeBase<BlockT> *DomRoot = DomTree.getRootNode();
|
||||
for (auto DomNode : post_order(DomRoot)) {
|
||||
@ -607,7 +606,7 @@ static void compareLoops(const LoopT *L, const LoopT *OtherL,
|
||||
|
||||
template <class BlockT, class LoopT>
|
||||
void LoopInfoBase<BlockT, LoopT>::verify(
|
||||
const DominatorTreeBase<BlockT> &DomTree) const {
|
||||
const DomTreeBase<BlockT> &DomTree) const {
|
||||
DenseSet<const LoopT*> Loops;
|
||||
for (iterator I = begin(), E = end(); I != E; ++I) {
|
||||
assert(!(*I)->getParentLoop() && "Top-level loop has a parent!");
|
||||
|
@ -22,10 +22,8 @@ namespace llvm {
|
||||
/// PostDominatorTree Class - Concrete subclass of DominatorTree that is used to
|
||||
/// compute the post-dominator tree.
|
||||
///
|
||||
struct PostDominatorTree : public DominatorTreeBase<BasicBlock> {
|
||||
typedef DominatorTreeBase<BasicBlock> Base;
|
||||
|
||||
PostDominatorTree() : DominatorTreeBase<BasicBlock>(true) {}
|
||||
struct PostDominatorTree : public PostDomTreeBase<BasicBlock> {
|
||||
typedef PostDomTreeBase<BasicBlock> Base;
|
||||
|
||||
/// Handle invalidation explicitly.
|
||||
bool invalidate(Function &F, const PreservedAnalyses &PA,
|
||||
|
@ -23,27 +23,24 @@ class MachineDominanceFrontier : public MachineFunctionPass {
|
||||
ForwardDominanceFrontierBase<MachineBasicBlock> Base;
|
||||
|
||||
public:
|
||||
using DomTreeT = DominatorTreeBase<MachineBasicBlock>;
|
||||
using DomTreeNodeT = DomTreeNodeBase<MachineBasicBlock>;
|
||||
using DomSetType = DominanceFrontierBase<MachineBasicBlock>::DomSetType;
|
||||
using iterator = DominanceFrontierBase<MachineBasicBlock>::iterator;
|
||||
using const_iterator =
|
||||
DominanceFrontierBase<MachineBasicBlock>::const_iterator;
|
||||
using DomTreeT = DomTreeBase<MachineBasicBlock>;
|
||||
using DomTreeNodeT = DomTreeNodeBase<MachineBasicBlock>;
|
||||
using DomSetType = DominanceFrontierBase<MachineBasicBlock, false>::DomSetType;
|
||||
using iterator = DominanceFrontierBase<MachineBasicBlock, false>::iterator;
|
||||
using const_iterator =
|
||||
DominanceFrontierBase<MachineBasicBlock, false>::const_iterator;
|
||||
|
||||
MachineDominanceFrontier(const MachineDominanceFrontier &) = delete;
|
||||
MachineDominanceFrontier &
|
||||
operator=(const MachineDominanceFrontier &) = delete;
|
||||
MachineDominanceFrontier(const MachineDominanceFrontier &) = delete;
|
||||
MachineDominanceFrontier &operator=(const MachineDominanceFrontier &) = delete;
|
||||
|
||||
static char ID;
|
||||
static char ID;
|
||||
|
||||
MachineDominanceFrontier();
|
||||
MachineDominanceFrontier();
|
||||
|
||||
DominanceFrontierBase<MachineBasicBlock> &getBase() {
|
||||
return Base;
|
||||
}
|
||||
DominanceFrontierBase<MachineBasicBlock, false> &getBase() { return Base; }
|
||||
|
||||
inline const std::vector<MachineBasicBlock*> &getRoots() const {
|
||||
return Base.getRoots();
|
||||
inline const std::vector<MachineBasicBlock *> &getRoots() const {
|
||||
return Base.getRoots();
|
||||
}
|
||||
|
||||
MachineBasicBlock *getRoot() const {
|
||||
@ -98,7 +95,7 @@ public:
|
||||
return Base.compareDomSet(DS1, DS2);
|
||||
}
|
||||
|
||||
bool compare(DominanceFrontierBase<MachineBasicBlock> &Other) const {
|
||||
bool compare(DominanceFrontierBase<MachineBasicBlock, false> &Other) const {
|
||||
return Base.compare(Other);
|
||||
}
|
||||
|
||||
|
@ -28,13 +28,15 @@
|
||||
|
||||
namespace llvm {
|
||||
|
||||
template<>
|
||||
inline void DominatorTreeBase<MachineBasicBlock>::addRoot(MachineBasicBlock* MBB) {
|
||||
template <>
|
||||
inline void DominatorTreeBase<MachineBasicBlock, false>::addRoot(
|
||||
MachineBasicBlock *MBB) {
|
||||
this->Roots.push_back(MBB);
|
||||
}
|
||||
|
||||
extern template class DomTreeNodeBase<MachineBasicBlock>;
|
||||
extern template class DominatorTreeBase<MachineBasicBlock>;
|
||||
extern template class DominatorTreeBase<MachineBasicBlock, false>; // DomTree
|
||||
extern template class DominatorTreeBase<MachineBasicBlock, true>; // PostDomTree
|
||||
|
||||
using MachineDomTreeNode = DomTreeNodeBase<MachineBasicBlock>;
|
||||
|
||||
@ -65,7 +67,7 @@ class MachineDominatorTree : public MachineFunctionPass {
|
||||
mutable SmallSet<MachineBasicBlock *, 32> NewBBs;
|
||||
|
||||
/// The DominatorTreeBase that is used to compute a normal dominator tree
|
||||
std::unique_ptr<DominatorTreeBase<MachineBasicBlock>> DT;
|
||||
std::unique_ptr<DomTreeBase<MachineBasicBlock>> DT;
|
||||
|
||||
/// \brief Apply all the recorded critical edges to the DT.
|
||||
/// This updates the underlying DT information in a way that uses
|
||||
@ -79,9 +81,8 @@ public:
|
||||
|
||||
MachineDominatorTree();
|
||||
|
||||
DominatorTreeBase<MachineBasicBlock> &getBase() {
|
||||
if (!DT)
|
||||
DT.reset(new DominatorTreeBase<MachineBasicBlock>(false));
|
||||
DomTreeBase<MachineBasicBlock> &getBase() {
|
||||
if (!DT) DT.reset(new DomTreeBase<MachineBasicBlock>());
|
||||
applySplitCriticalEdges();
|
||||
return *DT;
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ namespace llvm {
|
||||
///
|
||||
struct MachinePostDominatorTree : public MachineFunctionPass {
|
||||
private:
|
||||
DominatorTreeBase<MachineBasicBlock> *DT;
|
||||
PostDomTreeBase<MachineBasicBlock> *DT;
|
||||
|
||||
public:
|
||||
static char ID;
|
||||
|
@ -34,14 +34,19 @@ class Module;
|
||||
class raw_ostream;
|
||||
|
||||
extern template class DomTreeNodeBase<BasicBlock>;
|
||||
extern template class DominatorTreeBase<BasicBlock>;
|
||||
extern template class DominatorTreeBase<BasicBlock, false>; // DomTree
|
||||
extern template class DominatorTreeBase<BasicBlock, true>; // PostDomTree
|
||||
|
||||
namespace DomTreeBuilder {
|
||||
using BBDomTree = DominatorTreeBase<BasicBlock>;
|
||||
using BBDomTree = DomTreeBase<BasicBlock>;
|
||||
using BBPostDomTree = PostDomTreeBase<BasicBlock>;
|
||||
|
||||
extern template void Calculate<BBDomTree, Function>(BBDomTree &DT, Function &F);
|
||||
extern template void Calculate<BBPostDomTree, Function>(BBPostDomTree &DT,
|
||||
Function &F);
|
||||
|
||||
extern template bool Verify<BBDomTree>(const BBDomTree &DT);
|
||||
extern template bool Verify<BBPostDomTree>(const BBPostDomTree &DT);
|
||||
} // namespace DomTreeBuilder
|
||||
|
||||
using DomTreeNode = DomTreeNodeBase<BasicBlock>;
|
||||
@ -114,14 +119,12 @@ template <> struct DenseMapInfo<BasicBlockEdge> {
|
||||
/// the dominator tree is initially constructed may still exist in the tree,
|
||||
/// even if the tree is properly updated. Calling code should not rely on the
|
||||
/// preceding statements; this is stated only to assist human understanding.
|
||||
class DominatorTree : public DominatorTreeBase<BasicBlock> {
|
||||
public:
|
||||
using Base = DominatorTreeBase<BasicBlock>;
|
||||
class DominatorTree : public DominatorTreeBase<BasicBlock, false> {
|
||||
public:
|
||||
using Base = DominatorTreeBase<BasicBlock, false>;
|
||||
|
||||
DominatorTree() : DominatorTreeBase<BasicBlock>(false) {}
|
||||
explicit DominatorTree(Function &F) : DominatorTreeBase<BasicBlock>(false) {
|
||||
recalculate(F);
|
||||
}
|
||||
DominatorTree() = default;
|
||||
explicit DominatorTree(Function &F) { recalculate(F); }
|
||||
|
||||
/// Handle invalidation explicitly.
|
||||
bool invalidate(Function &F, const PreservedAnalyses &PA,
|
||||
|
@ -41,12 +41,14 @@
|
||||
|
||||
namespace llvm {
|
||||
|
||||
template <class NodeT> class DominatorTreeBase;
|
||||
template <typename NodeT, bool IsPostDom>
|
||||
class DominatorTreeBase;
|
||||
|
||||
/// \brief Base class for the actual dominator tree node.
|
||||
template <class NodeT> class DomTreeNodeBase {
|
||||
friend struct PostDominatorTree;
|
||||
friend class DominatorTreeBase<NodeT>;
|
||||
friend class DominatorTreeBase<NodeT, false>;
|
||||
friend class DominatorTreeBase<NodeT, true>;
|
||||
|
||||
NodeT *TheBB;
|
||||
DomTreeNodeBase *IDom;
|
||||
@ -185,7 +187,7 @@ template <typename DomTreeT, typename FuncT>
|
||||
void Calculate(DomTreeT &DT, FuncT &F);
|
||||
|
||||
// The verify function is provided in a separate header but referenced here.
|
||||
template <class DomTreeT>
|
||||
template <typename DomTreeT>
|
||||
bool Verify(const DomTreeT &DT);
|
||||
} // namespace DomTreeBuilder
|
||||
|
||||
@ -193,10 +195,10 @@ bool Verify(const DomTreeT &DT);
|
||||
///
|
||||
/// This class is a generic template over graph nodes. It is instantiated for
|
||||
/// various graphs in the LLVM IR or in the code generator.
|
||||
template <class NodeT> class DominatorTreeBase {
|
||||
template <typename NodeT, bool IsPostDom>
|
||||
class DominatorTreeBase {
|
||||
protected:
|
||||
std::vector<NodeT *> Roots;
|
||||
bool IsPostDominators;
|
||||
|
||||
using DomTreeNodeMapType =
|
||||
DenseMap<NodeT *, std::unique_ptr<DomTreeNodeBase<NodeT>>>;
|
||||
@ -213,11 +215,12 @@ template <class NodeT> class DominatorTreeBase {
|
||||
"Currently DominatorTreeBase supports only pointer nodes");
|
||||
using NodeType = NodeT;
|
||||
using NodePtr = NodeT *;
|
||||
explicit DominatorTreeBase(bool isPostDom) : IsPostDominators(isPostDom) {}
|
||||
static constexpr bool IsPostDominator = IsPostDom;
|
||||
|
||||
DominatorTreeBase() = default;
|
||||
|
||||
DominatorTreeBase(DominatorTreeBase &&Arg)
|
||||
: Roots(std::move(Arg.Roots)),
|
||||
IsPostDominators(Arg.IsPostDominators),
|
||||
DomTreeNodes(std::move(Arg.DomTreeNodes)),
|
||||
RootNode(std::move(Arg.RootNode)),
|
||||
DFSInfoValid(std::move(Arg.DFSInfoValid)),
|
||||
@ -227,7 +230,6 @@ template <class NodeT> class DominatorTreeBase {
|
||||
|
||||
DominatorTreeBase &operator=(DominatorTreeBase &&RHS) {
|
||||
Roots = std::move(RHS.Roots);
|
||||
IsPostDominators = RHS.IsPostDominators;
|
||||
DomTreeNodes = std::move(RHS.DomTreeNodes);
|
||||
RootNode = std::move(RHS.RootNode);
|
||||
DFSInfoValid = std::move(RHS.DFSInfoValid);
|
||||
@ -247,7 +249,7 @@ template <class NodeT> class DominatorTreeBase {
|
||||
|
||||
/// isPostDominator - Returns true if analysis based of postdoms
|
||||
///
|
||||
bool isPostDominator() const { return IsPostDominators; }
|
||||
bool isPostDominator() const { return IsPostDominator; }
|
||||
|
||||
/// compare - Return false if the other dominator tree base matches this
|
||||
/// dominator tree base. Otherwise return true.
|
||||
@ -522,7 +524,7 @@ template <class NodeT> class DominatorTreeBase {
|
||||
/// splitBlock - BB is split and now it has one successor. Update dominator
|
||||
/// tree to reflect this change.
|
||||
void splitBlock(NodeT *NewBB) {
|
||||
if (this->IsPostDominators)
|
||||
if (IsPostDominator)
|
||||
Split<Inverse<NodeT *>>(NewBB);
|
||||
else
|
||||
Split<NodeT *>(NewBB);
|
||||
@ -600,7 +602,7 @@ public:
|
||||
using TraitsTy = GraphTraits<FT *>;
|
||||
reset();
|
||||
|
||||
if (!IsPostDominators) {
|
||||
if (!IsPostDominator) {
|
||||
// Initialize root
|
||||
NodeT *entry = TraitsTy::getEntryNode(&F);
|
||||
addRoot(entry);
|
||||
@ -708,10 +710,17 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
using DomTreeBase = DominatorTreeBase<T, false>;
|
||||
|
||||
template <typename T>
|
||||
using PostDomTreeBase = DominatorTreeBase<T, true>;
|
||||
|
||||
// These two functions are declared out of line as a workaround for building
|
||||
// with old (< r147295) versions of clang because of pr11642.
|
||||
template <class NodeT>
|
||||
bool DominatorTreeBase<NodeT>::dominates(const NodeT *A, const NodeT *B) const {
|
||||
template <typename NodeT, bool IsPostDom>
|
||||
bool DominatorTreeBase<NodeT, IsPostDom>::dominates(const NodeT *A,
|
||||
const NodeT *B) const {
|
||||
if (A == B)
|
||||
return true;
|
||||
|
||||
@ -721,9 +730,9 @@ bool DominatorTreeBase<NodeT>::dominates(const NodeT *A, const NodeT *B) const {
|
||||
return dominates(getNode(const_cast<NodeT *>(A)),
|
||||
getNode(const_cast<NodeT *>(B)));
|
||||
}
|
||||
template <class NodeT>
|
||||
bool DominatorTreeBase<NodeT>::properlyDominates(const NodeT *A,
|
||||
const NodeT *B) const {
|
||||
template <typename NodeT, bool IsPostDom>
|
||||
bool DominatorTreeBase<NodeT, IsPostDom>::properlyDominates(
|
||||
const NodeT *A, const NodeT *B) const {
|
||||
if (A == B)
|
||||
return false;
|
||||
|
||||
|
@ -14,7 +14,8 @@
|
||||
using namespace llvm;
|
||||
|
||||
namespace llvm {
|
||||
template class DominanceFrontierBase<BasicBlock>;
|
||||
template class DominanceFrontierBase<BasicBlock, false>;
|
||||
template class DominanceFrontierBase<BasicBlock, true>;
|
||||
template class ForwardDominanceFrontierBase<BasicBlock>;
|
||||
}
|
||||
|
||||
|
@ -17,8 +17,8 @@
|
||||
#include <queue>
|
||||
|
||||
namespace llvm {
|
||||
template <class NodeTy>
|
||||
void IDFCalculator<NodeTy>::calculate(
|
||||
template <class NodeTy, bool IsPostDom>
|
||||
void IDFCalculator<NodeTy, IsPostDom>::calculate(
|
||||
SmallVectorImpl<BasicBlock *> &PHIBlocks) {
|
||||
// Use a priority queue keyed on dominator tree level so that inserted nodes
|
||||
// are handled from the bottom of the dominator tree upwards.
|
||||
@ -88,6 +88,6 @@ void IDFCalculator<NodeTy>::calculate(
|
||||
}
|
||||
}
|
||||
|
||||
template class IDFCalculator<BasicBlock *>;
|
||||
template class IDFCalculator<Inverse<BasicBlock *>>;
|
||||
template class IDFCalculator<BasicBlock *, false>;
|
||||
template class IDFCalculator<Inverse<BasicBlock *>, true>;
|
||||
}
|
||||
|
@ -609,7 +609,7 @@ Loop *UnloopUpdater::getNearestLoop(BasicBlock *BB, Loop *BBLoop) {
|
||||
return NearLoop;
|
||||
}
|
||||
|
||||
LoopInfo::LoopInfo(const DominatorTreeBase<BasicBlock> &DomTree) {
|
||||
LoopInfo::LoopInfo(const DomTreeBase<BasicBlock> &DomTree) {
|
||||
analyze(DomTree);
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,8 @@ using namespace llvm;
|
||||
|
||||
#define DEBUG_TYPE "postdomtree"
|
||||
|
||||
template class llvm::DominatorTreeBase<BasicBlock, true>; // PostDomTreeBase
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// PostDominatorTree Implementation
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -15,7 +15,8 @@
|
||||
using namespace llvm;
|
||||
|
||||
namespace llvm {
|
||||
template class DominanceFrontierBase<MachineBasicBlock>;
|
||||
template class DominanceFrontierBase<MachineBasicBlock, false>;
|
||||
template class DominanceFrontierBase<MachineBasicBlock, true>;
|
||||
template class ForwardDominanceFrontierBase<MachineBasicBlock>;
|
||||
}
|
||||
|
||||
|
@ -31,7 +31,7 @@ static cl::opt<bool, true> VerifyMachineDomInfoX(
|
||||
|
||||
namespace llvm {
|
||||
template class DomTreeNodeBase<MachineBasicBlock>;
|
||||
template class DominatorTreeBase<MachineBasicBlock>;
|
||||
template class DominatorTreeBase<MachineBasicBlock, false>; // DomTreeBase
|
||||
}
|
||||
|
||||
char MachineDominatorTree::ID = 0;
|
||||
@ -49,7 +49,7 @@ void MachineDominatorTree::getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
bool MachineDominatorTree::runOnMachineFunction(MachineFunction &F) {
|
||||
CriticalEdgesToSplit.clear();
|
||||
NewBBs.clear();
|
||||
DT.reset(new DominatorTreeBase<MachineBasicBlock>(false));
|
||||
DT.reset(new DomTreeBase<MachineBasicBlock>());
|
||||
DT->recalculate(F);
|
||||
return false;
|
||||
}
|
||||
@ -144,7 +144,7 @@ void MachineDominatorTree::verifyDomTree() const {
|
||||
return;
|
||||
MachineFunction &F = *getRoot()->getParent();
|
||||
|
||||
DominatorTreeBase<MachineBasicBlock> OtherDT(false);
|
||||
DomTreeBase<MachineBasicBlock> OtherDT;
|
||||
OtherDT.recalculate(F);
|
||||
if (getRootNode()->getBlock() != OtherDT.getRootNode()->getBlock() ||
|
||||
DT->compare(OtherDT)) {
|
||||
|
@ -16,6 +16,10 @@
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
namespace llvm {
|
||||
template class DominatorTreeBase<MachineBasicBlock, true>; // PostDomTreeBase
|
||||
}
|
||||
|
||||
char MachinePostDominatorTree::ID = 0;
|
||||
|
||||
//declare initializeMachinePostDominatorTreePass
|
||||
@ -24,8 +28,7 @@ INITIALIZE_PASS(MachinePostDominatorTree, "machinepostdomtree",
|
||||
|
||||
MachinePostDominatorTree::MachinePostDominatorTree() : MachineFunctionPass(ID) {
|
||||
initializeMachinePostDominatorTreePass(*PassRegistry::getPassRegistry());
|
||||
DT = new DominatorTreeBase<MachineBasicBlock>(true); //true indicate
|
||||
// postdominator
|
||||
DT = new PostDomTreeBase<MachineBasicBlock>();
|
||||
}
|
||||
|
||||
FunctionPass *
|
||||
|
@ -61,14 +61,20 @@ bool BasicBlockEdge::isSingleEdge() const {
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
template class llvm::DomTreeNodeBase<BasicBlock>;
|
||||
template class llvm::DominatorTreeBase<BasicBlock>;
|
||||
template class llvm::DominatorTreeBase<BasicBlock, false>; // DomTreeBase
|
||||
template class llvm::DominatorTreeBase<BasicBlock, true>; // PostDomTreeBase
|
||||
|
||||
template void
|
||||
llvm::DomTreeBuilder::Calculate<DomTreeBuilder::BBDomTree, Function>(
|
||||
DomTreeBuilder::BBDomTree &DT, Function &F);
|
||||
template void
|
||||
llvm::DomTreeBuilder::Calculate<DomTreeBuilder::BBPostDomTree, Function>(
|
||||
DomTreeBuilder::BBPostDomTree &DT, Function &F);
|
||||
|
||||
template bool llvm::DomTreeBuilder::Verify<DomTreeBuilder::BBDomTree>(
|
||||
const DomTreeBuilder::BBDomTree &DT);
|
||||
template bool llvm::DomTreeBuilder::Verify<DomTreeBuilder::BBPostDomTree>(
|
||||
const DomTreeBuilder::BBPostDomTree &DT);
|
||||
|
||||
bool DominatorTree::invalidate(Function &F, const PreservedAnalyses &PA,
|
||||
FunctionAnalysisManager::Invalidator &) {
|
||||
|
@ -173,8 +173,10 @@ protected:
|
||||
void printBlockEquivalence(raw_ostream &OS, const BasicBlock *BB);
|
||||
bool computeBlockWeights(Function &F);
|
||||
void findEquivalenceClasses(Function &F);
|
||||
template <bool IsPostDom>
|
||||
void findEquivalencesFor(BasicBlock *BB1, ArrayRef<BasicBlock *> Descendants,
|
||||
DominatorTreeBase<BasicBlock> *DomTree);
|
||||
DominatorTreeBase<BasicBlock, IsPostDom> *DomTree);
|
||||
|
||||
void propagateWeights(Function &F);
|
||||
uint64_t visitEdge(Edge E, unsigned *NumUnknownEdges, Edge *UnknownEdge);
|
||||
void buildEdges(Function &F);
|
||||
@ -217,7 +219,7 @@ protected:
|
||||
|
||||
/// \brief Dominance, post-dominance and loop information.
|
||||
std::unique_ptr<DominatorTree> DT;
|
||||
std::unique_ptr<DominatorTreeBase<BasicBlock>> PDT;
|
||||
std::unique_ptr<PostDomTreeBase<BasicBlock>> PDT;
|
||||
std::unique_ptr<LoopInfo> LI;
|
||||
|
||||
AssumptionCacheTracker *ACT;
|
||||
@ -773,9 +775,10 @@ bool SampleProfileLoader::inlineHotFunctions(
|
||||
/// \param DomTree Opposite dominator tree. If \p Descendants is filled
|
||||
/// with blocks from \p BB1's dominator tree, then
|
||||
/// this is the post-dominator tree, and vice versa.
|
||||
template <bool IsPostDom>
|
||||
void SampleProfileLoader::findEquivalencesFor(
|
||||
BasicBlock *BB1, ArrayRef<BasicBlock *> Descendants,
|
||||
DominatorTreeBase<BasicBlock> *DomTree) {
|
||||
DominatorTreeBase<BasicBlock, IsPostDom> *DomTree) {
|
||||
const BasicBlock *EC = EquivalenceClass[BB1];
|
||||
uint64_t Weight = BlockWeights[EC];
|
||||
for (const auto *BB2 : Descendants) {
|
||||
@ -1283,7 +1286,7 @@ void SampleProfileLoader::computeDominanceAndLoopInfo(Function &F) {
|
||||
DT.reset(new DominatorTree);
|
||||
DT->recalculate(F);
|
||||
|
||||
PDT.reset(new DominatorTreeBase<BasicBlock>(true));
|
||||
PDT.reset(new PostDomTreeBase<BasicBlock>());
|
||||
PDT->recalculate(F);
|
||||
|
||||
LI.reset(new LoopInfo);
|
||||
|
@ -19,18 +19,19 @@
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
struct PostDomTree : PostDomTreeBase<BasicBlock> {
|
||||
PostDomTree(Function &F) { recalculate(F); }
|
||||
};
|
||||
|
||||
/// Build the dominator tree for the function and run the Test.
|
||||
static void
|
||||
runWithDomTree(Module &M, StringRef FuncName,
|
||||
function_ref<void(Function &F, DominatorTree *DT,
|
||||
DominatorTreeBase<BasicBlock> *PDT)>
|
||||
Test) {
|
||||
static void runWithDomTree(
|
||||
Module &M, StringRef FuncName,
|
||||
function_ref<void(Function &F, DominatorTree *DT, PostDomTree *PDT)> Test) {
|
||||
auto *F = M.getFunction(FuncName);
|
||||
ASSERT_NE(F, nullptr) << "Could not find " << FuncName;
|
||||
// Compute the dominator tree for the function.
|
||||
DominatorTree DT(*F);
|
||||
DominatorTreeBase<BasicBlock> PDT(/*isPostDom*/ true);
|
||||
PDT.recalculate(*F);
|
||||
PostDomTree PDT(*F);
|
||||
Test(*F, &DT, &PDT);
|
||||
}
|
||||
|
||||
@ -72,8 +73,7 @@ TEST(DominatorTree, Unreachable) {
|
||||
std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
|
||||
|
||||
runWithDomTree(
|
||||
*M, "f",
|
||||
[&](Function &F, DominatorTree *DT, DominatorTreeBase<BasicBlock> *PDT) {
|
||||
*M, "f", [&](Function &F, DominatorTree *DT, PostDomTree *PDT) {
|
||||
Function::iterator FI = F.begin();
|
||||
|
||||
BasicBlock *BB0 = &*FI++;
|
||||
@ -293,8 +293,7 @@ TEST(DominatorTree, NonUniqueEdges) {
|
||||
std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
|
||||
|
||||
runWithDomTree(
|
||||
*M, "f",
|
||||
[&](Function &F, DominatorTree *DT, DominatorTreeBase<BasicBlock> *PDT) {
|
||||
*M, "f", [&](Function &F, DominatorTree *DT, PostDomTree *PDT) {
|
||||
Function::iterator FI = F.begin();
|
||||
|
||||
BasicBlock *BB0 = &*FI++;
|
||||
|
Loading…
x
Reference in New Issue
Block a user