[llvm] [CycleInfo] Remove GenericCycle::TopLevelCycle. NFC (PR #209677)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Jul 14 21:04:33 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-adt
Author: Fangrui Song (MaskRay)
<details>
<summary>Changes</summary>
moveTopLevelCycleToNewParent maintains TopLevelCycle eagerly, rewriting the
whole re-parented subtree with depth_first. When discovery nests k cycles
one by one this is quadratic, and the df_iterator walk plus its visited set
dominate construction on deep nests (~78% of time on a 1500-deep nest).
Walk ParentCycle links in getTopLevelParentCycle instead and delete the
member. The walk is valid during construction too: parent links are
always current, and discovery queries blocks whose innermost cycle sits
at the top of the forest being merged, so the walk is short.
Aided by Claude Fable 5
---
Full diff: https://github.com/llvm/llvm-project/pull/209677.diff
2 Files Affected:
- (modified) llvm/include/llvm/ADT/GenericCycleImpl.h (+3-9)
- (modified) llvm/include/llvm/ADT/GenericCycleInfo.h (+1-5)
``````````diff
diff --git a/llvm/include/llvm/ADT/GenericCycleImpl.h b/llvm/include/llvm/ADT/GenericCycleImpl.h
index dfeb479d764e5..1710141d39cad 100644
--- a/llvm/include/llvm/ADT/GenericCycleImpl.h
+++ b/llvm/include/llvm/ADT/GenericCycleImpl.h
@@ -227,11 +227,6 @@ void GenericCycle<ContextT>::verifyCycleNest() const {
if (ParentCycle) {
assert(is_contained(ParentCycle->children(), this) &&
"Cycle is not a subcycle of its parent!");
- assert(ParentCycle->TopLevelCycle == TopLevelCycle &&
- "Top level cycle of parent cycle must be the same");
- } else {
- assert(TopLevelCycle == this &&
- "Cycle without parent must be top-level cycle");
}
#endif
}
@@ -293,7 +288,9 @@ template <typename ContextT>
auto GenericCycleInfo<ContextT>::getTopLevelParentCycle(
const BlockT *Block) const -> CycleT * {
CycleT *Cycle = getCycle(Block);
- return Cycle ? Cycle->TopLevelCycle : nullptr;
+ while (Cycle && Cycle->ParentCycle)
+ Cycle = Cycle->ParentCycle;
+ return Cycle;
}
template <typename ContextT>
@@ -311,9 +308,6 @@ void GenericCycleInfo<ContextT>::moveTopLevelCycleToNewParent(CycleT *NewParent,
*Pos = std::move(CurrentContainer.back());
CurrentContainer.pop_back();
Child->ParentCycle = NewParent;
- Child->TopLevelCycle = NewParent;
- for (CycleT *Cycle : depth_first(Child))
- Cycle->TopLevelCycle = NewParent;
// This only relinks the cycle tree and does NOT touch BlockLayout, so it
// leaves every cycle's [IdxBegin, IdxEnd) range stale, i.e. BlockLayout is
// left invalid. The caller must call layoutBlocks() before any
diff --git a/llvm/include/llvm/ADT/GenericCycleInfo.h b/llvm/include/llvm/ADT/GenericCycleInfo.h
index c3093d4cf83e5..5a414d502225c 100644
--- a/llvm/include/llvm/ADT/GenericCycleInfo.h
+++ b/llvm/include/llvm/ADT/GenericCycleInfo.h
@@ -54,10 +54,6 @@ template <typename ContextT> class GenericCycle {
/// at the root.
GenericCycle *ParentCycle = nullptr;
- /// The top-level cycle this cycle is part of. Points to itself if this is
- /// a top-level cycle.
- GenericCycle *TopLevelCycle;
-
/// The entry block(s) of the cycle. The header is the only entry if
/// this is a loop. Is empty for the root "cycle", to avoid
/// unnecessary memory use.
@@ -108,7 +104,7 @@ template <typename ContextT> class GenericCycle {
GenericCycle &operator=(GenericCycle &&Rhs) = delete;
public:
- GenericCycle() : TopLevelCycle(this) {}
+ GenericCycle() = default;
/// \brief Whether the cycle is a natural loop.
bool isReducible() const { return Entries.size() == 1; }
``````````
</details>
https://github.com/llvm/llvm-project/pull/209677
More information about the llvm-commits
mailing list