[llvm] [DomTreeUpdater] Split implementations (PR #97027)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Jun 28 03:08:38 PDT 2024
https://github.com/paperchalice updated https://github.com/llvm/llvm-project/pull/97027
>From e6393eeb145f8310dfc1e5fae0e712235273dc30 Mon Sep 17 00:00:00 2001
From: PaperChalice <liujunchang97 at outlook.com>
Date: Fri, 28 Jun 2024 17:25:12 +0800
Subject: [PATCH 1/2] [DomTreeUpdater] Split implementations Move
implementations of `GenericDomTreeUpdater` to GenericDomTreeUpdaterImpl.h
---
llvm/include/llvm/Analysis/DomTreeUpdater.h | 25 +-
.../llvm/Analysis/GenericDomTreeUpdater.h | 377 ++------------
.../llvm/Analysis/GenericDomTreeUpdaterImpl.h | 477 ++++++++++++++++++
.../llvm/CodeGen/MachineDomTreeUpdater.h | 14 +-
llvm/lib/Analysis/DomTreeUpdater.cpp | 24 +
llvm/lib/CodeGen/MachineDomTreeUpdater.cpp | 8 +-
6 files changed, 555 insertions(+), 370 deletions(-)
create mode 100644 llvm/include/llvm/Analysis/GenericDomTreeUpdaterImpl.h
diff --git a/llvm/include/llvm/Analysis/DomTreeUpdater.h b/llvm/include/llvm/Analysis/DomTreeUpdater.h
index 2b838a311440e..9ffd4948c1750 100644
--- a/llvm/include/llvm/Analysis/DomTreeUpdater.h
+++ b/llvm/include/llvm/Analysis/DomTreeUpdater.h
@@ -16,7 +16,6 @@
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Analysis/GenericDomTreeUpdater.h"
-#include "llvm/Analysis/PostDominators.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/ValueHandle.h"
#include "llvm/Support/Compiler.h"
@@ -26,6 +25,8 @@
namespace llvm {
+class PostDominatorTree;
+
class DomTreeUpdater
: public GenericDomTreeUpdater<DomTreeUpdater, DominatorTree,
PostDominatorTree> {
@@ -110,27 +111,15 @@ class DomTreeUpdater
bool forceFlushDeletedBB();
/// Debug method to help view the internal state of this class.
- LLVM_DUMP_METHOD void dump() const {
- Base::dump();
-#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
- raw_ostream &OS = dbgs();
- OS << "Pending Callbacks:\n";
- int Index = 0;
- for (const auto &BB : Callbacks) {
- OS << " " << Index << " : ";
- ++Index;
- if (BB->hasName())
- OS << BB->getName() << "(";
- else
- OS << "(no_name)(";
- OS << BB << ")\n";
- }
-#endif
- }
+ LLVM_DUMP_METHOD void dump() const;
};
extern template class GenericDomTreeUpdater<DomTreeUpdater, DominatorTree,
PostDominatorTree>;
+
+extern template void
+GenericDomTreeUpdater<DomTreeUpdater, DominatorTree,
+ PostDominatorTree>::recalculate(Function &F);
} // namespace llvm
#endif // LLVM_ANALYSIS_DOMTREEUPDATER_H
diff --git a/llvm/include/llvm/Analysis/GenericDomTreeUpdater.h b/llvm/include/llvm/Analysis/GenericDomTreeUpdater.h
index 7092c67083a67..1a86398e4fc68 100644
--- a/llvm/include/llvm/Analysis/GenericDomTreeUpdater.h
+++ b/llvm/include/llvm/Analysis/GenericDomTreeUpdater.h
@@ -16,91 +16,67 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallSet.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/Compiler.h"
namespace llvm {
template <typename DerivedT, typename DomTreeT, typename PostDomTreeT>
class GenericDomTreeUpdater {
- DerivedT &derived() { return *static_cast<DerivedT *>(this); }
- const DerivedT &derived() const {
- return *static_cast<const DerivedT *>(this);
- }
+ DerivedT &derived();
+ const DerivedT &derived() const;
public:
enum class UpdateStrategy : unsigned char { Eager = 0, Lazy = 1 };
using BasicBlockT = typename DomTreeT::NodeType;
- explicit GenericDomTreeUpdater(UpdateStrategy Strategy_)
- : Strategy(Strategy_) {}
- GenericDomTreeUpdater(DomTreeT &DT_, UpdateStrategy Strategy_)
- : DT(&DT_), Strategy(Strategy_) {}
- GenericDomTreeUpdater(DomTreeT *DT_, UpdateStrategy Strategy_)
- : DT(DT_), Strategy(Strategy_) {}
- GenericDomTreeUpdater(PostDomTreeT &PDT_, UpdateStrategy Strategy_)
- : PDT(&PDT_), Strategy(Strategy_) {}
- GenericDomTreeUpdater(PostDomTreeT *PDT_, UpdateStrategy Strategy_)
- : PDT(PDT_), Strategy(Strategy_) {}
+ explicit GenericDomTreeUpdater(UpdateStrategy Strategy_);
+ GenericDomTreeUpdater(DomTreeT &DT_, UpdateStrategy Strategy_);
+ GenericDomTreeUpdater(DomTreeT *DT_, UpdateStrategy Strategy_);
+ GenericDomTreeUpdater(PostDomTreeT &PDT_, UpdateStrategy Strategy_);
+ GenericDomTreeUpdater(PostDomTreeT *PDT_, UpdateStrategy Strategy_);
GenericDomTreeUpdater(DomTreeT &DT_, PostDomTreeT &PDT_,
- UpdateStrategy Strategy_)
- : DT(&DT_), PDT(&PDT_), Strategy(Strategy_) {}
+ UpdateStrategy Strategy_);
GenericDomTreeUpdater(DomTreeT *DT_, PostDomTreeT *PDT_,
- UpdateStrategy Strategy_)
- : DT(DT_), PDT(PDT_), Strategy(Strategy_) {}
+ UpdateStrategy Strategy_);
- ~GenericDomTreeUpdater() { flush(); }
+ ~GenericDomTreeUpdater();
/// Returns true if the current strategy is Lazy.
- bool isLazy() const { return Strategy == UpdateStrategy::Lazy; };
+ bool isLazy() const;
/// Returns true if the current strategy is Eager.
- bool isEager() const { return Strategy == UpdateStrategy::Eager; };
+ bool isEager() const;
/// Returns true if it holds a DomTreeT.
- bool hasDomTree() const { return DT != nullptr; }
+ bool hasDomTree() const;
/// Returns true if it holds a PostDomTreeT.
- bool hasPostDomTree() const { return PDT != nullptr; }
+ bool hasPostDomTree() const;
/// Returns true if there is BasicBlockT awaiting deletion.
/// The deletion will only happen until a flush event and
/// all available trees are up-to-date.
/// Returns false under Eager UpdateStrategy.
- bool hasPendingDeletedBB() const { return !DeletedBBs.empty(); }
+ bool hasPendingDeletedBB() const;
/// Returns true if DelBB is awaiting deletion.
/// Returns false under Eager UpdateStrategy.
- bool isBBPendingDeletion(BasicBlockT *DelBB) const {
- if (Strategy == UpdateStrategy::Eager || DeletedBBs.empty())
- return false;
- return DeletedBBs.contains(DelBB);
- }
+ bool isBBPendingDeletion(BasicBlockT *DelBB) const;
/// Returns true if either of DT or PDT is valid and the tree has at
/// least one update pending. If DT or PDT is nullptr it is treated
/// as having no pending updates. This function does not check
/// whether there is MachineBasicBlock awaiting deletion.
/// Returns false under Eager UpdateStrategy.
- bool hasPendingUpdates() const {
- return hasPendingDomTreeUpdates() || hasPendingPostDomTreeUpdates();
- }
+ bool hasPendingUpdates() const;
/// Returns true if there are DomTreeT updates queued.
/// Returns false under Eager UpdateStrategy or DT is nullptr.
- bool hasPendingDomTreeUpdates() const {
- if (!DT)
- return false;
- return PendUpdates.size() != PendDTUpdateIndex;
- }
+ bool hasPendingDomTreeUpdates() const;
/// Returns true if there are PostDomTreeT updates queued.
/// Returns false under Eager UpdateStrategy or PDT is nullptr.
- bool hasPendingPostDomTreeUpdates() const {
- if (!PDT)
- return false;
- return PendUpdates.size() != PendPDTUpdateIndex;
- }
+ bool hasPendingPostDomTreeUpdates() const;
///@{
/// \name Mutation APIs
@@ -126,34 +102,7 @@ class GenericDomTreeUpdater {
/// Notify DTU that the entry block was replaced.
/// Recalculate all available trees and flush all BasicBlocks
/// awaiting deletion immediately.
- template <typename FuncT> void recalculate(FuncT &F) {
- if (Strategy == UpdateStrategy::Eager) {
- if (DT)
- DT->recalculate(F);
- if (PDT)
- PDT->recalculate(F);
- return;
- }
-
- // There is little performance gain if we pend the recalculation under
- // Lazy UpdateStrategy so we recalculate available trees immediately.
-
- // Prevent forceFlushDeletedBB() from erasing DomTree or PostDomTree nodes.
- IsRecalculatingDomTree = IsRecalculatingPostDomTree = true;
-
- // Because all trees are going to be up-to-date after recalculation,
- // flush awaiting deleted BasicBlocks.
- derived().forceFlushDeletedBB();
- if (DT)
- DT->recalculate(F);
- if (PDT)
- PDT->recalculate(F);
-
- // Resume forceFlushDeletedBB() to erase DomTree or PostDomTree nodes.
- IsRecalculatingDomTree = IsRecalculatingPostDomTree = false;
- PendDTUpdateIndex = PendPDTUpdateIndex = PendUpdates.size();
- dropOutOfDateUpdates();
- }
+ template <typename FuncT> void recalculate(FuncT &F);
/// Submit updates to all available trees.
/// The Eager Strategy flushes updates immediately while the Lazy Strategy
@@ -170,24 +119,7 @@ class GenericDomTreeUpdater {
/// 2. It is illegal to submit any update that has already been submitted,
/// i.e., you are supposed not to insert an existent edge or delete a
/// nonexistent edge.
- void applyUpdates(ArrayRef<typename DomTreeT::UpdateType> Updates) {
- if (!DT && !PDT)
- return;
-
- if (Strategy == UpdateStrategy::Lazy) {
- PendUpdates.reserve(PendUpdates.size() + Updates.size());
- for (const auto &U : Updates)
- if (!isSelfDominance(U))
- PendUpdates.push_back(U);
-
- return;
- }
-
- if (DT)
- DT->applyUpdates(Updates);
- if (PDT)
- PDT->applyUpdates(Updates);
- }
+ void applyUpdates(ArrayRef<typename DomTreeT::UpdateType> Updates);
/// Submit updates to all available trees. It will also
/// 1. discard duplicated updates,
@@ -210,58 +142,7 @@ class GenericDomTreeUpdater {
/// 3. It is only legal to submit updates to an edge in the order CFG changes
/// are made. The order you submit updates on different edges is not
/// restricted.
- void applyUpdatesPermissive(ArrayRef<typename DomTreeT::UpdateType> Updates) {
- if (!DT && !PDT)
- return;
-
- SmallSet<std::pair<BasicBlockT *, BasicBlockT *>, 8> Seen;
- SmallVector<typename DomTreeT::UpdateType, 8> DeduplicatedUpdates;
- for (const auto &U : Updates) {
- auto Edge = std::make_pair(U.getFrom(), U.getTo());
- // Because it is illegal to submit updates that have already been applied
- // and updates to an edge need to be strictly ordered,
- // it is safe to infer the existence of an edge from the first update
- // to this edge.
- // If the first update to an edge is "Delete", it means that the edge
- // existed before. If the first update to an edge is "Insert", it means
- // that the edge didn't exist before.
- //
- // For example, if the user submits {{Delete, A, B}, {Insert, A, B}},
- // because
- // 1. it is illegal to submit updates that have already been applied,
- // i.e., user cannot delete an nonexistent edge,
- // 2. updates to an edge need to be strictly ordered,
- // So, initially edge A -> B existed.
- // We can then safely ignore future updates to this edge and directly
- // inspect the current CFG:
- // a. If the edge still exists, because the user cannot insert an existent
- // edge, so both {Delete, A, B}, {Insert, A, B} actually happened and
- // resulted in a no-op. DTU won't submit any update in this case.
- // b. If the edge doesn't exist, we can then infer that {Delete, A, B}
- // actually happened but {Insert, A, B} was an invalid update which never
- // happened. DTU will submit {Delete, A, B} in this case.
- if (!isSelfDominance(U) && Seen.count(Edge) == 0) {
- Seen.insert(Edge);
- // If the update doesn't appear in the CFG, it means that
- // either the change isn't made or relevant operations
- // result in a no-op.
- if (isUpdateValid(U)) {
- if (isLazy())
- PendUpdates.push_back(U);
- else
- DeduplicatedUpdates.push_back(U);
- }
- }
- }
-
- if (Strategy == UpdateStrategy::Lazy)
- return;
-
- if (DT)
- DT->applyUpdates(DeduplicatedUpdates);
- if (PDT)
- PDT->applyUpdates(DeduplicatedUpdates);
- }
+ void applyUpdatesPermissive(ArrayRef<typename DomTreeT::UpdateType> Updates);
///@}
@@ -275,127 +156,22 @@ class GenericDomTreeUpdater {
/// Flush DomTree updates and return DomTree.
/// It flushes Deleted BBs if both trees are up-to-date.
/// It must only be called when it has a DomTree.
- DomTreeT &getDomTree() {
- assert(DT && "Invalid acquisition of a null DomTree");
- applyDomTreeUpdates();
- dropOutOfDateUpdates();
- return *DT;
- }
+ DomTreeT &getDomTree();
/// Flush PostDomTree updates and return PostDomTree.
/// It flushes Deleted BBs if both trees are up-to-date.
/// It must only be called when it has a PostDomTree.
- PostDomTreeT &getPostDomTree() {
- assert(PDT && "Invalid acquisition of a null PostDomTree");
- applyPostDomTreeUpdates();
- dropOutOfDateUpdates();
- return *PDT;
- }
+ PostDomTreeT &getPostDomTree();
/// Apply all pending updates to available trees and flush all BasicBlocks
/// awaiting deletion.
- void flush() {
- applyDomTreeUpdates();
- applyPostDomTreeUpdates();
- dropOutOfDateUpdates();
- }
+ void flush();
///@}
/// Debug method to help view the internal state of this class.
- LLVM_DUMP_METHOD void dump() const {
-#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
- raw_ostream &OS = llvm::dbgs();
-
- OS << "Available Trees: ";
- if (DT || PDT) {
- if (DT)
- OS << "DomTree ";
- if (PDT)
- OS << "PostDomTree ";
- OS << "\n";
- } else
- OS << "None\n";
-
- OS << "UpdateStrategy: ";
- if (Strategy == UpdateStrategy::Eager) {
- OS << "Eager\n";
- return;
- } else
- OS << "Lazy\n";
- int Index = 0;
-
- auto printUpdates =
- [&](typename ArrayRef<typename DomTreeT::UpdateType>::const_iterator
- begin,
- typename ArrayRef<typename DomTreeT::UpdateType>::const_iterator
- end) {
- if (begin == end)
- OS << " None\n";
- Index = 0;
- for (auto It = begin, ItEnd = end; It != ItEnd; ++It) {
- auto U = *It;
- OS << " " << Index << " : ";
- ++Index;
- if (U.getKind() == DomTreeT::Insert)
- OS << "Insert, ";
- else
- OS << "Delete, ";
- BasicBlockT *From = U.getFrom();
- if (From) {
- auto S = From->getName();
- if (!From->hasName())
- S = "(no name)";
- OS << S << "(" << From << "), ";
- } else {
- OS << "(badref), ";
- }
- BasicBlockT *To = U.getTo();
- if (To) {
- auto S = To->getName();
- if (!To->hasName())
- S = "(no_name)";
- OS << S << "(" << To << ")\n";
- } else {
- OS << "(badref)\n";
- }
- }
- };
-
- if (DT) {
- const auto I = PendUpdates.begin() + PendDTUpdateIndex;
- assert(PendUpdates.begin() <= I && I <= PendUpdates.end() &&
- "Iterator out of range.");
- OS << "Applied but not cleared DomTreeUpdates:\n";
- printUpdates(PendUpdates.begin(), I);
- OS << "Pending DomTreeUpdates:\n";
- printUpdates(I, PendUpdates.end());
- }
-
- if (PDT) {
- const auto I = PendUpdates.begin() + PendPDTUpdateIndex;
- assert(PendUpdates.begin() <= I && I <= PendUpdates.end() &&
- "Iterator out of range.");
- OS << "Applied but not cleared PostDomTreeUpdates:\n";
- printUpdates(PendUpdates.begin(), I);
- OS << "Pending PostDomTreeUpdates:\n";
- printUpdates(I, PendUpdates.end());
- }
-
- OS << "Pending DeletedBBs:\n";
- Index = 0;
- for (const auto *BB : DeletedBBs) {
- OS << " " << Index << " : ";
- ++Index;
- if (BB->hasName())
- OS << BB->getName() << "(";
- else
- OS << "(no_name)(";
- OS << BB << ")\n";
- }
-#endif
- }
+ LLVM_DUMP_METHOD void dump() const;
protected:
SmallVector<typename DomTreeT::UpdateType, 16> PendUpdates;
@@ -409,115 +185,30 @@ class GenericDomTreeUpdater {
bool IsRecalculatingPostDomTree = false;
/// Returns true if the update is self dominance.
- bool isSelfDominance(typename DomTreeT::UpdateType Update) const {
- // Won't affect DomTree and PostDomTree.
- return Update.getFrom() == Update.getTo();
- }
+ bool isSelfDominance(typename DomTreeT::UpdateType Update) const;
/// Helper function to apply all pending DomTree updates.
- void applyDomTreeUpdates() {
- // No pending DomTreeUpdates.
- if (Strategy != UpdateStrategy::Lazy || !DT)
- return;
-
- // Only apply updates not are applied by DomTree.
- if (hasPendingDomTreeUpdates()) {
- const auto I = PendUpdates.begin() + PendDTUpdateIndex;
- const auto E = PendUpdates.end();
- assert(I < E &&
- "Iterator range invalid; there should be DomTree updates.");
- DT->applyUpdates(ArrayRef<typename DomTreeT::UpdateType>(I, E));
- PendDTUpdateIndex = PendUpdates.size();
- }
- }
+ void applyDomTreeUpdates();
/// Helper function to apply all pending PostDomTree updates.
- void applyPostDomTreeUpdates() {
- // No pending PostDomTreeUpdates.
- if (Strategy != UpdateStrategy::Lazy || !PDT)
- return;
-
- // Only apply updates not are applied by PostDomTree.
- if (hasPendingPostDomTreeUpdates()) {
- const auto I = PendUpdates.begin() + PendPDTUpdateIndex;
- const auto E = PendUpdates.end();
- assert(I < E &&
- "Iterator range invalid; there should be PostDomTree updates.");
- PDT->applyUpdates(ArrayRef<typename DomTreeT::UpdateType>(I, E));
- PendPDTUpdateIndex = PendUpdates.size();
- }
- }
+ void applyPostDomTreeUpdates();
/// Returns true if the update appears in the LLVM IR.
/// It is used to check whether an update is valid in
/// insertEdge/deleteEdge or is unnecessary in the batch update.
- bool isUpdateValid(typename DomTreeT::UpdateType Update) const {
- const auto *From = Update.getFrom();
- const auto *To = Update.getTo();
- const auto Kind = Update.getKind();
-
- // Discard updates by inspecting the current state of successors of From.
- // Since isUpdateValid() must be called *after* the Terminator of From is
- // altered we can determine if the update is unnecessary for batch updates
- // or invalid for a single update.
- const bool HasEdge = llvm::is_contained(successors(From), To);
-
- // If the IR does not match the update,
- // 1. In batch updates, this update is unnecessary.
- // 2. When called by insertEdge*()/deleteEdge*(), this update is invalid.
- // Edge does not exist in IR.
- if (Kind == DomTreeT::Insert && !HasEdge)
- return false;
-
- // Edge exists in IR.
- if (Kind == DomTreeT::Delete && HasEdge)
- return false;
-
- return true;
- }
+ bool isUpdateValid(typename DomTreeT::UpdateType Update) const;
/// Erase Basic Block node that has been unlinked from Function
/// in the DomTree and PostDomTree.
- void eraseDelBBNode(BasicBlockT *DelBB) {
- if (DT && !IsRecalculatingDomTree)
- if (DT->getNode(DelBB))
- DT->eraseNode(DelBB);
-
- if (PDT && !IsRecalculatingPostDomTree)
- if (PDT->getNode(DelBB))
- PDT->eraseNode(DelBB);
- }
+ void eraseDelBBNode(BasicBlockT *DelBB);
/// Helper function to flush deleted BasicBlocks if all available
/// trees are up-to-date.
- void tryFlushDeletedBB() {
- if (!hasPendingUpdates())
- derived().forceFlushDeletedBB();
- }
+ void tryFlushDeletedBB();
/// Drop all updates applied by all available trees and delete BasicBlocks if
/// all available trees are up-to-date.
- void dropOutOfDateUpdates() {
- if (Strategy == UpdateStrategy::Eager)
- return;
-
- tryFlushDeletedBB();
-
- // Drop all updates applied by both trees.
- if (!DT)
- PendDTUpdateIndex = PendUpdates.size();
- if (!PDT)
- PendPDTUpdateIndex = PendUpdates.size();
-
- const size_t dropIndex = std::min(PendDTUpdateIndex, PendPDTUpdateIndex);
- const auto B = PendUpdates.begin();
- const auto E = PendUpdates.begin() + dropIndex;
- assert(B <= E && "Iterator out of range.");
- PendUpdates.erase(B, E);
- // Calculate current index.
- PendDTUpdateIndex -= dropIndex;
- PendPDTUpdateIndex -= dropIndex;
- }
+ void dropOutOfDateUpdates();
};
} // namespace llvm
diff --git a/llvm/include/llvm/Analysis/GenericDomTreeUpdaterImpl.h b/llvm/include/llvm/Analysis/GenericDomTreeUpdaterImpl.h
new file mode 100644
index 0000000000000..ec6c345b994ac
--- /dev/null
+++ b/llvm/include/llvm/Analysis/GenericDomTreeUpdaterImpl.h
@@ -0,0 +1,477 @@
+//===- GenericDomTreeUpdaterImpl.h ------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the GenericDomTreeUpdater class. This file should only
+// be included by files that implement a specialization of the relevant
+// templates. Currently these are:
+// - llvm/lib/Analysis/DomTreeUpdater.cpp
+// - llvm/lib/CodeGen/MachineDomTreeUpdater.cpp
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_ANALYSIS_GENERICDOMTREEUPDATERIMPL_H
+#define LLVM_ANALYSIS_GENERICDOMTREEUPDATERIMPL_H
+
+#include "llvm/Analysis/GenericDomTreeUpdater.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace llvm {
+
+template <typename DerivedT, typename DomTreeT, typename PostDomTreeT>
+DerivedT &GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::derived() {
+ return *static_cast<DerivedT *>(this);
+}
+
+template <typename DerivedT, typename DomTreeT, typename PostDomTreeT>
+const DerivedT &
+GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::derived() const {
+ return *static_cast<const DerivedT *>(this);
+}
+
+template <typename DerivedT, typename DomTreeT, typename PostDomTreeT>
+GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::GenericDomTreeUpdater(
+ UpdateStrategy Strategy_)
+ : Strategy(Strategy_) {}
+
+template <typename DerivedT, typename DomTreeT, typename PostDomTreeT>
+GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::GenericDomTreeUpdater(
+ DomTreeT &DT_, UpdateStrategy Strategy_)
+ : DT(&DT_), Strategy(Strategy_) {}
+
+template <typename DerivedT, typename DomTreeT, typename PostDomTreeT>
+GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::GenericDomTreeUpdater(
+ DomTreeT *DT_, UpdateStrategy Strategy_)
+ : DT(DT_), Strategy(Strategy_) {}
+
+template <typename DerivedT, typename DomTreeT, typename PostDomTreeT>
+GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::GenericDomTreeUpdater(
+ PostDomTreeT &PDT_, UpdateStrategy Strategy_)
+ : PDT(&PDT_), Strategy(Strategy_) {}
+
+template <typename DerivedT, typename DomTreeT, typename PostDomTreeT>
+GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::GenericDomTreeUpdater(
+ PostDomTreeT *PDT_, UpdateStrategy Strategy_)
+ : PDT(PDT_), Strategy(Strategy_) {}
+
+template <typename DerivedT, typename DomTreeT, typename PostDomTreeT>
+GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::GenericDomTreeUpdater(
+ DomTreeT &DT_, PostDomTreeT &PDT_, UpdateStrategy Strategy_)
+ : DT(&DT_), PDT(&PDT_), Strategy(Strategy_) {}
+
+template <typename DerivedT, typename DomTreeT, typename PostDomTreeT>
+GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::GenericDomTreeUpdater(
+ DomTreeT *DT_, PostDomTreeT *PDT_, UpdateStrategy Strategy_)
+ : DT(DT_), PDT(PDT_), Strategy(Strategy_) {}
+
+template <typename DerivedT, typename DomTreeT, typename PostDomTreeT>
+GenericDomTreeUpdater<DerivedT, DomTreeT,
+ PostDomTreeT>::~GenericDomTreeUpdater() {
+ flush();
+}
+
+template <typename DerivedT, typename DomTreeT, typename PostDomTreeT>
+bool GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::isLazy() const {
+ return Strategy == UpdateStrategy::Lazy;
+}
+
+template <typename DerivedT, typename DomTreeT, typename PostDomTreeT>
+bool GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::isEager() const {
+ return Strategy == UpdateStrategy::Eager;
+}
+
+template <typename DerivedT, typename DomTreeT, typename PostDomTreeT>
+bool GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::hasDomTree()
+ const {
+ return DT != nullptr;
+}
+
+template <typename DerivedT, typename DomTreeT, typename PostDomTreeT>
+bool GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::hasPostDomTree()
+ const {
+ return DT != nullptr;
+}
+
+template <typename DerivedT, typename DomTreeT, typename PostDomTreeT>
+bool GenericDomTreeUpdater<DerivedT, DomTreeT,
+ PostDomTreeT>::hasPendingDeletedBB() const {
+ return !DeletedBBs.empty();
+}
+
+template <typename DerivedT, typename DomTreeT, typename PostDomTreeT>
+bool GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::
+ isBBPendingDeletion(BasicBlockT *DelBB) const {
+ if (Strategy == UpdateStrategy::Eager || DeletedBBs.empty())
+ return false;
+ return DeletedBBs.contains(DelBB);
+}
+
+template <typename DerivedT, typename DomTreeT, typename PostDomTreeT>
+bool GenericDomTreeUpdater<DerivedT, DomTreeT,
+ PostDomTreeT>::hasPendingUpdates() const {
+ return hasPendingDomTreeUpdates() || hasPendingPostDomTreeUpdates();
+}
+
+template <typename DerivedT, typename DomTreeT, typename PostDomTreeT>
+bool GenericDomTreeUpdater<DerivedT, DomTreeT,
+ PostDomTreeT>::hasPendingDomTreeUpdates() const {
+ if (!DT)
+ return false;
+ return PendUpdates.size() != PendDTUpdateIndex;
+}
+
+template <typename DerivedT, typename DomTreeT, typename PostDomTreeT>
+bool GenericDomTreeUpdater<DerivedT, DomTreeT,
+ PostDomTreeT>::hasPendingPostDomTreeUpdates() const {
+ if (!PDT)
+ return false;
+ return PendUpdates.size() != PendPDTUpdateIndex;
+}
+
+template <typename DerivedT, typename DomTreeT, typename PostDomTreeT>
+template <typename FuncT>
+void GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::recalculate(
+ FuncT &F) {
+ if (Strategy == UpdateStrategy::Eager) {
+ if (DT)
+ DT->recalculate(F);
+ if (PDT)
+ PDT->recalculate(F);
+ return;
+ }
+
+ // There is little performance gain if we pend the recalculation under
+ // Lazy UpdateStrategy so we recalculate available trees immediately.
+
+ // Prevent forceFlushDeletedBB() from erasing DomTree or PostDomTree nodes.
+ IsRecalculatingDomTree = IsRecalculatingPostDomTree = true;
+
+ // Because all trees are going to be up-to-date after recalculation,
+ // flush awaiting deleted BasicBlocks.
+ derived().forceFlushDeletedBB();
+ if (DT)
+ DT->recalculate(F);
+ if (PDT)
+ PDT->recalculate(F);
+
+ // Resume forceFlushDeletedBB() to erase DomTree or PostDomTree nodes.
+ IsRecalculatingDomTree = IsRecalculatingPostDomTree = false;
+ PendDTUpdateIndex = PendPDTUpdateIndex = PendUpdates.size();
+ dropOutOfDateUpdates();
+}
+
+template <typename DerivedT, typename DomTreeT, typename PostDomTreeT>
+void GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::applyUpdates(
+ ArrayRef<typename DomTreeT::UpdateType> Updates) {
+ if (!DT && !PDT)
+ return;
+
+ if (Strategy == UpdateStrategy::Lazy) {
+ PendUpdates.reserve(PendUpdates.size() + Updates.size());
+ for (const auto &U : Updates)
+ if (!isSelfDominance(U))
+ PendUpdates.push_back(U);
+
+ return;
+ }
+
+ if (DT)
+ DT->applyUpdates(Updates);
+ if (PDT)
+ PDT->applyUpdates(Updates);
+}
+
+template <typename DerivedT, typename DomTreeT, typename PostDomTreeT>
+void GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::
+ applyUpdatesPermissive(ArrayRef<typename DomTreeT::UpdateType> Updates) {
+ if (!DT && !PDT)
+ return;
+
+ SmallSet<std::pair<BasicBlockT *, BasicBlockT *>, 8> Seen;
+ SmallVector<typename DomTreeT::UpdateType, 8> DeduplicatedUpdates;
+ for (const auto &U : Updates) {
+ auto Edge = std::make_pair(U.getFrom(), U.getTo());
+ // Because it is illegal to submit updates that have already been applied
+ // and updates to an edge need to be strictly ordered,
+ // it is safe to infer the existence of an edge from the first update
+ // to this edge.
+ // If the first update to an edge is "Delete", it means that the edge
+ // existed before. If the first update to an edge is "Insert", it means
+ // that the edge didn't exist before.
+ //
+ // For example, if the user submits {{Delete, A, B}, {Insert, A, B}},
+ // because
+ // 1. it is illegal to submit updates that have already been applied,
+ // i.e., user cannot delete an nonexistent edge,
+ // 2. updates to an edge need to be strictly ordered,
+ // So, initially edge A -> B existed.
+ // We can then safely ignore future updates to this edge and directly
+ // inspect the current CFG:
+ // a. If the edge still exists, because the user cannot insert an existent
+ // edge, so both {Delete, A, B}, {Insert, A, B} actually happened and
+ // resulted in a no-op. DTU won't submit any update in this case.
+ // b. If the edge doesn't exist, we can then infer that {Delete, A, B}
+ // actually happened but {Insert, A, B} was an invalid update which never
+ // happened. DTU will submit {Delete, A, B} in this case.
+ if (!isSelfDominance(U) && Seen.count(Edge) == 0) {
+ Seen.insert(Edge);
+ // If the update doesn't appear in the CFG, it means that
+ // either the change isn't made or relevant operations
+ // result in a no-op.
+ if (isUpdateValid(U)) {
+ if (isLazy())
+ PendUpdates.push_back(U);
+ else
+ DeduplicatedUpdates.push_back(U);
+ }
+ }
+ }
+
+ if (Strategy == UpdateStrategy::Lazy)
+ return;
+
+ if (DT)
+ DT->applyUpdates(DeduplicatedUpdates);
+ if (PDT)
+ PDT->applyUpdates(DeduplicatedUpdates);
+}
+
+template <typename DerivedT, typename DomTreeT, typename PostDomTreeT>
+DomTreeT &
+GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::getDomTree() {
+ assert(DT && "Invalid acquisition of a null DomTree");
+ applyDomTreeUpdates();
+ dropOutOfDateUpdates();
+ return *DT;
+}
+
+template <typename DerivedT, typename DomTreeT, typename PostDomTreeT>
+PostDomTreeT &
+GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::getPostDomTree() {
+ assert(PDT && "Invalid acquisition of a null PostDomTree");
+ applyPostDomTreeUpdates();
+ dropOutOfDateUpdates();
+ return *PDT;
+}
+
+template <typename DerivedT, typename DomTreeT, typename PostDomTreeT>
+void GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::flush() {
+ applyDomTreeUpdates();
+ applyPostDomTreeUpdates();
+ dropOutOfDateUpdates();
+}
+
+template <typename DerivedT, typename DomTreeT, typename PostDomTreeT>
+LLVM_DUMP_METHOD void
+GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::dump() const {
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
+ raw_ostream &OS = llvm::dbgs();
+
+ OS << "Available Trees: ";
+ if (DT || PDT) {
+ if (DT)
+ OS << "DomTree ";
+ if (PDT)
+ OS << "PostDomTree ";
+ OS << "\n";
+ } else
+ OS << "None\n";
+
+ OS << "UpdateStrategy: ";
+ if (Strategy == UpdateStrategy::Eager) {
+ OS << "Eager\n";
+ return;
+ } else
+ OS << "Lazy\n";
+ int Index = 0;
+
+ auto printUpdates =
+ [&](typename ArrayRef<typename DomTreeT::UpdateType>::const_iterator
+ begin,
+ typename ArrayRef<typename DomTreeT::UpdateType>::const_iterator
+ end) {
+ if (begin == end)
+ OS << " None\n";
+ Index = 0;
+ for (auto It = begin, ItEnd = end; It != ItEnd; ++It) {
+ auto U = *It;
+ OS << " " << Index << " : ";
+ ++Index;
+ if (U.getKind() == DomTreeT::Insert)
+ OS << "Insert, ";
+ else
+ OS << "Delete, ";
+ BasicBlockT *From = U.getFrom();
+ if (From) {
+ auto S = From->getName();
+ if (!From->hasName())
+ S = "(no name)";
+ OS << S << "(" << From << "), ";
+ } else {
+ OS << "(badref), ";
+ }
+ BasicBlockT *To = U.getTo();
+ if (To) {
+ auto S = To->getName();
+ if (!To->hasName())
+ S = "(no_name)";
+ OS << S << "(" << To << ")\n";
+ } else {
+ OS << "(badref)\n";
+ }
+ }
+ };
+
+ if (DT) {
+ const auto I = PendUpdates.begin() + PendDTUpdateIndex;
+ assert(PendUpdates.begin() <= I && I <= PendUpdates.end() &&
+ "Iterator out of range.");
+ OS << "Applied but not cleared DomTreeUpdates:\n";
+ printUpdates(PendUpdates.begin(), I);
+ OS << "Pending DomTreeUpdates:\n";
+ printUpdates(I, PendUpdates.end());
+ }
+
+ if (PDT) {
+ const auto I = PendUpdates.begin() + PendPDTUpdateIndex;
+ assert(PendUpdates.begin() <= I && I <= PendUpdates.end() &&
+ "Iterator out of range.");
+ OS << "Applied but not cleared PostDomTreeUpdates:\n";
+ printUpdates(PendUpdates.begin(), I);
+ OS << "Pending PostDomTreeUpdates:\n";
+ printUpdates(I, PendUpdates.end());
+ }
+
+ OS << "Pending DeletedBBs:\n";
+ Index = 0;
+ for (const auto *BB : DeletedBBs) {
+ OS << " " << Index << " : ";
+ ++Index;
+ if (BB->hasName())
+ OS << BB->getName() << "(";
+ else
+ OS << "(no_name)(";
+ OS << BB << ")\n";
+ }
+#endif
+}
+
+template <typename DerivedT, typename DomTreeT, typename PostDomTreeT>
+bool GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::isSelfDominance(
+ typename DomTreeT::UpdateType Update) const {
+ // Won't affect DomTree and PostDomTree.
+ return Update.getFrom() == Update.getTo();
+}
+
+template <typename DerivedT, typename DomTreeT, typename PostDomTreeT>
+void GenericDomTreeUpdater<DerivedT, DomTreeT,
+ PostDomTreeT>::applyDomTreeUpdates() {
+ // No pending DomTreeUpdates.
+ if (Strategy != UpdateStrategy::Lazy || !DT)
+ return;
+
+ // Only apply updates not are applied by DomTree.
+ if (hasPendingDomTreeUpdates()) {
+ const auto I = PendUpdates.begin() + PendDTUpdateIndex;
+ const auto E = PendUpdates.end();
+ assert(I < E && "Iterator range invalid; there should be DomTree updates.");
+ DT->applyUpdates(ArrayRef<typename DomTreeT::UpdateType>(I, E));
+ PendDTUpdateIndex = PendUpdates.size();
+ }
+}
+
+template <typename DerivedT, typename DomTreeT, typename PostDomTreeT>
+void GenericDomTreeUpdater<DerivedT, DomTreeT,
+ PostDomTreeT>::applyPostDomTreeUpdates() {
+ // No pending PostDomTreeUpdates.
+ if (Strategy != UpdateStrategy::Lazy || !PDT)
+ return;
+
+ // Only apply updates not are applied by PostDomTree.
+ if (hasPendingPostDomTreeUpdates()) {
+ const auto I = PendUpdates.begin() + PendPDTUpdateIndex;
+ const auto E = PendUpdates.end();
+ assert(I < E &&
+ "Iterator range invalid; there should be PostDomTree updates.");
+ PDT->applyUpdates(ArrayRef<typename DomTreeT::UpdateType>(I, E));
+ PendPDTUpdateIndex = PendUpdates.size();
+ }
+}
+
+template <typename DerivedT, typename DomTreeT, typename PostDomTreeT>
+bool GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::isUpdateValid(
+ typename DomTreeT::UpdateType Update) const {
+ const auto *From = Update.getFrom();
+ const auto *To = Update.getTo();
+ const auto Kind = Update.getKind();
+
+ // Discard updates by inspecting the current state of successors of From.
+ // Since isUpdateValid() must be called *after* the Terminator of From is
+ // altered we can determine if the update is unnecessary for batch updates
+ // or invalid for a single update.
+ const bool HasEdge = llvm::is_contained(successors(From), To);
+
+ // If the IR does not match the update,
+ // 1. In batch updates, this update is unnecessary.
+ // 2. When called by insertEdge*()/deleteEdge*(), this update is invalid.
+ // Edge does not exist in IR.
+ if (Kind == DomTreeT::Insert && !HasEdge)
+ return false;
+
+ // Edge exists in IR.
+ if (Kind == DomTreeT::Delete && HasEdge)
+ return false;
+
+ return true;
+}
+
+template <typename DerivedT, typename DomTreeT, typename PostDomTreeT>
+void GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::eraseDelBBNode(
+ BasicBlockT *DelBB) {
+ if (DT && !IsRecalculatingDomTree)
+ if (DT->getNode(DelBB))
+ DT->eraseNode(DelBB);
+
+ if (PDT && !IsRecalculatingPostDomTree)
+ if (PDT->getNode(DelBB))
+ PDT->eraseNode(DelBB);
+}
+
+template <typename DerivedT, typename DomTreeT, typename PostDomTreeT>
+void GenericDomTreeUpdater<DerivedT, DomTreeT,
+ PostDomTreeT>::tryFlushDeletedBB() {
+ if (!hasPendingUpdates())
+ derived().forceFlushDeletedBB();
+}
+
+template <typename DerivedT, typename DomTreeT, typename PostDomTreeT>
+void GenericDomTreeUpdater<DerivedT, DomTreeT,
+ PostDomTreeT>::dropOutOfDateUpdates() {
+ if (Strategy == UpdateStrategy::Eager)
+ return;
+
+ tryFlushDeletedBB();
+
+ // Drop all updates applied by both trees.
+ if (!DT)
+ PendDTUpdateIndex = PendUpdates.size();
+ if (!PDT)
+ PendPDTUpdateIndex = PendUpdates.size();
+
+ const size_t dropIndex = std::min(PendDTUpdateIndex, PendPDTUpdateIndex);
+ const auto B = PendUpdates.begin();
+ const auto E = PendUpdates.begin() + dropIndex;
+ assert(B <= E && "Iterator out of range.");
+ PendUpdates.erase(B, E);
+ // Calculate current index.
+ PendDTUpdateIndex -= dropIndex;
+ PendPDTUpdateIndex -= dropIndex;
+}
+
+} // namespace llvm
+
+#endif // LLVM_ANALYSIS_GENERICDOMTREEUPDATERIMPL_H
diff --git a/llvm/include/llvm/CodeGen/MachineDomTreeUpdater.h b/llvm/include/llvm/CodeGen/MachineDomTreeUpdater.h
index 9e59ba5f01ab7..e08b6b54c8e70 100644
--- a/llvm/include/llvm/CodeGen/MachineDomTreeUpdater.h
+++ b/llvm/include/llvm/CodeGen/MachineDomTreeUpdater.h
@@ -14,18 +14,13 @@
#ifndef LLVM_CODEGEN_MACHINEDOMTREEUPDATER_H
#define LLVM_CODEGEN_MACHINEDOMTREEUPDATER_H
-#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Analysis/GenericDomTreeUpdater.h"
#include "llvm/CodeGen/MachineDominators.h"
-#include "llvm/CodeGen/MachinePostDominators.h"
-#include "llvm/IR/ValueHandle.h"
-#include "llvm/Support/Compiler.h"
-#include <cstddef>
-#include <functional>
-#include <vector>
namespace llvm {
+class MachinePostDominatorTree;
+
class MachineDomTreeUpdater
: public GenericDomTreeUpdater<MachineDomTreeUpdater, MachineDominatorTree,
MachinePostDominatorTree> {
@@ -67,5 +62,10 @@ class MachineDomTreeUpdater
extern template class GenericDomTreeUpdater<
MachineDomTreeUpdater, MachineDominatorTree, MachinePostDominatorTree>;
+
+extern template void
+GenericDomTreeUpdater<MachineDomTreeUpdater, MachineDominatorTree,
+ MachinePostDominatorTree>::recalculate(MachineFunction
+ &MF);
} // namespace llvm
#endif // LLVM_CODEGEN_MACHINEDOMTREEUPDATER_H
diff --git a/llvm/lib/Analysis/DomTreeUpdater.cpp b/llvm/lib/Analysis/DomTreeUpdater.cpp
index 676cb87210176..6895317c1d03a 100644
--- a/llvm/lib/Analysis/DomTreeUpdater.cpp
+++ b/llvm/lib/Analysis/DomTreeUpdater.cpp
@@ -13,6 +13,7 @@
#include "llvm/Analysis/DomTreeUpdater.h"
#include "llvm/ADT/SmallSet.h"
+#include "llvm/Analysis/GenericDomTreeUpdaterImpl.h"
#include "llvm/Analysis/PostDominators.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Instructions.h"
@@ -26,6 +27,10 @@ namespace llvm {
template class GenericDomTreeUpdater<DomTreeUpdater, DominatorTree,
PostDominatorTree>;
+template void
+GenericDomTreeUpdater<DomTreeUpdater, DominatorTree,
+ PostDominatorTree>::recalculate(Function &F);
+
bool DomTreeUpdater::forceFlushDeletedBB() {
if (DeletedBBs.empty())
return false;
@@ -94,4 +99,23 @@ void DomTreeUpdater::validateDeleteBB(BasicBlock *DelBB) {
new UnreachableInst(DelBB->getContext(), DelBB);
}
+LLVM_DUMP_METHOD
+void DomTreeUpdater::dump() const {
+ Base::dump();
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
+ raw_ostream &OS = dbgs();
+ OS << "Pending Callbacks:\n";
+ int Index = 0;
+ for (const auto &BB : Callbacks) {
+ OS << " " << Index << " : ";
+ ++Index;
+ if (BB->hasName())
+ OS << BB->getName() << "(";
+ else
+ OS << "(no_name)(";
+ OS << BB << ")\n";
+ }
+#endif
+}
+
} // namespace llvm
diff --git a/llvm/lib/CodeGen/MachineDomTreeUpdater.cpp b/llvm/lib/CodeGen/MachineDomTreeUpdater.cpp
index 86b3185ca90a3..afffafb245e67 100644
--- a/llvm/lib/CodeGen/MachineDomTreeUpdater.cpp
+++ b/llvm/lib/CodeGen/MachineDomTreeUpdater.cpp
@@ -13,9 +13,8 @@
#include "llvm/CodeGen/MachineDomTreeUpdater.h"
#include "llvm/ADT/SmallSet.h"
+#include "llvm/Analysis/GenericDomTreeUpdaterImpl.h"
#include "llvm/CodeGen/MachinePostDominators.h"
-#include "llvm/IR/Constants.h"
-#include "llvm/IR/Instructions.h"
#include "llvm/Support/GenericDomTree.h"
#include <algorithm>
#include <functional>
@@ -26,6 +25,11 @@ namespace llvm {
template class GenericDomTreeUpdater<
MachineDomTreeUpdater, MachineDominatorTree, MachinePostDominatorTree>;
+template void
+GenericDomTreeUpdater<MachineDomTreeUpdater, MachineDominatorTree,
+ MachinePostDominatorTree>::recalculate(MachineFunction
+ &MF);
+
bool MachineDomTreeUpdater::forceFlushDeletedBB() {
if (DeletedBBs.empty())
return false;
>From e96e6624c2adbbd650f074891d3580f36b80acfc Mon Sep 17 00:00:00 2001
From: PaperChalice <liujunchang97 at outlook.com>
Date: Fri, 28 Jun 2024 18:06:10 +0800
Subject: [PATCH 2/2] Move trivial functions to header
---
.../llvm/Analysis/GenericDomTreeUpdater.h | 72 +++++++---
.../llvm/Analysis/GenericDomTreeUpdaterImpl.h | 124 ------------------
2 files changed, 51 insertions(+), 145 deletions(-)
diff --git a/llvm/include/llvm/Analysis/GenericDomTreeUpdater.h b/llvm/include/llvm/Analysis/GenericDomTreeUpdater.h
index 1a86398e4fc68..644230264bfe0 100644
--- a/llvm/include/llvm/Analysis/GenericDomTreeUpdater.h
+++ b/llvm/include/llvm/Analysis/GenericDomTreeUpdater.h
@@ -22,61 +22,84 @@ namespace llvm {
template <typename DerivedT, typename DomTreeT, typename PostDomTreeT>
class GenericDomTreeUpdater {
- DerivedT &derived();
- const DerivedT &derived() const;
+ DerivedT &derived() { return *static_cast<DerivedT *>(this); }
+ const DerivedT &derived() const {
+ return *static_cast<const DerivedT *>(this);
+ }
public:
enum class UpdateStrategy : unsigned char { Eager = 0, Lazy = 1 };
using BasicBlockT = typename DomTreeT::NodeType;
- explicit GenericDomTreeUpdater(UpdateStrategy Strategy_);
- GenericDomTreeUpdater(DomTreeT &DT_, UpdateStrategy Strategy_);
- GenericDomTreeUpdater(DomTreeT *DT_, UpdateStrategy Strategy_);
- GenericDomTreeUpdater(PostDomTreeT &PDT_, UpdateStrategy Strategy_);
- GenericDomTreeUpdater(PostDomTreeT *PDT_, UpdateStrategy Strategy_);
+ explicit GenericDomTreeUpdater(UpdateStrategy Strategy_)
+ : Strategy(Strategy_) {}
+ GenericDomTreeUpdater(DomTreeT &DT_, UpdateStrategy Strategy_)
+ : DT(&DT_), Strategy(Strategy_) {}
+ GenericDomTreeUpdater(DomTreeT *DT_, UpdateStrategy Strategy_)
+ : DT(DT_), Strategy(Strategy_) {}
+ GenericDomTreeUpdater(PostDomTreeT &PDT_, UpdateStrategy Strategy_)
+ : PDT(&PDT_), Strategy(Strategy_) {}
+ GenericDomTreeUpdater(PostDomTreeT *PDT_, UpdateStrategy Strategy_)
+ : PDT(PDT_), Strategy(Strategy_) {}
GenericDomTreeUpdater(DomTreeT &DT_, PostDomTreeT &PDT_,
- UpdateStrategy Strategy_);
+ UpdateStrategy Strategy_)
+ : DT(&DT_), PDT(&PDT_), Strategy(Strategy_) {}
GenericDomTreeUpdater(DomTreeT *DT_, PostDomTreeT *PDT_,
- UpdateStrategy Strategy_);
+ UpdateStrategy Strategy_)
+ : DT(DT_), PDT(PDT_), Strategy(Strategy_) {}
- ~GenericDomTreeUpdater();
+ ~GenericDomTreeUpdater() { flush(); }
/// Returns true if the current strategy is Lazy.
- bool isLazy() const;
+ bool isLazy() const { return Strategy == UpdateStrategy::Lazy; }
/// Returns true if the current strategy is Eager.
- bool isEager() const;
+ bool isEager() const { return Strategy == UpdateStrategy::Eager; }
/// Returns true if it holds a DomTreeT.
- bool hasDomTree() const;
+ bool hasDomTree() const { return DT != nullptr; }
/// Returns true if it holds a PostDomTreeT.
- bool hasPostDomTree() const;
+ bool hasPostDomTree() const { return PDT != nullptr; }
/// Returns true if there is BasicBlockT awaiting deletion.
/// The deletion will only happen until a flush event and
/// all available trees are up-to-date.
/// Returns false under Eager UpdateStrategy.
- bool hasPendingDeletedBB() const;
+ bool hasPendingDeletedBB() const { return !DeletedBBs.empty(); }
/// Returns true if DelBB is awaiting deletion.
/// Returns false under Eager UpdateStrategy.
- bool isBBPendingDeletion(BasicBlockT *DelBB) const;
+ bool isBBPendingDeletion(BasicBlockT *DelBB) const {
+ if (Strategy == UpdateStrategy::Eager || DeletedBBs.empty())
+ return false;
+ return DeletedBBs.contains(DelBB);
+ }
/// Returns true if either of DT or PDT is valid and the tree has at
/// least one update pending. If DT or PDT is nullptr it is treated
/// as having no pending updates. This function does not check
/// whether there is MachineBasicBlock awaiting deletion.
/// Returns false under Eager UpdateStrategy.
- bool hasPendingUpdates() const;
+ bool hasPendingUpdates() const {
+ return hasPendingDomTreeUpdates() || hasPendingPostDomTreeUpdates();
+ }
/// Returns true if there are DomTreeT updates queued.
/// Returns false under Eager UpdateStrategy or DT is nullptr.
- bool hasPendingDomTreeUpdates() const;
+ bool hasPendingDomTreeUpdates() const {
+ if (!DT)
+ return false;
+ return PendUpdates.size() != PendDTUpdateIndex;
+ }
/// Returns true if there are PostDomTreeT updates queued.
/// Returns false under Eager UpdateStrategy or PDT is nullptr.
- bool hasPendingPostDomTreeUpdates() const;
+ bool hasPendingPostDomTreeUpdates() const {
+ if (!PDT)
+ return false;
+ return PendUpdates.size() != PendPDTUpdateIndex;
+ }
///@{
/// \name Mutation APIs
@@ -166,7 +189,11 @@ class GenericDomTreeUpdater {
/// Apply all pending updates to available trees and flush all BasicBlocks
/// awaiting deletion.
- void flush();
+ void flush() {
+ applyDomTreeUpdates();
+ applyPostDomTreeUpdates();
+ dropOutOfDateUpdates();
+ }
///@}
@@ -185,7 +212,10 @@ class GenericDomTreeUpdater {
bool IsRecalculatingPostDomTree = false;
/// Returns true if the update is self dominance.
- bool isSelfDominance(typename DomTreeT::UpdateType Update) const;
+ bool isSelfDominance(typename DomTreeT::UpdateType Update) const {
+ // Won't affect DomTree and PostDomTree.
+ return Update.getFrom() == Update.getTo();
+ }
/// Helper function to apply all pending DomTree updates.
void applyDomTreeUpdates();
diff --git a/llvm/include/llvm/Analysis/GenericDomTreeUpdaterImpl.h b/llvm/include/llvm/Analysis/GenericDomTreeUpdaterImpl.h
index ec6c345b994ac..35c54a6062bfd 100644
--- a/llvm/include/llvm/Analysis/GenericDomTreeUpdaterImpl.h
+++ b/llvm/include/llvm/Analysis/GenericDomTreeUpdaterImpl.h
@@ -22,116 +22,6 @@
namespace llvm {
-template <typename DerivedT, typename DomTreeT, typename PostDomTreeT>
-DerivedT &GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::derived() {
- return *static_cast<DerivedT *>(this);
-}
-
-template <typename DerivedT, typename DomTreeT, typename PostDomTreeT>
-const DerivedT &
-GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::derived() const {
- return *static_cast<const DerivedT *>(this);
-}
-
-template <typename DerivedT, typename DomTreeT, typename PostDomTreeT>
-GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::GenericDomTreeUpdater(
- UpdateStrategy Strategy_)
- : Strategy(Strategy_) {}
-
-template <typename DerivedT, typename DomTreeT, typename PostDomTreeT>
-GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::GenericDomTreeUpdater(
- DomTreeT &DT_, UpdateStrategy Strategy_)
- : DT(&DT_), Strategy(Strategy_) {}
-
-template <typename DerivedT, typename DomTreeT, typename PostDomTreeT>
-GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::GenericDomTreeUpdater(
- DomTreeT *DT_, UpdateStrategy Strategy_)
- : DT(DT_), Strategy(Strategy_) {}
-
-template <typename DerivedT, typename DomTreeT, typename PostDomTreeT>
-GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::GenericDomTreeUpdater(
- PostDomTreeT &PDT_, UpdateStrategy Strategy_)
- : PDT(&PDT_), Strategy(Strategy_) {}
-
-template <typename DerivedT, typename DomTreeT, typename PostDomTreeT>
-GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::GenericDomTreeUpdater(
- PostDomTreeT *PDT_, UpdateStrategy Strategy_)
- : PDT(PDT_), Strategy(Strategy_) {}
-
-template <typename DerivedT, typename DomTreeT, typename PostDomTreeT>
-GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::GenericDomTreeUpdater(
- DomTreeT &DT_, PostDomTreeT &PDT_, UpdateStrategy Strategy_)
- : DT(&DT_), PDT(&PDT_), Strategy(Strategy_) {}
-
-template <typename DerivedT, typename DomTreeT, typename PostDomTreeT>
-GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::GenericDomTreeUpdater(
- DomTreeT *DT_, PostDomTreeT *PDT_, UpdateStrategy Strategy_)
- : DT(DT_), PDT(PDT_), Strategy(Strategy_) {}
-
-template <typename DerivedT, typename DomTreeT, typename PostDomTreeT>
-GenericDomTreeUpdater<DerivedT, DomTreeT,
- PostDomTreeT>::~GenericDomTreeUpdater() {
- flush();
-}
-
-template <typename DerivedT, typename DomTreeT, typename PostDomTreeT>
-bool GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::isLazy() const {
- return Strategy == UpdateStrategy::Lazy;
-}
-
-template <typename DerivedT, typename DomTreeT, typename PostDomTreeT>
-bool GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::isEager() const {
- return Strategy == UpdateStrategy::Eager;
-}
-
-template <typename DerivedT, typename DomTreeT, typename PostDomTreeT>
-bool GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::hasDomTree()
- const {
- return DT != nullptr;
-}
-
-template <typename DerivedT, typename DomTreeT, typename PostDomTreeT>
-bool GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::hasPostDomTree()
- const {
- return DT != nullptr;
-}
-
-template <typename DerivedT, typename DomTreeT, typename PostDomTreeT>
-bool GenericDomTreeUpdater<DerivedT, DomTreeT,
- PostDomTreeT>::hasPendingDeletedBB() const {
- return !DeletedBBs.empty();
-}
-
-template <typename DerivedT, typename DomTreeT, typename PostDomTreeT>
-bool GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::
- isBBPendingDeletion(BasicBlockT *DelBB) const {
- if (Strategy == UpdateStrategy::Eager || DeletedBBs.empty())
- return false;
- return DeletedBBs.contains(DelBB);
-}
-
-template <typename DerivedT, typename DomTreeT, typename PostDomTreeT>
-bool GenericDomTreeUpdater<DerivedT, DomTreeT,
- PostDomTreeT>::hasPendingUpdates() const {
- return hasPendingDomTreeUpdates() || hasPendingPostDomTreeUpdates();
-}
-
-template <typename DerivedT, typename DomTreeT, typename PostDomTreeT>
-bool GenericDomTreeUpdater<DerivedT, DomTreeT,
- PostDomTreeT>::hasPendingDomTreeUpdates() const {
- if (!DT)
- return false;
- return PendUpdates.size() != PendDTUpdateIndex;
-}
-
-template <typename DerivedT, typename DomTreeT, typename PostDomTreeT>
-bool GenericDomTreeUpdater<DerivedT, DomTreeT,
- PostDomTreeT>::hasPendingPostDomTreeUpdates() const {
- if (!PDT)
- return false;
- return PendUpdates.size() != PendPDTUpdateIndex;
-}
-
template <typename DerivedT, typename DomTreeT, typename PostDomTreeT>
template <typename FuncT>
void GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::recalculate(
@@ -258,13 +148,6 @@ GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::getPostDomTree() {
return *PDT;
}
-template <typename DerivedT, typename DomTreeT, typename PostDomTreeT>
-void GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::flush() {
- applyDomTreeUpdates();
- applyPostDomTreeUpdates();
- dropOutOfDateUpdates();
-}
-
template <typename DerivedT, typename DomTreeT, typename PostDomTreeT>
LLVM_DUMP_METHOD void
GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::dump() const {
@@ -360,13 +243,6 @@ GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::dump() const {
#endif
}
-template <typename DerivedT, typename DomTreeT, typename PostDomTreeT>
-bool GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::isSelfDominance(
- typename DomTreeT::UpdateType Update) const {
- // Won't affect DomTree and PostDomTree.
- return Update.getFrom() == Update.getTo();
-}
-
template <typename DerivedT, typename DomTreeT, typename PostDomTreeT>
void GenericDomTreeUpdater<DerivedT, DomTreeT,
PostDomTreeT>::applyDomTreeUpdates() {
More information about the llvm-commits
mailing list