[llvm] [NewPM/Codegen] Move MachineModuleInfo ownership outside of analysis (PR #80937)

Arthur Eubanks via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 6 21:13:23 PST 2024


https://github.com/aeubanks created https://github.com/llvm/llvm-project/pull/80937

With the legacy pass manager, MachineModuleInfoWrapperPass owned the MachineModuleInfo used in the codegen pipeline. It can do this since it's an ImmutablePass that doesn't get invalidated.

However, with the new pass manager, it is legal for the ModuleAnalysisManager to clear all of its analyses, regardless of if the analysis does not want to be invalidated. So we must move ownership of the MachineModuleInfo outside of the analysis (this is similar to PassInstrumentation). For now, make the PassBuilder user register a MachineModuleAnalysis that returns a reference to a MachineModuleInfo that the user owns. Perhaps we can find a better place to own the MachineModuleInfo to make using the codegen pass manager less cumbersome in the future.

>From d2418e220b738e6c8191a5c0dc5c8a0634237a5b Mon Sep 17 00:00:00 2001
From: Arthur Eubanks <aeubanks at google.com>
Date: Fri, 2 Feb 2024 04:06:28 +0000
Subject: [PATCH] [NewPM/Codegen] Move MachineModuleInfo ownership outside of
 analysis

With the legacy pass manager, MachineModuleInfoWrapperPass owned the
MachineModuleInfo used in the codegen pipeline. It can do this since
it's an ImmutablePass that doesn't get invalidated.

However, with the new pass manager, it is legal for the
ModuleAnalysisManager to clear all of its analyses, regardless of if the
analysis does not want to be invalidated. So we must move ownership of
the MachineModuleInfo outside of the analysis (this is similar to
PassInstrumentation). For now, make the PassBuilder user
register a MachineModuleAnalysis that returns a reference to a
MachineModuleInfo that the user owns.
---
 llvm/include/llvm/CodeGen/MachineModuleInfo.h | 22 ++++++++++++++-----
 llvm/lib/CodeGen/MachineModuleInfo.cpp        | 11 +++++-----
 llvm/lib/CodeGen/MachinePassManager.cpp       |  2 +-
 llvm/tools/llc/NewPMDriver.cpp                |  6 +++--
 llvm/unittests/CodeGen/PassManagerTest.cpp    |  8 ++++---
 .../MIR/PassBuilderCallbacksTest.cpp          |  7 +++---
 6 files changed, 35 insertions(+), 21 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/MachineModuleInfo.h b/llvm/include/llvm/CodeGen/MachineModuleInfo.h
index 4f0ada3d7e17a..08fc8542a4eeb 100644
--- a/llvm/include/llvm/CodeGen/MachineModuleInfo.h
+++ b/llvm/include/llvm/CodeGen/MachineModuleInfo.h
@@ -218,21 +218,31 @@ class MachineModuleInfoWrapperPass : public ImmutablePass {
   const MachineModuleInfo &getMMI() const { return MMI; }
 };
 
-/// An analysis that produces \c MachineInfo for a module.
+/// An analysis that produces \c MachineModuleInfo for a module.
+/// This does not produce its own MachineModuleInfo because we need a consistent
+/// MachineModuleInfo to keep ownership of MachineFunctions regardless of
+/// analysis invalidation/clearing. So something outside the analysis
+/// infrastructure must own the MachineModuleInfo.
 class MachineModuleAnalysis : public AnalysisInfoMixin<MachineModuleAnalysis> {
   friend AnalysisInfoMixin<MachineModuleAnalysis>;
   static AnalysisKey Key;
 
-  const LLVMTargetMachine *TM;
+  MachineModuleInfo &MMI;
 
 public:
-  /// Provide the result type for this analysis pass.
-  using Result = MachineModuleInfo;
+  class Result {
+    MachineModuleInfo &MMI;
+    Result(MachineModuleInfo &MMI) : MMI(MMI) {}
+    friend class MachineModuleAnalysis;
 
-  MachineModuleAnalysis(const LLVMTargetMachine *TM) : TM(TM) {}
+  public:
+    MachineModuleInfo &getMMI() { return MMI; }
+  };
+
+  MachineModuleAnalysis(MachineModuleInfo &MMI) : MMI(MMI) {}
 
   /// Run the analysis pass and produce machine module information.
-  MachineModuleInfo run(Module &M, ModuleAnalysisManager &);
+  Result run(Module &M, ModuleAnalysisManager &);
 };
 
 } // end namespace llvm
diff --git a/llvm/lib/CodeGen/MachineModuleInfo.cpp b/llvm/lib/CodeGen/MachineModuleInfo.cpp
index 921feb253d642..f24288bb69de0 100644
--- a/llvm/lib/CodeGen/MachineModuleInfo.cpp
+++ b/llvm/lib/CodeGen/MachineModuleInfo.cpp
@@ -237,11 +237,10 @@ bool MachineModuleInfoWrapperPass::doFinalization(Module &M) {
 
 AnalysisKey MachineModuleAnalysis::Key;
 
-MachineModuleInfo MachineModuleAnalysis::run(Module &M,
-                                             ModuleAnalysisManager &) {
-  MachineModuleInfo MMI(TM);
+MachineModuleAnalysis::Result
+MachineModuleAnalysis::run(Module &M, ModuleAnalysisManager &) {
   MMI.TheModule = &M;
-  MMI.DbgInfoAvailable = !DisableDebugInfoPrinting &&
-                         !M.debug_compile_units().empty();
-  return MMI;
+  MMI.DbgInfoAvailable =
+      !DisableDebugInfoPrinting && !M.debug_compile_units().empty();
+  return Result(MMI);
 }
diff --git a/llvm/lib/CodeGen/MachinePassManager.cpp b/llvm/lib/CodeGen/MachinePassManager.cpp
index 0770eba660b45..2d9b7980c1085 100644
--- a/llvm/lib/CodeGen/MachinePassManager.cpp
+++ b/llvm/lib/CodeGen/MachinePassManager.cpp
@@ -29,7 +29,7 @@ Error MachineFunctionPassManager::run(Module &M,
   // because we don't run any module pass in codegen pipeline. This is very
   // important because the codegen state is stored in MMI which is the analysis
   // result of MachineModuleAnalysis. MMI should not be recomputed.
-  auto &MMI = MFAM.getResult<MachineModuleAnalysis>(M);
+  auto &MMI = MFAM.getResult<MachineModuleAnalysis>(M).getMMI();
 
   (void)RequireCodeGenSCCOrder;
   assert(!RequireCodeGenSCCOrder && "not implemented");
diff --git a/llvm/tools/llc/NewPMDriver.cpp b/llvm/tools/llc/NewPMDriver.cpp
index 17ce77d6034de..e41f2d013855d 100644
--- a/llvm/tools/llc/NewPMDriver.cpp
+++ b/llvm/tools/llc/NewPMDriver.cpp
@@ -147,6 +147,8 @@ int llvm::compileModuleWithNewPM(
   Opt.DebugPM = DebugPM;
   Opt.RegAlloc = RegAlloc;
 
+  MachineModuleInfo MMI(&LLVMTM);
+
   PassInstrumentationCallbacks PIC;
   StandardInstrumentations SI(Context, Opt.DebugPM);
   SI.registerCallbacks(PIC);
@@ -164,7 +166,7 @@ int llvm::compileModuleWithNewPM(
   PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
 
   FAM.registerPass([&] { return TargetLibraryAnalysis(TLII); });
-  MAM.registerPass([&] { return MachineModuleAnalysis(&LLVMTM); });
+  MAM.registerPass([&] { return MachineModuleAnalysis(MMI); });
 
   MachineFunctionAnalysisManager MFAM(FAM, MAM);
 
@@ -185,7 +187,7 @@ int llvm::compileModuleWithNewPM(
     MFPM.addPass(PrintMIRPass(*OS));
     MFPM.addPass(FreeMachineFunctionPass());
 
-    auto &MMI = MFAM.getResult<MachineModuleAnalysis>(*M);
+    auto &MMI = MFAM.getResult<MachineModuleAnalysis>(*M).getMMI();
     if (MIR->parseMachineFunctions(*M, MMI))
       return 1;
 
diff --git a/llvm/unittests/CodeGen/PassManagerTest.cpp b/llvm/unittests/CodeGen/PassManagerTest.cpp
index 4d2c8b7bdb5f4..28003c2f4b3f1 100644
--- a/llvm/unittests/CodeGen/PassManagerTest.cpp
+++ b/llvm/unittests/CodeGen/PassManagerTest.cpp
@@ -118,7 +118,8 @@ struct TestMachineFunctionPass : public PassInfoMixin<TestMachineFunctionPass> {
 
     // Query module analysis result.
     MachineModuleInfo &MMI =
-        MFAM.getResult<MachineModuleAnalysis>(*MF.getFunction().getParent());
+        MFAM.getResult<MachineModuleAnalysis>(*MF.getFunction().getParent())
+            .getMMI();
     // 1 + 1 + 1 = 3
     Count += (MMI.getModule() == MF.getFunction().getParent());
 
@@ -144,7 +145,7 @@ struct TestMachineModulePass : public PassInfoMixin<TestMachineModulePass> {
       : Count(Count), MachineModulePassCount(MachineModulePassCount) {}
 
   Error run(Module &M, MachineFunctionAnalysisManager &MFAM) {
-    MachineModuleInfo &MMI = MFAM.getResult<MachineModuleAnalysis>(M);
+    MachineModuleInfo &MMI = MFAM.getResult<MachineModuleAnalysis>(M).getMMI();
     // + 1
     Count += (MMI.getModule() == &M);
     MachineModulePassCount.push_back(Count);
@@ -209,6 +210,7 @@ TEST_F(PassManagerTest, Basic) {
   LLVMTargetMachine *LLVMTM = static_cast<LLVMTargetMachine *>(TM.get());
   M->setDataLayout(TM->createDataLayout());
 
+  MachineModuleInfo MMI(LLVMTM);
   LoopAnalysisManager LAM;
   FunctionAnalysisManager FAM;
   CGSCCAnalysisManager CGAM;
@@ -220,7 +222,7 @@ TEST_F(PassManagerTest, Basic) {
 
   FAM.registerPass([&] { return TestFunctionAnalysis(); });
   FAM.registerPass([&] { return PassInstrumentationAnalysis(); });
-  MAM.registerPass([&] { return MachineModuleAnalysis(LLVMTM); });
+  MAM.registerPass([&] { return MachineModuleAnalysis(MMI); });
   MAM.registerPass([&] { return PassInstrumentationAnalysis(); });
 
   MachineFunctionAnalysisManager MFAM;
diff --git a/llvm/unittests/MIR/PassBuilderCallbacksTest.cpp b/llvm/unittests/MIR/PassBuilderCallbacksTest.cpp
index 0527d720f85f7..8ecde223cb510 100644
--- a/llvm/unittests/MIR/PassBuilderCallbacksTest.cpp
+++ b/llvm/unittests/MIR/PassBuilderCallbacksTest.cpp
@@ -298,6 +298,7 @@ class MachineFunctionCallbacksTest : public testing::Test {
   }
 
   std::unique_ptr<LLVMTargetMachine> TM;
+  std::unique_ptr<MachineModuleInfo> MMI;
 
   LLVMContext Context;
   std::unique_ptr<Module> M;
@@ -355,9 +356,9 @@ class MachineFunctionCallbacksTest : public testing::Test {
             TripleName, "", "", TargetOptions(), std::nullopt)));
     if (!TM)
       GTEST_SKIP();
-    MachineModuleInfo MMI(TM.get());
-    M = parseMIR(*TM, MIRString, MMI);
-    AM.registerPass([&] { return MachineModuleAnalysis(TM.get()); });
+    MMI = std::make_unique<MachineModuleInfo>(TM.get());
+    M = parseMIR(*TM, MIRString, *MMI);
+    AM.registerPass([&] { return MachineModuleAnalysis(*MMI); });
   }
 
   MachineFunctionCallbacksTest()



More information about the llvm-commits mailing list