[llvm] [LoopFusion] Return early when no two loops are at the same depth. (PR #226590)
Ehsan Amiri via llvm-commits
llvm-commits at lists.llvm.org
Mon Sep 28 07:46:00 PDT 2026
https://github.com/amehsan updated https://github.com/llvm/llvm-project/pull/226590
>From 118cc423e2222969782005a3acd71a39a76bca68 Mon Sep 17 00:00:00 2001
From: Ehsan Amiri <ehsan.amiri at huawei.com>
Date: Fri, 25 Sep 2026 17:00:07 -0400
Subject: [PATCH 1/3] [LoopFusion] Return early when no two loops are at the
same depth.
If there are no pair of loops who have the same parent, loop fusion is
obviously impossible. But loop fusion will still try to simplify loops
in such a funtion and possibly reconstruct postdom tree. Detecting early and
returning will save us compile time.
Assisted by Claude Code.
---
llvm/lib/Transforms/Scalar/LoopFuse.cpp | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/llvm/lib/Transforms/Scalar/LoopFuse.cpp b/llvm/lib/Transforms/Scalar/LoopFuse.cpp
index 20b05ce6a1302f..461df18c746dfa 100644
--- a/llvm/lib/Transforms/Scalar/LoopFuse.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopFuse.cpp
@@ -1908,10 +1908,21 @@ struct LoopFuser {
return finalizeFusedLoop(FC0, FC1);
}
};
+
+bool hasSiblingLoops(const LoopInfo &LI) {
+ ArrayRef<Loop *> Loops = LI.getTopLevelLoops();
+ while (Loops.size() == 1)
+ Loops = Loops.front()->getSubLoops();
+ return Loops.size() > 1;
+}
+
} // namespace
+
+
PreservedAnalyses LoopFusePass::run(Function &F, FunctionAnalysisManager &AM) {
auto &LI = AM.getResult<LoopAnalysis>(F);
+
auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
auto &DI = AM.getResult<DependenceAnalysis>(F);
auto &SE = AM.getResult<ScalarEvolutionAnalysis>(F);
@@ -1920,6 +1931,9 @@ PreservedAnalyses LoopFusePass::run(Function &F, FunctionAnalysisManager &AM) {
auto &AC = AM.getResult<AssumptionAnalysis>(F);
const TargetTransformInfo &TTI = AM.getResult<TargetIRAnalysis>(F);
+ if (!hasSiblingLoops(LI))
+ return PreservedAnalyses::all();
+
// Ensure loops are in simplifed form which is a pre-requisite for loop fusion
// pass. Added only for new PM since the legacy PM has already added
// LoopSimplify pass as a dependency.
>From 046dfaef7f0dd47483ee1ec2c12df5552504094b Mon Sep 17 00:00:00 2001
From: Ehsan Amiri <ehsan.amiri at huawei.com>
Date: Fri, 25 Sep 2026 23:39:27 -0400
Subject: [PATCH 2/3] remove unnecessary empty lines
---
llvm/lib/Transforms/Scalar/LoopFuse.cpp | 3 ---
1 file changed, 3 deletions(-)
diff --git a/llvm/lib/Transforms/Scalar/LoopFuse.cpp b/llvm/lib/Transforms/Scalar/LoopFuse.cpp
index 461df18c746dfa..23170de329d3ff 100644
--- a/llvm/lib/Transforms/Scalar/LoopFuse.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopFuse.cpp
@@ -1918,11 +1918,8 @@ bool hasSiblingLoops(const LoopInfo &LI) {
} // namespace
-
-
PreservedAnalyses LoopFusePass::run(Function &F, FunctionAnalysisManager &AM) {
auto &LI = AM.getResult<LoopAnalysis>(F);
-
auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
auto &DI = AM.getResult<DependenceAnalysis>(F);
auto &SE = AM.getResult<ScalarEvolutionAnalysis>(F);
>From b0d57880758143613a099ce52c56407a3fb8895b Mon Sep 17 00:00:00 2001
From: Ehsan Amiri <ehsan.amiri at huawei.com>
Date: Mon, 28 Sep 2026 10:45:12 -0400
Subject: [PATCH 3/3] run the check before requesting PDT
---
llvm/lib/Transforms/Scalar/LoopFuse.cpp | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/llvm/lib/Transforms/Scalar/LoopFuse.cpp b/llvm/lib/Transforms/Scalar/LoopFuse.cpp
index 23170de329d3ff..927005dfe1d011 100644
--- a/llvm/lib/Transforms/Scalar/LoopFuse.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopFuse.cpp
@@ -1920,6 +1920,10 @@ bool hasSiblingLoops(const LoopInfo &LI) {
PreservedAnalyses LoopFusePass::run(Function &F, FunctionAnalysisManager &AM) {
auto &LI = AM.getResult<LoopAnalysis>(F);
+
+ if (!hasSiblingLoops(LI))
+ return PreservedAnalyses::all();
+
auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
auto &DI = AM.getResult<DependenceAnalysis>(F);
auto &SE = AM.getResult<ScalarEvolutionAnalysis>(F);
@@ -1927,10 +1931,6 @@ PreservedAnalyses LoopFusePass::run(Function &F, FunctionAnalysisManager &AM) {
auto &ORE = AM.getResult<OptimizationRemarkEmitterAnalysis>(F);
auto &AC = AM.getResult<AssumptionAnalysis>(F);
const TargetTransformInfo &TTI = AM.getResult<TargetIRAnalysis>(F);
-
- if (!hasSiblingLoops(LI))
- return PreservedAnalyses::all();
-
// Ensure loops are in simplifed form which is a pre-requisite for loop fusion
// pass. Added only for new PM since the legacy PM has already added
// LoopSimplify pass as a dependency.
More information about the llvm-commits
mailing list