@@ -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,12 @@ 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+ void splitCriticalEdge (BasicBlockT *FromBB, BasicBlockT *ToBB,
155+ BasicBlockT *NewBB);
150156
151157 // / Submit updates to all available trees. It will also
152158 // / 1. discard duplicated updates,
@@ -169,7 +175,7 @@ class GenericDomTreeUpdater {
169175 // / 3. It is only legal to submit updates to an edge in the order CFG changes
170176 // / are made. The order you submit updates on different edges is not
171177 // / restricted.
172- void applyUpdatesPermissive (ArrayRef<typename DomTreeT::UpdateType > Updates);
178+ void applyUpdatesPermissive (ArrayRef<UpdateT > Updates);
173179
174180 // /@}
175181
@@ -205,7 +211,25 @@ class GenericDomTreeUpdater {
205211 LLVM_DUMP_METHOD void dump () const ;
206212
207213protected:
208- SmallVector<typename DomTreeT::UpdateType, 16 > PendUpdates;
214+ // / Helper structure used to hold all the basic blocks
215+ // / involved in the split of a critical edge.
216+ struct CriticalEdge {
217+ BasicBlockT *FromBB;
218+ BasicBlockT *ToBB;
219+ BasicBlockT *NewBB;
220+ };
221+
222+ struct DomTreeUpdate {
223+ bool IsCriticalEdgeSplit = false ;
224+ union {
225+ UpdateT Update;
226+ CriticalEdge EdgeSplit;
227+ };
228+ DomTreeUpdate (UpdateT Update) : Update(Update) {}
229+ DomTreeUpdate (CriticalEdge E) : IsCriticalEdgeSplit(true ), EdgeSplit(E) {}
230+ };
231+
232+ SmallVector<DomTreeUpdate, 16 > PendUpdates;
209233 size_t PendDTUpdateIndex = 0 ;
210234 size_t PendPDTUpdateIndex = 0 ;
211235 DomTreeT *DT = nullptr ;
@@ -216,21 +240,21 @@ class GenericDomTreeUpdater {
216240 bool IsRecalculatingPostDomTree = false ;
217241
218242 // / Returns true if the update is self dominance.
219- bool isSelfDominance (typename DomTreeT::UpdateType Update) const {
243+ bool isSelfDominance (UpdateT Update) const {
220244 // Won't affect DomTree and PostDomTree.
221245 return Update.getFrom () == Update.getTo ();
222246 }
223247
224248 // / Helper function to apply all pending DomTree updates.
225- void applyDomTreeUpdates ();
249+ void applyDomTreeUpdates () { applyUpdatesImpl< true >(); }
226250
227251 // / Helper function to apply all pending PostDomTree updates.
228- void applyPostDomTreeUpdates ();
252+ void applyPostDomTreeUpdates () { applyUpdatesImpl< false >(); }
229253
230254 // / Returns true if the update appears in the LLVM IR.
231255 // / It is used to check whether an update is valid in
232256 // / insertEdge/deleteEdge or is unnecessary in the batch update.
233- bool isUpdateValid (typename DomTreeT::UpdateType Update) const ;
257+ bool isUpdateValid (UpdateT Update) const ;
234258
235259 // / Erase Basic Block node before it is unlinked from Function
236260 // / in the DomTree and PostDomTree.
@@ -243,6 +267,11 @@ class GenericDomTreeUpdater {
243267 // / Drop all updates applied by all available trees and delete BasicBlocks if
244268 // / all available trees are up-to-date.
245269 void dropOutOfDateUpdates ();
270+
271+ private:
272+ void splitDTCriticalEdges (ArrayRef<CriticalEdge> Updates);
273+ void splitPDTCriticalEdges (ArrayRef<CriticalEdge> Updates);
274+ template <bool IsForward> void applyUpdatesImpl ();
246275};
247276
248277} // namespace llvm
0 commit comments