24#ifndef LLVM_SUPPORT_GENERICDOMTREE_H 
   25#define LLVM_SUPPORT_GENERICDOMTREE_H 
   45template <
typename NodeT, 
bool IsPostDom>
 
   49template <
typename DomTreeT>
 
   65  mutable unsigned DFSNumIn = ~0;
 
   66  mutable unsigned DFSNumOut = ~0;
 
   70      : TheBB(BB), IDom(iDom), Level(IDom ? IDom->Level + 1 : 0) {}
 
 
   95  bool isLeaf()
 const { 
return Children.empty(); }
 
  104    if (Level != 
Other->Level) 
return true;
 
  108      const NodeT *Nd = 
I->getBlock();
 
  113      const NodeT *
N = 
I->getBlock();
 
  114      if (OtherChildren.
count(
N) == 0)
 
 
  121    assert(IDom && 
"No immediate dominator?");
 
  122    if (IDom == NewIDom) 
return;
 
  124    auto I = 
find(IDom->Children, 
this);
 
  125    assert(
I != IDom->Children.end() &&
 
  126           "Not in immediate dominator children set!");
 
  128    IDom->Children.erase(
I);
 
  132    IDom->Children.push_back(
this);
 
 
  147    return this->DFSNumIn >= other->DFSNumIn &&
 
  148           this->DFSNumOut <= other->DFSNumOut;
 
  153    if (Level == IDom->Level + 1) 
return;
 
  157    while (!WorkStack.empty()) {
 
  159      Current->Level = Current->IDom->Level + 1;
 
  163        if (
C->Level != 
C->IDom->Level + 1) WorkStack.push_back(
C);
 
 
  169template <
class NodeT>
 
  171  if (
Node->getBlock())
 
  174    O << 
" <<exit node>>";
 
  176  O << 
" {" << 
Node->getDFSNumIn() << 
"," << 
Node->getDFSNumOut() << 
"} [" 
  177    << 
Node->getLevel() << 
"]\n";
 
 
  182template <
class NodeT>
 
  185  O.indent(2 * Lev) << 
"[" << Lev << 
"] " << 
N;
 
  186  for (
const auto &
I : *
N)
 
 
  190namespace DomTreeBuilder {
 
  192template <
typename DomTreeT>
 
  195template <
typename DomTreeT>
 
  199template <
typename DomTreeT>
 
  200void InsertEdge(DomTreeT &DT, 
typename DomTreeT::NodePtr From,
 
  201                typename DomTreeT::NodePtr To);
 
  203template <
typename DomTreeT>
 
  204void DeleteEdge(DomTreeT &DT, 
typename DomTreeT::NodePtr From,
 
  205                typename DomTreeT::NodePtr To);
 
  207template <
typename DomTreeT>
 
  209                  GraphDiff<
typename DomTreeT::NodePtr,
 
  210                            DomTreeT::IsPostDominator> &PreViewCFG,
 
  211                  GraphDiff<
typename DomTreeT::NodePtr,
 
  212                            DomTreeT::IsPostDominator> *PostViewCFG);
 
  214template <
typename DomTreeT>
 
  215bool Verify(
const DomTreeT &DT, 
typename DomTreeT::VerificationLevel VL);
 
  223  using ParentPtr = 
decltype(std::declval<NodePtr>()->getParent());
 
  224  static_assert(std::is_pointer_v<ParentPtr>,
 
  225                "Currently NodeT's parent must be a pointer type");
 
 
  236template <
typename NodeT, 
bool IsPostDom>
 
  239  static_assert(std::is_pointer_v<typename GraphTraits<NodeT *>::NodeRef>,
 
  240                "Currently DominatorTreeBase supports only pointer nodes");
 
  245  static_assert(std::is_pointer_v<ParentPtr>,
 
  246                "Currently NodeT's parent must be a pointer type");
 
  266  std::conditional_t<!GraphHasNodeNumbers<NodeT *>,
 
  341    if (!std::is_permutation(
Roots.begin(), 
Roots.end(), 
Other.Roots.begin()))
 
  355    size_t NumOtherNodes = 0;
 
  356    for (
const auto &OtherNode : 
Other.DomTreeNodes)
 
  359    return NumNodes != NumOtherNodes;
 
 
  363  std::optional<unsigned> getNodeIndex(
const NodeT *BB)
 const {
 
  368             "dominator tree used with outdated block numbers");
 
  377  unsigned getNodeIndexForInsert(
const NodeT *BB) {
 
  380      unsigned Idx = *getNodeIndex(BB);
 
  382        unsigned Max = GraphTraits<ParentPtr>::getMaxNumber(
Parent);
 
  403           "cannot get DomTreeNode of block with different parent");
 
  404    if (
auto Idx = getNodeIndex(BB); Idx && *Idx < 
DomTreeNodes.size())
 
 
  433    while (!WL.
empty()) {
 
  435      Result.push_back(
N->getBlock());
 
 
  458           "This is not implemented for post dominators");
 
 
  481    if (
B->getIDom() == 
A) 
return true;
 
  483    if (
A->getIDom() == 
B) 
return false;
 
  486    if (
A->getLevel() >= 
B->getLevel()) 
return false;
 
  490#ifdef EXPENSIVE_CHECKS 
  492            (dominatedBySlowTreeWalk(
A, 
B) == 
B->DominatedBy(
A))) &&
 
  493           "Tree walk disagrees with dfs numbers!");
 
  497      return B->DominatedBy(
A);
 
  504      return B->DominatedBy(
A);
 
  507    return dominatedBySlowTreeWalk(
A, 
B);
 
 
  513    assert(this->Roots.
size() == 1 && 
"Should always have entry node!");
 
  514    return this->Roots[0];
 
 
  520    assert(
A && 
B && 
"Pointers are not valid");
 
  522           "Two blocks are not in same function");
 
  529      if (
A == &Entry || 
B == &Entry)
 
  535    assert(NodeA && 
"A must be in the tree");
 
  536    assert(NodeB && 
"B must be in the tree");
 
  540    while (NodeA != NodeB) {
 
 
  550                                          const NodeT *
B)
 const {
 
  554                                      const_cast<NodeT *
>(
B));
 
 
  561  template <
typename IteratorTy>
 
  565    NodeT *NCD = *Nodes.
begin();
 
 
  625    if (Updates.
empty()) {
 
 
  688    assert(
getNode(BB) == 
nullptr && 
"Block already in dominator tree!");
 
  690    assert(IDomNode && 
"Not immediate dominator specified for block!");
 
 
  701    assert(
getNode(BB) == 
nullptr && 
"Block already in dominator tree!");
 
  703           "Cannot change root of post-dominator tree");
 
  704    DFSInfoValid = 
false;
 
  710      NodeT *OldRoot = 
Roots.front();
 
  713      OldNode->IDom = NewNode;
 
  714      OldNode->UpdateLevel();
 
 
  725    assert(
N && NewIDom && 
"Cannot change null node pointers!");
 
 
  738    std::optional<unsigned> IdxOpt = getNodeIndex(BB);
 
  740           "Removing node that isn't in dominator tree.");
 
  742    assert(
Node->isLeaf() && 
"Node is not a leaf node.");
 
  749      const auto I = 
find(IDom->Children, 
Node);
 
  750      assert(
I != IDom->Children.end() &&
 
  751             "Not in immediate dominator children set!");
 
  754      IDom->Children.pop_back();
 
  761    if (!IsPostDom) 
return;
 
  765    if (RIt != 
Roots.end()) {
 
 
  783    O << 
"=============================--------------------------------\n";
 
  785      O << 
"Inorder PostDominator Tree: ";
 
  787      O << 
"Inorder Dominator Tree: ";
 
  789      O << 
"DFSNumbers invalid: " << 
SlowQueries << 
" slow queries.";
 
  796      Block->printAsOperand(O, 
false);
 
 
  816    assert((!
Parent || ThisRoot) && 
"Empty constructed DomTree");
 
  825    ThisRoot->DFSNumIn = DFSNum++;
 
  827    while (!WorkStack.
empty()) {
 
  829      const auto ChildIt = WorkStack.
back().second;
 
  833      if (ChildIt == 
Node->end()) {
 
  834        Node->DFSNumOut = DFSNum++;
 
  839        ++WorkStack.
back().second;
 
  842        Child->DFSNumIn = DFSNum++;
 
 
  851  void updateBlockNumberEpoch() {
 
  861    updateBlockNumberEpoch();
 
 
  867    updateBlockNumberEpoch();
 
 
  872  template <
typename T = NodeT>
 
  874    updateBlockNumberEpoch();
 
  878    NewVector.
resize(MaxNumber + 1); 
 
  882      unsigned Idx = *getNodeIndex(
Node->getBlock());
 
  884      if (Idx >= NewVector.
size())
 
  885        NewVector.
resize(Idx + 1);
 
  886      NewVector[Idx] = std::move(
Node);
 
 
  925    auto Node = std::make_unique<DomTreeNodeBase<NodeT>>(BB, IDom);
 
  927    unsigned NodeIdx = getNodeIndexForInsert(BB);
 
 
  939    using NodeRef = 
typename GraphT::NodeRef;
 
  941           "NewBB should have a single successor!");
 
  942    NodeRef NewBBSucc = *GraphT::child_begin(NewBB);
 
  948    bool NewBBDominatesNewBBSucc = 
true;
 
  950      if (Pred != NewBB && !
dominates(NewBBSucc, Pred) &&
 
  952        NewBBDominatesNewBBSucc = 
false;
 
  959    NodeT *NewBBIDom = 
nullptr;
 
  961    for (i = 0; i < PredBlocks.
size(); ++i)
 
  963        NewBBIDom = PredBlocks[i];
 
  970    if (!NewBBIDom) 
return;
 
  972    for (i = i + 1; i < PredBlocks.
size(); ++i) {
 
  982    if (NewBBDominatesNewBBSucc) {
 
 
  995    const unsigned ALevel = 
A->getLevel();
 
 1000    while ((IDom = 
B->getIDom()) != 
nullptr && IDom->
getLevel() >= ALevel)
 
 
 1019template <
typename T>
 
 1022template <
typename T>
 
 1027template <
typename NodeT, 
bool IsPostDom>
 
 1029                                                    const NodeT *
B)
 const {
 
 
 1035template <
typename NodeT, 
bool IsPostDom>
 
 1037    const NodeT *
A, 
const NodeT *
B)
 const {
 
 
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
 
static msgpack::DocNode getNode(msgpack::DocNode DN, msgpack::Type Type, MCValue Val)
 
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
 
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
 
This file defines the DenseMap class.
 
This file defines the little GraphTraits<X> template class that should be specialized by classes that...
 
ppc ctr loops PowerPC CTR Loops Verify
 
static bool dominates(InstrPosIndexes &PosIndexes, const MachineInstr &A, const MachineInstr &B)
 
This file defines the SmallPtrSet class.
 
This file defines the SmallVector class.
 
void printAsOperand(OutputBuffer &OB, Prec P=Prec::Default, bool StrictlyWorse=false) const
 
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
 
bool empty() const
empty - Check if the array is empty.
 
Base class for the actual dominator tree node.
 
iterator_range< iterator > children()
 
const_iterator end() const
 
DomTreeNodeBase *& back()
 
void setIDom(DomTreeNodeBase *NewIDom)
 
typename SmallVector< DomTreeNodeBase *, 4 >::iterator iterator
 
DomTreeNodeBase *const & back() const
 
DomTreeNodeBase * getIDom() const
 
unsigned getDFSNumIn() const
getDFSNumIn/getDFSNumOut - These return the DFS visitation order for nodes in the dominator tree.
 
size_t getNumChildren() const
 
DomTreeNodeBase(NodeT *BB, DomTreeNodeBase *iDom)
 
bool compare(const DomTreeNodeBase *Other) const
 
friend class PostDominatorTree
 
unsigned getLevel() const
 
iterator_range< const_iterator > children() const
 
typename SmallVector< DomTreeNodeBase *, 4 >::const_iterator const_iterator
 
unsigned getDFSNumOut() const
 
const_iterator begin() const
 
void addChild(DomTreeNodeBase *C)
 
Core dominator tree base class.
 
DomTreeNodeTraits< BlockT > NodeTrait
 
bool isReachableFromEntry(const DomTreeNodeBase< NodeT > *A) const
 
void print(raw_ostream &O) const
print - Convert to human readable form
 
typename NodeTrait::NodeType NodeType
 
DomTreeNodeBase< NodeT > * operator[](const NodeT *BB) const
See getNode.
 
typename SmallVectorImpl< BlockT * >::iterator root_iterator
 
DomTreeNodeBase< NodeT > * getRootNode()
getRootNode - This returns the entry node for the CFG of the function.
 
bool verify(VerificationLevel VL=VerificationLevel::Full) const
verify - checks if the tree is correct.
 
void changeImmediateDominator(NodeT *BB, NodeT *NewBB)
 
NodeT * findNearestCommonDominator(NodeT *A, NodeT *B) const
Find nearest common dominator basic block for basic block A and B.
 
DominatorTreeBase()=default
 
void Split(typename GraphTraits< N >::NodeRef NewBB)
 
iterator_range< root_iterator > roots()
 
void changeImmediateDominator(DomTreeNodeBase< NodeT > *N, DomTreeNodeBase< NodeT > *NewIDom)
changeImmediateDominator - This method is used to update the dominator tree information when a node's...
 
std::remove_pointer_t< ParentPtr > ParentType
 
DominatorTreeBase(DominatorTreeBase &&Arg)
 
NodeT * findNearestCommonDominator(iterator_range< IteratorTy > Nodes) const
 
bool isPostDominator() const
isPostDominator - Returns true if analysis based of postdoms
 
bool dominates(const NodeT *A, const NodeT *B) const
 
const NodeT * findNearestCommonDominator(const NodeT *A, const NodeT *B) const
 
void getDescendants(NodeT *R, SmallVectorImpl< NodeT * > &Result) const
Get all nodes dominated by R, including R itself.
 
DomTreeNodeBase< NodeT > * addNewBlock(NodeT *BB, NodeT *DomBB)
Add a new node to the dominator tree information.
 
DomTreeNodeBase< NodeT > * createNode(NodeT *BB, DomTreeNodeBase< NodeT > *IDom=nullptr)
 
void applyUpdates(ArrayRef< UpdateType > Updates)
Inform the dominator tree about a sequence of CFG edge insertions and deletions and perform a batch u...
 
void insertEdge(NodeT *From, NodeT *To)
Inform the dominator tree about a CFG edge insertion and update the tree.
 
std::enable_if_t< GraphHasNodeNumbers< T * >, void > updateBlockNumbers()
Update dominator tree after renumbering blocks.
 
bool dominates(const DomTreeNodeBase< NodeT > *A, const DomTreeNodeBase< NodeT > *B) const
dominates - Returns true iff A dominates B.
 
iterator_range< const_root_iterator > roots() const
 
const_root_iterator root_end() const
 
void splitBlock(NodeT *NewBB)
splitBlock - BB is split and now it has one successor.
 
DominatorTreeBase & operator=(DominatorTreeBase &&RHS)
 
static constexpr UpdateKind Delete
 
void recalculate(ParentType &Func, ArrayRef< UpdateType > Updates)
 
void updateDFSNumbers() const
updateDFSNumbers - Assign In and Out numbers to the nodes while walking dominator tree in dfs order.
 
typename SmallVectorImpl< BlockT * >::const_iterator const_root_iterator
 
bool compare(const DominatorTreeBase &Other) const
compare - Return false if the other dominator tree base matches this dominator tree base.
 
DomTreeNodeBase< NodeT > * setNewRoot(NodeT *BB)
Add a new node to the forward dominator tree and make it a new root.
 
root_iterator root_begin()
 
DominatorTreeBase(const DominatorTreeBase &)=delete
 
static constexpr UpdateKind Insert
 
const_root_iterator root_begin() const
 
void recalculate(ParentType &Func)
recalculate - compute a dominator tree for the given function
 
SmallVector< BlockT *, IsPostDom ? 4 :1 > Roots
 
void eraseNode(NodeT *BB)
eraseNode - Removes a node from the dominator tree.
 
void deleteEdge(NodeT *From, NodeT *To)
Inform the dominator tree about a CFG edge deletion and update the tree.
 
const DomTreeNodeBase< NodeT > * getRootNode() const
 
std::conditional_t<!GraphHasNodeNumbers< BlockT * >, DenseMap< const BlockT *, unsigned >, std::tuple<> > NodeNumberMap
 
DomTreeNodeBase< BlockT > * RootNode
 
typename NodeTrait::NodePtr NodePtr
 
bool isReachableFromEntry(const NodeT *A) const
isReachableFromEntry - Return true if A is dominated by the entry block of the function containing it...
 
cfg::Update< NodePtr > UpdateType
 
cfg::UpdateKind UpdateKind
 
void applyUpdates(ArrayRef< UpdateType > Updates, ArrayRef< UpdateType > PostViewUpdates)
 
unsigned BlockNumberEpoch
 
DomTreeNodeStorageTy DomTreeNodes
 
DomTreeNodeBase< NodeT > * getNode(const NodeT *BB) const
getNode - return the (Post)DominatorTree node for the specified basic block.
 
bool properlyDominates(const NodeT *A, const NodeT *B) const
 
bool properlyDominates(const DomTreeNodeBase< NodeT > *A, const DomTreeNodeBase< NodeT > *B) const
properlyDominates - Returns true iff A dominates B and A != B.
 
bool isVirtualRoot(const DomTreeNodeBase< NodeT > *A) const
 
typename NodeTrait::ParentPtr ParentPtr
 
DominatorTreeBase & operator=(const DominatorTreeBase &)=delete
 
static constexpr bool IsPostDominator
 
SmallVector< std::unique_ptr< DomTreeNodeBase< BlockT > > > DomTreeNodeStorageTy
 
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
 
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
 
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
 
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
 
typename SuperClass::const_iterator const_iterator
 
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
 
typename SuperClass::iterator iterator
 
void push_back(const T &Elt)
 
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
 
A range adaptor for a pair of iterators.
 
This class implements an extremely fast bulk output stream that can only output to a stream.
 
@ C
The default llvm calling convention, compatible with C.
 
bool Verify(const DomTreeT &DT, typename DomTreeT::VerificationLevel VL)
 
void CalculateWithUpdates(DomTreeT &DT, ArrayRef< typename DomTreeT::UpdateType > Updates)
 
void DeleteEdge(DomTreeT &DT, typename DomTreeT::NodePtr From, typename DomTreeT::NodePtr To)
 
void Calculate(DomTreeT &DT)
 
void ApplyUpdates(DomTreeT &DT, GraphDiff< typename DomTreeT::NodePtr, DomTreeT::IsPostDominator > &PreViewCFG, GraphDiff< typename DomTreeT::NodePtr, DomTreeT::IsPostDominator > *PostViewCFG)
 
void InsertEdge(DomTreeT &DT, typename DomTreeT::NodePtr From, typename DomTreeT::NodePtr To)
 
This is an optimization pass for GlobalISel generic memory operations.
 
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
 
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
 
void PrintDomTree(const DomTreeNodeBase< NodeT > *N, raw_ostream &O, unsigned Lev)
 
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
 
constexpr bool GraphHasNodeNumbers
Indicate whether a GraphTraits<NodeT>::getNumber() is supported.
 
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
 
DominatorTreeBase< T, true > PostDomTreeBase
 
DominatorTreeBase< T, false > DomTreeBase
 
bool hasSingleElement(ContainerTy &&C)
Returns true if the given container only contains a single element.
 
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
 
iterator_range< typename GraphTraits< Inverse< GraphType > >::ChildIteratorType > inverse_children(const typename GraphTraits< GraphType >::NodeRef &G)
 
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
 
ArrayRef(const T &OneElt) -> ArrayRef< T >
 
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
 
iterator_range< typename GraphTraits< GraphType >::ChildIteratorType > children(const typename GraphTraits< GraphType >::NodeRef &G)
 
Implement std::hash so that hash_code can be used in STL containers.
 
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
 
Default DomTreeNode traits for NodeT.
 
static NodeT * getEntryNode(ParentPtr Parent)
 
std::remove_pointer_t< ParentPtr > ParentType
 
static ParentPtr getParent(NodePtr BB)
 
decltype(std::declval< NodePtr >() ->getParent()) ParentPtr
 
typename GraphType::UnknownGraphTypeError NodeRef