[llvm] [NewPM][Instrumentation] Support `MachineOptimizationRemarkEmitter` (PR #90563)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Apr 29 22:42:52 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-ir
Author: None (paperchalice)
<details>
<summary>Changes</summary>
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.
---
Full diff: https://github.com/llvm/llvm-project/pull/90563.diff
5 Files Affected:
- (modified) llvm/include/llvm/IR/Module.h (+1-1)
- (modified) llvm/include/llvm/Passes/StandardInstrumentations.h (+7)
- (modified) llvm/lib/Passes/StandardInstrumentations.cpp (+134-1)
- (added) llvm/test/tools/llc/new-pm/size-remark-emitter.mir (+44)
- (modified) llvm/tools/llc/NewPMDriver.cpp (+1-1)
``````````diff
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..7a2248da9da99e 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,51 @@ 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) {
+ Result R;
+ R.CountBefore = MF.getInstructionCount();
+ return R;
+ }
+};
+
+AnalysisKey MachineInstrCounterAnalysis::Key;
+
bool PreservedCFGCheckerInstrumentation::CFG::invalidate(
Function &F, const PreservedAnalyses &PA,
FunctionAnalysisManager::Invalidator &) {
@@ -2493,6 +2551,79 @@ void PrintCrashIRInstrumentation::registerCallbacks(
});
}
+void InstrCountChangedReporter::registerCallbacks(
+ PassInstrumentationCallbacks &PIC, ModuleAnalysisManager &MAM) {
+ 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);
+ 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);
+ }
+ }
+ });
+
+ 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 +2639,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);
``````````
</details>
https://github.com/llvm/llvm-project/pull/90563
More information about the llvm-commits
mailing list