[llvm] [PassManager][Loop] Merge loop pass manager when add it (PR #135150)

via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 15 22:23:21 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 4b614f3f1e897ec7b1581f4f91084b58376bdf94 Mon Sep 17 00:00:00 2001
From: PaperChalice <liujunchang97 at outlook.com>
Date: Wed, 16 Apr 2025 13:23:05 +0800
Subject: [PATCH 4/4] Use llvm::append_range

---
 llvm/include/llvm/Transforms/Scalar/LoopPassManager.h | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/llvm/include/llvm/Transforms/Scalar/LoopPassManager.h b/llvm/include/llvm/Transforms/Scalar/LoopPassManager.h
index 15edbf39b9c55..96820b9ebc3a7 100644
--- a/llvm/include/llvm/Transforms/Scalar/LoopPassManager.h
+++ b/llvm/include/llvm/Transforms/Scalar/LoopPassManager.h
@@ -136,12 +136,8 @@ 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()));
+    llvm::append_range(LoopPasses, std::move(PM.LoopPasses));
+    llvm::append_range(LoopNestPasses, std::move(PM.LoopNestPasses));
   }
 
   bool isEmpty() const { return LoopPasses.empty() && LoopNestPasses.empty(); }



More information about the llvm-commits mailing list