Skip to content

Commit e3ec08b

Browse files
committed
Reapply "[CodeGen] Introduce MachineDomTreeUpdater" (#96846)
This reverts commit 0f88493. Resolve conflict in `MachinePostDominators.h`
1 parent 0f88493 commit e3ec08b

10 files changed

+979
-510
lines changed

llvm/include/llvm/Analysis/DomTreeUpdater.h

Lines changed: 32 additions & 164 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
#define LLVM_ANALYSIS_DOMTREEUPDATER_H
1616

1717
#include "llvm/ADT/SmallPtrSet.h"
18+
#include "llvm/Analysis/GenericDomTreeUpdater.h"
19+
#include "llvm/Analysis/PostDominators.h"
1820
#include "llvm/IR/Dominators.h"
1921
#include "llvm/IR/ValueHandle.h"
2022
#include "llvm/Support/Compiler.h"
@@ -23,66 +25,17 @@
2325
#include <vector>
2426

2527
namespace llvm {
26-
class PostDominatorTree;
2728

28-
class DomTreeUpdater {
29-
public:
30-
enum class UpdateStrategy : unsigned char { Eager = 0, Lazy = 1 };
31-
32-
explicit DomTreeUpdater(UpdateStrategy Strategy_) : Strategy(Strategy_) {}
33-
DomTreeUpdater(DominatorTree &DT_, UpdateStrategy Strategy_)
34-
: DT(&DT_), Strategy(Strategy_) {}
35-
DomTreeUpdater(DominatorTree *DT_, UpdateStrategy Strategy_)
36-
: DT(DT_), Strategy(Strategy_) {}
37-
DomTreeUpdater(PostDominatorTree &PDT_, UpdateStrategy Strategy_)
38-
: PDT(&PDT_), Strategy(Strategy_) {}
39-
DomTreeUpdater(PostDominatorTree *PDT_, UpdateStrategy Strategy_)
40-
: PDT(PDT_), Strategy(Strategy_) {}
41-
DomTreeUpdater(DominatorTree &DT_, PostDominatorTree &PDT_,
42-
UpdateStrategy Strategy_)
43-
: DT(&DT_), PDT(&PDT_), Strategy(Strategy_) {}
44-
DomTreeUpdater(DominatorTree *DT_, PostDominatorTree *PDT_,
45-
UpdateStrategy Strategy_)
46-
: DT(DT_), PDT(PDT_), Strategy(Strategy_) {}
47-
48-
~DomTreeUpdater() { flush(); }
49-
50-
/// Returns true if the current strategy is Lazy.
51-
bool isLazy() const { return Strategy == UpdateStrategy::Lazy; };
52-
53-
/// Returns true if the current strategy is Eager.
54-
bool isEager() const { return Strategy == UpdateStrategy::Eager; };
55-
56-
/// Returns true if it holds a DominatorTree.
57-
bool hasDomTree() const { return DT != nullptr; }
58-
59-
/// Returns true if it holds a PostDominatorTree.
60-
bool hasPostDomTree() const { return PDT != nullptr; }
61-
62-
/// Returns true if there is BasicBlock awaiting deletion.
63-
/// The deletion will only happen until a flush event and
64-
/// all available trees are up-to-date.
65-
/// Returns false under Eager UpdateStrategy.
66-
bool hasPendingDeletedBB() const { return !DeletedBBs.empty(); }
67-
68-
/// Returns true if DelBB is awaiting deletion.
69-
/// Returns false under Eager UpdateStrategy.
70-
bool isBBPendingDeletion(BasicBlock *DelBB) const;
71-
72-
/// Returns true if either of DT or PDT is valid and the tree has at
73-
/// least one update pending. If DT or PDT is nullptr it is treated
74-
/// as having no pending updates. This function does not check
75-
/// whether there is BasicBlock awaiting deletion.
76-
/// Returns false under Eager UpdateStrategy.
77-
bool hasPendingUpdates() const;
29+
class DomTreeUpdater
30+
: public GenericDomTreeUpdater<DomTreeUpdater, DominatorTree,
31+
PostDominatorTree> {
32+
friend GenericDomTreeUpdater<DomTreeUpdater, DominatorTree,
33+
PostDominatorTree>;
7834

79-
/// Returns true if there are DominatorTree updates queued.
80-
/// Returns false under Eager UpdateStrategy or DT is nullptr.
81-
bool hasPendingDomTreeUpdates() const;
82-
83-
/// Returns true if there are PostDominatorTree updates queued.
84-
/// Returns false under Eager UpdateStrategy or PDT is nullptr.
85-
bool hasPendingPostDomTreeUpdates() const;
35+
public:
36+
using Base =
37+
GenericDomTreeUpdater<DomTreeUpdater, DominatorTree, PostDominatorTree>;
38+
using Base::Base;
8639

8740
///@{
8841
/// \name Mutation APIs
@@ -105,51 +58,6 @@ class DomTreeUpdater {
10558
/// Although GenericDomTree provides several update primitives,
10659
/// it is not encouraged to use these APIs directly.
10760

108-
/// Submit updates to all available trees.
109-
/// The Eager Strategy flushes updates immediately while the Lazy Strategy
110-
/// queues the updates.
111-
///
112-
/// Note: The "existence" of an edge in a CFG refers to the CFG which DTU is
113-
/// in sync with + all updates before that single update.
114-
///
115-
/// CAUTION!
116-
/// 1. It is required for the state of the LLVM IR to be updated
117-
/// *before* submitting the updates because the internal update routine will
118-
/// analyze the current state of the CFG to determine whether an update
119-
/// is valid.
120-
/// 2. It is illegal to submit any update that has already been submitted,
121-
/// i.e., you are supposed not to insert an existent edge or delete a
122-
/// nonexistent edge.
123-
void applyUpdates(ArrayRef<DominatorTree::UpdateType> Updates);
124-
125-
/// Submit updates to all available trees. It will also
126-
/// 1. discard duplicated updates,
127-
/// 2. remove invalid updates. (Invalid updates means deletion of an edge that
128-
/// still exists or insertion of an edge that does not exist.)
129-
/// The Eager Strategy flushes updates immediately while the Lazy Strategy
130-
/// queues the updates.
131-
///
132-
/// Note: The "existence" of an edge in a CFG refers to the CFG which DTU is
133-
/// in sync with + all updates before that single update.
134-
///
135-
/// CAUTION!
136-
/// 1. It is required for the state of the LLVM IR to be updated
137-
/// *before* submitting the updates because the internal update routine will
138-
/// analyze the current state of the CFG to determine whether an update
139-
/// is valid.
140-
/// 2. It is illegal to submit any update that has already been submitted,
141-
/// i.e., you are supposed not to insert an existent edge or delete a
142-
/// nonexistent edge.
143-
/// 3. It is only legal to submit updates to an edge in the order CFG changes
144-
/// are made. The order you submit updates on different edges is not
145-
/// restricted.
146-
void applyUpdatesPermissive(ArrayRef<DominatorTree::UpdateType> Updates);
147-
148-
/// Notify DTU that the entry block was replaced.
149-
/// Recalculate all available trees and flush all BasicBlocks
150-
/// awaiting deletion immediately.
151-
void recalculate(Function &F);
152-
15361
/// Delete DelBB. DelBB will be removed from its Parent and
15462
/// erased from available trees if it exists and finally get deleted.
15563
/// Under Eager UpdateStrategy, DelBB will be processed immediately.
@@ -172,33 +80,6 @@ class DomTreeUpdater {
17280

17381
///@}
17482

175-
///@{
176-
/// \name Flush APIs
177-
///
178-
/// CAUTION! By the moment these flush APIs are called, the current CFG needs
179-
/// to be the same as the CFG which DTU is in sync with + all updates
180-
/// submitted.
181-
182-
/// Flush DomTree updates and return DomTree.
183-
/// It flushes Deleted BBs if both trees are up-to-date.
184-
/// It must only be called when it has a DomTree.
185-
DominatorTree &getDomTree();
186-
187-
/// Flush PostDomTree updates and return PostDomTree.
188-
/// It flushes Deleted BBs if both trees are up-to-date.
189-
/// It must only be called when it has a PostDomTree.
190-
PostDominatorTree &getPostDomTree();
191-
192-
/// Apply all pending updates to available trees and flush all BasicBlocks
193-
/// awaiting deletion.
194-
195-
void flush();
196-
197-
///@}
198-
199-
/// Debug method to help view the internal state of this class.
200-
LLVM_DUMP_METHOD void dump() const;
201-
20283
private:
20384
class CallBackOnDeletion final : public CallbackVH {
20485
public:
@@ -216,16 +97,7 @@ class DomTreeUpdater {
21697
}
21798
};
21899

219-
SmallVector<DominatorTree::UpdateType, 16> PendUpdates;
220-
size_t PendDTUpdateIndex = 0;
221-
size_t PendPDTUpdateIndex = 0;
222-
DominatorTree *DT = nullptr;
223-
PostDominatorTree *PDT = nullptr;
224-
const UpdateStrategy Strategy;
225-
SmallPtrSet<BasicBlock *, 8> DeletedBBs;
226100
std::vector<CallBackOnDeletion> Callbacks;
227-
bool IsRecalculatingDomTree = false;
228-
bool IsRecalculatingPostDomTree = false;
229101

230102
/// First remove all the instructions of DelBB and then make sure DelBB has a
231103
/// valid terminator instruction which is necessary to have when DelBB still
@@ -237,32 +109,28 @@ class DomTreeUpdater {
237109
/// Returns true if at least one BasicBlock is deleted.
238110
bool forceFlushDeletedBB();
239111

240-
/// Helper function to apply all pending DomTree updates.
241-
void applyDomTreeUpdates();
242-
243-
/// Helper function to apply all pending PostDomTree updates.
244-
void applyPostDomTreeUpdates();
245-
246-
/// Helper function to flush deleted BasicBlocks if all available
247-
/// trees are up-to-date.
248-
void tryFlushDeletedBB();
249-
250-
/// Drop all updates applied by all available trees and delete BasicBlocks if
251-
/// all available trees are up-to-date.
252-
void dropOutOfDateUpdates();
253-
254-
/// Erase Basic Block node that has been unlinked from Function
255-
/// in the DomTree and PostDomTree.
256-
void eraseDelBBNode(BasicBlock *DelBB);
257-
258-
/// Returns true if the update appears in the LLVM IR.
259-
/// It is used to check whether an update is valid in
260-
/// insertEdge/deleteEdge or is unnecessary in the batch update.
261-
bool isUpdateValid(DominatorTree::UpdateType Update) const;
262-
263-
/// Returns true if the update is self dominance.
264-
bool isSelfDominance(DominatorTree::UpdateType Update) const;
112+
/// Debug method to help view the internal state of this class.
113+
LLVM_DUMP_METHOD void dump() const {
114+
Base::dump();
115+
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
116+
raw_ostream &OS = dbgs();
117+
OS << "Pending Callbacks:\n";
118+
int Index = 0;
119+
for (const auto &BB : Callbacks) {
120+
OS << " " << Index << " : ";
121+
++Index;
122+
if (BB->hasName())
123+
OS << BB->getName() << "(";
124+
else
125+
OS << "(no_name)(";
126+
OS << BB << ")\n";
127+
}
128+
#endif
129+
}
265130
};
131+
132+
extern template class GenericDomTreeUpdater<DomTreeUpdater, DominatorTree,
133+
PostDominatorTree>;
266134
} // namespace llvm
267135

268136
#endif // LLVM_ANALYSIS_DOMTREEUPDATER_H

0 commit comments

Comments
 (0)