diff --git a/llvm/include/llvm/Analysis/DomTreeUpdater.h b/llvm/include/llvm/Analysis/DomTreeUpdater.h index e07d2bf2b0df1..99ebe8d7923bf 100644 --- a/llvm/include/llvm/Analysis/DomTreeUpdater.h +++ b/llvm/include/llvm/Analysis/DomTreeUpdater.h @@ -83,6 +83,9 @@ class DomTreeUpdater ///@} + /// Debug method to help view the internal state of this class. + LLVM_DUMP_METHOD void dump() const; + private: class CallBackOnDeletion final : public CallbackVH { public: @@ -111,9 +114,6 @@ class DomTreeUpdater /// Returns true if at least one BasicBlock is deleted. bool forceFlushDeletedBB(); - - /// Debug method to help view the internal state of this class. - LLVM_DUMP_METHOD void dump() const; }; extern template class GenericDomTreeUpdater Updates); + /// Apply updates that the critical edge (FromBB, ToBB) has been + /// split with NewBB. + /// + /// \note Do not use this method with regular edges. + /// + /// \note This kind updates are incompatible with generic updates, + /// call this method will submit all generic updates in lazy mode. + /// It is not recommended to interleave applyUpdates and + /// applyUpdatesForCriticalEdgeSplitting. + void applyUpdatesForCriticalEdgeSplitting(BasicBlockT *FromBB, + BasicBlockT *ToBB, + BasicBlockT *NewBB); + /// Submit updates to all available trees. It will also /// 1. discard duplicated updates, /// 2. remove invalid updates. (Invalid updates means deletion of an edge that @@ -197,6 +220,7 @@ class GenericDomTreeUpdater { applyDomTreeUpdates(); applyPostDomTreeUpdates(); dropOutOfDateUpdates(); + applySplitCriticalEdges(); } ///@} @@ -243,6 +267,35 @@ class GenericDomTreeUpdater { /// Drop all updates applied by all available trees and delete BasicBlocks if /// all available trees are up-to-date. void dropOutOfDateUpdates(); + +private: + /// Helper structure used to hold all the basic blocks + /// involved in the split of a critical edge. + struct CriticalEdge { + BasicBlockT *FromBB; + BasicBlockT *ToBB; + BasicBlockT *NewBB; + }; + + /// Pile up all the critical edges to be split. + /// The splitting of a critical edge is local and thus, it is possible + /// to apply several of those changes at the same time. + SmallVector CriticalEdgesToSplit; + + /// Remember all the basic blocks that are inserted during + /// edge splitting. + /// Invariant: NewBBs == all the basic blocks contained in the NewBB + /// field of all the elements of CriticalEdgesToSplit. + /// I.e., forall elt in CriticalEdgesToSplit, it exists BB in NewBBs + /// such as BB == elt.NewBB. + SmallSet NewBBs; + + /// Apply all the recorded critical edges to the DT. + /// This updates the underlying DT information in a way that uses + /// the fast query path of DT as much as possible. + /// + /// \post CriticalEdgesToSplit.empty(). + void applySplitCriticalEdges(); }; } // namespace llvm diff --git a/llvm/include/llvm/Analysis/GenericDomTreeUpdaterImpl.h b/llvm/include/llvm/Analysis/GenericDomTreeUpdaterImpl.h index 35c54a6062bfd..eafc7244160aa 100644 --- a/llvm/include/llvm/Analysis/GenericDomTreeUpdaterImpl.h +++ b/llvm/include/llvm/Analysis/GenericDomTreeUpdaterImpl.h @@ -16,6 +16,7 @@ #ifndef LLVM_ANALYSIS_GENERICDOMTREEUPDATERIMPL_H #define LLVM_ANALYSIS_GENERICDOMTREEUPDATERIMPL_H +#include "llvm/ADT/SmallBitVector.h" #include "llvm/Analysis/GenericDomTreeUpdater.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" @@ -61,6 +62,9 @@ void GenericDomTreeUpdater::applyUpdates( return; if (Strategy == UpdateStrategy::Lazy) { + if (!CriticalEdgesToSplit.empty()) + applySplitCriticalEdges(); + PendUpdates.reserve(PendUpdates.size() + Updates.size()); for (const auto &U : Updates) if (!isSelfDominance(U)) @@ -136,6 +140,7 @@ GenericDomTreeUpdater::getDomTree() { assert(DT && "Invalid acquisition of a null DomTree"); applyDomTreeUpdates(); dropOutOfDateUpdates(); + applySplitCriticalEdges(); return *DT; } @@ -145,6 +150,7 @@ GenericDomTreeUpdater::getPostDomTree() { assert(PDT && "Invalid acquisition of a null PostDomTree"); applyPostDomTreeUpdates(); dropOutOfDateUpdates(); + applySplitCriticalEdges(); return *PDT; } @@ -201,7 +207,7 @@ GenericDomTreeUpdater::dump() const { if (To) { auto S = To->getName(); if (!To->hasName()) - S = "(no_name)"; + S = "(no name)"; OS << S << "(" << To << ")\n"; } else { OS << "(badref)\n"; @@ -229,6 +235,22 @@ GenericDomTreeUpdater::dump() const { printUpdates(I, PendUpdates.end()); } + auto printCriticalEdges = [&](const CriticalEdge &E) { + auto FromName = E.FromBB->getName(); + if (!E.FromBB->hasName()) + FromName = "(no name)"; + auto NewName = E.NewBB->getName(); + if (!E.NewBB->hasName()) + NewName = "(no name)"; + auto ToName = E.ToBB->getName(); + if (!E.ToBB->hasName()) + ToName = "(no name)"; + OS << " " << FromName << ", " << NewName << ", " << ToName << '\n'; + }; + OS << "Critical edges to be split:\n"; + for (const auto &E : CriticalEdgesToSplit) + printCriticalEdges(E); + OS << "Pending DeletedBBs:\n"; Index = 0; for (const auto *BB : DeletedBBs) { @@ -237,7 +259,7 @@ GenericDomTreeUpdater::dump() const { if (BB->hasName()) OS << BB->getName() << "("; else - OS << "(no_name)("; + OS << "(no name)("; OS << BB << ")\n"; } #endif @@ -348,6 +370,123 @@ void GenericDomTreeUpdater +void GenericDomTreeUpdater:: + applyUpdatesForCriticalEdgeSplitting(BasicBlockT *FromBB, BasicBlockT *ToBB, + BasicBlockT *NewBB) { + if (!DT && !PDT) + return; + CriticalEdgesToSplit.push_back({FromBB, ToBB, NewBB}); + bool Inserted = NewBBs.insert(NewBB).second; + (void)Inserted; + assert(Inserted && + "A basic block inserted via edge splitting cannot appear twice"); + if (Strategy == UpdateStrategy::Lazy) { + applyDomTreeUpdates(); + applyPostDomTreeUpdates(); + } + if (Strategy == UpdateStrategy::Eager) + applySplitCriticalEdges(); +} + +template +void GenericDomTreeUpdater::applySplitCriticalEdges() { + // Bail out early if there is nothing to do. + if (CriticalEdgesToSplit.empty()) + return; + + // For each element in CriticalEdgesToSplit, remember whether or not element + // is the new immediate domminator of its successor. The mapping is done by + // index, i.e., the information for the ith element of CriticalEdgesToSplit is + // the ith element of IsNewIDom. + SmallBitVector IsNewIDom(CriticalEdgesToSplit.size(), true); + SmallBitVector IsNewIPDom(CriticalEdgesToSplit.size(), true); + size_t Idx = 0; + + // Collect all the dominance properties info, before invalidating + // the underlying DT. + for (CriticalEdge &Edge : CriticalEdgesToSplit) { + // Update dominator information. + if (DT) { + BasicBlockT *Succ = Edge.ToBB; + auto *SuccDTNode = DT->getNode(Succ); + + for (BasicBlockT *PredBB : predecessors(Succ)) { + if (PredBB == Edge.NewBB) + continue; + // If we are in this situation: + // FromBB1 FromBB2 + // + + + // + + + + + // + + + + + // ... Split1 Split2 ... + // + + + // + + + // + + // Succ + // Instead of checking the domiance property with Split2, we check it + // with FromBB2 since Split2 is still unknown of the underlying DT + // structure. + if (NewBBs.count(PredBB)) { + assert(pred_size(PredBB) == 1 && "A basic block resulting from a " + "critical edge split has more " + "than one predecessor!"); + PredBB = *pred_begin(PredBB); + } + if (!DT->dominates(SuccDTNode, DT->getNode(PredBB))) { + IsNewIDom[Idx] = false; + break; + } + } + } + + // Same as DT version but from another direction. + if (PDT) { + BasicBlockT *Pred = Edge.FromBB; + auto *PredDTNode = PDT->getNode(Pred); + for (BasicBlockT *SuccBB : successors(Pred)) { + if (SuccBB == Edge.NewBB) + continue; + if (NewBBs.count(SuccBB)) { + assert(succ_size(SuccBB) == 1 && "A basic block resulting from a " + "critical edge split has more " + "than one predecessor!"); + SuccBB = *succ_begin(SuccBB); + } + if (!PDT->dominates(PredDTNode, PDT->getNode(SuccBB))) { + IsNewIPDom[Idx] = false; + break; + } + } + } + ++Idx; + } + + // Now, update DT with the collected dominance properties info. + Idx = 0; + for (CriticalEdge &Edge : CriticalEdgesToSplit) { + if (DT) { + // We know FromBB dominates NewBB. + auto *NewDTNode = DT->addNewBlock(Edge.NewBB, Edge.FromBB); + + // If all the other predecessors of "Succ" are dominated by "Succ" itself + // then the new block is the new immediate dominator of "Succ". Otherwise, + // the new block doesn't dominate anything. + if (IsNewIDom[Idx]) + DT->changeImmediateDominator(DT->getNode(Edge.ToBB), NewDTNode); + } + if (PDT) { + auto *NewPDTNode = PDT->addNewBlock(Edge.NewBB, Edge.ToBB); + if (IsNewIPDom[Idx]) + PDT->changeImmediateDominator(PDT->getNode(Edge.FromBB), NewPDTNode); + } + ++Idx; + } + NewBBs.clear(); + CriticalEdgesToSplit.clear(); +} + } // namespace llvm #endif // LLVM_ANALYSIS_GENERICDOMTREEUPDATERIMPL_H diff --git a/llvm/include/llvm/CodeGen/MachineBasicBlock.h b/llvm/include/llvm/CodeGen/MachineBasicBlock.h index b8153fd5d3fb7..ca47dbace8c0a 100644 --- a/llvm/include/llvm/CodeGen/MachineBasicBlock.h +++ b/llvm/include/llvm/CodeGen/MachineBasicBlock.h @@ -32,6 +32,7 @@ namespace llvm { class BasicBlock; +class MachineDomTreeUpdater; class MachineFunction; class MCSymbol; class ModuleSlotTracker; @@ -970,15 +971,17 @@ class MachineBasicBlock /// MachineLoopInfo, as applicable. MachineBasicBlock * SplitCriticalEdge(MachineBasicBlock *Succ, Pass &P, - std::vector> *LiveInSets = nullptr) { - return SplitCriticalEdge(Succ, &P, nullptr, LiveInSets); + std::vector> *LiveInSets = nullptr, + MachineDomTreeUpdater *MDTU = nullptr) { + return SplitCriticalEdge(Succ, &P, nullptr, LiveInSets, MDTU); } MachineBasicBlock * SplitCriticalEdge(MachineBasicBlock *Succ, MachineFunctionAnalysisManager &MFAM, - std::vector> *LiveInSets = nullptr) { - return SplitCriticalEdge(Succ, nullptr, &MFAM, LiveInSets); + std::vector> *LiveInSets = nullptr, + MachineDomTreeUpdater *MDTU = nullptr) { + return SplitCriticalEdge(Succ, nullptr, &MFAM, LiveInSets, MDTU); } /// Check if the edge between this block and the given successor \p @@ -1256,10 +1259,9 @@ class MachineBasicBlock void removePredecessor(MachineBasicBlock *Pred); // Helper method for new pass manager migration. - MachineBasicBlock * - SplitCriticalEdge(MachineBasicBlock *Succ, Pass *P, - MachineFunctionAnalysisManager *MFAM, - std::vector> *LiveInSets); + MachineBasicBlock *SplitCriticalEdge( + MachineBasicBlock *Succ, Pass *P, MachineFunctionAnalysisManager *MFAM, + std::vector> *LiveInSets, MachineDomTreeUpdater *MDTU); }; raw_ostream& operator<<(raw_ostream &OS, const MachineBasicBlock &MBB); @@ -1341,6 +1343,12 @@ inline auto successors(const MachineBasicBlock *BB) { return BB->successors(); } inline auto predecessors(const MachineBasicBlock *BB) { return BB->predecessors(); } +inline auto succ_size(const MachineBasicBlock *BB) { return BB->succ_size(); } +inline auto pred_size(const MachineBasicBlock *BB) { return BB->pred_size(); } +inline auto succ_begin(const MachineBasicBlock *BB) { return BB->succ_begin(); } +inline auto pred_begin(const MachineBasicBlock *BB) { return BB->pred_begin(); } +inline auto succ_end(const MachineBasicBlock *BB) { return BB->succ_end(); } +inline auto pred_end(const MachineBasicBlock *BB) { return BB->pred_end(); } /// MachineInstrSpan provides an interface to get an iteration range /// containing the instruction it was initialized with, along with all diff --git a/llvm/include/llvm/CodeGen/MachineDominators.h b/llvm/include/llvm/CodeGen/MachineDominators.h index 74cf94398736d..61635ff64502d 100644 --- a/llvm/include/llvm/CodeGen/MachineDominators.h +++ b/llvm/include/llvm/CodeGen/MachineDominators.h @@ -73,86 +73,22 @@ extern template bool Verify(const MBBDomTree &DT, /// compute a normal dominator tree. /// class MachineDominatorTree : public DomTreeBase { - /// Helper structure used to hold all the basic blocks - /// involved in the split of a critical edge. - struct CriticalEdge { - MachineBasicBlock *FromBB; - MachineBasicBlock *ToBB; - MachineBasicBlock *NewBB; - }; - - /// Pile up all the critical edges to be split. - /// The splitting of a critical edge is local and thus, it is possible - /// to apply several of those changes at the same time. - mutable SmallVector CriticalEdgesToSplit; - - /// Remember all the basic blocks that are inserted during - /// edge splitting. - /// Invariant: NewBBs == all the basic blocks contained in the NewBB - /// field of all the elements of CriticalEdgesToSplit. - /// I.e., forall elt in CriticalEdgesToSplit, it exists BB in NewBBs - /// such as BB == elt.NewBB. - mutable SmallSet NewBBs; - - /// Apply all the recorded critical edges to the DT. - /// This updates the underlying DT information in a way that uses - /// the fast query path of DT as much as possible. - /// FIXME: This method should not be a const member! - /// - /// \post CriticalEdgesToSplit.empty(). - void applySplitCriticalEdges() const; public: using Base = DomTreeBase; MachineDominatorTree() = default; - explicit MachineDominatorTree(MachineFunction &MF) { calculate(MF); } + explicit MachineDominatorTree(MachineFunction &MF) { recalculate(MF); } /// Handle invalidation explicitly. bool invalidate(MachineFunction &, const PreservedAnalyses &PA, MachineFunctionAnalysisManager::Invalidator &); - // FIXME: If there is an updater for MachineDominatorTree, - // migrate to this updater and remove these wrappers. - - MachineDominatorTree &getBase() { - applySplitCriticalEdges(); - return *this; - } - - MachineBasicBlock *getRoot() const { - applySplitCriticalEdges(); - return Base::getRoot(); - } - - MachineDomTreeNode *getRootNode() const { - applySplitCriticalEdges(); - return const_cast(Base::getRootNode()); - } - - void calculate(MachineFunction &F); - - bool dominates(const MachineDomTreeNode *A, - const MachineDomTreeNode *B) const { - applySplitCriticalEdges(); - return Base::dominates(A, B); - } - - void getDescendants(MachineBasicBlock *A, - SmallVectorImpl &Result) { - applySplitCriticalEdges(); - Base::getDescendants(A, Result); - } - - bool dominates(const MachineBasicBlock *A, const MachineBasicBlock *B) const { - applySplitCriticalEdges(); - return Base::dominates(A, B); - } + using Base::dominates; // dominates - Return true if A dominates B. This performs the // special checks necessary if A and B are in the same basic block. bool dominates(const MachineInstr *A, const MachineInstr *B) const { - applySplitCriticalEdges(); const MachineBasicBlock *BBA = A->getParent(), *BBB = B->getParent(); if (BBA != BBB) return Base::dominates(BBA, BBB); @@ -164,107 +100,6 @@ class MachineDominatorTree : public DomTreeBase { return &*I == A; } - - bool properlyDominates(const MachineDomTreeNode *A, - const MachineDomTreeNode *B) const { - applySplitCriticalEdges(); - return Base::properlyDominates(A, B); - } - - bool properlyDominates(const MachineBasicBlock *A, - const MachineBasicBlock *B) const { - applySplitCriticalEdges(); - return Base::properlyDominates(A, B); - } - - /// findNearestCommonDominator - Find nearest common dominator basic block - /// for basic block A and B. If there is no such block then return NULL. - MachineBasicBlock *findNearestCommonDominator(MachineBasicBlock *A, - MachineBasicBlock *B) { - applySplitCriticalEdges(); - return Base::findNearestCommonDominator(A, B); - } - - MachineDomTreeNode *operator[](MachineBasicBlock *BB) const { - applySplitCriticalEdges(); - return Base::getNode(BB); - } - - /// getNode - return the (Post)DominatorTree node for the specified basic - /// block. This is the same as using operator[] on this class. - /// - MachineDomTreeNode *getNode(MachineBasicBlock *BB) const { - applySplitCriticalEdges(); - return Base::getNode(BB); - } - - /// addNewBlock - Add a new node to the dominator tree information. This - /// creates a new node as a child of DomBB dominator node,linking it into - /// the children list of the immediate dominator. - MachineDomTreeNode *addNewBlock(MachineBasicBlock *BB, - MachineBasicBlock *DomBB) { - applySplitCriticalEdges(); - return Base::addNewBlock(BB, DomBB); - } - - /// changeImmediateDominator - This method is used to update the dominator - /// tree information when a node's immediate dominator changes. - /// - void changeImmediateDominator(MachineBasicBlock *N, - MachineBasicBlock *NewIDom) { - applySplitCriticalEdges(); - Base::changeImmediateDominator(N, NewIDom); - } - - void changeImmediateDominator(MachineDomTreeNode *N, - MachineDomTreeNode *NewIDom) { - applySplitCriticalEdges(); - Base::changeImmediateDominator(N, NewIDom); - } - - /// eraseNode - Removes a node from the dominator tree. Block must not - /// dominate any other blocks. Removes node from its immediate dominator's - /// children list. Deletes dominator node associated with basic block BB. - void eraseNode(MachineBasicBlock *BB) { - applySplitCriticalEdges(); - Base::eraseNode(BB); - } - - /// splitBlock - BB is split and now it has one successor. Update dominator - /// tree to reflect this change. - void splitBlock(MachineBasicBlock* NewBB) { - applySplitCriticalEdges(); - Base::splitBlock(NewBB); - } - - /// isReachableFromEntry - Return true if A is dominated by the entry - /// block of the function containing it. - bool isReachableFromEntry(const MachineBasicBlock *A) { - applySplitCriticalEdges(); - return Base::isReachableFromEntry(A); - } - - /// Record that the critical edge (FromBB, ToBB) has been - /// split with NewBB. - /// This is best to use this method instead of directly update the - /// underlying information, because this helps mitigating the - /// number of time the DT information is invalidated. - /// - /// \note Do not use this method with regular edges. - /// - /// \note To benefit from the compile time improvement incurred by this - /// method, the users of this method have to limit the queries to the DT - /// interface between two edges splitting. In other words, they have to - /// pack the splitting of critical edges as much as possible. - void recordSplitCriticalEdge(MachineBasicBlock *FromBB, - MachineBasicBlock *ToBB, - MachineBasicBlock *NewBB) { - bool Inserted = NewBBs.insert(NewBB).second; - (void)Inserted; - assert(Inserted && - "A basic block inserted via edge splitting cannot appear twice"); - CriticalEdgesToSplit.push_back({FromBB, ToBB, NewBB}); - } }; /// \brief Analysis pass which computes a \c MachineDominatorTree. diff --git a/llvm/include/llvm/CodeGen/MachineSSAContext.h b/llvm/include/llvm/CodeGen/MachineSSAContext.h index b70450c19f283..0e4304f69380f 100644 --- a/llvm/include/llvm/CodeGen/MachineSSAContext.h +++ b/llvm/include/llvm/CodeGen/MachineSSAContext.h @@ -24,12 +24,6 @@ class MachineInstr; class MachineFunction; class Register; -inline unsigned succ_size(const MachineBasicBlock *BB) { - return BB->succ_size(); -} -inline unsigned pred_size(const MachineBasicBlock *BB) { - return BB->pred_size(); -} inline auto instrs(const MachineBasicBlock &BB) { return BB.instrs(); } template <> struct GenericSSATraits { diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 91b5703944f3d..29ccd71c4dff0 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -1698,7 +1698,7 @@ void AsmPrinter::emitFunctionBody() { MDT = MDTWrapper ? &MDTWrapper->getDomTree() : nullptr; if (!MDT) { OwnedMDT = std::make_unique(); - OwnedMDT->getBase().recalculate(*MF); + OwnedMDT->recalculate(*MF); MDT = OwnedMDT.get(); } @@ -1707,7 +1707,7 @@ void AsmPrinter::emitFunctionBody() { MLI = MLIWrapper ? &MLIWrapper->getLI() : nullptr; if (!MLI) { OwnedMLI = std::make_unique(); - OwnedMLI->analyze(MDT->getBase()); + OwnedMLI->analyze(*MDT); MLI = OwnedMLI.get(); } } diff --git a/llvm/lib/CodeGen/LazyMachineBlockFrequencyInfo.cpp b/llvm/lib/CodeGen/LazyMachineBlockFrequencyInfo.cpp index 2561f2e5c9bbb..6fd84646009be 100644 --- a/llvm/lib/CodeGen/LazyMachineBlockFrequencyInfo.cpp +++ b/llvm/lib/CodeGen/LazyMachineBlockFrequencyInfo.cpp @@ -74,13 +74,13 @@ LazyMachineBlockFrequencyInfoPass::calculateIfNotAvailable() const { if (!MDT) { LLVM_DEBUG(dbgs() << "Building DominatorTree on the fly\n"); OwnedMDT = std::make_unique(); - OwnedMDT->getBase().recalculate(*MF); + OwnedMDT->recalculate(*MF); MDT = OwnedMDT.get(); } // Generate LoopInfo from it. OwnedMLI = std::make_unique(); - OwnedMLI->analyze(MDT->getBase()); + OwnedMLI->analyze(*MDT); MLI = OwnedMLI.get(); } diff --git a/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp b/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp index 0a6ce6a135817..5a34320dba692 100644 --- a/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp +++ b/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp @@ -2787,7 +2787,7 @@ void InstrRefBasedLDV::BlockPHIPlacement( // Apply IDF calculator to the designated set of location defs, storing // required PHIs into PHIBlocks. Uses the dominator tree stored in the // InstrRefBasedLDV object. - IDFCalculatorBase IDF(DomTree->getBase()); + IDFCalculatorBase IDF(*DomTree); IDF.setLiveInBlocks(AllBlocks); IDF.setDefiningBlocks(DefBlocks); diff --git a/llvm/lib/CodeGen/LiveDebugValues/LiveDebugValues.cpp b/llvm/lib/CodeGen/LiveDebugValues/LiveDebugValues.cpp index 0c0a4e13c7c9e..15642969457aa 100644 --- a/llvm/lib/CodeGen/LiveDebugValues/LiveDebugValues.cpp +++ b/llvm/lib/CodeGen/LiveDebugValues/LiveDebugValues.cpp @@ -120,7 +120,7 @@ bool LiveDebugValues::runOnMachineFunction(MachineFunction &MF) { MachineDominatorTree *DomTree = nullptr; if (InstrRefBased) { DomTree = &MDT; - MDT.calculate(MF); + MDT.recalculate(MF); TheImpl = &*InstrRefImpl; } diff --git a/llvm/lib/CodeGen/MachineBasicBlock.cpp b/llvm/lib/CodeGen/MachineBasicBlock.cpp index d681d00b5d8c4..b1dcf39fb80a5 100644 --- a/llvm/lib/CodeGen/MachineBasicBlock.cpp +++ b/llvm/lib/CodeGen/MachineBasicBlock.cpp @@ -16,11 +16,13 @@ #include "llvm/CodeGen/LiveIntervals.h" #include "llvm/CodeGen/LivePhysRegs.h" #include "llvm/CodeGen/LiveVariables.h" +#include "llvm/CodeGen/MachineDomTreeUpdater.h" #include "llvm/CodeGen/MachineDominators.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineJumpTableInfo.h" #include "llvm/CodeGen/MachineLoopInfo.h" +#include "llvm/CodeGen/MachinePostDominators.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/SlotIndexes.h" #include "llvm/CodeGen/TargetInstrInfo.h" @@ -1146,7 +1148,7 @@ class SlotIndexUpdateDelegate : public MachineFunction::Delegate { MachineBasicBlock *MachineBasicBlock::SplitCriticalEdge( MachineBasicBlock *Succ, Pass *P, MachineFunctionAnalysisManager *MFAM, - std::vector> *LiveInSets) { + std::vector> *LiveInSets, MachineDomTreeUpdater *MDTU) { assert((P || MFAM) && "Need a way to get analysis results!"); if (!canSplitCriticalEdge(Succ)) return nullptr; @@ -1346,8 +1348,8 @@ MachineBasicBlock *MachineBasicBlock::SplitCriticalEdge( LIS->repairIntervalsInRange(this, getFirstTerminator(), end(), UsedRegs); } - if (auto *MDT = GET_RESULT(MachineDominatorTree, getDomTree, )) - MDT->recordSplitCriticalEdge(this, Succ, NMBB); + if (MDTU) + MDTU->applyUpdatesForCriticalEdgeSplitting(this, Succ, NMBB); if (MachineLoopInfo *MLI = GET_RESULT(MachineLoop, getLI, Info)) if (MachineLoop *TIL = MLI->getLoopFor(this)) { diff --git a/llvm/lib/CodeGen/MachineDomTreeUpdater.cpp b/llvm/lib/CodeGen/MachineDomTreeUpdater.cpp index afffafb245e67..f39981b61cb33 100644 --- a/llvm/lib/CodeGen/MachineDomTreeUpdater.cpp +++ b/llvm/lib/CodeGen/MachineDomTreeUpdater.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "llvm/CodeGen/MachineDomTreeUpdater.h" +#include "llvm/ADT/SmallBitVector.h" #include "llvm/ADT/SmallSet.h" #include "llvm/Analysis/GenericDomTreeUpdaterImpl.h" #include "llvm/CodeGen/MachinePostDominators.h" diff --git a/llvm/lib/CodeGen/MachineDominanceFrontier.cpp b/llvm/lib/CodeGen/MachineDominanceFrontier.cpp index 6a8ede4feb937..ed69ed931c5cb 100644 --- a/llvm/lib/CodeGen/MachineDominanceFrontier.cpp +++ b/llvm/lib/CodeGen/MachineDominanceFrontier.cpp @@ -38,8 +38,7 @@ char &llvm::MachineDominanceFrontierID = MachineDominanceFrontier::ID; bool MachineDominanceFrontier::runOnMachineFunction(MachineFunction &) { releaseMemory(); - Base.analyze( - getAnalysis().getDomTree().getBase()); + Base.analyze(getAnalysis().getDomTree()); return false; } diff --git a/llvm/lib/CodeGen/MachineDominators.cpp b/llvm/lib/CodeGen/MachineDominators.cpp index a2cc8fdfa7c9f..67a91c87bb1bc 100644 --- a/llvm/lib/CodeGen/MachineDominators.cpp +++ b/llvm/lib/CodeGen/MachineDominators.cpp @@ -95,12 +95,6 @@ MachineDominatorTreeWrapperPass::MachineDominatorTreeWrapperPass() *PassRegistry::getPassRegistry()); } -void MachineDominatorTree::calculate(MachineFunction &F) { - CriticalEdgesToSplit.clear(); - NewBBs.clear(); - recalculate(F); -} - char &llvm::MachineDominatorsID = MachineDominatorTreeWrapperPass::ID; bool MachineDominatorTreeWrapperPass::runOnMachineFunction(MachineFunction &F) { @@ -121,71 +115,3 @@ void MachineDominatorTreeWrapperPass::print(raw_ostream &OS, if (DT) DT->print(OS); } - -void MachineDominatorTree::applySplitCriticalEdges() const { - // Bail out early if there is nothing to do. - if (CriticalEdgesToSplit.empty()) - return; - - // For each element in CriticalEdgesToSplit, remember whether or not element - // is the new immediate domminator of its successor. The mapping is done by - // index, i.e., the information for the ith element of CriticalEdgesToSplit is - // the ith element of IsNewIDom. - SmallBitVector IsNewIDom(CriticalEdgesToSplit.size(), true); - size_t Idx = 0; - - // Collect all the dominance properties info, before invalidating - // the underlying DT. - for (CriticalEdge &Edge : CriticalEdgesToSplit) { - // Update dominator information. - MachineBasicBlock *Succ = Edge.ToBB; - MachineDomTreeNode *SuccDTNode = Base::getNode(Succ); - - for (MachineBasicBlock *PredBB : Succ->predecessors()) { - if (PredBB == Edge.NewBB) - continue; - // If we are in this situation: - // FromBB1 FromBB2 - // + + - // + + + + - // + + + + - // ... Split1 Split2 ... - // + + - // + + - // + - // Succ - // Instead of checking the domiance property with Split2, we check it with - // FromBB2 since Split2 is still unknown of the underlying DT structure. - if (NewBBs.count(PredBB)) { - assert(PredBB->pred_size() == 1 && "A basic block resulting from a " - "critical edge split has more " - "than one predecessor!"); - PredBB = *PredBB->pred_begin(); - } - if (!Base::dominates(SuccDTNode, Base::getNode(PredBB))) { - IsNewIDom[Idx] = false; - break; - } - } - ++Idx; - } - - // Now, update DT with the collected dominance properties info. - Idx = 0; - for (CriticalEdge &Edge : CriticalEdgesToSplit) { - // We know FromBB dominates NewBB. - MachineDomTreeNode *NewDTNode = - const_cast(this)->Base::addNewBlock( - Edge.NewBB, Edge.FromBB); - - // If all the other predecessors of "Succ" are dominated by "Succ" itself - // then the new block is the new immediate dominator of "Succ". Otherwise, - // the new block doesn't dominate anything. - if (IsNewIDom[Idx]) - const_cast(this)->Base::changeImmediateDominator( - Base::getNode(Edge.ToBB), NewDTNode); - ++Idx; - } - NewBBs.clear(); - CriticalEdgesToSplit.clear(); -} diff --git a/llvm/lib/CodeGen/MachineLICM.cpp b/llvm/lib/CodeGen/MachineLICM.cpp index f24ab187ef400..c123144f0c4a3 100644 --- a/llvm/lib/CodeGen/MachineLICM.cpp +++ b/llvm/lib/CodeGen/MachineLICM.cpp @@ -24,6 +24,7 @@ #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineBlockFrequencyInfo.h" +#include "llvm/CodeGen/MachineDomTreeUpdater.h" #include "llvm/CodeGen/MachineDominators.h" #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineFunction.h" @@ -131,7 +132,7 @@ namespace { AliasAnalysis *AA = nullptr; // Alias analysis info. MachineBlockFrequencyInfo *MBFI = nullptr; // Machine block frequncy info MachineLoopInfo *MLI = nullptr; // Current MachineLoopInfo - MachineDominatorTree *DT = nullptr; // Machine dominator tree for the cur loop + MachineDomTreeUpdater *MDTU = nullptr; // Wraps current dominator tree // State that is updated as we process loops bool Changed = false; // True if a loop is changed. @@ -261,8 +262,7 @@ namespace { DenseMap &OpenChildren, const DenseMap &ParentMap); - void HoistOutOfLoop(MachineDomTreeNode *HeaderN, MachineLoop *CurLoop, - MachineBasicBlock *CurPreheader); + void HoistOutOfLoop(MachineLoop *CurLoop, MachineBasicBlock *CurPreheader); void InitRegPressure(MachineBasicBlock *BB); @@ -375,8 +375,11 @@ bool MachineLICMBase::runOnMachineFunction(MachineFunction &MF) { if (DisableHoistingToHotterBlocks != UseBFI::None) MBFI = &getAnalysis().getMBFI(); MLI = &getAnalysis().getLI(); - DT = &getAnalysis().getDomTree(); + auto *DT = &getAnalysis().getDomTree(); AA = &getAnalysis().getAAResults(); + MachineDomTreeUpdater Updater(DT, + MachineDomTreeUpdater::UpdateStrategy::Lazy); + MDTU = &Updater; if (HoistConstLoads) InitializeLoadsHoistableLoops(); @@ -391,9 +394,8 @@ bool MachineLICMBase::runOnMachineFunction(MachineFunction &MF) { else { // CSEMap is initialized for loop header when the first instruction is // being hoisted. - MachineDomTreeNode *N = DT->getNode(CurLoop->getHeader()); FirstInLoop = true; - HoistOutOfLoop(N, CurLoop, CurPreheader); + HoistOutOfLoop(CurLoop, CurPreheader); CSEMap.clear(); } } @@ -734,7 +736,7 @@ bool MachineLICMBase::IsGuaranteedToExecute(MachineBasicBlock *BB, SmallVector CurrentLoopExitingBlocks; CurLoop->getExitingBlocks(CurrentLoopExitingBlocks); for (MachineBasicBlock *CurrentLoopExitingBlock : CurrentLoopExitingBlocks) - if (!DT->dominates(BB, CurrentLoopExitingBlock)) { + if (!MDTU->getDomTree().dominates(BB, CurrentLoopExitingBlock)) { SpeculationState = SpeculateTrue; return false; } @@ -796,13 +798,15 @@ void MachineLICMBase::ExitScopeIfDone(MachineDomTreeNode *Node, /// specified header block, and that are in the current loop) in depth first /// order w.r.t the DominatorTree. This allows us to visit definitions before /// uses, allowing us to hoist a loop body in one pass without iteration. -void MachineLICMBase::HoistOutOfLoop(MachineDomTreeNode *HeaderN, - MachineLoop *CurLoop, +void MachineLICMBase::HoistOutOfLoop(MachineLoop *CurLoop, MachineBasicBlock *CurPreheader) { MachineBasicBlock *Preheader = getCurPreheader(CurLoop, CurPreheader); if (!Preheader) return; + MachineDomTreeNode *HeaderN = + MDTU->getDomTree().getNode(CurLoop->getHeader()); + SmallVector Scopes; SmallVector WorkList; DenseMap ParentMap; @@ -1573,7 +1577,7 @@ bool MachineLICMBase::MayCSE(MachineInstr *MI) { unsigned Opcode = MI->getOpcode(); for (auto &Map : CSEMap) { // Check this CSEMap's preheader dominates MI's basic block. - if (DT->dominates(Map.first, MI->getParent())) { + if (MDTU->getDomTree().dominates(Map.first, MI->getParent())) { DenseMap>::iterator CI = Map.second.find(Opcode); // Do not CSE implicit_def so ProcessImplicitDefs can properly propagate @@ -1641,7 +1645,7 @@ unsigned MachineLICMBase::Hoist(MachineInstr *MI, MachineBasicBlock *Preheader, bool HasCSEDone = false; for (auto &Map : CSEMap) { // Check this CSEMap's preheader dominates MI's basic block. - if (DT->dominates(Map.first, MI->getParent())) { + if (MDTU->getDomTree().dominates(Map.first, MI->getParent())) { DenseMap>::iterator CI = Map.second.find(Opcode); if (CI != Map.second.end()) { @@ -1704,7 +1708,8 @@ MachineLICMBase::getCurPreheader(MachineLoop *CurLoop, return nullptr; } - CurPreheader = Pred->SplitCriticalEdge(CurLoop->getHeader(), *this); + CurPreheader = Pred->SplitCriticalEdge(CurLoop->getHeader(), *this, + /*LiveInSets=*/nullptr, MDTU); if (!CurPreheader) { CurPreheader = reinterpret_cast(-1); return nullptr; diff --git a/llvm/lib/CodeGen/MachineLoopInfo.cpp b/llvm/lib/CodeGen/MachineLoopInfo.cpp index a03c008e6045a..ea3f4fbaff479 100644 --- a/llvm/lib/CodeGen/MachineLoopInfo.cpp +++ b/llvm/lib/CodeGen/MachineLoopInfo.cpp @@ -77,7 +77,7 @@ bool MachineLoopInfo::invalidate( void MachineLoopInfo::calculate(MachineDominatorTree &MDT) { releaseMemory(); - analyze(MDT.getBase()); + analyze(MDT); } void MachineLoopInfoWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const { diff --git a/llvm/lib/CodeGen/MachineSink.cpp b/llvm/lib/CodeGen/MachineSink.cpp index 4b3ff57fb478a..c687af762bfb7 100644 --- a/llvm/lib/CodeGen/MachineSink.cpp +++ b/llvm/lib/CodeGen/MachineSink.cpp @@ -30,6 +30,7 @@ #include "llvm/CodeGen/MachineBlockFrequencyInfo.h" #include "llvm/CodeGen/MachineBranchProbabilityInfo.h" #include "llvm/CodeGen/MachineCycleAnalysis.h" +#include "llvm/CodeGen/MachineDomTreeUpdater.h" #include "llvm/CodeGen/MachineDominators.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineFunctionPass.h" @@ -744,8 +745,11 @@ bool MachineSinking::runOnMachineFunction(MachineFunction &MF) { MadeChange |= ProcessBlock(MBB); // If we have anything we marked as toSplit, split it now. + MachineDomTreeUpdater MDTU(DT, PDT, + MachineDomTreeUpdater::UpdateStrategy::Lazy); for (const auto &Pair : ToSplit) { - auto NewSucc = Pair.first->SplitCriticalEdge(Pair.second, *this); + auto NewSucc = + Pair.first->SplitCriticalEdge(Pair.second, *this, nullptr, &MDTU); if (NewSucc != nullptr) { LLVM_DEBUG(dbgs() << " *** Splitting critical edge: " << printMBBReference(*Pair.first) << " -- " diff --git a/llvm/lib/CodeGen/MachineUniformityAnalysis.cpp b/llvm/lib/CodeGen/MachineUniformityAnalysis.cpp index 7548fc8141ec5..a4b78c1c75ceb 100644 --- a/llvm/lib/CodeGen/MachineUniformityAnalysis.cpp +++ b/llvm/lib/CodeGen/MachineUniformityAnalysis.cpp @@ -199,8 +199,7 @@ void MachineUniformityAnalysisPass::getAnalysisUsage(AnalysisUsage &AU) const { } bool MachineUniformityAnalysisPass::runOnMachineFunction(MachineFunction &MF) { - auto &DomTree = - getAnalysis().getDomTree().getBase(); + auto &DomTree = getAnalysis().getDomTree(); auto &CI = getAnalysis().getCycleInfo(); // FIXME: Query TTI::hasBranchDivergence. -run-pass seems to end up with a // default NoTTI diff --git a/llvm/lib/CodeGen/PHIElimination.cpp b/llvm/lib/CodeGen/PHIElimination.cpp index e5f40771eda86..b71e5b8538689 100644 --- a/llvm/lib/CodeGen/PHIElimination.cpp +++ b/llvm/lib/CodeGen/PHIElimination.cpp @@ -22,6 +22,7 @@ #include "llvm/CodeGen/LiveIntervals.h" #include "llvm/CodeGen/LiveVariables.h" #include "llvm/CodeGen/MachineBasicBlock.h" +#include "llvm/CodeGen/MachineDomTreeUpdater.h" #include "llvm/CodeGen/MachineDominators.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineFunctionPass.h" @@ -90,7 +91,8 @@ class PHIEliminationImpl { /// Split critical edges where necessary for good coalescer performance. bool SplitPHIEdges(MachineFunction &MF, MachineBasicBlock &MBB, MachineLoopInfo *MLI, - std::vector> *LiveInSets); + std::vector> *LiveInSets, + MachineDomTreeUpdater &MDTU); // These functions are temporary abstractions around LiveVariables and // LiveIntervals, so they can go away when LiveVariables does. @@ -203,6 +205,16 @@ void PHIElimination::getAnalysisUsage(AnalysisUsage &AU) const { bool PHIEliminationImpl::run(MachineFunction &MF) { MRI = &MF.getRegInfo(); + MachineDominatorTree *MDT = nullptr; + if (P) { + auto *MDTWrapper = + P->getAnalysisIfAvailable(); + MDT = MDTWrapper ? &MDTWrapper->getDomTree() : nullptr; + } else { + MDT = MFAM->getCachedResult(MF); + } + MachineDomTreeUpdater MDTU(MDT, MachineDomTreeUpdater::UpdateStrategy::Lazy); + bool Changed = false; // Split critical edges to help the coalescer. @@ -237,7 +249,8 @@ bool PHIEliminationImpl::run(MachineFunction &MF) { } for (auto &MBB : MF) - Changed |= SplitPHIEdges(MF, MBB, MLI, (LV ? &LiveInSets : nullptr)); + Changed |= + SplitPHIEdges(MF, MBB, MLI, (LV ? &LiveInSets : nullptr), MDTU); } // This pass takes the function out of SSA form. @@ -268,10 +281,6 @@ bool PHIEliminationImpl::run(MachineFunction &MF) { MF.deleteMachineInstr(I.first); } - // TODO: we should use the incremental DomTree updater here. - if (Changed && MDT) - MDT->getBase().recalculate(MF); - LoweredPHIs.clear(); ImpDefs.clear(); VRegPHIUseCount.clear(); @@ -752,7 +761,7 @@ void PHIEliminationImpl::analyzePHINodes(const MachineFunction &MF) { bool PHIEliminationImpl::SplitPHIEdges( MachineFunction &MF, MachineBasicBlock &MBB, MachineLoopInfo *MLI, - std::vector> *LiveInSets) { + std::vector> *LiveInSets, MachineDomTreeUpdater &MDTU) { if (MBB.empty() || !MBB.front().isPHI() || MBB.isEHPad()) return false; // Quick exit for basic blocks without PHIs. @@ -819,8 +828,8 @@ bool PHIEliminationImpl::SplitPHIEdges( } if (!ShouldSplit && !SplitAllCriticalEdges) continue; - if (!(P ? PreMBB->SplitCriticalEdge(&MBB, *P, LiveInSets) - : PreMBB->SplitCriticalEdge(&MBB, *MFAM, LiveInSets))) { + if (!(P ? PreMBB->SplitCriticalEdge(&MBB, *P, LiveInSets, &MDTU) + : PreMBB->SplitCriticalEdge(&MBB, *MFAM, LiveInSets, &MDTU))) { LLVM_DEBUG(dbgs() << "Failed to split critical edge.\n"); continue; } diff --git a/llvm/lib/CodeGen/XRayInstrumentation.cpp b/llvm/lib/CodeGen/XRayInstrumentation.cpp index d7cc5d5c2b41d..5c0ff6155c358 100644 --- a/llvm/lib/CodeGen/XRayInstrumentation.cpp +++ b/llvm/lib/CodeGen/XRayInstrumentation.cpp @@ -175,7 +175,7 @@ bool XRayInstrumentation::runOnMachineFunction(MachineFunction &MF) { auto *MDT = MDTWrapper ? &MDTWrapper->getDomTree() : nullptr; MachineDominatorTree ComputedMDT; if (!MDT) { - ComputedMDT.getBase().recalculate(MF); + ComputedMDT.recalculate(MF); MDT = &ComputedMDT; } @@ -184,7 +184,7 @@ bool XRayInstrumentation::runOnMachineFunction(MachineFunction &MF) { auto *MLI = MLIWrapper ? &MLIWrapper->getLI() : nullptr; MachineLoopInfo ComputedMLI; if (!MLI) { - ComputedMLI.analyze(MDT->getBase()); + ComputedMLI.analyze(*MDT); MLI = &ComputedMLI; } diff --git a/llvm/lib/Target/AMDGPU/AMDGPURegBankSelect.cpp b/llvm/lib/Target/AMDGPU/AMDGPURegBankSelect.cpp index d1985f46b1c44..8135805cd696b 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPURegBankSelect.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPURegBankSelect.cpp @@ -66,9 +66,8 @@ bool AMDGPURegBankSelect::runOnMachineFunction(MachineFunction &MF) { MachineDominatorTree &DomTree = getAnalysis().getDomTree(); - MachineUniformityInfo Uniformity = - computeMachineUniformityInfo(MF, CycleInfo, DomTree.getBase(), - !ST.isSingleLaneExecution(F)); + MachineUniformityInfo Uniformity = computeMachineUniformityInfo( + MF, CycleInfo, DomTree, !ST.isSingleLaneExecution(F)); (void)Uniformity; // TODO: Use this assignRegisterBanks(MF); diff --git a/llvm/lib/Target/AMDGPU/SILateBranchLowering.cpp b/llvm/lib/Target/AMDGPU/SILateBranchLowering.cpp index afc6353ec8116..6d1ad90a83147 100644 --- a/llvm/lib/Target/AMDGPU/SILateBranchLowering.cpp +++ b/llvm/lib/Target/AMDGPU/SILateBranchLowering.cpp @@ -114,7 +114,7 @@ static void splitBlock(MachineBasicBlock &MBB, MachineInstr &MI, DTUpdates.push_back({DomTreeT::Delete, &MBB, Succ}); } DTUpdates.push_back({DomTreeT::Insert, &MBB, SplitBB}); - MDT->getBase().applyUpdates(DTUpdates); + MDT->applyUpdates(DTUpdates); } void SILateBranchLowering::expandChainCall(MachineInstr &MI) { @@ -142,7 +142,7 @@ void SILateBranchLowering::earlyTerm(MachineInstr &MI, splitBlock(MBB, *BranchMI, MDT); MBB.addSuccessor(EarlyExitBlock); - MDT->getBase().insertEdge(&MBB, EarlyExitBlock); + MDT->insertEdge(&MBB, EarlyExitBlock); } bool SILateBranchLowering::runOnMachineFunction(MachineFunction &MF) { @@ -238,7 +238,7 @@ bool SILateBranchLowering::runOnMachineFunction(MachineFunction &MF) { } MBB->addSuccessor(EmptyMBBAtEnd); - MDT->getBase().insertEdge(MBB, EmptyMBBAtEnd); + MDT->insertEdge(MBB, EmptyMBBAtEnd); BuildMI(*MBB, MI, MI->getDebugLoc(), TII->get(AMDGPU::S_BRANCH)) .addMBB(EmptyMBBAtEnd); MI->eraseFromParent(); diff --git a/llvm/lib/Target/AMDGPU/SILowerI1Copies.cpp b/llvm/lib/Target/AMDGPU/SILowerI1Copies.cpp index a9ee74dec1203..056ef62cd82e8 100644 --- a/llvm/lib/Target/AMDGPU/SILowerI1Copies.cpp +++ b/llvm/lib/Target/AMDGPU/SILowerI1Copies.cpp @@ -548,7 +548,7 @@ bool PhiLoweringHelper::lowerPhis() { if (Vreg1Phis.empty()) return false; - DT->getBase().updateDFSNumbers(); + DT->updateDFSNumbers(); MachineBasicBlock *PrevMBB = nullptr; for (MachineInstr *MI : Vreg1Phis) { MachineBasicBlock &MBB = *MI->getParent(); diff --git a/llvm/lib/Target/AMDGPU/SIWholeQuadMode.cpp b/llvm/lib/Target/AMDGPU/SIWholeQuadMode.cpp index df7906ebd8a7e..25a271cd6eddc 100644 --- a/llvm/lib/Target/AMDGPU/SIWholeQuadMode.cpp +++ b/llvm/lib/Target/AMDGPU/SIWholeQuadMode.cpp @@ -781,7 +781,7 @@ MachineBasicBlock *SIWholeQuadMode::splitBlock(MachineBasicBlock *BB, } DTUpdates.push_back({DomTreeT::Insert, BB, SplitBB}); if (MDT) - MDT->getBase().applyUpdates(DTUpdates); + MDT->applyUpdates(DTUpdates); if (PDT) PDT->applyUpdates(DTUpdates); diff --git a/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp b/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp index 6ca18528591af..e5fbdd405e0d0 100644 --- a/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp +++ b/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp @@ -413,7 +413,7 @@ void HexagonFrameLowering::findShrunkPrologEpilog(MachineFunction &MF, auto &HRI = *MF.getSubtarget().getRegisterInfo(); MachineDominatorTree MDT; - MDT.calculate(MF); + MDT.recalculate(MF); MachinePostDominatorTree MPT; MPT.recalculate(MF); diff --git a/llvm/lib/Target/X86/X86FlagsCopyLowering.cpp b/llvm/lib/Target/X86/X86FlagsCopyLowering.cpp index ab8b3dc3dd6d5..73f574aa07f6d 100644 --- a/llvm/lib/Target/X86/X86FlagsCopyLowering.cpp +++ b/llvm/lib/Target/X86/X86FlagsCopyLowering.cpp @@ -279,8 +279,7 @@ bool X86FlagsCopyLoweringPass::runOnMachineFunction(MachineFunction &MF) { if (MDTWrapper) { MDT = &MDTWrapper->getDomTree(); } else { - OwnedMDT = std::make_unique(); - OwnedMDT->getBase().recalculate(MF); + OwnedMDT = std::make_unique(MF); MDT = OwnedMDT.get(); } diff --git a/llvm/tools/llvm-reduce/deltas/ReduceInstructionsMIR.cpp b/llvm/tools/llvm-reduce/deltas/ReduceInstructionsMIR.cpp index 5f0697f5aaad7..40bc6b180fb88 100644 --- a/llvm/tools/llvm-reduce/deltas/ReduceInstructionsMIR.cpp +++ b/llvm/tools/llvm-reduce/deltas/ReduceInstructionsMIR.cpp @@ -65,7 +65,7 @@ static bool shouldNotRemoveInstruction(const TargetInstrInfo &TII, static void extractInstrFromFunction(Oracle &O, MachineFunction &MF) { MachineDominatorTree MDT; - MDT.calculate(MF); + MDT.recalculate(MF); auto MRI = &MF.getRegInfo(); SetVector ToDelete; diff --git a/llvm/unittests/Analysis/DomTreeUpdaterTest.cpp b/llvm/unittests/Analysis/DomTreeUpdaterTest.cpp index 0777bbe3887bc..046765688ebd5 100644 --- a/llvm/unittests/Analysis/DomTreeUpdaterTest.cpp +++ b/llvm/unittests/Analysis/DomTreeUpdaterTest.cpp @@ -15,6 +15,7 @@ #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" #include "llvm/Support/SourceMgr.h" +#include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "gtest/gtest.h" #include @@ -787,3 +788,45 @@ TEST(DomTreeUpdater, LazyUpdateDeduplicationTest) { DTU.applyUpdates({{DominatorTree::Insert, BB0, BB2}}); ASSERT_TRUE(DTU.getDomTree().verify()); } + +TEST(DomTreeUpdater, CriticalEdgeSplitTest) { + StringRef FuncName = "f"; + StringRef ModuleString = R"( +declare void @use1(i32) + +define void @f(i32 %i, i1 %c) { +entry: + %A = icmp eq i32 %i, 0 ; [#uses=1] + br i1 %A, label %brtrue, label %brfalse + +brtrue: ; preds = %entry + call void @use1( i32 %i ) + br label %brfalse + +brfalse: ; preds = %brtrue, %entry + call void @use1( i32 %i ) + ret void +} + )"; + // Make the module. + LLVMContext Context; + std::unique_ptr M = makeLLVMModule(Context, ModuleString); + Function *F = M->getFunction(FuncName); + + // Make the DTU. + DominatorTree DT(*F); + DomTreeUpdater DTU(&DT, nullptr, DomTreeUpdater::UpdateStrategy::Lazy); + ASSERT_TRUE(DTU.getDomTree().verify()); + + CriticalEdgeSplittingOptions Opts; + SplitAllCriticalEdges(*F, Opts); + + Function::iterator FI = F->begin(); + BasicBlock *BBEntry = &*FI++; + BasicBlock *SplitB = &*FI++; + [[maybe_unused]] BasicBlock *BBTrue = &*FI++; + BasicBlock *BBFalse = &*FI++; + DTU.applyUpdatesForCriticalEdgeSplitting(BBEntry, BBFalse, SplitB); + DominatorTree NewDT(*F); + ASSERT_FALSE(NewDT.compare(DTU.getDomTree())); +} diff --git a/llvm/unittests/Target/WebAssembly/WebAssemblyExceptionInfoTest.cpp b/llvm/unittests/Target/WebAssembly/WebAssemblyExceptionInfoTest.cpp index 5838ab6f782ba..85bfd3b37c0f3 100644 --- a/llvm/unittests/Target/WebAssembly/WebAssemblyExceptionInfoTest.cpp +++ b/llvm/unittests/Target/WebAssembly/WebAssemblyExceptionInfoTest.cpp @@ -168,8 +168,8 @@ body: | WebAssemblyExceptionInfo WEI; MachineDominatorTree MDT; MachineDominanceFrontier MDF; - MDT.calculate(*MF); - MDF.getBase().analyze(MDT.getBase()); + MDT.recalculate(*MF); + MDF.getBase().analyze(MDT); WEI.recalculate(*MF, MDT, MDF); // Exception info structure: @@ -343,8 +343,8 @@ body: | WebAssemblyExceptionInfo WEI; MachineDominatorTree MDT; MachineDominanceFrontier MDF; - MDT.calculate(*MF); - MDF.getBase().analyze(MDT.getBase()); + MDT.recalculate(*MF); + MDF.getBase().analyze(MDT); WEI.recalculate(*MF, MDT, MDF); // Exception info structure: