1 ///===- MachineOptimizationRemarkEmitter.cpp - Opt Diagnostic -*- C++ -*---===//
3 /// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 /// See https://llvm.org/LICENSE.txt for license information.
5 /// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 ///===---------------------------------------------------------------------===//
9 /// Optimization diagnostic interfaces for machine passes. It's packaged as an
10 /// analysis pass so that by using this service passes become dependent on MBFI
11 /// as well. MBFI is used to compute the "hotness" of the diagnostic message.
13 ///===---------------------------------------------------------------------===//
15 #include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
16 #include "llvm/CodeGen/LazyMachineBlockFrequencyInfo.h"
17 #include "llvm/CodeGen/MachineInstr.h"
18 #include "llvm/IR/DiagnosticInfo.h"
19 #include "llvm/IR/LLVMContext.h"
20 #include "llvm/InitializePasses.h"
25 DiagnosticInfoMIROptimization::MachineArgument::MachineArgument(
26 StringRef MKey
, const MachineInstr
&MI
) {
27 Key
= std::string(MKey
);
29 raw_string_ostream
OS(Val
);
30 MI
.print(OS
, /*IsStandalone=*/true, /*SkipOpers=*/false,
31 /*SkipDebugLoc=*/true);
34 bool MachineOptimizationRemarkEmitter::invalidate(
35 MachineFunction
&MF
, const PreservedAnalyses
&PA
,
36 MachineFunctionAnalysisManager::Invalidator
&Inv
) {
37 // This analysis has no state and so can be trivially preserved but it needs
38 // a fresh view of BFI if it was constructed with one.
39 return MBFI
&& Inv
.invalidate
<MachineBlockFrequencyAnalysis
>(MF
, PA
);
42 std::optional
<uint64_t>
43 MachineOptimizationRemarkEmitter::computeHotness(const MachineBasicBlock
&MBB
) {
47 return MBFI
->getBlockProfileCount(&MBB
);
50 void MachineOptimizationRemarkEmitter::computeHotness(
51 DiagnosticInfoMIROptimization
&Remark
) {
52 const MachineBasicBlock
*MBB
= Remark
.getBlock();
54 Remark
.setHotness(computeHotness(*MBB
));
57 void MachineOptimizationRemarkEmitter::emit(
58 DiagnosticInfoOptimizationBase
&OptDiagCommon
) {
59 auto &OptDiag
= cast
<DiagnosticInfoMIROptimization
>(OptDiagCommon
);
60 computeHotness(OptDiag
);
62 LLVMContext
&Ctx
= MF
.getFunction().getContext();
64 // Only emit it if its hotness meets the threshold.
65 if (OptDiag
.getHotness().value_or(0) < Ctx
.getDiagnosticsHotnessThreshold())
68 Ctx
.diagnose(OptDiag
);
71 MachineOptimizationRemarkEmitterPass::MachineOptimizationRemarkEmitterPass()
72 : MachineFunctionPass(ID
) {
73 initializeMachineOptimizationRemarkEmitterPassPass(
74 *PassRegistry::getPassRegistry());
77 bool MachineOptimizationRemarkEmitterPass::runOnMachineFunction(
78 MachineFunction
&MF
) {
79 MachineBlockFrequencyInfo
*MBFI
;
81 if (MF
.getFunction().getContext().getDiagnosticsHotnessRequested())
82 MBFI
= &getAnalysis
<LazyMachineBlockFrequencyInfoPass
>().getBFI();
86 ORE
= std::make_unique
<MachineOptimizationRemarkEmitter
>(MF
, MBFI
);
90 void MachineOptimizationRemarkEmitterPass::getAnalysisUsage(
91 AnalysisUsage
&AU
) const {
92 AU
.addRequired
<LazyMachineBlockFrequencyInfoPass
>();
94 MachineFunctionPass::getAnalysisUsage(AU
);
97 AnalysisKey
MachineOptimizationRemarkEmitterAnalysis::Key
;
99 MachineOptimizationRemarkEmitterAnalysis::Result
100 MachineOptimizationRemarkEmitterAnalysis::run(
101 MachineFunction
&MF
, MachineFunctionAnalysisManager
&MFAM
) {
102 MachineBlockFrequencyInfo
*MBFI
=
103 MF
.getFunction().getContext().getDiagnosticsHotnessRequested()
104 ? &MFAM
.getResult
<MachineBlockFrequencyAnalysis
>(MF
)
106 return Result(MF
, MBFI
);
109 char MachineOptimizationRemarkEmitterPass::ID
= 0;
110 static const char ore_name
[] = "Machine Optimization Remark Emitter";
111 #define ORE_NAME "machine-opt-remark-emitter"
113 INITIALIZE_PASS_BEGIN(MachineOptimizationRemarkEmitterPass
, ORE_NAME
, ore_name
,
115 INITIALIZE_PASS_DEPENDENCY(LazyMachineBlockFrequencyInfoPass
)
116 INITIALIZE_PASS_END(MachineOptimizationRemarkEmitterPass
, ORE_NAME
, ore_name
,