[llvm] [CycleInfo] Drop GraphTraits and df_iterator. NFC (PR #209847)
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Wed Jul 15 18:50:45 PDT 2026
https://github.com/MaskRay updated https://github.com/llvm/llvm-project/pull/209847
>From e2d5783f57eff289a947f09173e024cc7d7be66d Mon Sep 17 00:00:00 2001
From: Fangrui Song <i at maskray.me>
Date: Wed, 15 Jul 2026 10:58:21 -0700
Subject: [PATCH 1/2] [CycleInfo] Drop GraphTraits and df_iterator. NFC
depth_first uses SmallPtrSet visited-set, which is pure overhead on a
tree. Replace them with explicit child-stack walks and delete the unused
GraphTraits specializations to prevent misuse.
---
llvm/include/llvm/ADT/GenericCycleImpl.h | 46 ++++++++++++--------
llvm/include/llvm/ADT/GenericCycleInfo.h | 44 -------------------
llvm/lib/Transforms/Utils/FixIrreducible.cpp | 7 ++-
3 files changed, 35 insertions(+), 62 deletions(-)
diff --git a/llvm/include/llvm/ADT/GenericCycleImpl.h b/llvm/include/llvm/ADT/GenericCycleImpl.h
index 8196912a23cd3..9f83efc2aa946 100644
--- a/llvm/include/llvm/ADT/GenericCycleImpl.h
+++ b/llvm/include/llvm/ADT/GenericCycleImpl.h
@@ -485,8 +485,13 @@ void GenericCycleInfoCompute<ContextT>::run(FunctionT *F) {
/// \brief Recompute depth values of \p SubTree and all descendants.
template <typename ContextT>
void GenericCycleInfoCompute<ContextT>::updateDepth(CycleT *SubTree) {
- for (CycleT *Cycle : depth_first(SubTree))
+ SmallVector<CycleT *, 8> Worklist = {SubTree};
+ while (!Worklist.empty()) {
+ CycleT *Cycle = Worklist.pop_back_val();
Cycle->Depth = Cycle->ParentCycle ? Cycle->ParentCycle->Depth + 1 : 1;
+ for (CycleT *Child : Cycle->children())
+ Worklist.push_back(Child);
+ }
}
/// \brief Compute a DFS of basic blocks starting at the function entry.
@@ -634,21 +639,23 @@ void GenericCycleInfo<ContextT>::verifyCycleNest(bool VerifyFull) const {
#ifndef NDEBUG
DenseSet<BlockT *> CycleHeaders;
- for (CycleT *TopCycle : toplevel_cycles()) {
- for (CycleT *Cycle : depth_first(TopCycle)) {
- BlockT *Header = Cycle->getHeader();
- assert(CycleHeaders.insert(Header).second);
- if (VerifyFull)
- verifyCycle(*Cycle);
- else
- verifyCycleNest(*Cycle);
- // Check the block map entries for blocks contained in this cycle.
- for (BlockT *BB : getBlocks(*Cycle)) {
- CycleT *CycleInBlockMap = getCycle(BB);
- assert(CycleInBlockMap != nullptr);
- assert(Cycle->contains(CycleInBlockMap));
- }
+ SmallVector<CycleT *, 8> Worklist(toplevel_begin(), toplevel_end());
+ while (!Worklist.empty()) {
+ CycleT *Cycle = Worklist.pop_back_val();
+ BlockT *Header = Cycle->getHeader();
+ assert(CycleHeaders.insert(Header).second);
+ if (VerifyFull)
+ verifyCycle(*Cycle);
+ else
+ verifyCycleNest(*Cycle);
+ // Check the block map entries for blocks contained in this cycle.
+ for (BlockT *BB : getBlocks(*Cycle)) {
+ CycleT *CycleInBlockMap = getCycle(BB);
+ assert(CycleInBlockMap != nullptr);
+ assert(Cycle->contains(CycleInBlockMap));
}
+ for (CycleT *Child : Cycle->children())
+ Worklist.push_back(Child);
}
#endif
}
@@ -661,12 +668,17 @@ template <typename ContextT> void GenericCycleInfo<ContextT>::verify() const {
/// \brief Print the cycle info.
template <typename ContextT>
void GenericCycleInfo<ContextT>::print(raw_ostream &Out) const {
- for (const auto *TLC : toplevel_cycles()) {
- for (const CycleT *Cycle : depth_first(TLC)) {
+ SmallVector<const CycleT *, 8> Stack;
+ for (const CycleT *TLC : toplevel_cycles()) {
+ Stack.push_back(TLC);
+ while (!Stack.empty()) {
+ const CycleT *Cycle = Stack.pop_back_val();
for (unsigned I = 0; I < Cycle->Depth; ++I)
Out << " ";
Out << print(Cycle) << '\n';
+ for (const auto &Child : reverse(Cycle->Children))
+ Stack.push_back(Child.get());
}
}
}
diff --git a/llvm/include/llvm/ADT/GenericCycleInfo.h b/llvm/include/llvm/ADT/GenericCycleInfo.h
index e67f9f0939fd9..448f2fa2db127 100644
--- a/llvm/include/llvm/ADT/GenericCycleInfo.h
+++ b/llvm/include/llvm/ADT/GenericCycleInfo.h
@@ -351,50 +351,6 @@ template <typename ContextT> class GenericCycleInfo {
//@}
};
-/// \brief GraphTraits for iterating over a sub-tree of the CycleT tree.
-template <typename CycleRefT, typename ChildIteratorT> struct CycleGraphTraits {
- using NodeRef = CycleRefT;
-
- using nodes_iterator = ChildIteratorT;
- using ChildIteratorType = nodes_iterator;
-
- static NodeRef getEntryNode(NodeRef Graph) { return Graph; }
-
- static ChildIteratorType child_begin(NodeRef Ref) {
- return Ref->child_begin();
- }
- static ChildIteratorType child_end(NodeRef Ref) { return Ref->child_end(); }
-
- // Not implemented:
- // static nodes_iterator nodes_begin(GraphType *G)
- // static nodes_iterator nodes_end (GraphType *G)
- // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
-
- // typedef EdgeRef - Type of Edge token in the graph, which should
- // be cheap to copy.
- // typedef ChildEdgeIteratorType - Type used to iterate over children edges in
- // graph, dereference to a EdgeRef.
-
- // static ChildEdgeIteratorType child_edge_begin(NodeRef)
- // static ChildEdgeIteratorType child_edge_end(NodeRef)
- // Return iterators that point to the beginning and ending of the
- // edge list for the given callgraph node.
- //
- // static NodeRef edge_dest(EdgeRef)
- // Return the destination node of an edge.
- // static unsigned size (GraphType *G)
- // Return total number of nodes in the graph
-};
-
-template <typename BlockT>
-struct GraphTraits<const GenericCycle<BlockT> *>
- : CycleGraphTraits<const GenericCycle<BlockT> *,
- typename GenericCycle<BlockT>::const_child_iterator> {};
-template <typename BlockT>
-struct GraphTraits<GenericCycle<BlockT> *>
- : CycleGraphTraits<GenericCycle<BlockT> *,
- typename GenericCycle<BlockT>::const_child_iterator> {};
-
} // namespace llvm
#endif // LLVM_ADT_GENERICCYCLEINFO_H
diff --git a/llvm/lib/Transforms/Utils/FixIrreducible.cpp b/llvm/lib/Transforms/Utils/FixIrreducible.cpp
index 087515122bada..9ef0eedcad887 100644
--- a/llvm/lib/Transforms/Utils/FixIrreducible.cpp
+++ b/llvm/lib/Transforms/Utils/FixIrreducible.cpp
@@ -429,9 +429,14 @@ static bool FixIrreducibleImpl(Function &F, CycleInfo &CI, DominatorTree &DT,
<< F.getName() << "\n");
bool Changed = false;
+ SmallVector<Cycle *, 8> Worklist;
for (Cycle *TopCycle : CI.toplevel_cycles()) {
- for (Cycle *C : depth_first(TopCycle)) {
+ Worklist.push_back(TopCycle);
+ while (!Worklist.empty()) {
+ Cycle *C = Worklist.pop_back_val();
Changed |= fixIrreducible(*C, CI, DT, LI);
+ SmallVector<Cycle *, 4> Children(C->child_begin(), C->child_end());
+ Worklist.append(Children.rbegin(), Children.rend());
}
}
>From d7d5fd4867c1ce258580d4475746ab6e5eeb7da1 Mon Sep 17 00:00:00 2001
From: Fangrui Song <i at maskray.me>
Date: Wed, 15 Jul 2026 18:50:34 -0700
Subject: [PATCH 2/2] update iterator type; use reverse(children)
---
llvm/include/llvm/ADT/GenericCycleInfo.h | 8 ++++++--
llvm/lib/Transforms/Utils/FixIrreducible.cpp | 3 +--
2 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/llvm/include/llvm/ADT/GenericCycleInfo.h b/llvm/include/llvm/ADT/GenericCycleInfo.h
index 448f2fa2db127..96b5fb1f4e66a 100644
--- a/llvm/include/llvm/ADT/GenericCycleInfo.h
+++ b/llvm/include/llvm/ADT/GenericCycleInfo.h
@@ -130,9 +130,13 @@ template <typename ContextT> class GenericCycle {
using const_child_iterator_base =
typename std::vector<std::unique_ptr<GenericCycle>>::const_iterator;
struct const_child_iterator
- : iterator_adaptor_base<const_child_iterator, const_child_iterator_base> {
+ : iterator_adaptor_base<const_child_iterator, const_child_iterator_base,
+ std::random_access_iterator_tag, GenericCycle *,
+ std::ptrdiff_t, GenericCycle *, GenericCycle *> {
using Base =
- iterator_adaptor_base<const_child_iterator, const_child_iterator_base>;
+ iterator_adaptor_base<const_child_iterator, const_child_iterator_base,
+ std::random_access_iterator_tag, GenericCycle *,
+ std::ptrdiff_t, GenericCycle *, GenericCycle *>;
const_child_iterator() = default;
explicit const_child_iterator(const_child_iterator_base I) : Base(I) {}
diff --git a/llvm/lib/Transforms/Utils/FixIrreducible.cpp b/llvm/lib/Transforms/Utils/FixIrreducible.cpp
index 9ef0eedcad887..81feb34eb953d 100644
--- a/llvm/lib/Transforms/Utils/FixIrreducible.cpp
+++ b/llvm/lib/Transforms/Utils/FixIrreducible.cpp
@@ -435,8 +435,7 @@ static bool FixIrreducibleImpl(Function &F, CycleInfo &CI, DominatorTree &DT,
while (!Worklist.empty()) {
Cycle *C = Worklist.pop_back_val();
Changed |= fixIrreducible(*C, CI, DT, LI);
- SmallVector<Cycle *, 4> Children(C->child_begin(), C->child_end());
- Worklist.append(Children.rbegin(), Children.rend());
+ llvm::append_range(Worklist, reverse(C->children()));
}
}
More information about the llvm-commits
mailing list