[llvm] [DomTreeUpdater] Move critical edge splitting code to updater (PR #115111)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Nov 17 21:43:04 PST 2024
https://github.com/paperchalice updated https://github.com/llvm/llvm-project/pull/115111
>From 3ee69c84559156a153c02d12f84dca3e3c9625f6 Mon Sep 17 00:00:00 2001
From: PaperChalice <liujunchang97 at outlook.com>
Date: Sat, 27 Jul 2024 14:47:31 +0800
Subject: [PATCH] [DomTreeUpdater] Move critical edge splitting code to updater
---
llvm/include/llvm/Analysis/DomTreeUpdater.h | 6 +-
.../llvm/Analysis/GenericDomTreeUpdater.h | 45 +++-
.../llvm/Analysis/GenericDomTreeUpdaterImpl.h | 251 +++++++++++++++---
llvm/include/llvm/CodeGen/MachineBasicBlock.h | 24 +-
llvm/include/llvm/CodeGen/MachineDominators.h | 169 +-----------
llvm/include/llvm/CodeGen/MachineSSAContext.h | 6 -
llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 4 +-
.../CodeGen/LazyMachineBlockFrequencyInfo.cpp | 4 +-
.../LiveDebugValues/InstrRefBasedImpl.cpp | 2 +-
.../LiveDebugValues/LiveDebugValues.cpp | 2 +-
llvm/lib/CodeGen/MachineBasicBlock.cpp | 8 +-
llvm/lib/CodeGen/MachineDominanceFrontier.cpp | 3 +-
llvm/lib/CodeGen/MachineDominators.cpp | 74 ------
llvm/lib/CodeGen/MachineLICM.cpp | 17 +-
llvm/lib/CodeGen/MachineLoopInfo.cpp | 2 +-
llvm/lib/CodeGen/MachineSink.cpp | 6 +-
.../lib/CodeGen/MachineUniformityAnalysis.cpp | 3 +-
llvm/lib/CodeGen/PHIElimination.cpp | 27 +-
llvm/lib/CodeGen/XRayInstrumentation.cpp | 4 +-
.../lib/Target/AMDGPU/AMDGPURegBankSelect.cpp | 5 +-
.../Target/AMDGPU/SILateBranchLowering.cpp | 6 +-
llvm/lib/Target/AMDGPU/SILowerI1Copies.cpp | 2 +-
llvm/lib/Target/AMDGPU/SIWholeQuadMode.cpp | 2 +-
.../Target/Hexagon/HexagonFrameLowering.cpp | 2 +-
llvm/lib/Target/X86/X86FlagsCopyLowering.cpp | 3 +-
.../deltas/ReduceInstructionsMIR.cpp | 2 +-
.../unittests/Analysis/DomTreeUpdaterTest.cpp | 43 +++
.../WebAssemblyExceptionInfoTest.cpp | 8 +-
28 files changed, 376 insertions(+), 354 deletions(-)
diff --git a/llvm/include/llvm/Analysis/DomTreeUpdater.h b/llvm/include/llvm/Analysis/DomTreeUpdater.h
index c120a6cc6ce5ab..c54f5cc5c1759a 100644
--- a/llvm/include/llvm/Analysis/DomTreeUpdater.h
+++ b/llvm/include/llvm/Analysis/DomTreeUpdater.h
@@ -81,6 +81,9 @@ class DomTreeUpdater
///@}
+ /// Debug method to help view the internal state of this class.
+ LLVM_DUMP_METHOD void dump() const;
+
private:
class CallBackOnDeletion final : public CallbackVH {
public:
@@ -109,9 +112,6 @@ class DomTreeUpdater
/// Returns true if at least one BasicBlock is deleted.
bool forceFlushDeletedBB();
-
- /// Debug method to help view the internal state of this class.
- LLVM_DUMP_METHOD void dump() const;
};
extern template class GenericDomTreeUpdater<DomTreeUpdater, DominatorTree,
diff --git a/llvm/include/llvm/Analysis/GenericDomTreeUpdater.h b/llvm/include/llvm/Analysis/GenericDomTreeUpdater.h
index ca4ce68b85cbcf..6ec64de1b140ed 100644
--- a/llvm/include/llvm/Analysis/GenericDomTreeUpdater.h
+++ b/llvm/include/llvm/Analysis/GenericDomTreeUpdater.h
@@ -30,6 +30,7 @@ class GenericDomTreeUpdater {
public:
enum class UpdateStrategy : unsigned char { Eager = 0, Lazy = 1 };
using BasicBlockT = typename DomTreeT::NodeType;
+ using UpdateT = typename DomTreeT::UpdateType;
explicit GenericDomTreeUpdater(UpdateStrategy Strategy_)
: Strategy(Strategy_) {}
@@ -146,7 +147,19 @@ 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);
+ void applyUpdates(ArrayRef<UpdateT> Updates);
+
+ /// Apply updates that the critical edge (FromBB, ToBB) has been
+ /// split with NewBB.
+ ///
+ /// \note Do not use this method with regular edges.
+ ///
+ /// \note This kind updates are incompatible with generic updates,
+ /// call this method will submit all generic updates in lazy mode.
+ /// It is not recommended to interleave applyUpdates and
+ /// applyUpdatesForCriticalEdgeSplitting.
+ void splitCriticalEdge(BasicBlockT *FromBB, BasicBlockT *ToBB,
+ BasicBlockT *NewBB);
/// Submit updates to all available trees. It will also
/// 1. discard duplicated updates,
@@ -169,7 +182,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);
+ void applyUpdatesPermissive(ArrayRef<UpdateT> Updates);
///@}
@@ -205,7 +218,25 @@ class GenericDomTreeUpdater {
LLVM_DUMP_METHOD void dump() const;
protected:
- SmallVector<typename DomTreeT::UpdateType, 16> PendUpdates;
+ /// Helper structure used to hold all the basic blocks
+ /// involved in the split of a critical edge.
+ struct CriticalEdge {
+ BasicBlockT *FromBB;
+ BasicBlockT *ToBB;
+ BasicBlockT *NewBB;
+ };
+
+ struct DomTreeUpdate {
+ bool IsCriticalEdgeSplit = false;
+ union {
+ UpdateT Update;
+ CriticalEdge EdgeSplit;
+ };
+ DomTreeUpdate(UpdateT Update) : Update(Update) {}
+ DomTreeUpdate(CriticalEdge E) : IsCriticalEdgeSplit(true), EdgeSplit(E) {}
+ };
+
+ SmallVector<DomTreeUpdate, 16> PendUpdates;
size_t PendDTUpdateIndex = 0;
size_t PendPDTUpdateIndex = 0;
DomTreeT *DT = nullptr;
@@ -216,7 +247,7 @@ class GenericDomTreeUpdater {
bool IsRecalculatingPostDomTree = false;
/// Returns true if the update is self dominance.
- bool isSelfDominance(typename DomTreeT::UpdateType Update) const {
+ bool isSelfDominance(UpdateT Update) const {
// Won't affect DomTree and PostDomTree.
return Update.getFrom() == Update.getTo();
}
@@ -230,7 +261,7 @@ class GenericDomTreeUpdater {
/// 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;
+ bool isUpdateValid(UpdateT Update) const;
/// Erase Basic Block node before it is unlinked from Function
/// in the DomTree and PostDomTree.
@@ -243,6 +274,10 @@ class GenericDomTreeUpdater {
/// Drop all updates applied by all available trees and delete BasicBlocks if
/// all available trees are up-to-date.
void dropOutOfDateUpdates();
+
+private:
+ void splitDTCriticalEdges(ArrayRef<CriticalEdge> Updates);
+ void splitPDTCriticalEdges(ArrayRef<CriticalEdge> Updates);
};
} // namespace llvm
diff --git a/llvm/include/llvm/Analysis/GenericDomTreeUpdaterImpl.h b/llvm/include/llvm/Analysis/GenericDomTreeUpdaterImpl.h
index b79eaef57710fa..a5698f4a777057 100644
--- a/llvm/include/llvm/Analysis/GenericDomTreeUpdaterImpl.h
+++ b/llvm/include/llvm/Analysis/GenericDomTreeUpdaterImpl.h
@@ -16,6 +16,7 @@
#ifndef LLVM_ANALYSIS_GENERICDOMTREEUPDATERIMPL_H
#define LLVM_ANALYSIS_GENERICDOMTREEUPDATERIMPL_H
+#include "llvm/ADT/SmallBitVector.h"
#include "llvm/Analysis/GenericDomTreeUpdater.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
@@ -56,7 +57,7 @@ void GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::recalculate(
template <typename DerivedT, typename DomTreeT, typename PostDomTreeT>
void GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::applyUpdates(
- ArrayRef<typename DomTreeT::UpdateType> Updates) {
+ ArrayRef<UpdateT> Updates) {
if (!DT && !PDT)
return;
@@ -77,12 +78,12 @@ void GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::applyUpdates(
template <typename DerivedT, typename DomTreeT, typename PostDomTreeT>
void GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::
- applyUpdatesPermissive(ArrayRef<typename DomTreeT::UpdateType> Updates) {
+ applyUpdatesPermissive(ArrayRef<UpdateT> Updates) {
if (!DT && !PDT)
return;
SmallSet<std::pair<BasicBlockT *, BasicBlockT *>, 8> Seen;
- SmallVector<typename DomTreeT::UpdateType, 8> DeduplicatedUpdates;
+ SmallVector<UpdateT, 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
@@ -129,6 +130,24 @@ void GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::
PDT->applyUpdates(DeduplicatedUpdates);
}
+template <typename DerivedT, typename DomTreeT, typename PostDomTreeT>
+void GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::splitCriticalEdge(
+ BasicBlockT *FromBB, BasicBlockT *ToBB, BasicBlockT *NewBB) {
+ if (!DT && !PDT)
+ return;
+
+ CriticalEdge E = {FromBB, ToBB, NewBB};
+ if (Strategy == UpdateStrategy::Lazy) {
+ PendUpdates.push_back(E);
+ return;
+ }
+
+ if (DT)
+ splitDTCriticalEdges(E);
+ if (PDT)
+ splitPDTCriticalEdges(E);
+}
+
template <typename DerivedT, typename DomTreeT, typename PostDomTreeT>
DomTreeT &
GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::getDomTree() {
@@ -171,45 +190,46 @@ GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::dump() const {
OS << "Lazy\n";
int Index = 0;
+ auto printBlockInfo = [&](BasicBlockT *BB, StringRef Ending) {
+ if (BB) {
+ auto S = BB->getName();
+ if (!BB->hasName())
+ S = "(no name)";
+ OS << S << "(" << BB << ")" << Ending;
+ } else {
+ OS << "(badref)" << Ending;
+ }
+ };
+
auto printUpdates =
- [&](typename ArrayRef<typename DomTreeT::UpdateType>::const_iterator
- begin,
- typename ArrayRef<typename DomTreeT::UpdateType>::const_iterator
- end) {
+ [&](typename ArrayRef<DomTreeUpdate>::const_iterator begin,
+ typename ArrayRef<DomTreeUpdate>::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";
+ if (!It->IsCriticalEdgeSplit) {
+ auto U = It->Update;
+ OS << " " << Index << " : ";
+ ++Index;
+ if (U.getKind() == DomTreeT::Insert)
+ OS << "Insert, ";
+ else
+ OS << "Delete, ";
+ printBlockInfo(U.getFrom(), ", ");
+ printBlockInfo(U.getTo(), "\n");
} else {
- OS << "(badref)\n";
+ const auto &Edge = It->EdgeSplit;
+ OS << " " << Index++ << " : Split critical edge, ";
+ printBlockInfo(Edge.FromBB, ", ");
+ printBlockInfo(Edge.ToBB, ", ");
+ printBlockInfo(Edge.NewBB, "\n");
}
}
};
if (DT) {
- const auto I = PendUpdates.begin() + PendDTUpdateIndex;
+ auto I = PendUpdates.begin() + PendDTUpdateIndex;
assert(PendUpdates.begin() <= I && I <= PendUpdates.end() &&
"Iterator out of range.");
OS << "Applied but not cleared DomTreeUpdates:\n";
@@ -219,7 +239,7 @@ GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::dump() const {
}
if (PDT) {
- const auto I = PendUpdates.begin() + PendPDTUpdateIndex;
+ auto I = PendUpdates.begin() + PendPDTUpdateIndex;
assert(PendUpdates.begin() <= I && I <= PendUpdates.end() &&
"Iterator out of range.");
OS << "Applied but not cleared PostDomTreeUpdates:\n";
@@ -236,7 +256,7 @@ GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::dump() const {
if (BB->hasName())
OS << BB->getName() << "(";
else
- OS << "(no_name)(";
+ OS << "(no name)(";
OS << BB << ")\n";
}
#endif
@@ -250,12 +270,23 @@ void GenericDomTreeUpdater<DerivedT, DomTreeT,
return;
// Only apply updates not are applied by DomTree.
- if (hasPendingDomTreeUpdates()) {
- const auto I = PendUpdates.begin() + PendDTUpdateIndex;
+ while (hasPendingDomTreeUpdates()) {
+ 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();
+ if (!I->IsCriticalEdgeSplit) {
+ SmallVector<UpdateT, 32> NormalUpdates;
+ while (I != E && !I->IsCriticalEdgeSplit)
+ NormalUpdates.push_back((I++)->Update);
+ DT->applyUpdates(NormalUpdates);
+ PendDTUpdateIndex += NormalUpdates.size();
+ } else {
+ SmallVector<CriticalEdge, 32> CriticalEdges;
+ while (I != E && I->IsCriticalEdgeSplit)
+ CriticalEdges.push_back((I++)->EdgeSplit);
+ splitDTCriticalEdges(CriticalEdges);
+ PendDTUpdateIndex += CriticalEdges.size();
+ }
}
}
@@ -267,19 +298,30 @@ void GenericDomTreeUpdater<DerivedT, DomTreeT,
return;
// Only apply updates not are applied by PostDomTree.
- if (hasPendingPostDomTreeUpdates()) {
- const auto I = PendUpdates.begin() + PendPDTUpdateIndex;
+ while (hasPendingPostDomTreeUpdates()) {
+ 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();
+ if (!I->IsCriticalEdgeSplit) {
+ SmallVector<UpdateT, 32> NormalUpdates;
+ while (I != E && !I->IsCriticalEdgeSplit)
+ NormalUpdates.push_back((I++)->Update);
+ PDT->applyUpdates(NormalUpdates);
+ PendPDTUpdateIndex += NormalUpdates.size();
+ } else {
+ SmallVector<CriticalEdge, 32> CriticalEdges;
+ while (I != E && I->IsCriticalEdgeSplit)
+ CriticalEdges.push_back((I++)->EdgeSplit);
+ splitPDTCriticalEdges(CriticalEdges);
+ PendPDTUpdateIndex += CriticalEdges.size();
+ }
}
}
template <typename DerivedT, typename DomTreeT, typename PostDomTreeT>
bool GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::isUpdateValid(
- typename DomTreeT::UpdateType Update) const {
+ UpdateT Update) const {
const auto *From = Update.getFrom();
const auto *To = Update.getTo();
const auto Kind = Update.getKind();
@@ -347,6 +389,131 @@ void GenericDomTreeUpdater<DerivedT, DomTreeT,
PendPDTUpdateIndex -= dropIndex;
}
+template <typename DerivedT, typename DomTreeT, typename PostDomTreeT>
+void GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::
+ splitDTCriticalEdges(ArrayRef<CriticalEdge> Edges) {
+ // Bail out early if there is nothing to do.
+ if (Edges.empty())
+ return;
+
+ // Remember all the basic blocks that are inserted during
+ // edge splitting.
+ // Invariant: NewBBs == all the basic blocks contained in the NewBB
+ // field of all the elements of Edges.
+ // I.e., forall elt in Edges, it exists BB in NewBBs
+ // such as BB == elt.NewBB.
+ SmallSet<BasicBlockT *, 32> NewBBs;
+ for (auto &Edge : Edges)
+ NewBBs.insert(Edge.NewBB);
+ // For each element in Edges, remember whether or not element
+ // is the new immediate domminator of its successor. The mapping is done by
+ // index, i.e., the information for the ith element of Edges is
+ // the ith element of IsNewIDom.
+ SmallBitVector IsNewIDom(Edges.size(), true);
+ size_t Idx = 0;
+
+ // Collect all the dominance properties info, before invalidating
+ // the underlying DT.
+ for (const auto &Edge : Edges) {
+ // Update dominator information.
+ if (DT) {
+ BasicBlockT *Succ = Edge.ToBB;
+ auto *SuccDTNode = DT->getNode(Succ);
+
+ for (BasicBlockT *PredBB : predecessors(Succ)) {
+ if (PredBB == Edge.NewBB)
+ continue;
+ // If we are in this situation:
+ // FromBB1 FromBB2
+ // + +
+ // + + + +
+ // + + + +
+ // ... Split1 Split2 ...
+ // + +
+ // + +
+ // +
+ // Succ
+ // Instead of checking the domiance property with Split2, we check it
+ // with FromBB2 since Split2 is still unknown of the underlying DT
+ // structure.
+ if (NewBBs.count(PredBB)) {
+ assert(pred_size(PredBB) == 1 && "A basic block resulting from a "
+ "critical edge split has more "
+ "than one predecessor!");
+ PredBB = *pred_begin(PredBB);
+ }
+ if (!DT->dominates(SuccDTNode, DT->getNode(PredBB))) {
+ IsNewIDom[Idx] = false;
+ break;
+ }
+ }
+ }
+ ++Idx;
+ }
+
+ // Now, update DT with the collected dominance properties info.
+ Idx = 0;
+ for (const auto &Edge : Edges) {
+ if (DT) {
+ // We know FromBB dominates NewBB.
+ auto *NewDTNode = DT->addNewBlock(Edge.NewBB, Edge.FromBB);
+
+ // If all the other predecessors of "Succ" are dominated by "Succ" itself
+ // then the new block is the new immediate dominator of "Succ". Otherwise,
+ // the new block doesn't dominate anything.
+ if (IsNewIDom[Idx])
+ DT->changeImmediateDominator(DT->getNode(Edge.ToBB), NewDTNode);
+ }
+ ++Idx;
+ }
+}
+
+template <typename DerivedT, typename DomTreeT, typename PostDomTreeT>
+void GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::
+ splitPDTCriticalEdges(ArrayRef<CriticalEdge> Edges) {
+ // Bail out early if there is nothing to do.
+ if (Edges.empty())
+ return;
+
+ SmallBitVector IsNewIPDom(Edges.size(), true);
+ SmallSet<BasicBlockT *, 32> NewBBs;
+ for (const auto &Edge : Edges)
+ NewBBs.insert(Edge.NewBB);
+ size_t Idx = 0;
+ for (const auto &Edge : Edges) {
+ // Same as DT version but from another direction.
+ if (PDT) {
+ BasicBlockT *Pred = Edge.FromBB;
+ auto *PredDTNode = PDT->getNode(Pred);
+ for (BasicBlockT *SuccBB : successors(Pred)) {
+ if (SuccBB == Edge.NewBB)
+ continue;
+ if (NewBBs.count(SuccBB)) {
+ assert(succ_size(SuccBB) == 1 && "A basic block resulting from a "
+ "critical edge split has more "
+ "than one predecessor!");
+ SuccBB = *succ_begin(SuccBB);
+ }
+ if (!PDT->dominates(PredDTNode, PDT->getNode(SuccBB))) {
+ IsNewIPDom[Idx] = false;
+ break;
+ }
+ }
+ }
+ ++Idx;
+ }
+
+ Idx = 0;
+ for (const auto &Edge : Edges) {
+ if (PDT) {
+ auto *NewPDTNode = PDT->addNewBlock(Edge.NewBB, Edge.ToBB);
+ if (IsNewIPDom[Idx])
+ PDT->changeImmediateDominator(PDT->getNode(Edge.FromBB), NewPDTNode);
+ }
+ ++Idx;
+ }
+}
+
} // namespace llvm
#endif // LLVM_ANALYSIS_GENERICDOMTREEUPDATERIMPL_H
diff --git a/llvm/include/llvm/CodeGen/MachineBasicBlock.h b/llvm/include/llvm/CodeGen/MachineBasicBlock.h
index 6cf151c951b19f..7fe33c3913f2dd 100644
--- a/llvm/include/llvm/CodeGen/MachineBasicBlock.h
+++ b/llvm/include/llvm/CodeGen/MachineBasicBlock.h
@@ -32,6 +32,7 @@
namespace llvm {
class BasicBlock;
+class MachineDomTreeUpdater;
class MachineFunction;
class MCSymbol;
class ModuleSlotTracker;
@@ -972,22 +973,23 @@ class MachineBasicBlock
/// MachineLoopInfo, as applicable.
MachineBasicBlock *
SplitCriticalEdge(MachineBasicBlock *Succ, Pass &P,
- std::vector<SparseBitVector<>> *LiveInSets = nullptr) {
- return SplitCriticalEdge(Succ, &P, nullptr, LiveInSets);
+ std::vector<SparseBitVector<>> *LiveInSets = nullptr,
+ MachineDomTreeUpdater *MDTU = nullptr) {
+ return SplitCriticalEdge(Succ, &P, nullptr, LiveInSets, MDTU);
}
MachineBasicBlock *
SplitCriticalEdge(MachineBasicBlock *Succ,
MachineFunctionAnalysisManager &MFAM,
- std::vector<SparseBitVector<>> *LiveInSets = nullptr) {
- return SplitCriticalEdge(Succ, nullptr, &MFAM, LiveInSets);
+ std::vector<SparseBitVector<>> *LiveInSets = nullptr,
+ MachineDomTreeUpdater *MDTU = nullptr) {
+ return SplitCriticalEdge(Succ, nullptr, &MFAM, LiveInSets, MDTU);
}
// Helper method for new pass manager migration.
- MachineBasicBlock *
- SplitCriticalEdge(MachineBasicBlock *Succ, Pass *P,
- MachineFunctionAnalysisManager *MFAM,
- std::vector<SparseBitVector<>> *LiveInSets);
+ MachineBasicBlock *SplitCriticalEdge(
+ MachineBasicBlock *Succ, Pass *P, MachineFunctionAnalysisManager *MFAM,
+ std::vector<SparseBitVector<>> *LiveInSets, MachineDomTreeUpdater *MDTU);
/// Check if the edge between this block and the given successor \p
/// Succ, can be split. If this returns true a subsequent call to
@@ -1375,6 +1377,12 @@ inline auto successors(const MachineBasicBlock *BB) { return BB->successors(); }
inline auto predecessors(const MachineBasicBlock *BB) {
return BB->predecessors();
}
+inline auto succ_size(const MachineBasicBlock *BB) { return BB->succ_size(); }
+inline auto pred_size(const MachineBasicBlock *BB) { return BB->pred_size(); }
+inline auto succ_begin(const MachineBasicBlock *BB) { return BB->succ_begin(); }
+inline auto pred_begin(const MachineBasicBlock *BB) { return BB->pred_begin(); }
+inline auto succ_end(const MachineBasicBlock *BB) { return BB->succ_end(); }
+inline auto pred_end(const MachineBasicBlock *BB) { return BB->pred_end(); }
/// MachineInstrSpan provides an interface to get an iteration range
/// containing the instruction it was initialized with, along with all
diff --git a/llvm/include/llvm/CodeGen/MachineDominators.h b/llvm/include/llvm/CodeGen/MachineDominators.h
index 74cf94398736dd..61635ff64502da 100644
--- a/llvm/include/llvm/CodeGen/MachineDominators.h
+++ b/llvm/include/llvm/CodeGen/MachineDominators.h
@@ -73,86 +73,22 @@ extern template bool Verify<MBBDomTree>(const MBBDomTree &DT,
/// compute a normal dominator tree.
///
class MachineDominatorTree : public DomTreeBase<MachineBasicBlock> {
- /// Helper structure used to hold all the basic blocks
- /// involved in the split of a critical edge.
- struct CriticalEdge {
- MachineBasicBlock *FromBB;
- MachineBasicBlock *ToBB;
- MachineBasicBlock *NewBB;
- };
-
- /// Pile up all the critical edges to be split.
- /// The splitting of a critical edge is local and thus, it is possible
- /// to apply several of those changes at the same time.
- mutable SmallVector<CriticalEdge, 32> CriticalEdgesToSplit;
-
- /// Remember all the basic blocks that are inserted during
- /// edge splitting.
- /// Invariant: NewBBs == all the basic blocks contained in the NewBB
- /// field of all the elements of CriticalEdgesToSplit.
- /// I.e., forall elt in CriticalEdgesToSplit, it exists BB in NewBBs
- /// such as BB == elt.NewBB.
- mutable SmallSet<MachineBasicBlock *, 32> NewBBs;
-
- /// Apply all the recorded critical edges to the DT.
- /// This updates the underlying DT information in a way that uses
- /// the fast query path of DT as much as possible.
- /// FIXME: This method should not be a const member!
- ///
- /// \post CriticalEdgesToSplit.empty().
- void applySplitCriticalEdges() const;
public:
using Base = DomTreeBase<MachineBasicBlock>;
MachineDominatorTree() = default;
- explicit MachineDominatorTree(MachineFunction &MF) { calculate(MF); }
+ explicit MachineDominatorTree(MachineFunction &MF) { recalculate(MF); }
/// Handle invalidation explicitly.
bool invalidate(MachineFunction &, const PreservedAnalyses &PA,
MachineFunctionAnalysisManager::Invalidator &);
- // FIXME: If there is an updater for MachineDominatorTree,
- // migrate to this updater and remove these wrappers.
-
- MachineDominatorTree &getBase() {
- applySplitCriticalEdges();
- return *this;
- }
-
- MachineBasicBlock *getRoot() const {
- applySplitCriticalEdges();
- return Base::getRoot();
- }
-
- MachineDomTreeNode *getRootNode() const {
- applySplitCriticalEdges();
- return const_cast<MachineDomTreeNode *>(Base::getRootNode());
- }
-
- void calculate(MachineFunction &F);
-
- bool dominates(const MachineDomTreeNode *A,
- const MachineDomTreeNode *B) const {
- applySplitCriticalEdges();
- return Base::dominates(A, B);
- }
-
- void getDescendants(MachineBasicBlock *A,
- SmallVectorImpl<MachineBasicBlock *> &Result) {
- applySplitCriticalEdges();
- Base::getDescendants(A, Result);
- }
-
- bool dominates(const MachineBasicBlock *A, const MachineBasicBlock *B) const {
- applySplitCriticalEdges();
- return Base::dominates(A, B);
- }
+ using Base::dominates;
// dominates - Return true if A dominates B. This performs the
// special checks necessary if A and B are in the same basic block.
bool dominates(const MachineInstr *A, const MachineInstr *B) const {
- applySplitCriticalEdges();
const MachineBasicBlock *BBA = A->getParent(), *BBB = B->getParent();
if (BBA != BBB)
return Base::dominates(BBA, BBB);
@@ -164,107 +100,6 @@ class MachineDominatorTree : public DomTreeBase<MachineBasicBlock> {
return &*I == A;
}
-
- bool properlyDominates(const MachineDomTreeNode *A,
- const MachineDomTreeNode *B) const {
- applySplitCriticalEdges();
- return Base::properlyDominates(A, B);
- }
-
- bool properlyDominates(const MachineBasicBlock *A,
- const MachineBasicBlock *B) const {
- applySplitCriticalEdges();
- return Base::properlyDominates(A, B);
- }
-
- /// findNearestCommonDominator - Find nearest common dominator basic block
- /// for basic block A and B. If there is no such block then return NULL.
- MachineBasicBlock *findNearestCommonDominator(MachineBasicBlock *A,
- MachineBasicBlock *B) {
- applySplitCriticalEdges();
- return Base::findNearestCommonDominator(A, B);
- }
-
- MachineDomTreeNode *operator[](MachineBasicBlock *BB) const {
- applySplitCriticalEdges();
- return Base::getNode(BB);
- }
-
- /// getNode - return the (Post)DominatorTree node for the specified basic
- /// block. This is the same as using operator[] on this class.
- ///
- MachineDomTreeNode *getNode(MachineBasicBlock *BB) const {
- applySplitCriticalEdges();
- return Base::getNode(BB);
- }
-
- /// addNewBlock - Add a new node to the dominator tree information. This
- /// creates a new node as a child of DomBB dominator node,linking it into
- /// the children list of the immediate dominator.
- MachineDomTreeNode *addNewBlock(MachineBasicBlock *BB,
- MachineBasicBlock *DomBB) {
- applySplitCriticalEdges();
- return Base::addNewBlock(BB, DomBB);
- }
-
- /// changeImmediateDominator - This method is used to update the dominator
- /// tree information when a node's immediate dominator changes.
- ///
- void changeImmediateDominator(MachineBasicBlock *N,
- MachineBasicBlock *NewIDom) {
- applySplitCriticalEdges();
- Base::changeImmediateDominator(N, NewIDom);
- }
-
- void changeImmediateDominator(MachineDomTreeNode *N,
- MachineDomTreeNode *NewIDom) {
- applySplitCriticalEdges();
- Base::changeImmediateDominator(N, NewIDom);
- }
-
- /// eraseNode - Removes a node from the dominator tree. Block must not
- /// dominate any other blocks. Removes node from its immediate dominator's
- /// children list. Deletes dominator node associated with basic block BB.
- void eraseNode(MachineBasicBlock *BB) {
- applySplitCriticalEdges();
- Base::eraseNode(BB);
- }
-
- /// splitBlock - BB is split and now it has one successor. Update dominator
- /// tree to reflect this change.
- void splitBlock(MachineBasicBlock* NewBB) {
- applySplitCriticalEdges();
- Base::splitBlock(NewBB);
- }
-
- /// isReachableFromEntry - Return true if A is dominated by the entry
- /// block of the function containing it.
- bool isReachableFromEntry(const MachineBasicBlock *A) {
- applySplitCriticalEdges();
- return Base::isReachableFromEntry(A);
- }
-
- /// Record that the critical edge (FromBB, ToBB) has been
- /// split with NewBB.
- /// This is best to use this method instead of directly update the
- /// underlying information, because this helps mitigating the
- /// number of time the DT information is invalidated.
- ///
- /// \note Do not use this method with regular edges.
- ///
- /// \note To benefit from the compile time improvement incurred by this
- /// method, the users of this method have to limit the queries to the DT
- /// interface between two edges splitting. In other words, they have to
- /// pack the splitting of critical edges as much as possible.
- void recordSplitCriticalEdge(MachineBasicBlock *FromBB,
- MachineBasicBlock *ToBB,
- MachineBasicBlock *NewBB) {
- bool Inserted = NewBBs.insert(NewBB).second;
- (void)Inserted;
- assert(Inserted &&
- "A basic block inserted via edge splitting cannot appear twice");
- CriticalEdgesToSplit.push_back({FromBB, ToBB, NewBB});
- }
};
/// \brief Analysis pass which computes a \c MachineDominatorTree.
diff --git a/llvm/include/llvm/CodeGen/MachineSSAContext.h b/llvm/include/llvm/CodeGen/MachineSSAContext.h
index b70450c19f283a..0e4304f69380fe 100644
--- a/llvm/include/llvm/CodeGen/MachineSSAContext.h
+++ b/llvm/include/llvm/CodeGen/MachineSSAContext.h
@@ -24,12 +24,6 @@ class MachineInstr;
class MachineFunction;
class Register;
-inline unsigned succ_size(const MachineBasicBlock *BB) {
- return BB->succ_size();
-}
-inline unsigned pred_size(const MachineBasicBlock *BB) {
- return BB->pred_size();
-}
inline auto instrs(const MachineBasicBlock &BB) { return BB.instrs(); }
template <> struct GenericSSATraits<MachineFunction> {
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 1d24fa44a5cea0..0e43c555b1719b 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -1773,7 +1773,7 @@ void AsmPrinter::emitFunctionBody() {
MDT = MDTWrapper ? &MDTWrapper->getDomTree() : nullptr;
if (!MDT) {
OwnedMDT = std::make_unique<MachineDominatorTree>();
- OwnedMDT->getBase().recalculate(*MF);
+ OwnedMDT->recalculate(*MF);
MDT = OwnedMDT.get();
}
@@ -1782,7 +1782,7 @@ void AsmPrinter::emitFunctionBody() {
MLI = MLIWrapper ? &MLIWrapper->getLI() : nullptr;
if (!MLI) {
OwnedMLI = std::make_unique<MachineLoopInfo>();
- OwnedMLI->analyze(MDT->getBase());
+ OwnedMLI->analyze(*MDT);
MLI = OwnedMLI.get();
}
}
diff --git a/llvm/lib/CodeGen/LazyMachineBlockFrequencyInfo.cpp b/llvm/lib/CodeGen/LazyMachineBlockFrequencyInfo.cpp
index 2561f2e5c9bbb0..6fd84646009bec 100644
--- a/llvm/lib/CodeGen/LazyMachineBlockFrequencyInfo.cpp
+++ b/llvm/lib/CodeGen/LazyMachineBlockFrequencyInfo.cpp
@@ -74,13 +74,13 @@ LazyMachineBlockFrequencyInfoPass::calculateIfNotAvailable() const {
if (!MDT) {
LLVM_DEBUG(dbgs() << "Building DominatorTree on the fly\n");
OwnedMDT = std::make_unique<MachineDominatorTree>();
- OwnedMDT->getBase().recalculate(*MF);
+ OwnedMDT->recalculate(*MF);
MDT = OwnedMDT.get();
}
// Generate LoopInfo from it.
OwnedMLI = std::make_unique<MachineLoopInfo>();
- OwnedMLI->analyze(MDT->getBase());
+ OwnedMLI->analyze(*MDT);
MLI = OwnedMLI.get();
}
diff --git a/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp b/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp
index a9d28a39c4418b..6c4d832f3c929b 100644
--- a/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp
+++ b/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp
@@ -2782,7 +2782,7 @@ void InstrRefBasedLDV::BlockPHIPlacement(
// Apply IDF calculator to the designated set of location defs, storing
// required PHIs into PHIBlocks. Uses the dominator tree stored in the
// InstrRefBasedLDV object.
- IDFCalculatorBase<MachineBasicBlock, false> IDF(DomTree->getBase());
+ IDFCalculatorBase<MachineBasicBlock, false> IDF(*DomTree);
IDF.setLiveInBlocks(AllBlocks);
IDF.setDefiningBlocks(DefBlocks);
diff --git a/llvm/lib/CodeGen/LiveDebugValues/LiveDebugValues.cpp b/llvm/lib/CodeGen/LiveDebugValues/LiveDebugValues.cpp
index a2b1662271940d..a7f089928f84df 100644
--- a/llvm/lib/CodeGen/LiveDebugValues/LiveDebugValues.cpp
+++ b/llvm/lib/CodeGen/LiveDebugValues/LiveDebugValues.cpp
@@ -112,7 +112,7 @@ bool LiveDebugValues::runOnMachineFunction(MachineFunction &MF) {
MachineDominatorTree *DomTree = nullptr;
if (InstrRefBased) {
DomTree = &MDT;
- MDT.calculate(MF);
+ MDT.recalculate(MF);
TheImpl = &*InstrRefImpl;
}
diff --git a/llvm/lib/CodeGen/MachineBasicBlock.cpp b/llvm/lib/CodeGen/MachineBasicBlock.cpp
index 5d06af3ebf3360..5ac6472a01e9fc 100644
--- a/llvm/lib/CodeGen/MachineBasicBlock.cpp
+++ b/llvm/lib/CodeGen/MachineBasicBlock.cpp
@@ -16,11 +16,13 @@
#include "llvm/CodeGen/LiveIntervals.h"
#include "llvm/CodeGen/LivePhysRegs.h"
#include "llvm/CodeGen/LiveVariables.h"
+#include "llvm/CodeGen/MachineDomTreeUpdater.h"
#include "llvm/CodeGen/MachineDominators.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineJumpTableInfo.h"
#include "llvm/CodeGen/MachineLoopInfo.h"
+#include "llvm/CodeGen/MachinePostDominators.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/SlotIndexes.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
@@ -1146,7 +1148,7 @@ class SlotIndexUpdateDelegate : public MachineFunction::Delegate {
MachineBasicBlock *MachineBasicBlock::SplitCriticalEdge(
MachineBasicBlock *Succ, Pass *P, MachineFunctionAnalysisManager *MFAM,
- std::vector<SparseBitVector<>> *LiveInSets) {
+ std::vector<SparseBitVector<>> *LiveInSets, MachineDomTreeUpdater *MDTU) {
assert((P || MFAM) && "Need a way to get analysis results!");
if (!canSplitCriticalEdge(Succ))
return nullptr;
@@ -1346,8 +1348,8 @@ MachineBasicBlock *MachineBasicBlock::SplitCriticalEdge(
LIS->repairIntervalsInRange(this, getFirstTerminator(), end(), UsedRegs);
}
- if (auto *MDT = GET_RESULT(MachineDominatorTree, getDomTree, ))
- MDT->recordSplitCriticalEdge(this, Succ, NMBB);
+ if (MDTU)
+ MDTU->splitCriticalEdge(this, Succ, NMBB);
if (MachineLoopInfo *MLI = GET_RESULT(MachineLoop, getLI, Info))
if (MachineLoop *TIL = MLI->getLoopFor(this)) {
diff --git a/llvm/lib/CodeGen/MachineDominanceFrontier.cpp b/llvm/lib/CodeGen/MachineDominanceFrontier.cpp
index 6a8ede4feb9378..ed69ed931c5cba 100644
--- a/llvm/lib/CodeGen/MachineDominanceFrontier.cpp
+++ b/llvm/lib/CodeGen/MachineDominanceFrontier.cpp
@@ -38,8 +38,7 @@ char &llvm::MachineDominanceFrontierID = MachineDominanceFrontier::ID;
bool MachineDominanceFrontier::runOnMachineFunction(MachineFunction &) {
releaseMemory();
- Base.analyze(
- getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree().getBase());
+ Base.analyze(getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree());
return false;
}
diff --git a/llvm/lib/CodeGen/MachineDominators.cpp b/llvm/lib/CodeGen/MachineDominators.cpp
index a2cc8fdfa7c9f9..67a91c87bb1bca 100644
--- a/llvm/lib/CodeGen/MachineDominators.cpp
+++ b/llvm/lib/CodeGen/MachineDominators.cpp
@@ -95,12 +95,6 @@ MachineDominatorTreeWrapperPass::MachineDominatorTreeWrapperPass()
*PassRegistry::getPassRegistry());
}
-void MachineDominatorTree::calculate(MachineFunction &F) {
- CriticalEdgesToSplit.clear();
- NewBBs.clear();
- recalculate(F);
-}
-
char &llvm::MachineDominatorsID = MachineDominatorTreeWrapperPass::ID;
bool MachineDominatorTreeWrapperPass::runOnMachineFunction(MachineFunction &F) {
@@ -121,71 +115,3 @@ void MachineDominatorTreeWrapperPass::print(raw_ostream &OS,
if (DT)
DT->print(OS);
}
-
-void MachineDominatorTree::applySplitCriticalEdges() const {
- // Bail out early if there is nothing to do.
- if (CriticalEdgesToSplit.empty())
- return;
-
- // For each element in CriticalEdgesToSplit, remember whether or not element
- // is the new immediate domminator of its successor. The mapping is done by
- // index, i.e., the information for the ith element of CriticalEdgesToSplit is
- // the ith element of IsNewIDom.
- SmallBitVector IsNewIDom(CriticalEdgesToSplit.size(), true);
- size_t Idx = 0;
-
- // Collect all the dominance properties info, before invalidating
- // the underlying DT.
- for (CriticalEdge &Edge : CriticalEdgesToSplit) {
- // Update dominator information.
- MachineBasicBlock *Succ = Edge.ToBB;
- MachineDomTreeNode *SuccDTNode = Base::getNode(Succ);
-
- for (MachineBasicBlock *PredBB : Succ->predecessors()) {
- if (PredBB == Edge.NewBB)
- continue;
- // If we are in this situation:
- // FromBB1 FromBB2
- // + +
- // + + + +
- // + + + +
- // ... Split1 Split2 ...
- // + +
- // + +
- // +
- // Succ
- // Instead of checking the domiance property with Split2, we check it with
- // FromBB2 since Split2 is still unknown of the underlying DT structure.
- if (NewBBs.count(PredBB)) {
- assert(PredBB->pred_size() == 1 && "A basic block resulting from a "
- "critical edge split has more "
- "than one predecessor!");
- PredBB = *PredBB->pred_begin();
- }
- if (!Base::dominates(SuccDTNode, Base::getNode(PredBB))) {
- IsNewIDom[Idx] = false;
- break;
- }
- }
- ++Idx;
- }
-
- // Now, update DT with the collected dominance properties info.
- Idx = 0;
- for (CriticalEdge &Edge : CriticalEdgesToSplit) {
- // We know FromBB dominates NewBB.
- MachineDomTreeNode *NewDTNode =
- const_cast<MachineDominatorTree *>(this)->Base::addNewBlock(
- Edge.NewBB, Edge.FromBB);
-
- // If all the other predecessors of "Succ" are dominated by "Succ" itself
- // then the new block is the new immediate dominator of "Succ". Otherwise,
- // the new block doesn't dominate anything.
- if (IsNewIDom[Idx])
- const_cast<MachineDominatorTree *>(this)->Base::changeImmediateDominator(
- Base::getNode(Edge.ToBB), NewDTNode);
- ++Idx;
- }
- NewBBs.clear();
- CriticalEdgesToSplit.clear();
-}
diff --git a/llvm/lib/CodeGen/MachineLICM.cpp b/llvm/lib/CodeGen/MachineLICM.cpp
index 48c901b8d06d61..60a4efd7400176 100644
--- a/llvm/lib/CodeGen/MachineLICM.cpp
+++ b/llvm/lib/CodeGen/MachineLICM.cpp
@@ -24,6 +24,7 @@
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
+#include "llvm/CodeGen/MachineDomTreeUpdater.h"
#include "llvm/CodeGen/MachineDominators.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
@@ -133,7 +134,7 @@ namespace {
AliasAnalysis *AA = nullptr; // Alias analysis info.
MachineBlockFrequencyInfo *MBFI = nullptr; // Machine block frequncy info
MachineLoopInfo *MLI = nullptr; // Current MachineLoopInfo
- MachineDominatorTree *DT = nullptr; // Machine dominator tree for the cur loop
+ MachineDomTreeUpdater *MDTU = nullptr; // Wraps current dominator tree
// State that is updated as we process loops
bool Changed = false; // True if a loop is changed.
@@ -375,7 +376,9 @@ bool MachineLICMImpl::run(MachineFunction &MF) {
.getManager()
.getResult<AAManager>(MF.getFunction())
: &LegacyPass->getAnalysis<AAResultsWrapperPass>().getAAResults();
- DT = GET_RESULT(MachineDominatorTree, getDomTree, );
+ MachineDomTreeUpdater DTU(GET_RESULT(MachineDominatorTree, getDomTree, ),
+ MachineDomTreeUpdater::UpdateStrategy::Lazy);
+ MDTU = &DTU;
MLI = GET_RESULT(MachineLoop, getLI, Info);
MBFI = DisableHoistingToHotterBlocks != UseBFI::None
? GET_RESULT(MachineBlockFrequency, getMBFI, Info)
@@ -421,7 +424,7 @@ bool MachineLICMImpl::run(MachineFunction &MF) {
else {
// CSEMap is initialized for loop header when the first instruction is
// being hoisted.
- MachineDomTreeNode *N = DT->getNode(CurLoop->getHeader());
+ MachineDomTreeNode *N = MDTU->getDomTree().getNode(CurLoop->getHeader());
FirstInLoop = true;
HoistOutOfLoop(N, CurLoop, CurPreheader);
CSEMap.clear();
@@ -764,7 +767,7 @@ bool MachineLICMImpl::IsGuaranteedToExecute(MachineBasicBlock *BB,
SmallVector<MachineBasicBlock*, 8> CurrentLoopExitingBlocks;
CurLoop->getExitingBlocks(CurrentLoopExitingBlocks);
for (MachineBasicBlock *CurrentLoopExitingBlock : CurrentLoopExitingBlocks)
- if (!DT->dominates(BB, CurrentLoopExitingBlock)) {
+ if (!MDTU->getDomTree().dominates(BB, CurrentLoopExitingBlock)) {
SpeculationState = SpeculateTrue;
return false;
}
@@ -1600,7 +1603,7 @@ bool MachineLICMImpl::MayCSE(MachineInstr *MI) {
unsigned Opcode = MI->getOpcode();
for (auto &Map : CSEMap) {
// Check this CSEMap's preheader dominates MI's basic block.
- if (DT->dominates(Map.first, MI->getParent())) {
+ if (MDTU->getDomTree().dominates(Map.first, MI->getParent())) {
DenseMap<unsigned, std::vector<MachineInstr *>>::iterator CI =
Map.second.find(Opcode);
// Do not CSE implicit_def so ProcessImplicitDefs can properly propagate
@@ -1668,7 +1671,7 @@ unsigned MachineLICMImpl::Hoist(MachineInstr *MI, MachineBasicBlock *Preheader,
bool HasCSEDone = false;
for (auto &Map : CSEMap) {
// Check this CSEMap's preheader dominates MI's basic block.
- if (DT->dominates(Map.first, MI->getParent())) {
+ if (MDTU->getDomTree().dominates(Map.first, MI->getParent())) {
DenseMap<unsigned, std::vector<MachineInstr *>>::iterator CI =
Map.second.find(Opcode);
if (CI != Map.second.end()) {
@@ -1732,7 +1735,7 @@ MachineLICMImpl::getCurPreheader(MachineLoop *CurLoop,
}
CurPreheader = Pred->SplitCriticalEdge(CurLoop->getHeader(), LegacyPass,
- MFAM, nullptr);
+ MFAM, nullptr, MDTU);
if (!CurPreheader) {
CurPreheader = reinterpret_cast<MachineBasicBlock *>(-1);
return nullptr;
diff --git a/llvm/lib/CodeGen/MachineLoopInfo.cpp b/llvm/lib/CodeGen/MachineLoopInfo.cpp
index b0d74ecd6a8549..d6906bacde0e29 100644
--- a/llvm/lib/CodeGen/MachineLoopInfo.cpp
+++ b/llvm/lib/CodeGen/MachineLoopInfo.cpp
@@ -77,7 +77,7 @@ bool MachineLoopInfo::invalidate(
void MachineLoopInfo::calculate(MachineDominatorTree &MDT) {
releaseMemory();
- analyze(MDT.getBase());
+ analyze(MDT);
}
void MachineLoopInfoWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
diff --git a/llvm/lib/CodeGen/MachineSink.cpp b/llvm/lib/CodeGen/MachineSink.cpp
index c470bd71dfb29f..e93b84553ead80 100644
--- a/llvm/lib/CodeGen/MachineSink.cpp
+++ b/llvm/lib/CodeGen/MachineSink.cpp
@@ -30,6 +30,7 @@
#include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
#include "llvm/CodeGen/MachineBranchProbabilityInfo.h"
#include "llvm/CodeGen/MachineCycleAnalysis.h"
+#include "llvm/CodeGen/MachineDomTreeUpdater.h"
#include "llvm/CodeGen/MachineDominators.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
@@ -747,8 +748,11 @@ bool MachineSinking::runOnMachineFunction(MachineFunction &MF) {
MadeChange |= ProcessBlock(MBB);
// If we have anything we marked as toSplit, split it now.
+ MachineDomTreeUpdater MDTU(DT, PDT,
+ MachineDomTreeUpdater::UpdateStrategy::Lazy);
for (const auto &Pair : ToSplit) {
- auto NewSucc = Pair.first->SplitCriticalEdge(Pair.second, *this);
+ auto NewSucc =
+ Pair.first->SplitCriticalEdge(Pair.second, *this, nullptr, &MDTU);
if (NewSucc != nullptr) {
LLVM_DEBUG(dbgs() << " *** Splitting critical edge: "
<< printMBBReference(*Pair.first) << " -- "
diff --git a/llvm/lib/CodeGen/MachineUniformityAnalysis.cpp b/llvm/lib/CodeGen/MachineUniformityAnalysis.cpp
index 7548fc8141ec56..a4b78c1c75ceb0 100644
--- a/llvm/lib/CodeGen/MachineUniformityAnalysis.cpp
+++ b/llvm/lib/CodeGen/MachineUniformityAnalysis.cpp
@@ -199,8 +199,7 @@ void MachineUniformityAnalysisPass::getAnalysisUsage(AnalysisUsage &AU) const {
}
bool MachineUniformityAnalysisPass::runOnMachineFunction(MachineFunction &MF) {
- auto &DomTree =
- getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree().getBase();
+ auto &DomTree = getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
auto &CI = getAnalysis<MachineCycleInfoWrapperPass>().getCycleInfo();
// FIXME: Query TTI::hasBranchDivergence. -run-pass seems to end up with a
// default NoTTI
diff --git a/llvm/lib/CodeGen/PHIElimination.cpp b/llvm/lib/CodeGen/PHIElimination.cpp
index e5f40771eda86a..b71e5b8538689c 100644
--- a/llvm/lib/CodeGen/PHIElimination.cpp
+++ b/llvm/lib/CodeGen/PHIElimination.cpp
@@ -22,6 +22,7 @@
#include "llvm/CodeGen/LiveIntervals.h"
#include "llvm/CodeGen/LiveVariables.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/MachineDomTreeUpdater.h"
#include "llvm/CodeGen/MachineDominators.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
@@ -90,7 +91,8 @@ class PHIEliminationImpl {
/// Split critical edges where necessary for good coalescer performance.
bool SplitPHIEdges(MachineFunction &MF, MachineBasicBlock &MBB,
MachineLoopInfo *MLI,
- std::vector<SparseBitVector<>> *LiveInSets);
+ std::vector<SparseBitVector<>> *LiveInSets,
+ MachineDomTreeUpdater &MDTU);
// These functions are temporary abstractions around LiveVariables and
// LiveIntervals, so they can go away when LiveVariables does.
@@ -203,6 +205,16 @@ void PHIElimination::getAnalysisUsage(AnalysisUsage &AU) const {
bool PHIEliminationImpl::run(MachineFunction &MF) {
MRI = &MF.getRegInfo();
+ MachineDominatorTree *MDT = nullptr;
+ if (P) {
+ auto *MDTWrapper =
+ P->getAnalysisIfAvailable<MachineDominatorTreeWrapperPass>();
+ MDT = MDTWrapper ? &MDTWrapper->getDomTree() : nullptr;
+ } else {
+ MDT = MFAM->getCachedResult<MachineDominatorTreeAnalysis>(MF);
+ }
+ MachineDomTreeUpdater MDTU(MDT, MachineDomTreeUpdater::UpdateStrategy::Lazy);
+
bool Changed = false;
// Split critical edges to help the coalescer.
@@ -237,7 +249,8 @@ bool PHIEliminationImpl::run(MachineFunction &MF) {
}
for (auto &MBB : MF)
- Changed |= SplitPHIEdges(MF, MBB, MLI, (LV ? &LiveInSets : nullptr));
+ Changed |=
+ SplitPHIEdges(MF, MBB, MLI, (LV ? &LiveInSets : nullptr), MDTU);
}
// This pass takes the function out of SSA form.
@@ -268,10 +281,6 @@ bool PHIEliminationImpl::run(MachineFunction &MF) {
MF.deleteMachineInstr(I.first);
}
- // TODO: we should use the incremental DomTree updater here.
- if (Changed && MDT)
- MDT->getBase().recalculate(MF);
-
LoweredPHIs.clear();
ImpDefs.clear();
VRegPHIUseCount.clear();
@@ -752,7 +761,7 @@ void PHIEliminationImpl::analyzePHINodes(const MachineFunction &MF) {
bool PHIEliminationImpl::SplitPHIEdges(
MachineFunction &MF, MachineBasicBlock &MBB, MachineLoopInfo *MLI,
- std::vector<SparseBitVector<>> *LiveInSets) {
+ std::vector<SparseBitVector<>> *LiveInSets, MachineDomTreeUpdater &MDTU) {
if (MBB.empty() || !MBB.front().isPHI() || MBB.isEHPad())
return false; // Quick exit for basic blocks without PHIs.
@@ -819,8 +828,8 @@ bool PHIEliminationImpl::SplitPHIEdges(
}
if (!ShouldSplit && !SplitAllCriticalEdges)
continue;
- if (!(P ? PreMBB->SplitCriticalEdge(&MBB, *P, LiveInSets)
- : PreMBB->SplitCriticalEdge(&MBB, *MFAM, LiveInSets))) {
+ if (!(P ? PreMBB->SplitCriticalEdge(&MBB, *P, LiveInSets, &MDTU)
+ : PreMBB->SplitCriticalEdge(&MBB, *MFAM, LiveInSets, &MDTU))) {
LLVM_DEBUG(dbgs() << "Failed to split critical edge.\n");
continue;
}
diff --git a/llvm/lib/CodeGen/XRayInstrumentation.cpp b/llvm/lib/CodeGen/XRayInstrumentation.cpp
index 8f718d884cd067..c8b0f9369bd39d 100644
--- a/llvm/lib/CodeGen/XRayInstrumentation.cpp
+++ b/llvm/lib/CodeGen/XRayInstrumentation.cpp
@@ -175,7 +175,7 @@ bool XRayInstrumentation::runOnMachineFunction(MachineFunction &MF) {
auto *MDT = MDTWrapper ? &MDTWrapper->getDomTree() : nullptr;
MachineDominatorTree ComputedMDT;
if (!MDT) {
- ComputedMDT.getBase().recalculate(MF);
+ ComputedMDT.recalculate(MF);
MDT = &ComputedMDT;
}
@@ -184,7 +184,7 @@ bool XRayInstrumentation::runOnMachineFunction(MachineFunction &MF) {
auto *MLI = MLIWrapper ? &MLIWrapper->getLI() : nullptr;
MachineLoopInfo ComputedMLI;
if (!MLI) {
- ComputedMLI.analyze(MDT->getBase());
+ ComputedMLI.analyze(*MDT);
MLI = &ComputedMLI;
}
diff --git a/llvm/lib/Target/AMDGPU/AMDGPURegBankSelect.cpp b/llvm/lib/Target/AMDGPU/AMDGPURegBankSelect.cpp
index d1985f46b1c448..8135805cd696b2 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPURegBankSelect.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPURegBankSelect.cpp
@@ -66,9 +66,8 @@ bool AMDGPURegBankSelect::runOnMachineFunction(MachineFunction &MF) {
MachineDominatorTree &DomTree =
getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
- MachineUniformityInfo Uniformity =
- computeMachineUniformityInfo(MF, CycleInfo, DomTree.getBase(),
- !ST.isSingleLaneExecution(F));
+ MachineUniformityInfo Uniformity = computeMachineUniformityInfo(
+ MF, CycleInfo, DomTree, !ST.isSingleLaneExecution(F));
(void)Uniformity; // TODO: Use this
assignRegisterBanks(MF);
diff --git a/llvm/lib/Target/AMDGPU/SILateBranchLowering.cpp b/llvm/lib/Target/AMDGPU/SILateBranchLowering.cpp
index 8dec5ded848c6f..d02173f57ee379 100644
--- a/llvm/lib/Target/AMDGPU/SILateBranchLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/SILateBranchLowering.cpp
@@ -113,7 +113,7 @@ static void splitBlock(MachineBasicBlock &MBB, MachineInstr &MI,
DTUpdates.push_back({DomTreeT::Delete, &MBB, Succ});
}
DTUpdates.push_back({DomTreeT::Insert, &MBB, SplitBB});
- MDT->getBase().applyUpdates(DTUpdates);
+ MDT->applyUpdates(DTUpdates);
}
void SILateBranchLowering::expandChainCall(MachineInstr &MI) {
@@ -141,7 +141,7 @@ void SILateBranchLowering::earlyTerm(MachineInstr &MI,
splitBlock(MBB, *BranchMI, MDT);
MBB.addSuccessor(EarlyExitBlock);
- MDT->getBase().insertEdge(&MBB, EarlyExitBlock);
+ MDT->insertEdge(&MBB, EarlyExitBlock);
}
bool SILateBranchLowering::runOnMachineFunction(MachineFunction &MF) {
@@ -237,7 +237,7 @@ bool SILateBranchLowering::runOnMachineFunction(MachineFunction &MF) {
}
MBB->addSuccessor(EmptyMBBAtEnd);
- MDT->getBase().insertEdge(MBB, EmptyMBBAtEnd);
+ MDT->insertEdge(MBB, EmptyMBBAtEnd);
BuildMI(*MBB, MI, MI->getDebugLoc(), TII->get(AMDGPU::S_BRANCH))
.addMBB(EmptyMBBAtEnd);
MI->eraseFromParent();
diff --git a/llvm/lib/Target/AMDGPU/SILowerI1Copies.cpp b/llvm/lib/Target/AMDGPU/SILowerI1Copies.cpp
index 3c76da40852754..5805ec658fd613 100644
--- a/llvm/lib/Target/AMDGPU/SILowerI1Copies.cpp
+++ b/llvm/lib/Target/AMDGPU/SILowerI1Copies.cpp
@@ -486,7 +486,7 @@ bool PhiLoweringHelper::lowerPhis() {
if (Vreg1Phis.empty())
return false;
- DT->getBase().updateDFSNumbers();
+ DT->updateDFSNumbers();
MachineBasicBlock *PrevMBB = nullptr;
for (MachineInstr *MI : Vreg1Phis) {
MachineBasicBlock &MBB = *MI->getParent();
diff --git a/llvm/lib/Target/AMDGPU/SIWholeQuadMode.cpp b/llvm/lib/Target/AMDGPU/SIWholeQuadMode.cpp
index fba1d0c0269589..9fbb847da2af1c 100644
--- a/llvm/lib/Target/AMDGPU/SIWholeQuadMode.cpp
+++ b/llvm/lib/Target/AMDGPU/SIWholeQuadMode.cpp
@@ -786,7 +786,7 @@ MachineBasicBlock *SIWholeQuadMode::splitBlock(MachineBasicBlock *BB,
}
DTUpdates.push_back({DomTreeT::Insert, BB, SplitBB});
if (MDT)
- MDT->getBase().applyUpdates(DTUpdates);
+ MDT->applyUpdates(DTUpdates);
if (PDT)
PDT->applyUpdates(DTUpdates);
diff --git a/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp b/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp
index 48acd9da9587fe..a35f7a3350f8c1 100644
--- a/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp
@@ -413,7 +413,7 @@ void HexagonFrameLowering::findShrunkPrologEpilog(MachineFunction &MF,
auto &HRI = *MF.getSubtarget<HexagonSubtarget>().getRegisterInfo();
MachineDominatorTree MDT;
- MDT.calculate(MF);
+ MDT.recalculate(MF);
MachinePostDominatorTree MPT;
MPT.recalculate(MF);
diff --git a/llvm/lib/Target/X86/X86FlagsCopyLowering.cpp b/llvm/lib/Target/X86/X86FlagsCopyLowering.cpp
index ea1b6e97aa32db..ab4c70aee486ac 100644
--- a/llvm/lib/Target/X86/X86FlagsCopyLowering.cpp
+++ b/llvm/lib/Target/X86/X86FlagsCopyLowering.cpp
@@ -277,8 +277,7 @@ bool X86FlagsCopyLoweringPass::runOnMachineFunction(MachineFunction &MF) {
if (MDTWrapper) {
MDT = &MDTWrapper->getDomTree();
} else {
- OwnedMDT = std::make_unique<MachineDominatorTree>();
- OwnedMDT->getBase().recalculate(MF);
+ OwnedMDT = std::make_unique<MachineDominatorTree>(MF);
MDT = OwnedMDT.get();
}
diff --git a/llvm/tools/llvm-reduce/deltas/ReduceInstructionsMIR.cpp b/llvm/tools/llvm-reduce/deltas/ReduceInstructionsMIR.cpp
index 5f0697f5aaad75..40bc6b180fb887 100644
--- a/llvm/tools/llvm-reduce/deltas/ReduceInstructionsMIR.cpp
+++ b/llvm/tools/llvm-reduce/deltas/ReduceInstructionsMIR.cpp
@@ -65,7 +65,7 @@ static bool shouldNotRemoveInstruction(const TargetInstrInfo &TII,
static void extractInstrFromFunction(Oracle &O, MachineFunction &MF) {
MachineDominatorTree MDT;
- MDT.calculate(MF);
+ MDT.recalculate(MF);
auto MRI = &MF.getRegInfo();
SetVector<MachineInstr *> ToDelete;
diff --git a/llvm/unittests/Analysis/DomTreeUpdaterTest.cpp b/llvm/unittests/Analysis/DomTreeUpdaterTest.cpp
index 0777bbe3887bce..cabfc2aba57cf5 100644
--- a/llvm/unittests/Analysis/DomTreeUpdaterTest.cpp
+++ b/llvm/unittests/Analysis/DomTreeUpdaterTest.cpp
@@ -15,6 +15,7 @@
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/SourceMgr.h"
+#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "gtest/gtest.h"
#include <algorithm>
@@ -787,3 +788,45 @@ TEST(DomTreeUpdater, LazyUpdateDeduplicationTest) {
DTU.applyUpdates({{DominatorTree::Insert, BB0, BB2}});
ASSERT_TRUE(DTU.getDomTree().verify());
}
+
+TEST(DomTreeUpdater, CriticalEdgeSplitTest) {
+ StringRef FuncName = "f";
+ StringRef ModuleString = R"(
+declare void @use1(i32)
+
+define void @f(i32 %i, i1 %c) {
+entry:
+ %A = icmp eq i32 %i, 0 ; <i1> [#uses=1]
+ br i1 %A, label %brtrue, label %brfalse
+
+brtrue: ; preds = %entry
+ call void @use1( i32 %i )
+ br label %brfalse
+
+brfalse: ; preds = %brtrue, %entry
+ call void @use1( i32 %i )
+ ret void
+}
+ )";
+ // Make the module.
+ LLVMContext Context;
+ std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
+ Function *F = M->getFunction(FuncName);
+
+ // Make the DTU.
+ DominatorTree DT(*F);
+ DomTreeUpdater DTU(&DT, nullptr, DomTreeUpdater::UpdateStrategy::Lazy);
+ ASSERT_TRUE(DTU.getDomTree().verify());
+
+ CriticalEdgeSplittingOptions Opts;
+ SplitAllCriticalEdges(*F, Opts);
+
+ Function::iterator FI = F->begin();
+ BasicBlock *BBEntry = &*FI++;
+ BasicBlock *SplitB = &*FI++;
+ [[maybe_unused]] BasicBlock *BBTrue = &*FI++;
+ BasicBlock *BBFalse = &*FI++;
+ DTU.splitCriticalEdge(BBEntry, BBFalse, SplitB);
+ DominatorTree NewDT(*F);
+ ASSERT_FALSE(NewDT.compare(DTU.getDomTree()));
+}
diff --git a/llvm/unittests/Target/WebAssembly/WebAssemblyExceptionInfoTest.cpp b/llvm/unittests/Target/WebAssembly/WebAssemblyExceptionInfoTest.cpp
index 9bbbb352efdce4..223a5714f62f27 100644
--- a/llvm/unittests/Target/WebAssembly/WebAssemblyExceptionInfoTest.cpp
+++ b/llvm/unittests/Target/WebAssembly/WebAssemblyExceptionInfoTest.cpp
@@ -167,8 +167,8 @@ body: |
WebAssemblyExceptionInfo WEI;
MachineDominatorTree MDT;
MachineDominanceFrontier MDF;
- MDT.calculate(*MF);
- MDF.getBase().analyze(MDT.getBase());
+ MDT.recalculate(*MF);
+ MDF.getBase().analyze(MDT);
WEI.recalculate(*MF, MDT, MDF);
// Exception info structure:
@@ -341,8 +341,8 @@ body: |
WebAssemblyExceptionInfo WEI;
MachineDominatorTree MDT;
MachineDominanceFrontier MDF;
- MDT.calculate(*MF);
- MDF.getBase().analyze(MDT.getBase());
+ MDT.recalculate(*MF);
+ MDF.getBase().analyze(MDT);
WEI.recalculate(*MF, MDT, MDF);
// Exception info structure:
More information about the llvm-commits
mailing list