@@ -30,6 +30,7 @@ class GenericDomTreeUpdater {
3030public:
3131 enum class UpdateStrategy : unsigned char { Eager = 0 , Lazy = 1 };
3232 using BasicBlockT = typename DomTreeT::NodeType;
33+ using UpdateT = typename DomTreeT::UpdateType;
3334
3435 explicit GenericDomTreeUpdater (UpdateStrategy Strategy_)
3536 : Strategy(Strategy_) {}
@@ -146,7 +147,19 @@ class GenericDomTreeUpdater {
146147 // / 2. It is illegal to submit any update that has already been submitted,
147148 // / i.e., you are supposed not to insert an existent edge or delete a
148149 // / nonexistent edge.
149- void applyUpdates (ArrayRef<typename DomTreeT::UpdateType> Updates);
150+ void applyUpdates (ArrayRef<UpdateT> Updates);
151+
152+ // / Apply updates that the critical edge (FromBB, ToBB) has been
153+ // / split with NewBB.
154+ // /
155+ // / \note Do not use this method with regular edges.
156+ // /
157+ // / \note This kind updates are incompatible with generic updates,
158+ // / call this method will submit all generic updates in lazy mode.
159+ // / It is not recommended to interleave applyUpdates and
160+ // / applyUpdatesForCriticalEdgeSplitting.
161+ void splitCriticalEdge (BasicBlockT *FromBB, BasicBlockT *ToBB,
162+ BasicBlockT *NewBB);
150163
151164 // / Submit updates to all available trees. It will also
152165 // / 1. discard duplicated updates,
@@ -169,7 +182,7 @@ class GenericDomTreeUpdater {
169182 // / 3. It is only legal to submit updates to an edge in the order CFG changes
170183 // / are made. The order you submit updates on different edges is not
171184 // / restricted.
172- void applyUpdatesPermissive (ArrayRef<typename DomTreeT::UpdateType > Updates);
185+ void applyUpdatesPermissive (ArrayRef<UpdateT > Updates);
173186
174187 // /@}
175188
@@ -205,7 +218,25 @@ class GenericDomTreeUpdater {
205218 LLVM_DUMP_METHOD void dump () const ;
206219
207220protected:
208- SmallVector<typename DomTreeT::UpdateType, 16 > PendUpdates;
221+ // / Helper structure used to hold all the basic blocks
222+ // / involved in the split of a critical edge.
223+ struct CriticalEdge {
224+ BasicBlockT *FromBB;
225+ BasicBlockT *ToBB;
226+ BasicBlockT *NewBB;
227+ };
228+
229+ struct DomTreeUpdate {
230+ bool IsCriticalEdgeSplit = false ;
231+ union {
232+ UpdateT Update;
233+ CriticalEdge EdgeSplit;
234+ };
235+ DomTreeUpdate (UpdateT Update) : Update(Update) {}
236+ DomTreeUpdate (CriticalEdge E) : IsCriticalEdgeSplit(true ), EdgeSplit(E) {}
237+ };
238+
239+ SmallVector<DomTreeUpdate, 16 > PendUpdates;
209240 size_t PendDTUpdateIndex = 0 ;
210241 size_t PendPDTUpdateIndex = 0 ;
211242 DomTreeT *DT = nullptr ;
@@ -216,7 +247,7 @@ class GenericDomTreeUpdater {
216247 bool IsRecalculatingPostDomTree = false ;
217248
218249 // / Returns true if the update is self dominance.
219- bool isSelfDominance (typename DomTreeT::UpdateType Update) const {
250+ bool isSelfDominance (UpdateT Update) const {
220251 // Won't affect DomTree and PostDomTree.
221252 return Update.getFrom () == Update.getTo ();
222253 }
@@ -230,7 +261,7 @@ class GenericDomTreeUpdater {
230261 // / Returns true if the update appears in the LLVM IR.
231262 // / It is used to check whether an update is valid in
232263 // / insertEdge/deleteEdge or is unnecessary in the batch update.
233- bool isUpdateValid (typename DomTreeT::UpdateType Update) const ;
264+ bool isUpdateValid (UpdateT Update) const ;
234265
235266 // / Erase Basic Block node before it is unlinked from Function
236267 // / in the DomTree and PostDomTree.
@@ -243,6 +274,10 @@ class GenericDomTreeUpdater {
243274 // / Drop all updates applied by all available trees and delete BasicBlocks if
244275 // / all available trees are up-to-date.
245276 void dropOutOfDateUpdates ();
277+
278+ private:
279+ void splitDTCriticalEdges (ArrayRef<CriticalEdge> Updates);
280+ void splitPDTCriticalEdges (ArrayRef<CriticalEdge> Updates);
246281};
247282
248283} // namespace llvm
0 commit comments