[llvm] [NewPM][Instrumentation] Support `MachineOptimizationRemarkEmitter` (PR #90563)

via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 29 23:40:32 PDT 2024


https://github.com/paperchalice updated https://github.com/llvm/llvm-project/pull/90563

>From 1c8f86283d212aa9eeda06c6ce90a6d98029242f Mon Sep 17 00:00:00 2001
From: PaperChalice <liujunchang97 at outlook.com>
Date: Tue, 30 Apr 2024 13:37:39 +0800
Subject: [PATCH] [NewPM][Instrumentation] Support
 `MachineOptimizationRemarkEmitter` in instrumentation Port size remark
 emitter part to instrumentation. It supports both machine module pass and
 machine function pass, so we can remove the workaround in `MachineOutliner`
 in future.

---
 llvm/include/llvm/IR/Module.h                 |   2 +-
 .../llvm/Passes/StandardInstrumentations.h    |   7 +
 llvm/lib/Passes/StandardInstrumentations.cpp  | 138 +++++++++++++++++-
 .../tools/llc/new-pm/size-remark-emitter.mir  |  44 ++++++
 llvm/tools/llc/NewPMDriver.cpp                |   2 +-
 llvm/tools/opt/NewPMDriver.cpp                |   3 +-
 6 files changed, 192 insertions(+), 4 deletions(-)
 create mode 100644 llvm/test/tools/llc/new-pm/size-remark-emitter.mir

diff --git a/llvm/include/llvm/IR/Module.h b/llvm/include/llvm/IR/Module.h
index 6135e15fd030f7..855ec4561208bd 100644
--- a/llvm/include/llvm/IR/Module.h
+++ b/llvm/include/llvm/IR/Module.h
@@ -317,7 +317,7 @@ class LLVM_EXTERNAL_VISIBILITY Module {
 
   /// Return true if size-info optimization remark is enabled, false
   /// otherwise.
-  bool shouldEmitInstrCountChangedRemark() {
+  bool shouldEmitInstrCountChangedRemark() const {
     return getContext().getDiagHandlerPtr()->isAnalysisRemarkEnabled(
         "size-info");
   }
diff --git a/llvm/include/llvm/Passes/StandardInstrumentations.h b/llvm/include/llvm/Passes/StandardInstrumentations.h
index 84d1b541171bf1..8d44d140290c91 100644
--- a/llvm/include/llvm/Passes/StandardInstrumentations.h
+++ b/llvm/include/llvm/Passes/StandardInstrumentations.h
@@ -577,6 +577,12 @@ class PrintCrashIRInstrumentation {
   static void SignalHandler(void *);
 };
 
+class InstrCountChangedReporter {
+public:
+  void registerCallbacks(PassInstrumentationCallbacks &PIC,
+                         ModuleAnalysisManager &MAM);
+};
+
 /// This class provides an interface to register all the standard pass
 /// instrumentations and manages their state (if any).
 class StandardInstrumentations {
@@ -594,6 +600,7 @@ class StandardInstrumentations {
   PrintCrashIRInstrumentation PrintCrashIR;
   IRChangedTester ChangeTester;
   VerifyInstrumentation Verify;
+  InstrCountChangedReporter EmitMFSizeRemarks;
 
   bool VerifyEach;
 
diff --git a/llvm/lib/Passes/StandardInstrumentations.cpp b/llvm/lib/Passes/StandardInstrumentations.cpp
index 63490c83e85f05..49bd00c31a6720 100644
--- a/llvm/lib/Passes/StandardInstrumentations.cpp
+++ b/llvm/lib/Passes/StandardInstrumentations.cpp
@@ -19,9 +19,13 @@
 #include "llvm/Analysis/CallGraphSCCPass.h"
 #include "llvm/Analysis/LazyCallGraph.h"
 #include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Analysis/OptimizationRemarkEmitter.h"
 #include "llvm/CodeGen/MIRPrinter.h"
 #include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineFunctionAnalysis.h"
 #include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
+#include "llvm/CodeGen/MachinePassManager.h"
 #include "llvm/IR/Constants.h"
 #include "llvm/IR/Function.h"
 #include "llvm/IR/Module.h"
@@ -48,6 +52,7 @@
 #include <vector>
 
 using namespace llvm;
+using namespace ore;
 
 static cl::opt<bool> VerifyAnalysisInvalidation("verify-analysis-invalidation",
                                                 cl::Hidden,
@@ -374,6 +379,14 @@ bool isInteresting(Any IR, StringRef PassID, StringRef PassName) {
   return true;
 }
 
+bool isMachineModulePass(StringRef PassID) {
+#define MACHINE_MODULE_PASS(NAME, CREATE_PASS)                                 \
+  if (PassID == std::remove_reference_t<decltype(CREATE_PASS)>::name())        \
+    return true;
+#include "llvm/Passes/MachinePassRegistry.def"
+  return false;
+}
+
 } // namespace
 
 template <typename T> ChangeReporter<T>::~ChangeReporter() {
@@ -1329,6 +1342,49 @@ struct PreservedModuleHashAnalysis
 
 AnalysisKey PreservedModuleHashAnalysis::Key;
 
+struct MachineInstrCounterAnalysis
+    : public AnalysisInfoMixin<MachineInstrCounterAnalysis> {
+  static AnalysisKey Key;
+
+  struct Result {
+    bool invalidate(MachineFunction &MF, const PreservedAnalyses &,
+                    MachineFunctionAnalysisManager::Invalidator &) {
+      return false;
+    }
+
+    void emitRemark(MachineFunction &MF, StringRef PassID) {
+      CountAfter = MF.getInstructionCount();
+      if (CountBefore == CountAfter)
+        return;
+
+      MachineOptimizationRemarkEmitter MORE(MF, nullptr);
+      MORE.emit([&]() {
+        int64_t Delta = static_cast<int64_t>(CountAfter) -
+                        static_cast<int64_t>(CountBefore);
+        MachineOptimizationRemarkAnalysis R("size-info", "FunctionMISizeChange",
+                                            MF.getFunction().getSubprogram(),
+                                            &MF.front());
+        R << NV("Pass", PassID)
+          << ": Function: " << NV("Function", MF.getName()) << ": "
+          << "MI Instruction count changed from "
+          << NV("MIInstrsBefore", CountBefore) << " to "
+          << NV("MIInstrsAfter", CountAfter)
+          << "; Delta: " << NV("Delta", Delta);
+        return R;
+      });
+    }
+
+    unsigned CountBefore = 0;
+    unsigned CountAfter = 0;
+  };
+
+  Result run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM) {
+    return Result();
+  }
+};
+
+AnalysisKey MachineInstrCounterAnalysis::Key;
+
 bool PreservedCFGCheckerInstrumentation::CFG::invalidate(
     Function &F, const PreservedAnalyses &PA,
     FunctionAnalysisManager::Invalidator &) {
@@ -2493,6 +2549,84 @@ void PrintCrashIRInstrumentation::registerCallbacks(
       });
 }
 
+void InstrCountChangedReporter::registerCallbacks(
+    PassInstrumentationCallbacks &PIC, ModuleAnalysisManager &MAM) {
+  if (!DiagnosticHandler().isAnalysisRemarkEnabled("size-info"))
+    return;
+
+  PIC.registerBeforeNonSkippedPassCallback([this, &MAM, Registered = false](
+                                               StringRef PassID,
+                                               Any IR) mutable {
+    if (isIgnored(PassID))
+      return;
+    bool ShouldEmitSizeRemarks =
+        unwrapModule(IR, /*force=*/true)->shouldEmitInstrCountChangedRemark();
+    if (!ShouldEmitSizeRemarks)
+      return;
+
+    auto &MFAM = MAM.getResult<MachineFunctionAnalysisManagerModuleProxy>(
+                        const_cast<Module &>(*unwrapModule(IR)))
+                     .getManager();
+    if (!Registered) {
+      MFAM.registerPass([] { return MachineInstrCounterAnalysis(); });
+      Registered = true;
+    }
+
+    if (auto *MF =
+            const_cast<MachineFunction *>(unwrapIR<MachineFunction>(IR))) {
+      MFAM.getResult<MachineInstrCounterAnalysis>(*MF).CountBefore =
+          MF->getInstructionCount();
+      return;
+    }
+
+    // FIXME: Currently except debugify passes, `MachineOutlinerPass`
+    // is the only "machine module pass".
+    if (!isMachineModulePass(PassID))
+      return;
+    if (auto *M = const_cast<Module *>(unwrapIR<Module>(IR))) {
+      auto &FAM =
+          MAM.getResult<FunctionAnalysisManagerModuleProxy>(*M).getManager();
+      auto &MFAM = MAM.getResult<MachineFunctionAnalysisManagerModuleProxy>(*M)
+                       .getManager();
+      for (auto &F : *M) {
+        auto &MF = FAM.getResult<MachineFunctionAnalysis>(F).getMF();
+        MFAM.getResult<MachineInstrCounterAnalysis>(MF).CountBefore =
+            MF.getInstructionCount();
+      }
+    }
+  });
+
+  PIC.registerAfterPassCallback([this, &MAM](StringRef PassID, Any IR,
+                                             const PreservedAnalyses &) {
+    if (isIgnored(PassID))
+      return;
+    bool ShouldEmitSizeRemarks =
+        unwrapModule(IR, /*force=*/true)->shouldEmitInstrCountChangedRemark();
+    if (!ShouldEmitSizeRemarks)
+      return;
+
+    auto &MFAM = MAM.getResult<MachineFunctionAnalysisManagerModuleProxy>(
+                        const_cast<Module &>(*unwrapModule(IR)))
+                     .getManager();
+    if (auto *MF =
+            const_cast<MachineFunction *>(unwrapIR<MachineFunction>(IR))) {
+      MFAM.getResult<MachineInstrCounterAnalysis>(*MF).emitRemark(*MF, PassID);
+      return;
+    }
+
+    if (!isMachineModulePass(PassID))
+      return;
+    if (auto *M = const_cast<Module *>(unwrapIR<Module>(IR))) {
+      auto &FAM =
+          MAM.getResult<FunctionAnalysisManagerModuleProxy>(*M).getManager();
+      for (auto &F : *M) {
+        auto &MF = FAM.getResult<MachineFunctionAnalysis>(F).getMF();
+        MFAM.getResult<MachineInstrCounterAnalysis>(MF).emitRemark(MF, PassID);
+      }
+    }
+  });
+}
+
 void StandardInstrumentations::registerCallbacks(
     PassInstrumentationCallbacks &PIC, ModuleAnalysisManager *MAM) {
   PrintIR.registerCallbacks(PIC);
@@ -2508,8 +2642,10 @@ void StandardInstrumentations::registerCallbacks(
   WebsiteChangeReporter.registerCallbacks(PIC);
   ChangeTester.registerCallbacks(PIC);
   PrintCrashIR.registerCallbacks(PIC);
-  if (MAM)
+  if (MAM) {
     PreservedCFGChecker.registerCallbacks(PIC, *MAM);
+    EmitMFSizeRemarks.registerCallbacks(PIC, *MAM);
+  }
 
   // TimeProfiling records the pass running time cost.
   // Its 'BeforePassCallback' can be appended at the tail of all the
diff --git a/llvm/test/tools/llc/new-pm/size-remark-emitter.mir b/llvm/test/tools/llc/new-pm/size-remark-emitter.mir
new file mode 100644
index 00000000000000..f7968addad8d39
--- /dev/null
+++ b/llvm/test/tools/llc/new-pm/size-remark-emitter.mir
@@ -0,0 +1,44 @@
+# REQUIRES: x86-registered-target
+
+# RUN: llc -mtriple=x86_64-unknown-linux-gnu -filetype=null %s \
+# RUN: -p dead-mi-elimination -pass-remarks-analysis='size-info' \
+# RUN: -pass-remarks-output=%t.yaml < %s 2> %t; \
+# RUN: cat %t %t.yaml | FileCheck %s
+
+--- |
+  source_filename = "size-remark-emitter.mir"
+  target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
+  target triple = "x86_64-unknown-linux-gnu"
+  
+  define void @test() {
+  entry:
+    unreachable
+  }
+
+...
+---
+name:            test
+body:             |
+  bb.0:
+    %1:gr64 = MOV64ri 0
+    %2:gr64 = MOV64ri 0
+    $eax = COPY %1
+    RET64 implicit $eax
+...
+
+# CHECK: --- !Analysis
+# CHECK: Pass:            size-info
+# CHECK: Name:            FunctionMISizeChange
+# CHECK: Function:        test
+# CHECK: Args:
+# CHECK:   - Pass:            DeadMachineInstructionElimPass
+# CHECK:   - String:          ': Function: '
+# CHECK:   - Function:        test
+# CHECK:   - String:          ': '
+# CHECK:   - String:          'MI Instruction count changed from '
+# CHECK:   - MIInstrsBefore:  '4'
+# CHECK:   - String:          ' to '
+# CHECK:   - MIInstrsAfter:   '3'
+# CHECK:   - String:          '; Delta: '
+# CHECK:   - Delta:           '-1'
+# CHECK: ...
diff --git a/llvm/tools/llc/NewPMDriver.cpp b/llvm/tools/llc/NewPMDriver.cpp
index 6d9956ea07d356..320d02bfbc49a0 100644
--- a/llvm/tools/llc/NewPMDriver.cpp
+++ b/llvm/tools/llc/NewPMDriver.cpp
@@ -116,7 +116,6 @@ int llvm::compileModuleWithNewPM(
 
   PassInstrumentationCallbacks PIC;
   StandardInstrumentations SI(Context, Opt.DebugPM);
-  SI.registerCallbacks(PIC);
   registerCodeGenCallback(PIC, LLVMTM);
 
   MachineFunctionAnalysisManager MFAM;
@@ -124,6 +123,7 @@ int llvm::compileModuleWithNewPM(
   FunctionAnalysisManager FAM;
   CGSCCAnalysisManager CGAM;
   ModuleAnalysisManager MAM;
+  SI.registerCallbacks(PIC, &MAM);
   PassBuilder PB(Target.get(), PipelineTuningOptions(), std::nullopt, &PIC);
   PB.registerModuleAnalyses(MAM);
   PB.registerCGSCCAnalyses(CGAM);
diff --git a/llvm/tools/opt/NewPMDriver.cpp b/llvm/tools/opt/NewPMDriver.cpp
index 374698083763b0..370e051bcef4d9 100644
--- a/llvm/tools/opt/NewPMDriver.cpp
+++ b/llvm/tools/opt/NewPMDriver.cpp
@@ -404,6 +404,7 @@ bool llvm::runPassPipeline(
   if (TM)
     TM->setPGOOption(P);
 
+  MachineFunctionAnalysisManager MFAM;
   LoopAnalysisManager LAM;
   FunctionAnalysisManager FAM;
   CGSCCAnalysisManager CGAM;
@@ -470,7 +471,7 @@ bool llvm::runPassPipeline(
   PB.registerCGSCCAnalyses(CGAM);
   PB.registerFunctionAnalyses(FAM);
   PB.registerLoopAnalyses(LAM);
-  PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
+  PB.crossRegisterProxies(LAM, FAM, CGAM, MAM, &MFAM);
 
   ModulePassManager MPM;
   if (EnableDebugify)



More information about the llvm-commits mailing list