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"
2325#include < vector>
2426
2527namespace llvm {
26- class PostDominatorTree ;
2728
28- class DomTreeUpdater {
29- public:
30- enum class UpdateStrategy : unsigned char { Eager = 0 , Lazy = 1 };
29+ class DomTreeUpdater
30+ : public GenericDomTreeUpdater<DomTreeUpdater, DominatorTree,
31+ PostDominatorTree> {
32+ friend GenericDomTreeUpdater<DomTreeUpdater, DominatorTree,
33+ PostDominatorTree>;
3134
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_) {}
35+ public:
36+ using Base =
37+ GenericDomTreeUpdater<DomTreeUpdater, DominatorTree, PostDominatorTree>;
38+ using Base::Base;
4739
4840 ~DomTreeUpdater () { flush (); }
4941
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 ;
78-
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 ;
86-
8742 // /@{
8843 // / \name Mutation APIs
8944 // /
@@ -105,51 +60,6 @@ class DomTreeUpdater {
10560 // / Although GenericDomTree provides several update primitives,
10661 // / it is not encouraged to use these APIs directly.
10762
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-
15363 // / Delete DelBB. DelBB will be removed from its Parent and
15464 // / erased from available trees if it exists and finally get deleted.
15565 // / Under Eager UpdateStrategy, DelBB will be processed immediately.
@@ -172,33 +82,6 @@ class DomTreeUpdater {
17282
17383 // /@}
17484
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-
20285private:
20386 class CallBackOnDeletion final : public CallbackVH {
20487 public:
@@ -216,16 +99,7 @@ class DomTreeUpdater {
21699 }
217100 };
218101
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;
226102 std::vector<CallBackOnDeletion> Callbacks;
227- bool IsRecalculatingDomTree = false ;
228- bool IsRecalculatingPostDomTree = false ;
229103
230104 // / First remove all the instructions of DelBB and then make sure DelBB has a
231105 // / valid terminator instruction which is necessary to have when DelBB still
@@ -237,32 +111,28 @@ class DomTreeUpdater {
237111 // / Returns true if at least one BasicBlock is deleted.
238112 bool forceFlushDeletedBB ();
239113
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 ;
114+ // / Debug method to help view the internal state of this class.
115+ LLVM_DUMP_METHOD void dump () const {
116+ Base::dump ();
117+ #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
118+ raw_ostream &OS = dbgs ();
119+ OS << " Pending Callbacks:\n " ;
120+ int Index = 0 ;
121+ for (const auto &BB : Callbacks) {
122+ OS << " " << Index << " : " ;
123+ ++Index;
124+ if (BB->hasName ())
125+ OS << BB->getName () << " (" ;
126+ else
127+ OS << " (no_name)(" ;
128+ OS << BB << " )\n " ;
129+ }
130+ #endif
131+ }
265132};
133+
134+ extern template class GenericDomTreeUpdater <DomTreeUpdater, DominatorTree,
135+ PostDominatorTree>;
266136} // namespace llvm
267137
268138#endif // LLVM_ANALYSIS_DOMTREEUPDATER_H
0 commit comments