[Stream] Fix O(N²) compile-time scaling in partitionRegionConcurrency (#24958) When analyzing execution regions where many operations share a common resource operand, `partitionRegionConcurrencyReference` previously invoked `tiedOp.hasAnyTiedUses(operand)` inside the `operand.getUsers()` loop. Because checking whether an operand has tied uses involves scanning its use sites, repeating this check inside the loop caused quadratic $O(N^2)$ traversal over the users of that operand. This change hoists the check out of the loop using the static helper `IREE::Util::TiedOpInterface::hasAnyTiedUses(operand)` as an early exit. Inside the loop, it now only checks whether the candidate user implements `TiedOpInterface`. This eliminates redundant scans and resolves the compiler performance bottleneck while preserving existing partitioning semantics. Fixes #24928 Signed-off-by: @isa-Lai Assisted-by: Gemini CLI Signed-off-by: isa-lai <isabellai1004@gmail.com>
diff --git a/compiler/src/iree/compiler/Dialect/Stream/Analysis/Partitioning/ReferencePartitioning.cpp b/compiler/src/iree/compiler/Dialect/Stream/Analysis/Partitioning/ReferencePartitioning.cpp index 12f4a03..d8764cb 100644 --- a/compiler/src/iree/compiler/Dialect/Stream/Analysis/Partitioning/ReferencePartitioning.cpp +++ b/compiler/src/iree/compiler/Dialect/Stream/Analysis/Partitioning/ReferencePartitioning.cpp
@@ -767,13 +767,16 @@ if (!isa<IREE::Stream::ResourceType>(operand.getType())) { continue; } + if (!IREE::Util::TiedOpInterface::hasAnyTiedUses(operand)) { + continue; + } for (auto user : operand.getUsers()) { if (user == &op || user->getBlock() != block || user->isBeforeInBlock(&op)) { continue; } auto tiedOp = dyn_cast<IREE::Util::TiedOpInterface>(user); - if (!tiedOp || !tiedOp.hasAnyTiedUses(operand)) { + if (!tiedOp) { continue; } auto userInfoIt = opInfos.find(user);