@@ -290,6 +290,93 @@ class DominatorTreeWrapperPass : public FunctionPass {
290
290
void print (raw_ostream &OS, const Module *M = nullptr ) const override ;
291
291
};
292
292
293
+ // ===-------------------------------------
294
+ // / \brief Class to defer updates to a DominatorTree.
295
+ // /
296
+ // / Definition: Applying updates to every edge insertion and deletion is
297
+ // / expensive and not necessary. When one needs the DominatorTree for analysis
298
+ // / they can request a flush() to perform a larger batch update. This has the
299
+ // / advantage of the DominatorTree inspecting the set of updates to find
300
+ // / duplicates or unnecessary subtree updates.
301
+ // /
302
+ // / The scope of DeferredDominance operates at a Function level.
303
+ // /
304
+ // / It is not necessary for the user to scrub the updates for duplicates or
305
+ // / updates that point to the same block (Delete, BB_A, BB_A). Performance
306
+ // / can be gained if the caller attempts to batch updates before submitting
307
+ // / to applyUpdates(ArrayRef) in cases where duplicate edge requests will
308
+ // / occur.
309
+ // /
310
+ // / It is required for the state of the LLVM IR to be applied *before*
311
+ // / submitting updates. The update routines must analyze the current state
312
+ // / between a pair of (From, To) basic blocks to determine if the update
313
+ // / needs to be queued.
314
+ // / Example (good):
315
+ // / TerminatorInstructionBB->removeFromParent();
316
+ // / DDT->deleteEdge(BB, Successor);
317
+ // / Example (bad):
318
+ // / DDT->deleteEdge(BB, Successor);
319
+ // / TerminatorInstructionBB->removeFromParent();
320
+ class DeferredDominance {
321
+ public:
322
+ DeferredDominance (DominatorTree &DT_) : DT(DT_) {}
323
+
324
+ // / \brief Queues multiple updates and discards duplicates.
325
+ void applyUpdates (ArrayRef<DominatorTree::UpdateType> Updates);
326
+
327
+ // / \brief Helper method for a single edge insertion. It's almost always
328
+ // / better to batch updates and call applyUpdates to quickly remove duplicate
329
+ // / edges. This is best used when there is only a single insertion needed to
330
+ // / update Dominators.
331
+ void insertEdge (BasicBlock *From, BasicBlock *To);
332
+
333
+ // / \brief Helper method for a single edge deletion. It's almost always better
334
+ // / to batch updates and call applyUpdates to quickly remove duplicate edges.
335
+ // / This is best used when there is only a single deletion needed to update
336
+ // / Dominators.
337
+ void deleteEdge (BasicBlock *From, BasicBlock *To);
338
+
339
+ // / \brief Delays the deletion of a basic block until a flush() event.
340
+ void deleteBB (BasicBlock *DelBB);
341
+
342
+ // / \brief Returns true if DelBB is awaiting deletion at a flush() event.
343
+ bool pendingDeletedBB (BasicBlock *DelBB);
344
+
345
+ // / \brief Returns true if pending DT updates are queued for a flush() event.
346
+ bool pending ();
347
+
348
+ // / \brief Flushes all pending updates and block deletions. Returns a
349
+ // / correct DominatorTree reference to be used by the caller for analysis.
350
+ DominatorTree &flush ();
351
+
352
+ // / \brief Drops all internal state and forces a (slow) recalculation of the
353
+ // / DominatorTree based on the current state of the LLVM IR in F. This should
354
+ // / only be used in corner cases such as the Entry block of F being deleted.
355
+ void recalculate (Function &F);
356
+
357
+ // / \brief Debug method to help view the state of pending updates.
358
+ LLVM_DUMP_METHOD void dump () const ;
359
+
360
+ private:
361
+ DominatorTree &DT;
362
+ SmallVector<DominatorTree::UpdateType, 16 > PendUpdates;
363
+ SmallPtrSet<BasicBlock *, 8 > DeletedBBs;
364
+
365
+ // / Apply an update (Kind, From, To) to the internal queued updates. The
366
+ // / update is only added when determined to be necessary. Checks for
367
+ // / self-domination, unnecessary updates, duplicate requests, and balanced
368
+ // / pairs of requests are all performed. Returns true if the update is
369
+ // / queued and false if it is discarded.
370
+ bool applyUpdate (DominatorTree::UpdateKind Kind, BasicBlock *From,
371
+ BasicBlock *To);
372
+
373
+ // / Performs all pending basic block deletions. We have to defer the deletion
374
+ // / of these blocks until after the DominatorTree updates are applied. The
375
+ // / internal workings of the DominatorTree code expect every update's From
376
+ // / and To blocks to exist and to be a member of the same Function.
377
+ bool flushDelBB ();
378
+ };
379
+
293
380
} // end namespace llvm
294
381
295
382
#endif // LLVM_IR_DOMINATORS_H
0 commit comments