Index: include/llvm/IR/DomTreeUpdater.h =================================================================== --- include/llvm/IR/DomTreeUpdater.h +++ include/llvm/IR/DomTreeUpdater.h @@ -73,26 +73,27 @@ bool hasPendingUpdates() const; /// Returns true if there are DominatorTree updates queued. - /// Returns false under Eager UpdateStrategy. + /// Returns false under Eager UpdateStrategy or DT is nullptr. bool hasPendingDomTreeUpdates() const; /// Returns true if there are PostDominatorTree updates queued. - /// Returns false under Eager UpdateStrategy. + /// Returns false under Eager UpdateStrategy or PDT is nullptr. bool hasPendingPostDomTreeUpdates() const; /// Apply updates on all available trees. Under Eager UpdateStrategy with /// ForceRemoveDuplicates enabled or under Lazy UpdateStrategy, it will - /// discard duplicated updates and self-dominance 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. + /// 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. void applyUpdates(ArrayRef Updates, bool ForceRemoveDuplicates = false); - /// Notify all available trees on an edge insertion. Under either Strategy, + /// 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 @@ -103,17 +104,18 @@ void insertEdge(BasicBlock *From, BasicBlock *To); /// Notify all available trees on an edge insertion. - /// Under either Strategy, these updates will be discard silently in the - /// following sequence + /// 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. Returns true if the update is valid. - bool insertEdgeRelaxed(BasicBlock *From, BasicBlock *To); + /// update. + void insertEdgeRelaxed(BasicBlock *From, BasicBlock *To); - /// Notify all available trees on an edge deletion. Under either Strategy, + /// 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 @@ -124,21 +126,22 @@ void deleteEdge(BasicBlock *From, BasicBlock *To); /// Notify all available trees on an edge deletion. - /// Under either Strategy, these updates will be discard silently in the - /// following sequence: + /// 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. Returns true if the update is valid. - bool deleteEdgeRelaxed(BasicBlock *From, BasicBlock *To); + /// update. + void deleteEdgeRelaxed(BasicBlock *From, BasicBlock *To); /// Delete DelBB. DelBB will be removed from its Parent and /// erased from available trees if it exists and finally get deleted. /// Under Eager UpdateStrategy, DelBB will be processed immediately. /// Under Lazy UpdateStrategy, DelBB will be queued until a flush event and - /// all available trees are up-to-date. + /// all available trees are up-to-date. When both DT and PDT are nullptrs, + /// DelBB will be queued until flush() is called. void deleteBB(BasicBlock *DelBB); /// Delete DelBB. DelBB will be removed from its Parent and Index: lib/IR/DomTreeUpdater.cpp =================================================================== --- lib/IR/DomTreeUpdater.cpp +++ lib/IR/DomTreeUpdater.cpp @@ -56,6 +56,8 @@ bool DomTreeUpdater::applyLazyUpdate(DominatorTree::UpdateKind Kind, BasicBlock *From, BasicBlock *To) { + assert(DT || + PDT && "Call applyLazyUpdate() when both DT and PDT are nullptrs."); assert(Strategy == DomTreeUpdater::UpdateStrategy::Lazy && "Call applyLazyUpdate() with Eager strategy error"); // Analyze pending updates to determine if the update is unnecessary. @@ -260,6 +262,9 @@ void DomTreeUpdater::applyUpdates(ArrayRef Updates, bool ForceRemoveDuplicates) { + if (!DT && !PDT) + return; + if (Strategy == UpdateStrategy::Lazy || ForceRemoveDuplicates) { SmallVector Seen; for (const auto U : Updates) @@ -310,6 +315,9 @@ "Inserted edge does not appear in the CFG"); #endif + if (!DT && !PDT) + return; + // Won't affect DomTree and PostDomTree; discard update. if (From == To) return; @@ -325,23 +333,25 @@ applyLazyUpdate(DominatorTree::Insert, From, To); } -bool DomTreeUpdater::insertEdgeRelaxed(BasicBlock *From, BasicBlock *To) { - if (!isUpdateValid({DominatorTree::Insert, From, To})) - return false; - +void DomTreeUpdater::insertEdgeRelaxed(BasicBlock *From, BasicBlock *To) { if (From == To) - return true; + return; + + if (!DT && !PDT) + return; + + if (!isUpdateValid({DominatorTree::Insert, From, To})) + return; if (Strategy == UpdateStrategy::Eager) { if (DT) DT->insertEdge(From, To); if (PDT) PDT->insertEdge(From, To); - return true; + return; } applyLazyUpdate(DominatorTree::Insert, From, To); - return true; } void DomTreeUpdater::deleteEdge(BasicBlock *From, BasicBlock *To) { @@ -351,6 +361,9 @@ "Deleted edge still exists in the CFG!"); #endif + if (!DT && !PDT) + return; + // Won't affect DomTree and PostDomTree; discard update. if (From == To) return; @@ -366,23 +379,25 @@ applyLazyUpdate(DominatorTree::Delete, From, To); } -bool DomTreeUpdater::deleteEdgeRelaxed(BasicBlock *From, BasicBlock *To) { - if (!isUpdateValid({DominatorTree::Delete, From, To})) - return false; - +void DomTreeUpdater::deleteEdgeRelaxed(BasicBlock *From, BasicBlock *To) { if (From == To) - return true; + return; + + if (!DT && !PDT) + return; + + if (!isUpdateValid({DominatorTree::Delete, From, To})) + return; if (Strategy == UpdateStrategy::Eager) { if (DT) DT->deleteEdge(From, To); if (PDT) PDT->deleteEdge(From, To); - return true; + return; } applyLazyUpdate(DominatorTree::Delete, From, To); - return true; } void DomTreeUpdater::dropOutOfDateUpdates() { Index: unittests/IR/DomTreeUpdaterTest.cpp =================================================================== --- unittests/IR/DomTreeUpdaterTest.cpp +++ unittests/IR/DomTreeUpdaterTest.cpp @@ -71,8 +71,8 @@ SwitchInst *SI = dyn_cast(BB0->getTerminator()); ASSERT_NE(SI, nullptr) << "Couldn't get SwitchInst."; - ASSERT_FALSE(DTU.insertEdgeRelaxed(BB0, BB0)); - ASSERT_TRUE(DTU.deleteEdgeRelaxed(BB0, BB0)); + DTU.insertEdgeRelaxed(BB0, BB0); + DTU.deleteEdgeRelaxed(BB0, BB0); // Delete edge bb0 -> bb3 and push the update twice to verify duplicate // entries are discarded. @@ -105,9 +105,9 @@ ASSERT_FALSE(DTU.hasPendingUpdates()); // Invalid Insert: no edge bb1 -> bb2 after change to bb0. - ASSERT_FALSE(DTU.insertEdgeRelaxed(BB1, BB2)); + DTU.insertEdgeRelaxed(BB1, BB2); // Invalid Delete: edge exists bb0 -> bb1 after change to bb0. - ASSERT_FALSE(DTU.deleteEdgeRelaxed(BB0, BB1)); + DTU.deleteEdgeRelaxed(BB0, BB1); // DTU working with Eager UpdateStrategy does not need to flush. ASSERT_TRUE(DT.verify()); @@ -181,7 +181,7 @@ EXPECT_EQ(F->begin()->getName(), NewEntry->getName()); EXPECT_TRUE(&F->getEntryBlock() == NewEntry); - ASSERT_TRUE(DTU.insertEdgeRelaxed(NewEntry, BB0)); + DTU.insertEdgeRelaxed(NewEntry, BB0); // Changing the Entry BB requires a full recalculation of DomTree. DTU.recalculate(*F);