[llvm-branch-commits] [llvm] [NewPM] Introduce MFAnalysisGetter for a common analysis getter (PR #116166)

Akshat Oke via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Wed Nov 13 23:25:24 PST 2024


https://github.com/optimisan updated https://github.com/llvm/llvm-project/pull/116166

>From 7e31c7d84a9aa87a226bb9f1341fa4a6bae9e7bb Mon Sep 17 00:00:00 2001
From: Akshat Oke <Akshat.Oke at amd.com>
Date: Thu, 14 Nov 2024 05:57:01 +0000
Subject: [PATCH 1/2] [NewPM] Introduce MFAnalysisGetter for a common analysis
 getter

---
 .../include/llvm/CodeGen/MachinePassManager.h | 78 +++++++++++++++++++
 1 file changed, 78 insertions(+)

diff --git a/llvm/include/llvm/CodeGen/MachinePassManager.h b/llvm/include/llvm/CodeGen/MachinePassManager.h
index 69b5f6e92940c4..e8b7b96240d148 100644
--- a/llvm/include/llvm/CodeGen/MachinePassManager.h
+++ b/llvm/include/llvm/CodeGen/MachinePassManager.h
@@ -24,8 +24,10 @@
 #include "llvm/ADT/FunctionExtras.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/IR/Function.h"
 #include "llvm/IR/PassManager.h"
 #include "llvm/IR/PassManagerInternal.h"
+#include "llvm/Pass.h"
 #include "llvm/Support/Error.h"
 
 namespace llvm {
@@ -236,6 +238,82 @@ using MachineFunctionPassManager = PassManager<MachineFunction>;
 /// preserve.
 PreservedAnalyses getMachineFunctionPassPreservedAnalyses();
 
+/// For migrating to new pass manager
+/// Provides a common interface to fetch analyses instead of doing it twice in
+/// the *LegacyPass::runOnMachineFunction and NPM Pass::run.
+///
+/// NPM analyses must have the LegacyWrapper type to indicate which legacy
+/// analysis to run. Legacy wrapper analyses must have `getResult()` method.
+/// This can be added on a needs-to basis.
+///
+/// Outer analyses passes(Module or Function) can also be requested through
+/// `getAnalysis` or `getCachedAnalysis`.
+class MFAnalysisGetter {
+private:
+  Pass *LegacyPass;
+  MachineFunctionAnalysisManager *MFAM;
+
+  template <typename T>
+  using type_of_run =
+      typename function_traits<decltype(&T::run)>::template arg_t<0>;
+
+  template <typename T>
+  static constexpr bool IsFunctionAnalysis =
+      std::is_same_v<Function, type_of_run<T>>;
+
+  template <typename T>
+  static constexpr bool IsModuleAnalysis =
+      std::is_same_v<Module, type_of_run<T>>;
+
+public:
+  MFAnalysisGetter(Pass *LegacyPass) : LegacyPass(LegacyPass) {}
+  MFAnalysisGetter(MachineFunctionAnalysisManager *MFAM) : MFAM(MFAM) {}
+
+  /// Outer analyses requested from NPM will be cached results and can be null
+  template <typename AnalysisT>
+  typename AnalysisT::Result *getAnalysis(MachineFunction &MF) {
+    if (MFAM) {
+      // need a proxy to get the result for outer analyses
+      // this can return null
+      if constexpr (IsModuleAnalysis<AnalysisT>)
+        return MFAM->getResult<ModuleAnalysisManagerMachineFunctionProxy>(MF)
+            .getCachedResult<AnalysisT>(*MF.getFunction().getParent());
+      else if constexpr (IsFunctionAnalysis<AnalysisT>) {
+        return &MFAM->getResult<FunctionAnalysisManagerMachineFunctionProxy>(MF)
+                    .getManager()
+                    .getResult<AnalysisT>(MF.getFunction());
+      }
+      return &MFAM->getResult<AnalysisT>(MF);
+    }
+    return &LegacyPass->getAnalysis<typename AnalysisT::LegacyWrapper>()
+                .getResult();
+  }
+
+  template <typename AnalysisT>
+  typename AnalysisT::Result *getCachedAnalysis(MachineFunction &MF) {
+    if (MFAM) {
+      if constexpr (IsFunctionAnalysis<AnalysisT>) {
+        return MFAM->getResult<FunctionAnalysisManagerMachineFunctionProxy>(MF)
+            .getManager()
+            .getCachedResult<AnalysisT>(MF.getFunction());
+      } else if constexpr (IsModuleAnalysis<AnalysisT>)
+        return MFAM->getResult<ModuleAnalysisManagerMachineFunctionProxy>(MF)
+            .getCachedResult<AnalysisT>(*MF.getFunction().getParent());
+
+      return &MFAM->getCachedResult<AnalysisT>(MF);
+    }
+
+    if (auto *P =
+            LegacyPass->getAnalysisIfAvailable<AnalysisT::LegacyWrapper>())
+      return &P->getResult();
+    return nullptr;
+  }
+
+  /// This is not intended to be used to invoke getAnalysis()
+  Pass *getLegacyPass() const { return LegacyPass; }
+  MachineFunctionAnalysisManager *getMFAM() const { return MFAM; }
+};
+
 } // end namespace llvm
 
 #endif // LLVM_CODEGEN_MACHINEPASSMANAGER_H

>From 125b82d45358690f146b259b779616d79eccd267 Mon Sep 17 00:00:00 2001
From: Akshat Oke <Akshat.Oke at amd.com>
Date: Thu, 14 Nov 2024 06:49:23 +0000
Subject: [PATCH 2/2] Initialize with null

---
 llvm/include/llvm/CodeGen/MachinePassManager.h | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/MachinePassManager.h b/llvm/include/llvm/CodeGen/MachinePassManager.h
index e8b7b96240d148..bba41ed343f10d 100644
--- a/llvm/include/llvm/CodeGen/MachinePassManager.h
+++ b/llvm/include/llvm/CodeGen/MachinePassManager.h
@@ -250,8 +250,8 @@ PreservedAnalyses getMachineFunctionPassPreservedAnalyses();
 /// `getAnalysis` or `getCachedAnalysis`.
 class MFAnalysisGetter {
 private:
-  Pass *LegacyPass;
-  MachineFunctionAnalysisManager *MFAM;
+  Pass *LegacyPass = nullptr;
+  MachineFunctionAnalysisManager *MFAM = nullptr;
 
   template <typename T>
   using type_of_run =
@@ -259,11 +259,11 @@ class MFAnalysisGetter {
 
   template <typename T>
   static constexpr bool IsFunctionAnalysis =
-      std::is_same_v<Function, type_of_run<T>>;
+      std::is_same_v<Function &, type_of_run<T>>;
 
   template <typename T>
   static constexpr bool IsModuleAnalysis =
-      std::is_same_v<Module, type_of_run<T>>;
+      std::is_same_v<Module &, type_of_run<T>>;
 
 public:
   MFAnalysisGetter(Pass *LegacyPass) : LegacyPass(LegacyPass) {}



More information about the llvm-branch-commits mailing list