[llvm] [PassManager][Loop] Merge loop pass manager when add it (PR #135150)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 16 19:38:15 PDT 2025
https://github.com/paperchalice updated https://github.com/llvm/llvm-project/pull/135150
>From 2867ba7cd413809ad6b1fdaead1fc9400744f680 Mon Sep 17 00:00:00 2001
From: PaperChalice <liujunchang97 at outlook.com>
Date: Sun, 6 Apr 2025 16:34:03 +0800
Subject: [PATCH 1/4] [PassManager][Loop] Merge two loop pass manager when
possible
---
.../llvm/Transforms/Scalar/LoopPassManager.h | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/llvm/include/llvm/Transforms/Scalar/LoopPassManager.h b/llvm/include/llvm/Transforms/Scalar/LoopPassManager.h
index f55022fbff07c..02eb87cbda3db 100644
--- a/llvm/include/llvm/Transforms/Scalar/LoopPassManager.h
+++ b/llvm/include/llvm/Transforms/Scalar/LoopPassManager.h
@@ -130,6 +130,20 @@ class PassManager<Loop, LoopAnalysisManager, LoopStandardAnalysisResults &,
new LoopNestPassModelT(std::forward<PassT>(Pass))));
}
+ LLVM_ATTRIBUTE_MINSIZE
+ void addPass(PassManager &&PM) {
+ std::size_t VecSize = PM.IsLoopNestPass.size();
+ IsLoopNestPass.reserve(IsLoopNestPass.size() + VecSize);
+ for (std::size_t I = 0; I != VecSize; ++I)
+ IsLoopNestPass.push_back(PM.IsLoopNestPass[I]);
+ LoopPasses.insert(LoopPasses.end(),
+ std::make_move_iterator(PM.LoopPasses.begin()),
+ std::make_move_iterator(PM.LoopPasses.end()));
+ LoopNestPasses.insert(LoopNestPasses.end(),
+ std::make_move_iterator(PM.LoopNestPasses.begin()),
+ std::make_move_iterator(PM.LoopNestPasses.end()));
+ }
+
bool isEmpty() const { return LoopPasses.empty() && LoopNestPasses.empty(); }
static bool isRequired() { return true; }
>From 62f897bdac26b7edd9929f083bfb46c9c5b27b8f Mon Sep 17 00:00:00 2001
From: PaperChalice <liujunchang97 at outlook.com>
Date: Fri, 11 Apr 2025 09:33:25 +0800
Subject: [PATCH 2/4] add unit test
---
.../Transforms/Scalar/LoopPassManagerTest.cpp | 30 +++++++++++++++++++
1 file changed, 30 insertions(+)
diff --git a/llvm/unittests/Transforms/Scalar/LoopPassManagerTest.cpp b/llvm/unittests/Transforms/Scalar/LoopPassManagerTest.cpp
index cb3d1001e4110..f1cb9da31c574 100644
--- a/llvm/unittests/Transforms/Scalar/LoopPassManagerTest.cpp
+++ b/llvm/unittests/Transforms/Scalar/LoopPassManagerTest.cpp
@@ -22,6 +22,7 @@
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/PassManager.h"
+#include "llvm/Passes/PassBuilder.h"
#include "llvm/Support/SourceMgr.h"
#include "gmock/gmock.h"
@@ -328,6 +329,21 @@ class LoopPassManagerTest : public ::testing::Test {
}
};
+template<std::size_t Tag, typename MemberPtrT>
+struct PrivateVisitor {
+ inline static MemberPtrT Ptr;
+};
+template<std::size_t Tag, auto MemberPtrV>
+struct PrivateVisitorHelper {
+ struct Assigner {
+ Assigner() {
+ PrivateVisitor<Tag, decltype(MemberPtrV)>::Ptr = MemberPtrV;
+ }
+ };
+ inline static Assigner A;
+};
+template struct PrivateVisitorHelper<0, &LoopPassManager::IsLoopNestPass>;
+
TEST_F(LoopPassManagerTest, Basic) {
ModulePassManager MPM;
::testing::InSequence MakeExpectationsSequenced;
@@ -385,6 +401,20 @@ TEST_F(LoopPassManagerTest, Basic) {
// And now run the pipeline across the module.
MPM.run(*M, MAM);
+
+ // Test pass managers can be merged.
+ {
+ LoopPassManager LPM1, LPM2;
+ LPM1.addPass(NoOpLoopPass());
+ LPM2.addPass(NoOpLoopNestPass());
+ LPM2.addPass(NoOpLoopNestPass());
+ LPM1.addPass(std::move(LPM2));
+ auto &IsLoopNestPass = LPM1.*PrivateVisitor<0, BitVector LoopPassManager::*>::Ptr;
+ EXPECT_EQ(IsLoopNestPass.size(), 3u);
+ BitVector FTT(3, true);
+ FTT[0] = false;
+ EXPECT_EQ(IsLoopNestPass, FTT);
+ }
}
TEST_F(LoopPassManagerTest, FunctionPassInvalidationOfLoopAnalyses) {
>From 4283f919c299fc88fbdb4d931a2f6e6988d76df6 Mon Sep 17 00:00:00 2001
From: PaperChalice <liujunchang97 at outlook.com>
Date: Fri, 11 Apr 2025 09:35:29 +0800
Subject: [PATCH 3/4] address comments
---
.../llvm/Transforms/Scalar/LoopPassManager.h | 4 ++--
.../Transforms/Scalar/LoopPassManagerTest.cpp | 13 +++++--------
2 files changed, 7 insertions(+), 10 deletions(-)
diff --git a/llvm/include/llvm/Transforms/Scalar/LoopPassManager.h b/llvm/include/llvm/Transforms/Scalar/LoopPassManager.h
index 02eb87cbda3db..15edbf39b9c55 100644
--- a/llvm/include/llvm/Transforms/Scalar/LoopPassManager.h
+++ b/llvm/include/llvm/Transforms/Scalar/LoopPassManager.h
@@ -132,9 +132,9 @@ class PassManager<Loop, LoopAnalysisManager, LoopStandardAnalysisResults &,
LLVM_ATTRIBUTE_MINSIZE
void addPass(PassManager &&PM) {
- std::size_t VecSize = PM.IsLoopNestPass.size();
+ size_t VecSize = PM.IsLoopNestPass.size();
IsLoopNestPass.reserve(IsLoopNestPass.size() + VecSize);
- for (std::size_t I = 0; I != VecSize; ++I)
+ for (size_t I = 0; I != VecSize; ++I)
IsLoopNestPass.push_back(PM.IsLoopNestPass[I]);
LoopPasses.insert(LoopPasses.end(),
std::make_move_iterator(PM.LoopPasses.begin()),
diff --git a/llvm/unittests/Transforms/Scalar/LoopPassManagerTest.cpp b/llvm/unittests/Transforms/Scalar/LoopPassManagerTest.cpp
index f1cb9da31c574..d82de715ca525 100644
--- a/llvm/unittests/Transforms/Scalar/LoopPassManagerTest.cpp
+++ b/llvm/unittests/Transforms/Scalar/LoopPassManagerTest.cpp
@@ -329,16 +329,12 @@ class LoopPassManagerTest : public ::testing::Test {
}
};
-template<std::size_t Tag, typename MemberPtrT>
-struct PrivateVisitor {
+template <size_t Tag, typename MemberPtrT> struct PrivateVisitor {
inline static MemberPtrT Ptr;
};
-template<std::size_t Tag, auto MemberPtrV>
-struct PrivateVisitorHelper {
+template <size_t Tag, auto MemberPtrV> struct PrivateVisitorHelper {
struct Assigner {
- Assigner() {
- PrivateVisitor<Tag, decltype(MemberPtrV)>::Ptr = MemberPtrV;
- }
+ Assigner() { PrivateVisitor<Tag, decltype(MemberPtrV)>::Ptr = MemberPtrV; }
};
inline static Assigner A;
};
@@ -409,7 +405,8 @@ TEST_F(LoopPassManagerTest, Basic) {
LPM2.addPass(NoOpLoopNestPass());
LPM2.addPass(NoOpLoopNestPass());
LPM1.addPass(std::move(LPM2));
- auto &IsLoopNestPass = LPM1.*PrivateVisitor<0, BitVector LoopPassManager::*>::Ptr;
+ auto &IsLoopNestPass =
+ LPM1.*PrivateVisitor<0, BitVector LoopPassManager::*>::Ptr;
EXPECT_EQ(IsLoopNestPass.size(), 3u);
BitVector FTT(3, true);
FTT[0] = false;
>From 3f59974bd8b78ba543a173319128f69719e97e8e Mon Sep 17 00:00:00 2001
From: PaperChalice <liujunchang97 at outlook.com>
Date: Thu, 17 Apr 2025 10:37:58 +0800
Subject: [PATCH 4/4] Use range-based for
---
llvm/include/llvm/Transforms/Scalar/LoopPassManager.h | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/llvm/include/llvm/Transforms/Scalar/LoopPassManager.h b/llvm/include/llvm/Transforms/Scalar/LoopPassManager.h
index 15edbf39b9c55..4c4b09a9d03ee 100644
--- a/llvm/include/llvm/Transforms/Scalar/LoopPassManager.h
+++ b/llvm/include/llvm/Transforms/Scalar/LoopPassManager.h
@@ -136,12 +136,10 @@ class PassManager<Loop, LoopAnalysisManager, LoopStandardAnalysisResults &,
IsLoopNestPass.reserve(IsLoopNestPass.size() + VecSize);
for (size_t I = 0; I != VecSize; ++I)
IsLoopNestPass.push_back(PM.IsLoopNestPass[I]);
- LoopPasses.insert(LoopPasses.end(),
- std::make_move_iterator(PM.LoopPasses.begin()),
- std::make_move_iterator(PM.LoopPasses.end()));
- LoopNestPasses.insert(LoopNestPasses.end(),
- std::make_move_iterator(PM.LoopNestPasses.begin()),
- std::make_move_iterator(PM.LoopNestPasses.end()));
+ for (auto &P : PM.LoopPasses)
+ LoopPasses.push_back(std::move(P));
+ for (auto &P : PM.LoopNestPasses)
+ LoopNestPasses.push_back(std::move(P));
}
bool isEmpty() const { return LoopPasses.empty() && LoopNestPasses.empty(); }
More information about the llvm-commits
mailing list