LLVM 20.0.0git
DominanceFrontierImpl.h
Go to the documentation of this file.
1//===- llvm/Analysis/DominanceFrontier.h - Dominator Frontiers --*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This is the generic implementation of the DominanceFrontier class, which
10// calculate and holds the dominance frontier for a function for.
11//
12// This should be considered deprecated, don't add any more uses of this data
13// structure.
14//
15//===----------------------------------------------------------------------===//
16
17#ifndef LLVM_ANALYSIS_DOMINANCEFRONTIERIMPL_H
18#define LLVM_ANALYSIS_DOMINANCEFRONTIERIMPL_H
19
22#include "llvm/Config/llvm-config.h"
23#include "llvm/Support/Debug.h"
26#include <cassert>
27#include <set>
28#include <utility>
29#include <vector>
30
31namespace llvm {
32
33template <class BlockT>
35public:
37
38 DFCalculateWorkObject(BlockT *B, BlockT *P, const DomTreeNodeT *N,
39 const DomTreeNodeT *PN)
40 : currentBB(B), parentBB(P), Node(N), parentNode(PN) {}
41
42 BlockT *currentBB;
43 BlockT *parentBB;
46};
47
48template <class BlockT, bool IsPostDom>
50 for (const_iterator I = begin(), E = end(); I != E; ++I) {
51 OS << " DomFrontier for BB ";
52 if (I->first)
53 I->first->printAsOperand(OS, false);
54 else
55 OS << " <<exit node>>";
56 OS << " is:\t";
57
58 const SetVector<BlockT *> &BBs = I->second;
59
60 for (const BlockT *BB : BBs) {
61 OS << ' ';
62 if (BB)
63 BB->printAsOperand(OS, false);
64 else
65 OS << "<<exit node>>";
66 }
67 OS << '\n';
68 }
69}
70
71#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
72template <class BlockT, bool IsPostDom>
74 print(dbgs());
75}
76#endif
77
78template <class BlockT>
81 const DomTreeNodeT *Node) {
82 BlockT *BB = Node->getBlock();
83 DomSetType *Result = nullptr;
84
85 std::vector<DFCalculateWorkObject<BlockT>> workList;
87
88 workList.push_back(DFCalculateWorkObject<BlockT>(BB, nullptr, Node, nullptr));
89 do {
90 DFCalculateWorkObject<BlockT> *currentW = &workList.back();
91 assert(currentW && "Missing work object.");
92
93 BlockT *currentBB = currentW->currentBB;
94 BlockT *parentBB = currentW->parentBB;
95 const DomTreeNodeT *currentNode = currentW->Node;
96 const DomTreeNodeT *parentNode = currentW->parentNode;
97 assert(currentBB && "Invalid work object. Missing current Basic Block");
98 assert(currentNode && "Invalid work object. Missing current Node");
99 DomSetType &S = this->Frontiers[currentBB];
100
101 // Visit each block only once.
102 if (visited.insert(currentBB).second) {
103 // Loop over CFG successors to calculate DFlocal[currentNode]
104 for (const auto Succ : children<BlockT *>(currentBB)) {
105 // Does Node immediately dominate this successor?
106 if (DT[Succ]->getIDom() != currentNode)
107 S.insert(Succ);
108 }
109 }
110
111 // At this point, S is DFlocal. Now we union in DFup's of our children...
112 // Loop through and visit the nodes that Node immediately dominates (Node's
113 // children in the IDomTree)
114 bool visitChild = false;
115 for (typename DomTreeNodeT::const_iterator NI = currentNode->begin(),
116 NE = currentNode->end();
117 NI != NE; ++NI) {
118 DomTreeNodeT *IDominee = *NI;
119 BlockT *childBB = IDominee->getBlock();
120 if (visited.count(childBB) == 0) {
121 workList.push_back(DFCalculateWorkObject<BlockT>(
122 childBB, currentBB, IDominee, currentNode));
123 visitChild = true;
124 }
125 }
126
127 // If all children are visited or there is any child then pop this block
128 // from the workList.
129 if (!visitChild) {
130 if (!parentBB) {
131 Result = &S;
132 break;
133 }
134
135 typename DomSetType::const_iterator CDFI = S.begin(), CDFE = S.end();
136 DomSetType &parentSet = this->Frontiers[parentBB];
137 for (; CDFI != CDFE; ++CDFI) {
138 if (!DT.properlyDominates(parentNode, DT[*CDFI]))
139 parentSet.insert(*CDFI);
140 }
141 workList.pop_back();
142 }
143
144 } while (!workList.empty());
145
146 return *Result;
147}
148
149} // end namespace llvm
150
151#endif // LLVM_ANALYSIS_DOMINANCEFRONTIERIMPL_H
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file defines a set of templates that efficiently compute a dominator tree over a generic graph.
#define I(x, y, z)
Definition: MD5.cpp:58
#define P(N)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
raw_pwrite_stream & OS
This file defines the SmallPtrSet class.
DFCalculateWorkObject(BlockT *B, BlockT *P, const DomTreeNodeT *N, const DomTreeNodeT *PN)
Base class for the actual dominator tree node.
void print(raw_ostream &OS) const
print - Convert to human readable form
void dump() const
dump - Dump the dominance frontier to dbgs().
typename DomSetMapType::const_iterator const_iterator
Core dominator tree base class.
bool properlyDominates(const DomTreeNodeBase< NodeT > *A, const DomTreeNodeBase< NodeT > *B) const
properlyDominates - Returns true iff A dominates B and A != B.
const DomSetType & calculate(const DomTreeT &DT, const DomTreeNodeT *Node)
typename DominanceFrontierBase< BlockT, false >::DomSetType DomSetType
A vector that has set insertion semantics.
Definition: SetVector.h:57
iterator end()
Get an iterator to the end of the SetVector.
Definition: SetVector.h:113
iterator begin()
Get an iterator to the beginning of the SetVector.
Definition: SetVector.h:103
bool insert(const value_type &X)
Insert a new element into the SetVector.
Definition: SetVector.h:162
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
Definition: SmallPtrSet.h:452
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
Definition: SmallPtrSet.h:384
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
Definition: SmallPtrSet.h:519
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
#define N