15
15
#define LLVM_ANALYSIS_DOMTREEUPDATER_H
16
16
17
17
#include " llvm/ADT/SmallPtrSet.h"
18
+ #include " llvm/Analysis/GenericDomTreeUpdater.h"
19
+ #include " llvm/Analysis/PostDominators.h"
18
20
#include " llvm/IR/Dominators.h"
19
21
#include " llvm/IR/ValueHandle.h"
20
22
#include " llvm/Support/Compiler.h"
23
25
#include < vector>
24
26
25
27
namespace llvm {
26
- class PostDominatorTree ;
27
28
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>;
78
34
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;
86
39
87
40
// /@{
88
41
// / \name Mutation APIs
@@ -105,51 +58,6 @@ class DomTreeUpdater {
105
58
// / Although GenericDomTree provides several update primitives,
106
59
// / it is not encouraged to use these APIs directly.
107
60
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
-
153
61
// / Delete DelBB. DelBB will be removed from its Parent and
154
62
// / erased from available trees if it exists and finally get deleted.
155
63
// / Under Eager UpdateStrategy, DelBB will be processed immediately.
@@ -172,33 +80,6 @@ class DomTreeUpdater {
172
80
173
81
// /@}
174
82
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
-
202
83
private:
203
84
class CallBackOnDeletion final : public CallbackVH {
204
85
public:
@@ -216,16 +97,7 @@ class DomTreeUpdater {
216
97
}
217
98
};
218
99
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;
226
100
std::vector<CallBackOnDeletion> Callbacks;
227
- bool IsRecalculatingDomTree = false ;
228
- bool IsRecalculatingPostDomTree = false ;
229
101
230
102
// / First remove all the instructions of DelBB and then make sure DelBB has a
231
103
// / valid terminator instruction which is necessary to have when DelBB still
@@ -237,32 +109,28 @@ class DomTreeUpdater {
237
109
// / Returns true if at least one BasicBlock is deleted.
238
110
bool forceFlushDeletedBB ();
239
111
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
+ }
265
130
};
131
+
132
+ extern template class GenericDomTreeUpdater <DomTreeUpdater, DominatorTree,
133
+ PostDominatorTree>;
266
134
} // namespace llvm
267
135
268
136
#endif // LLVM_ANALYSIS_DOMTREEUPDATER_H
0 commit comments