X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FSupport%2FGenericDomTree.h;h=723509c3eedcbd2ef29fb049edc3beb42124926c;hb=02d62886678db69e8cc86baec381c5d86517fb25;hp=876ab6ec71a5205c85d0b50ab8ca31c4c83899af;hpb=f5ec1bd705460cb98a7c5218987b2b1d72d82d8a;p=oota-llvm.git diff --git a/include/llvm/Support/GenericDomTree.h b/include/llvm/Support/GenericDomTree.h index 876ab6ec71a..723509c3eed 100644 --- a/include/llvm/Support/GenericDomTree.h +++ b/include/llvm/Support/GenericDomTree.h @@ -15,12 +15,13 @@ /// //===----------------------------------------------------------------------===// -#ifndef LLVM_SUPPORT_GENERIC_DOM_TREE_H -#define LLVM_SUPPORT_GENERIC_DOM_TREE_H +#ifndef LLVM_SUPPORT_GENERICDOMTREE_H +#define LLVM_SUPPORT_GENERICDOMTREE_H #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DepthFirstIterator.h" #include "llvm/ADT/GraphTraits.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Support/Compiler.h" @@ -29,76 +30,79 @@ namespace llvm { -//===----------------------------------------------------------------------===// -/// DominatorBase - Base class that other, more interesting dominator analyses +/// \brief Base class that other, more interesting dominator analyses /// inherit from. -/// -template -class DominatorBase { +template class DominatorBase { protected: - std::vector Roots; - const bool IsPostDominators; - inline explicit DominatorBase(bool isPostDom) : - Roots(), IsPostDominators(isPostDom) {} -public: + std::vector Roots; + bool IsPostDominators; + explicit DominatorBase(bool isPostDom) + : Roots(), IsPostDominators(isPostDom) {} + DominatorBase(DominatorBase &&Arg) + : Roots(std::move(Arg.Roots)), + IsPostDominators(std::move(Arg.IsPostDominators)) { + Arg.Roots.clear(); + } + DominatorBase &operator=(DominatorBase &&RHS) { + Roots = std::move(RHS.Roots); + IsPostDominators = std::move(RHS.IsPostDominators); + RHS.Roots.clear(); + return *this; + } +public: /// 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 &getRoots() const { return Roots; } + const std::vector &getRoots() const { return Roots; } /// isPostDominator - Returns true if analysis based of postdoms /// bool isPostDominator() const { return IsPostDominators; } }; - -//===----------------------------------------------------------------------===// -// DomTreeNodeBase - Dominator Tree Node -template class DominatorTreeBase; +template class DominatorTreeBase; struct PostDominatorTree; -template -class DomTreeNodeBase { +/// \brief Base class for the actual dominator tree node. +template class DomTreeNodeBase { NodeT *TheBB; DomTreeNodeBase *IDom; std::vector *> Children; mutable int DFSNumIn, DFSNumOut; - template friend class DominatorTreeBase; + template friend class DominatorTreeBase; friend struct PostDominatorTree; + public: typedef typename std::vector *>::iterator iterator; typedef typename std::vector *>::const_iterator - const_iterator; + const_iterator; - iterator begin() { return Children.begin(); } - iterator end() { return Children.end(); } + iterator begin() { return Children.begin(); } + iterator end() { return Children.end(); } const_iterator begin() const { return Children.begin(); } - const_iterator end() const { return Children.end(); } + const_iterator end() const { return Children.end(); } NodeT *getBlock() const { return TheBB; } DomTreeNodeBase *getIDom() const { return IDom; } - const std::vector*> &getChildren() const { + const std::vector *> &getChildren() const { return Children; } DomTreeNodeBase(NodeT *BB, DomTreeNodeBase *iDom) - : TheBB(BB), IDom(iDom), DFSNumIn(-1), DFSNumOut(-1) { } + : TheBB(BB), IDom(iDom), DFSNumIn(-1), DFSNumOut(-1) {} - DomTreeNodeBase *addChild(DomTreeNodeBase *C) { - Children.push_back(C); + std::unique_ptr> + addChild(std::unique_ptr> C) { + Children.push_back(C.get()); return C; } - size_t getNumChildren() const { - return Children.size(); - } + size_t getNumChildren() const { return Children.size(); } - void clearAllChildren() { - Children.clear(); - } + void clearAllChildren() { Children.clear(); } bool compare(const DomTreeNodeBase *Other) const { if (getNumChildren() != Other->getNumChildren()) @@ -121,8 +125,8 @@ public: void setIDom(DomTreeNodeBase *NewIDom) { assert(IDom && "No immediate dominator?"); if (IDom != NewIDom) { - typename std::vector*>::iterator I = - std::find(IDom->Children.begin(), IDom->Children.end(), this); + typename std::vector *>::iterator I = + std::find(IDom->Children.begin(), IDom->Children.end(), this); assert(I != IDom->Children.end() && "Not in immediate dominator children set!"); // I am no longer your child... @@ -138,18 +142,18 @@ public: /// not call them. unsigned getDFSNumIn() const { return DFSNumIn; } unsigned getDFSNumOut() const { return DFSNumOut; } + private: // Return true if this node is dominated by other. Use this only if DFS info // is valid. bool DominatedBy(const DomTreeNodeBase *other) const { return this->DFSNumIn >= other->DFSNumIn && - this->DFSNumOut <= other->DFSNumOut; + this->DFSNumOut <= other->DFSNumOut; } }; -template -inline raw_ostream &operator<<(raw_ostream &o, - const DomTreeNodeBase *Node) { +template +raw_ostream &operator<<(raw_ostream &o, const DomTreeNodeBase *Node) { if (Node->getBlock()) Node->getBlock()->printAsOperand(o, false); else @@ -160,25 +164,29 @@ inline raw_ostream &operator<<(raw_ostream &o, return o << "\n"; } -template -inline void PrintDomTree(const DomTreeNodeBase *N, raw_ostream &o, - unsigned Lev) { - o.indent(2*Lev) << "[" << Lev << "] " << N; +template +void PrintDomTree(const DomTreeNodeBase *N, raw_ostream &o, + unsigned Lev) { + o.indent(2 * Lev) << "[" << Lev << "] " << N; for (typename DomTreeNodeBase::const_iterator I = N->begin(), - E = N->end(); I != E; ++I) - PrintDomTree(*I, o, Lev+1); + E = N->end(); + I != E; ++I) + PrintDomTree(*I, o, Lev + 1); } -//===----------------------------------------------------------------------===// -/// DominatorTree - Calculate the immediate dominator tree for a function. -/// +// The calculate routine is provided in a separate header but referenced here. +template +void Calculate(DominatorTreeBase::NodeType> &DT, + FuncT &F); -template -void Calculate(DominatorTreeBase::NodeType>& DT, - FuncT& F); +/// \brief Core dominator tree base class. +/// +/// 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 DominatorTreeBase : public DominatorBase { + DominatorTreeBase(const DominatorTreeBase &) LLVM_DELETED_FUNCTION; + DominatorTreeBase &operator=(const DominatorTreeBase &) LLVM_DELETED_FUNCTION; -template -class DominatorTreeBase : public DominatorBase { bool dominatedBySlowTreeWalk(const DomTreeNodeBase *A, const DomTreeNodeBase *B) const { assert(A != B); @@ -187,12 +195,25 @@ class DominatorTreeBase : public DominatorBase { const DomTreeNodeBase *IDom; while ((IDom = B->getIDom()) != nullptr && IDom != A && IDom != B) - B = IDom; // Walk up the tree + B = IDom; // Walk up the tree return IDom != nullptr; } + /// \brief Wipe this tree's state without releasing any resources. + /// + /// This is essentially a post-move helper only. It leaves the object in an + /// assignable and destroyable state, but otherwise invalid. + void wipe() { + DomTreeNodes.clear(); + IDoms.clear(); + Vertex.clear(); + Info.clear(); + RootNode = nullptr; + } + protected: - typedef DenseMap*> DomTreeNodeMapType; + typedef DenseMap>> + DomTreeNodeMapType; DomTreeNodeMapType DomTreeNodes; DomTreeNodeBase *RootNode; @@ -208,18 +229,15 @@ protected: InfoRec() : DFSNum(0), Parent(0), Semi(0), Label(nullptr) {} }; - DenseMap IDoms; + DenseMap IDoms; // Vertex - Map the DFS number to the NodeT* - std::vector Vertex; + std::vector Vertex; // Info - Collection of information used during the computation of idoms. - DenseMap Info; + DenseMap Info; void reset() { - for (typename DomTreeNodeMapType::iterator I = this->DomTreeNodes.begin(), - E = DomTreeNodes.end(); I != E; ++I) - delete I->second; DomTreeNodes.clear(); IDoms.clear(); this->Roots.clear(); @@ -229,27 +247,29 @@ protected: // NewBB is split and now it has one successor. Update dominator tree to // reflect this change. - template - void Split(DominatorTreeBase& DT, - typename GraphT::NodeType* NewBB) { + template + void Split(DominatorTreeBase &DT, + typename GraphT::NodeType *NewBB) { assert(std::distance(GraphT::child_begin(NewBB), GraphT::child_end(NewBB)) == 1 && "NewBB should have a single successor!"); - typename GraphT::NodeType* NewBBSucc = *GraphT::child_begin(NewBB); - - std::vector PredBlocks; - typedef GraphTraits > InvTraits; - for (typename InvTraits::ChildIteratorType PI = - InvTraits::child_begin(NewBB), - PE = InvTraits::child_end(NewBB); PI != PE; ++PI) + typename GraphT::NodeType *NewBBSucc = *GraphT::child_begin(NewBB); + + std::vector PredBlocks; + typedef GraphTraits> InvTraits; + for (typename InvTraits::ChildIteratorType + PI = InvTraits::child_begin(NewBB), + PE = InvTraits::child_end(NewBB); + PI != PE; ++PI) PredBlocks.push_back(*PI); assert(!PredBlocks.empty() && "No predblocks?"); bool NewBBDominatesNewBBSucc = true; - for (typename InvTraits::ChildIteratorType PI = - InvTraits::child_begin(NewBBSucc), - E = InvTraits::child_end(NewBBSucc); PI != E; ++PI) { + for (typename InvTraits::ChildIteratorType + PI = InvTraits::child_begin(NewBBSucc), + E = InvTraits::child_end(NewBBSucc); + PI != E; ++PI) { typename InvTraits::NodeType *ND = *PI; if (ND != NewBB && !DT.dominates(NewBBSucc, ND) && DT.isReachableFromEntry(ND)) { @@ -292,8 +312,31 @@ protected: public: explicit DominatorTreeBase(bool isPostDom) - : DominatorBase(isPostDom), DFSInfoValid(false), SlowQueries(0) {} - virtual ~DominatorTreeBase() { reset(); } + : DominatorBase(isPostDom), DFSInfoValid(false), SlowQueries(0) {} + + DominatorTreeBase(DominatorTreeBase &&Arg) + : DominatorBase( + std::move(static_cast &>(Arg))), + DomTreeNodes(std::move(Arg.DomTreeNodes)), + RootNode(std::move(Arg.RootNode)), + DFSInfoValid(std::move(Arg.DFSInfoValid)), + SlowQueries(std::move(Arg.SlowQueries)), IDoms(std::move(Arg.IDoms)), + Vertex(std::move(Arg.Vertex)), Info(std::move(Arg.Info)) { + Arg.wipe(); + } + DominatorTreeBase &operator=(DominatorTreeBase &&RHS) { + DominatorBase::operator=( + std::move(static_cast &>(RHS))); + DomTreeNodes = std::move(RHS.DomTreeNodes); + RootNode = std::move(RHS.RootNode); + DFSInfoValid = std::move(RHS.DFSInfoValid); + SlowQueries = std::move(RHS.SlowQueries); + IDoms = std::move(RHS.IDoms); + Vertex = std::move(RHS.Vertex); + Info = std::move(RHS.Info); + RHS.wipe(); + return *this; + } /// compare - Return false if the other dominator tree base matches this /// dominator tree base. Otherwise return true. @@ -304,35 +347,38 @@ public: return true; for (typename DomTreeNodeMapType::const_iterator - I = this->DomTreeNodes.begin(), - E = this->DomTreeNodes.end(); I != E; ++I) { + I = this->DomTreeNodes.begin(), + E = this->DomTreeNodes.end(); + I != E; ++I) { NodeT *BB = I->first; - typename DomTreeNodeMapType::const_iterator OI = OtherDomTreeNodes.find(BB); + typename DomTreeNodeMapType::const_iterator OI = + OtherDomTreeNodes.find(BB); if (OI == OtherDomTreeNodes.end()) return true; - DomTreeNodeBase* MyNd = I->second; - DomTreeNodeBase* OtherNd = OI->second; + DomTreeNodeBase &MyNd = *I->second; + DomTreeNodeBase &OtherNd = *OI->second; - if (MyNd->compare(OtherNd)) + if (MyNd.compare(&OtherNd)) return true; } return false; } - virtual void releaseMemory() { reset(); } + void releaseMemory() { reset(); } /// getNode - return the (Post)DominatorTree node for the specified basic /// block. This is the same as using operator[] on this class. /// - inline DomTreeNodeBase *getNode(NodeT *BB) const { - return DomTreeNodes.lookup(BB); + DomTreeNodeBase *getNode(NodeT *BB) const { + auto I = DomTreeNodes.find(BB); + if (I != DomTreeNodes.end()) + return I->second.get(); + return nullptr; } - inline DomTreeNodeBase *operator[](NodeT *BB) const { - return getNode(BB); - } + DomTreeNodeBase *operator[](NodeT *BB) const { return getNode(BB); } /// getRootNode - This returns the entry node for the CFG of the function. If /// this tree represents the post-dominance relations for a function, however, @@ -376,21 +422,19 @@ public: /// isReachableFromEntry - Return true if A is dominated by the entry /// block of the function containing it. - bool isReachableFromEntry(const NodeT* A) const { + bool isReachableFromEntry(const NodeT *A) const { assert(!this->isPostDominator() && "This is not implemented for post dominators"); return isReachableFromEntry(getNode(const_cast(A))); } - inline bool isReachableFromEntry(const DomTreeNodeBase *A) const { - return A; - } + bool isReachableFromEntry(const DomTreeNodeBase *A) const { return A; } /// dominates - Returns true iff A dominates B. Note that this is not a /// constant time operation! /// - inline bool dominates(const DomTreeNodeBase *A, - const DomTreeNodeBase *B) const { + bool dominates(const DomTreeNodeBase *A, + const DomTreeNodeBase *B) const { // A node trivially dominates itself. if (B == A) return true; @@ -473,7 +517,7 @@ public: } // Collect NodeA dominators set. - SmallPtrSet*, 16> NodeADoms; + SmallPtrSet *, 16> NodeADoms; NodeADoms.insert(NodeA); DomTreeNodeBase *IDomA = NodeA->getIDom(); while (IDomA) { @@ -512,8 +556,8 @@ public: DomTreeNodeBase *IDomNode = getNode(DomBB); assert(IDomNode && "Not immediate dominator specified for block!"); DFSInfoValid = false; - return DomTreeNodes[BB] = - IDomNode->addChild(new DomTreeNodeBase(BB, IDomNode)); + return (DomTreeNodes[BB] = IDomNode->addChild( + llvm::make_unique>(BB, IDomNode))).get(); } /// changeImmediateDominator - This method is used to update the dominator @@ -538,11 +582,11 @@ public: assert(Node && "Removing node that isn't in dominator tree."); assert(Node->getChildren().empty() && "Node is not a leaf node."); - // Remove node from immediate dominator's children list. + // Remove node from immediate dominator's children list. DomTreeNodeBase *IDom = Node->getIDom(); if (IDom) { - typename std::vector*>::iterator I = - std::find(IDom->Children.begin(), IDom->Children.end(), Node); + typename std::vector *>::iterator I = + std::find(IDom->Children.begin(), IDom->Children.end(), Node); assert(I != IDom->Children.end() && "Not in immediate dominator children set!"); // I am no longer your child... @@ -550,24 +594,16 @@ public: } DomTreeNodes.erase(BB); - delete Node; - } - - /// removeNode - Removes a node from the dominator tree. Block must not - /// dominate any other blocks. Invalidates any node pointing to removed - /// block. - void removeNode(NodeT *BB) { - assert(getNode(BB) && "Removing node that isn't in dominator tree."); - DomTreeNodes.erase(BB); } /// splitBlock - BB is split and now it has one successor. Update dominator /// tree to reflect this change. - void splitBlock(NodeT* NewBB) { + void splitBlock(NodeT *NewBB) { if (this->IsPostDominators) - this->Split, GraphTraits > >(*this, NewBB); + this->Split, GraphTraits>>(*this, + NewBB); else - this->Split >(*this, NewBB); + this->Split>(*this, NewBB); } /// print - Convert to human readable form @@ -588,28 +624,27 @@ public: } protected: - template - friend typename GraphT::NodeType* Eval( - DominatorTreeBase& DT, - typename GraphT::NodeType* V, - unsigned LastLinked); + template + friend typename GraphT::NodeType * + Eval(DominatorTreeBase &DT, + typename GraphT::NodeType *V, unsigned LastLinked); - template - friend unsigned DFSPass(DominatorTreeBase& DT, - typename GraphT::NodeType* V, - unsigned N); + template + friend unsigned DFSPass(DominatorTreeBase &DT, + typename GraphT::NodeType *V, unsigned N); - template - friend void Calculate(DominatorTreeBase::NodeType>& DT, - FuncT& F); + template + friend void + Calculate(DominatorTreeBase::NodeType> &DT, FuncT &F); /// updateDFSNumbers - Assign In and Out numbers to the nodes while walking /// dominator tree in dfs order. void updateDFSNumbers() const { unsigned DFSNum = 0; - SmallVector*, - typename DomTreeNodeBase::const_iterator>, 32> WorkStack; + SmallVector *, + typename DomTreeNodeBase::const_iterator>, + 32> WorkStack; const DomTreeNodeBase *ThisRoot = getRootNode(); @@ -626,7 +661,7 @@ protected: while (!WorkStack.empty()) { const DomTreeNodeBase *Node = WorkStack.back().first; typename DomTreeNodeBase::const_iterator ChildIt = - WorkStack.back().second; + WorkStack.back().second; // If we visited all of the children of this node, "recurse" back up the // stack setting the DFOutNum. @@ -660,23 +695,18 @@ protected: // Add a new tree node for this NodeT, and link it as a child of // IDomNode - DomTreeNodeBase *C = new DomTreeNodeBase(BB, IDomNode); - return this->DomTreeNodes[BB] = IDomNode->addChild(C); + return (this->DomTreeNodes[BB] = IDomNode->addChild( + llvm::make_unique>(BB, IDomNode))).get(); } - inline NodeT *getIDom(NodeT *BB) const { - return IDoms.lookup(BB); - } + NodeT *getIDom(NodeT *BB) const { return IDoms.lookup(BB); } - inline void addRoot(NodeT* BB) { - this->Roots.push_back(BB); - } + void addRoot(NodeT *BB) { this->Roots.push_back(BB); } public: /// recalculate - compute a dominator tree for the given function - template - void recalculate(FT& F) { - typedef GraphTraits TraitsTy; + template void recalculate(FT &F) { + typedef GraphTraits TraitsTy; reset(); this->Vertex.push_back(nullptr); @@ -687,27 +717,29 @@ public: this->IDoms[entry] = nullptr; this->DomTreeNodes[entry] = nullptr; - Calculate(*this, F); + Calculate(*this, F); } else { // Initialize the roots list for (typename TraitsTy::nodes_iterator I = TraitsTy::nodes_begin(&F), - E = TraitsTy::nodes_end(&F); I != E; ++I) { + E = TraitsTy::nodes_end(&F); + I != E; ++I) { if (TraitsTy::child_begin(I) == TraitsTy::child_end(I)) addRoot(I); - // Prepopulate maps so that we don't get iterator invalidation issues later. + // Prepopulate maps so that we don't get iterator invalidation issues + // later. this->IDoms[I] = nullptr; this->DomTreeNodes[I] = nullptr; } - Calculate >(*this, F); + Calculate>(*this, F); } } }; // These two functions are declared out of line as a workaround for building // with old (< r147295) versions of clang because of pr11642. -template +template bool DominatorTreeBase::dominates(const NodeT *A, const NodeT *B) const { if (A == B) return true; @@ -718,9 +750,9 @@ bool DominatorTreeBase::dominates(const NodeT *A, const NodeT *B) const { return dominates(getNode(const_cast(A)), getNode(const_cast(B))); } -template -bool -DominatorTreeBase::properlyDominates(const NodeT *A, const NodeT *B) const { +template +bool DominatorTreeBase::properlyDominates(const NodeT *A, + const NodeT *B) const { if (A == B) return false;