Skip to content

[DomTreeUpdater] Move critical edge splitting code to updater #115111

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Dec 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions llvm/include/llvm/Analysis/DomTreeUpdater.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,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:
Expand Down Expand Up @@ -109,9 +112,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<DomTreeUpdater, DominatorTree,
Expand All @@ -120,6 +120,13 @@ extern template class GenericDomTreeUpdater<DomTreeUpdater, DominatorTree,
extern template void
GenericDomTreeUpdater<DomTreeUpdater, DominatorTree,
PostDominatorTree>::recalculate(Function &F);

extern template void
GenericDomTreeUpdater<DomTreeUpdater, DominatorTree, PostDominatorTree>::
applyUpdatesImpl</*IsForward=*/true>();
extern template void
GenericDomTreeUpdater<DomTreeUpdater, DominatorTree, PostDominatorTree>::
applyUpdatesImpl</*IsForward=*/false>();
} // namespace llvm

#endif // LLVM_ANALYSIS_DOMTREEUPDATER_H
43 changes: 36 additions & 7 deletions llvm/include/llvm/Analysis/GenericDomTreeUpdater.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class GenericDomTreeUpdater {
public:
enum class UpdateStrategy : unsigned char { Eager = 0, Lazy = 1 };
using BasicBlockT = typename DomTreeT::NodeType;
using UpdateT = typename DomTreeT::UpdateType;

explicit GenericDomTreeUpdater(UpdateStrategy Strategy_)
: Strategy(Strategy_) {}
Expand Down Expand Up @@ -146,7 +147,12 @@ class GenericDomTreeUpdater {
/// 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<typename DomTreeT::UpdateType> Updates);
void applyUpdates(ArrayRef<UpdateT> Updates);

/// Apply updates that the critical edge (FromBB, ToBB) has been
/// split with NewBB.
void splitCriticalEdge(BasicBlockT *FromBB, BasicBlockT *ToBB,
BasicBlockT *NewBB);

/// Submit updates to all available trees. It will also
/// 1. discard duplicated updates,
Expand All @@ -169,7 +175,7 @@ class GenericDomTreeUpdater {
/// 3. It is only legal to submit updates to an edge in the order CFG changes
/// are made. The order you submit updates on different edges is not
/// restricted.
void applyUpdatesPermissive(ArrayRef<typename DomTreeT::UpdateType> Updates);
void applyUpdatesPermissive(ArrayRef<UpdateT> Updates);

///@}

Expand Down Expand Up @@ -205,7 +211,25 @@ class GenericDomTreeUpdater {
LLVM_DUMP_METHOD void dump() const;

protected:
SmallVector<typename DomTreeT::UpdateType, 16> PendUpdates;
/// 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;
};

struct DomTreeUpdate {
bool IsCriticalEdgeSplit = false;
union {
UpdateT Update;
CriticalEdge EdgeSplit;
};
DomTreeUpdate(UpdateT Update) : Update(Update) {}
DomTreeUpdate(CriticalEdge E) : IsCriticalEdgeSplit(true), EdgeSplit(E) {}
};

SmallVector<DomTreeUpdate, 16> PendUpdates;
size_t PendDTUpdateIndex = 0;
size_t PendPDTUpdateIndex = 0;
DomTreeT *DT = nullptr;
Expand All @@ -216,21 +240,21 @@ class GenericDomTreeUpdater {
bool IsRecalculatingPostDomTree = false;

/// Returns true if the update is self dominance.
bool isSelfDominance(typename DomTreeT::UpdateType Update) const {
bool isSelfDominance(UpdateT Update) const {
// Won't affect DomTree and PostDomTree.
return Update.getFrom() == Update.getTo();
}

/// Helper function to apply all pending DomTree updates.
void applyDomTreeUpdates();
void applyDomTreeUpdates() { applyUpdatesImpl<true>(); }

/// Helper function to apply all pending PostDomTree updates.
void applyPostDomTreeUpdates();
void applyPostDomTreeUpdates() { applyUpdatesImpl<false>(); }

/// Returns true if the update appears in the LLVM IR.
/// It is used to check whether an update is valid in
/// insertEdge/deleteEdge or is unnecessary in the batch update.
bool isUpdateValid(typename DomTreeT::UpdateType Update) const;
bool isUpdateValid(UpdateT Update) const;

/// Erase Basic Block node before it is unlinked from Function
/// in the DomTree and PostDomTree.
Expand All @@ -243,6 +267,11 @@ class GenericDomTreeUpdater {
/// Drop all updates applied by all available trees and delete BasicBlocks if
/// all available trees are up-to-date.
void dropOutOfDateUpdates();

private:
void splitDTCriticalEdges(ArrayRef<CriticalEdge> Updates);
void splitPDTCriticalEdges(ArrayRef<CriticalEdge> Updates);
template <bool IsForward> void applyUpdatesImpl();
};

} // namespace llvm
Expand Down
Loading
Loading