[Mlir-commits] [mlir] [mlir][affine][NFC] Add visited set to hasDependencePath (PR #199011)
Mehdi Amini
llvmlistbot at llvm.org
Wed May 27 01:55:28 PDT 2026
https://github.com/joker-eph updated https://github.com/llvm/llvm-project/pull/199011
>From a27a5ba56d37365c3bb173e131f90e1d7976fafc Mon Sep 17 00:00:00 2001
From: Ryan Kim <chokobole33 at gmail.com>
Date: Thu, 21 May 2026 18:55:03 +0900
Subject: [PATCH] [mlir][affine][NFC] Add visited set to hasDependencePath
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
`MemRefDependenceGraph::hasDependencePath` does a DFS with no visited
set. The MDG is a DAG, so every diamond merge re-walks the paths
through it — worst case `O(2^V)` in node count, which is enough for
`affine-loop-fusion` to hang at 99% CPU on workloads with many
independent memref accesses on one buffer between several `affine.for`
loops.
Gate each per-edge push on `visited.insert(edge.id).second` so each
node is pushed at most once. Worst case becomes `O(V + E)`; the
returned answer is unchanged because every reachable node is still
visited at least once.
---
mlir/lib/Dialect/Affine/Analysis/Utils.cpp | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/mlir/lib/Dialect/Affine/Analysis/Utils.cpp b/mlir/lib/Dialect/Affine/Analysis/Utils.cpp
index ebe932a14694a..5ede347df4354 100644
--- a/mlir/lib/Dialect/Affine/Analysis/Utils.cpp
+++ b/mlir/lib/Dialect/Affine/Analysis/Utils.cpp
@@ -574,6 +574,9 @@ bool MemRefDependenceGraph::hasDependencePath(unsigned srcId,
SmallVector<std::pair<unsigned, unsigned>, 4> worklist;
worklist.push_back({srcId, 0});
Operation *dstOp = getNode(dstId)->op;
+ // Track nodes already pushed onto the worklist to avoid redundant visit.
+ DenseSet<unsigned> visited;
+ visited.insert(srcId);
// Run DFS traversal to see if 'dstId' is reachable from 'srcId'.
while (!worklist.empty()) {
auto &idAndIndex = worklist.back();
@@ -595,7 +598,8 @@ bool MemRefDependenceGraph::hasDependencePath(unsigned srcId,
// nodes that are "after" dstId in the containing block; one can't have a
// path to `dstId` from any of those nodes.
bool afterDst = dstOp->isBeforeInBlock(getNode(edge.id)->op);
- if (!afterDst && edge.id != idAndIndex.first)
+ if (!afterDst && edge.id != idAndIndex.first &&
+ visited.insert(edge.id).second)
worklist.push_back({edge.id, 0});
}
return false;
More information about the Mlir-commits
mailing list