From f3d4166132aa1c9de7c08784422236bf6d1e55f5 Mon Sep 17 00:00:00 2001 From: Chijun Sima Date: Wed, 20 Feb 2019 05:49:01 +0000 Subject: [PATCH] [DTU] Refine the document of mutation APIs [NFC] (PR40528) Summary: It was pointed out in [[ https://bugs.llvm.org/show_bug.cgi?id=40528 | Bug 40528 ]] that it is not clear whether insert/deleteEdge can be used to perform multiple updates and [[ https://reviews.llvm.org/D57316#1388344 | a comment in D57316 ]] reveals that the difference between several ways to update the DominatorTree is confusing. This patch tries to address issues above. Reviewers: mkazantsev, kuhar, asbirlea, chandlerc, brzycki Reviewed By: mkazantsev, kuhar, brzycki Subscribers: llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D57881 llvm-svn: 354437 --- llvm/include/llvm/Analysis/DomTreeUpdater.h | 138 ++++++++++++-------- 1 file changed, 86 insertions(+), 52 deletions(-) diff --git a/llvm/include/llvm/Analysis/DomTreeUpdater.h b/llvm/include/llvm/Analysis/DomTreeUpdater.h index fcfd3c12f52a..7c8ebc5433ac 100644 --- a/llvm/include/llvm/Analysis/DomTreeUpdater.h +++ b/llvm/include/llvm/Analysis/DomTreeUpdater.h @@ -82,60 +82,89 @@ public: /// Returns false under Eager UpdateStrategy or PDT is nullptr. bool hasPendingPostDomTreeUpdates() const; - /// Apply updates on all available trees. Under Eager UpdateStrategy with + ///@{ + /// \name Mutation APIs + /// + /// These methods provide APIs for submitting updates to the DominatorTree and + /// the PostDominatorTree. + /// + /// Note: There are two strategies to update the DominatorTree and the + /// PostDominatorTree: + /// 1. Eager UpdateStrategy: Updates are submitted and then flushed + /// immediately. + /// 2. Lazy UpdateStrategy: Updates are submitted but only flushed when you + /// explicitly call Flush APIs. It is recommended to use this update strategy + /// when you submit a bunch of updates multiple times which can then + /// add up to a large number of updates between two queries on the + /// DominatorTree. The incremental updater can reschedule the updates or + /// decide to recalculate the dominator tree in order to speedup the updating + /// process depending on the number of updates. + /// + /// Although GenericDomTree provides several update primitives, + /// it is not encouraged to use these APIs directly. + + /// Submit updates to all available trees. Under Eager UpdateStrategy with /// ForceRemoveDuplicates enabled or under Lazy UpdateStrategy, it will - /// discard duplicated updates and self-dominance updates. If both DT and PDT - /// are nullptrs, this function discards all updates. The Eager Strategy - /// applies the updates immediately while the Lazy Strategy queues the - /// updates. It is required for the state of the LLVM IR to be updated - /// *before* applying the Updates because the internal update routine will - /// analyze the current state of the relationship between a pair of (From, To) - /// BasicBlocks to determine whether a single update needs to be discarded. + /// 1. discard duplicated updates, + /// 2. remove invalid updates. (Invalid updates means deletion of an edge that + /// still exists or insertion of an edge that does not exist.) + /// The Eager Strategy flushes updates immediately while the Lazy Strategy + /// queues the updates. + /// + /// Note: The "existence" of an edge in a CFG refers to the CFG which DTU is + /// in sync with + all updates before that single update. + /// + /// CAUTION! + /// 1. It is required for the state of the LLVM IR to be updated + /// *before* submitting the updates because the internal update routine will + /// analyze the current state of the CFG to determine whether an update + /// is valid. + /// 2. It is illegal to submit any update that has already been submitted, + /// i.e., you are supposed not to insert an existent edge or delete a + /// nonexistent edge. void applyUpdates(ArrayRef Updates, bool ForceRemoveDuplicates = false); - /// Notify all available trees on an edge insertion. If both DT and PDT are - /// nullptrs, this function discards the update. Under either Strategy, - /// self-dominance update will be removed. The Eager Strategy applies - /// the update immediately while the Lazy Strategy queues the update. - /// It is recommended to only use this method when you have exactly one - /// insertion (and no deletions). It is recommended to use applyUpdates() in - /// all other cases. This function has to be called *after* making the update - /// on the actual CFG. An internal functions checks if the edge exists in the - /// CFG in DEBUG mode. + /// Notify DTU that the entry block was replaced. + /// Recalculate all available trees and flush all BasicBlocks + /// awaiting deletion immediately. + void recalculate(Function &F); + + /// \deprecated { Submit an edge insertion to all available trees. The Eager + /// Strategy flushes this update immediately while the Lazy Strategy queues + /// the update. An internal function checks if the edge exists in the CFG in + /// DEBUG mode. CAUTION! This function has to be called *after* making the + /// update on the actual CFG. It is illegal to submit any update that has + /// already been applied. } void insertEdge(BasicBlock *From, BasicBlock *To); - /// Notify all available trees on an edge insertion. - /// Under either Strategy, the following updates will be discard silently - /// 1. Invalid - Inserting an edge that does not exist in the CFG. - /// 2. Self-dominance update. - /// 3. Both DT and PDT are nullptrs. - /// The Eager Strategy applies the update immediately while the Lazy Strategy - /// queues the update. It is recommended to only use this method when you have - /// exactly one insertion (and no deletions) and want to discard an invalid - /// update. + /// \deprecated {Submit an edge insertion to all available trees. + /// Under either Strategy, an invalid update will be discard silently. + /// Invalid update means inserting an edge that does not exist in the CFG. + /// The Eager Strategy flushes this update immediately while the Lazy Strategy + /// queues the update. It is only recommended to use this method when you + /// want to discard an invalid update. + /// CAUTION! It is illegal to submit any update that has already been + /// submitted. } void insertEdgeRelaxed(BasicBlock *From, BasicBlock *To); - /// Notify all available trees on an edge deletion. If both DT and PDT are - /// nullptrs, this function discards the update. Under either Strategy, - /// self-dominance update will be removed. The Eager Strategy applies - /// the update immediately while the Lazy Strategy queues the update. - /// It is recommended to only use this method when you have exactly one - /// deletion (and no insertions). It is recommended to use applyUpdates() in - /// all other cases. This function has to be called *after* making the update - /// on the actual CFG. An internal functions checks if the edge doesn't exist - /// in the CFG in DEBUG mode. + /// \deprecated { Submit an edge deletion to all available trees. The Eager + /// Strategy flushes this update immediately while the Lazy Strategy queues + /// the update. An internal function checks if the edge doesn't exist in the + /// CFG in DEBUG mode. + /// CAUTION! This function has to be called *after* making the update on the + /// actual CFG. It is illegal to submit any update that has already been + /// submitted. } void deleteEdge(BasicBlock *From, BasicBlock *To); - /// Notify all available trees on an edge deletion. - /// Under either Strategy, the following updates will be discard silently - /// 1. Invalid - Deleting an edge that still exists in the CFG. - /// 2. Self-dominance update. - /// 3. Both DT and PDT are nullptrs. - /// The Eager Strategy applies the update immediately while the Lazy Strategy - /// queues the update. It is recommended to only use this method when you have - /// exactly one deletion (and no insertions) and want to discard an invalid - /// update. + /// \deprecated { Submit an edge deletion to all available trees. + /// Under either Strategy, an invalid update will be discard silently. + /// Invalid update means deleting an edge that exists in the CFG. + /// The Eager Strategy flushes this update immediately while the Lazy Strategy + /// queues the update. It is only recommended to use this method when you + /// want to discard an invalid update. + /// CAUTION! It is illegal to submit any update that has already been + /// submitted. } void deleteEdgeRelaxed(BasicBlock *From, BasicBlock *To); /// Delete DelBB. DelBB will be removed from its Parent and @@ -158,27 +187,32 @@ public: void callbackDeleteBB(BasicBlock *DelBB, std::function Callback); - /// Recalculate all available trees and flush all BasicBlocks - /// awaiting deletion immediately. - void recalculate(Function &F); + ///@} + + ///@{ + /// \name Flush APIs + /// + /// CAUTION! By the moment these flush APIs are called, the current CFG needs + /// to be the same as the CFG which DTU is in sync with + all updates + /// submitted. /// Flush DomTree updates and return DomTree. - /// It also flush out of date updates applied by all available trees - /// and flush Deleted BBs if both trees are up-to-date. + /// It flushes Deleted BBs if both trees are up-to-date. /// It must only be called when it has a DomTree. DominatorTree &getDomTree(); /// Flush PostDomTree updates and return PostDomTree. - /// It also flush out of date updates applied by all available trees - /// and flush Deleted BBs if both trees are up-to-date. + /// It flushes Deleted BBs if both trees are up-to-date. /// It must only be called when it has a PostDomTree. PostDominatorTree &getPostDomTree(); /// Apply all pending updates to available trees and flush all BasicBlocks /// awaiting deletion. - /// Does nothing under Eager UpdateStrategy. + void flush(); + ///@} + /// Debug method to help view the internal state of this class. LLVM_DUMP_METHOD void dump() const;