16#ifndef LLVM_ANALYSIS_GENERICDOMTREEUPDATERIMPL_H
17#define LLVM_ANALYSIS_GENERICDOMTREEUPDATERIMPL_H
25template <
typename DerivedT,
typename DomTreeT,
typename PostDomTreeT>
26template <
typename FuncT>
29 if (Strategy == UpdateStrategy::Eager) {
41 IsRecalculatingDomTree = IsRecalculatingPostDomTree =
true;
45 derived().forceFlushDeletedBB();
52 IsRecalculatingDomTree = IsRecalculatingPostDomTree =
false;
53 PendDTUpdateIndex = PendPDTUpdateIndex = PendUpdates.size();
54 dropOutOfDateUpdates();
57template <
typename DerivedT,
typename DomTreeT,
typename PostDomTreeT>
63 if (Strategy == UpdateStrategy::Lazy) {
64 PendUpdates.reserve(PendUpdates.size() + Updates.
size());
65 for (
const auto &U : Updates)
66 if (!isSelfDominance(U))
67 PendUpdates.push_back(U);
73 DT->applyUpdates(Updates);
75 PDT->applyUpdates(Updates);
78template <
typename DerivedT,
typename DomTreeT,
typename PostDomTreeT>
86 for (
const auto &U : Updates) {
87 auto Edge = std::make_pair(U.getFrom(), U.getTo());
110 if (!isSelfDominance(U) && Seen.
count(Edge) == 0) {
115 if (isUpdateValid(U)) {
117 PendUpdates.push_back(U);
124 if (Strategy == UpdateStrategy::Lazy)
128 DT->applyUpdates(DeduplicatedUpdates);
130 PDT->applyUpdates(DeduplicatedUpdates);
133template <
typename DerivedT,
typename DomTreeT,
typename PostDomTreeT>
136 assert(DT &&
"Invalid acquisition of a null DomTree");
137 applyDomTreeUpdates();
138 dropOutOfDateUpdates();
142template <
typename DerivedT,
typename DomTreeT,
typename PostDomTreeT>
145 assert(PDT &&
"Invalid acquisition of a null PostDomTree");
146 applyPostDomTreeUpdates();
147 dropOutOfDateUpdates();
151template <
typename DerivedT,
typename DomTreeT,
typename PostDomTreeT>
154#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
157 OS <<
"Available Trees: ";
162 OS <<
"PostDomTree ";
167 OS <<
"UpdateStrategy: ";
168 if (Strategy == UpdateStrategy::Eager) {
183 for (
auto It = begin, ItEnd = end; It != ItEnd; ++It) {
187 if (U.getKind() == DomTreeT::Insert)
193 auto S =
From->getName();
194 if (!
From->hasName())
196 OS << S <<
"(" <<
From <<
"), ";
200 BasicBlockT *To = U.getTo();
202 auto S = To->getName();
205 OS << S <<
"(" << To <<
")\n";
213 const auto I = PendUpdates.begin() + PendDTUpdateIndex;
214 assert(PendUpdates.begin() <=
I &&
I <= PendUpdates.end() &&
215 "Iterator out of range.");
216 OS <<
"Applied but not cleared DomTreeUpdates:\n";
217 printUpdates(PendUpdates.begin(),
I);
218 OS <<
"Pending DomTreeUpdates:\n";
219 printUpdates(
I, PendUpdates.end());
223 const auto I = PendUpdates.begin() + PendPDTUpdateIndex;
224 assert(PendUpdates.begin() <=
I &&
I <= PendUpdates.end() &&
225 "Iterator out of range.");
226 OS <<
"Applied but not cleared PostDomTreeUpdates:\n";
227 printUpdates(PendUpdates.begin(),
I);
228 OS <<
"Pending PostDomTreeUpdates:\n";
229 printUpdates(
I, PendUpdates.end());
232 OS <<
"Pending DeletedBBs:\n";
234 for (
const auto *BB : DeletedBBs) {
238 OS << BB->getName() <<
"(";
246template <
typename DerivedT,
typename DomTreeT,
typename PostDomTreeT>
248 PostDomTreeT>::applyDomTreeUpdates() {
250 if (Strategy != UpdateStrategy::Lazy || !DT)
254 if (hasPendingDomTreeUpdates()) {
255 const auto I = PendUpdates.begin() + PendDTUpdateIndex;
256 const auto E = PendUpdates.end();
257 assert(
I <
E &&
"Iterator range invalid; there should be DomTree updates.");
259 PendDTUpdateIndex = PendUpdates.size();
263template <
typename DerivedT,
typename DomTreeT,
typename PostDomTreeT>
265 PostDomTreeT>::applyPostDomTreeUpdates() {
267 if (Strategy != UpdateStrategy::Lazy || !PDT)
271 if (hasPendingPostDomTreeUpdates()) {
272 const auto I = PendUpdates.begin() + PendPDTUpdateIndex;
273 const auto E = PendUpdates.end();
275 "Iterator range invalid; there should be PostDomTree updates.");
277 PendPDTUpdateIndex = PendUpdates.size();
281template <
typename DerivedT,
typename DomTreeT,
typename PostDomTreeT>
283 typename DomTreeT::UpdateType Update)
const {
284 const auto *
From = Update.getFrom();
285 const auto *To = Update.getTo();
286 const auto Kind = Update.getKind();
298 if (Kind == DomTreeT::Insert && !HasEdge)
302 if (Kind == DomTreeT::Delete && HasEdge)
308template <
typename DerivedT,
typename DomTreeT,
typename PostDomTreeT>
311 if (DT && !IsRecalculatingDomTree)
312 if (DT->getNode(DelBB))
313 DT->eraseNode(DelBB);
315 if (PDT && !IsRecalculatingPostDomTree)
316 if (PDT->getNode(DelBB))
317 PDT->eraseNode(DelBB);
320template <
typename DerivedT,
typename DomTreeT,
typename PostDomTreeT>
322 PostDomTreeT>::tryFlushDeletedBB() {
323 if (!hasPendingUpdates())
324 derived().forceFlushDeletedBB();
327template <
typename DerivedT,
typename DomTreeT,
typename PostDomTreeT>
329 PostDomTreeT>::dropOutOfDateUpdates() {
330 if (Strategy == UpdateStrategy::Eager)
337 PendDTUpdateIndex = PendUpdates.size();
339 PendPDTUpdateIndex = PendUpdates.size();
341 const size_t dropIndex = std::min(PendDTUpdateIndex, PendPDTUpdateIndex);
342 const auto B = PendUpdates.begin();
343 const auto E = PendUpdates.begin() + dropIndex;
344 assert(
B <=
E &&
"Iterator out of range.");
345 PendUpdates.erase(
B,
E);
347 PendDTUpdateIndex -= dropIndex;
348 PendPDTUpdateIndex -= dropIndex;
BlockVerifier::State From
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
DomTreeT & getDomTree()
Flush DomTree updates and return DomTree.
PostDomTreeT & getPostDomTree()
Flush PostDomTree updates and return PostDomTree.
void applyUpdatesPermissive(ArrayRef< typename DomTreeT::UpdateType > Updates)
Submit updates to all available trees.
void applyUpdates(ArrayRef< typename DomTreeT::UpdateType > Updates)
Submit updates to all available trees.
void eraseDelBBNode(BasicBlockT *DelBB)
Erase Basic Block node before it is unlinked from Function in the DomTree and PostDomTree.
typename DomTreeT::NodeType BasicBlockT
bool isUpdateValid(typename DomTreeT::UpdateType Update) const
Returns true if the update appears in the LLVM IR.
void recalculate(FuncT &F)
Notify DTU that the entry block was replaced.
LLVM_DUMP_METHOD void dump() const
Debug method to help view the internal state of this class.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This class implements an extremely fast bulk output stream that can only output to a stream.
This is an optimization pass for GlobalISel generic memory operations.
auto successors(const MachineBasicBlock *BB)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.