1 ///===- MachineOptimizationRemarkEmitter.h - Opt Diagnostics -*- C++ -*----===//
3 /// The LLVM Compiler Infrastructure
5 /// This file is distributed under the University of Illinois Open Source
6 /// License. See LICENSE.TXT for details.
8 ///===---------------------------------------------------------------------===//
10 /// Optimization diagnostic interfaces for machine passes. It's packaged as an
11 /// analysis pass so that by using this service passes become dependent on MBFI
12 /// as well. MBFI is used to compute the "hotness" of the diagnostic message.
14 ///===---------------------------------------------------------------------===//
16 #ifndef LLVM_CODEGEN_MACHINEOPTIMIZATIONREMARKEMITTER_H
17 #define LLVM_CODEGEN_MACHINEOPTIMIZATIONREMARKEMITTER_H
19 #include "llvm/Analysis/OptimizationDiagnosticInfo.h"
20 #include "llvm/CodeGen/MachineFunctionPass.h"
23 class MachineBasicBlock;
24 class MachineBlockFrequencyInfo;
27 /// \brief Common features for diagnostics dealing with optimization remarks
28 /// that are used by machine passes.
29 class DiagnosticInfoMIROptimization : public DiagnosticInfoOptimizationBase {
31 DiagnosticInfoMIROptimization(enum DiagnosticKind Kind, const char *PassName,
33 const DiagnosticLocation &Loc,
34 const MachineBasicBlock *MBB)
35 : DiagnosticInfoOptimizationBase(Kind, DS_Remark, PassName, RemarkName,
36 *MBB->getParent()->getFunction(), Loc),
39 /// MI-specific kinds of diagnostic Arguments.
40 struct MachineArgument : public DiagnosticInfoOptimizationBase::Argument {
41 /// Print an entire MachineInstr.
42 MachineArgument(StringRef Key, const MachineInstr &MI);
45 static bool classof(const DiagnosticInfo *DI) {
46 return DI->getKind() >= DK_FirstMachineRemark &&
47 DI->getKind() <= DK_LastMachineRemark;
50 const MachineBasicBlock *getBlock() const { return MBB; }
53 const MachineBasicBlock *MBB;
56 /// Diagnostic information for applied optimization remarks.
57 class MachineOptimizationRemark : public DiagnosticInfoMIROptimization {
59 /// \p PassName is the name of the pass emitting this diagnostic. If this name
60 /// matches the regular expression given in -Rpass=, then the diagnostic will
61 /// be emitted. \p RemarkName is a textual identifier for the remark. \p
62 /// Loc is the debug location and \p MBB is the block that the optimization
64 MachineOptimizationRemark(const char *PassName, StringRef RemarkName,
65 const DiagnosticLocation &Loc,
66 const MachineBasicBlock *MBB)
67 : DiagnosticInfoMIROptimization(DK_MachineOptimizationRemark, PassName,
68 RemarkName, Loc, MBB) {}
70 static bool classof(const DiagnosticInfo *DI) {
71 return DI->getKind() == DK_MachineOptimizationRemark;
74 /// \see DiagnosticInfoOptimizationBase::isEnabled.
75 bool isEnabled() const override {
76 return OptimizationRemark::isEnabled(getPassName());
80 /// Diagnostic information for missed-optimization remarks.
81 class MachineOptimizationRemarkMissed : public DiagnosticInfoMIROptimization {
83 /// \p PassName is the name of the pass emitting this diagnostic. If this name
84 /// matches the regular expression given in -Rpass-missed=, then the
85 /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
86 /// remark. \p Loc is the debug location and \p MBB is the block that the
87 /// optimization operates in.
88 MachineOptimizationRemarkMissed(const char *PassName, StringRef RemarkName,
89 const DiagnosticLocation &Loc,
90 const MachineBasicBlock *MBB)
91 : DiagnosticInfoMIROptimization(DK_MachineOptimizationRemarkMissed,
92 PassName, RemarkName, Loc, MBB) {}
94 static bool classof(const DiagnosticInfo *DI) {
95 return DI->getKind() == DK_MachineOptimizationRemarkMissed;
98 /// \see DiagnosticInfoOptimizationBase::isEnabled.
99 bool isEnabled() const override {
100 return OptimizationRemarkMissed::isEnabled(getPassName());
104 /// Diagnostic information for optimization analysis remarks.
105 class MachineOptimizationRemarkAnalysis : public DiagnosticInfoMIROptimization {
107 /// \p PassName is the name of the pass emitting this diagnostic. If this name
108 /// matches the regular expression given in -Rpass-analysis=, then the
109 /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
110 /// remark. \p Loc is the debug location and \p MBB is the block that the
111 /// optimization operates in.
112 MachineOptimizationRemarkAnalysis(const char *PassName, StringRef RemarkName,
113 const DiagnosticLocation &Loc,
114 const MachineBasicBlock *MBB)
115 : DiagnosticInfoMIROptimization(DK_MachineOptimizationRemarkAnalysis,
116 PassName, RemarkName, Loc, MBB) {}
118 static bool classof(const DiagnosticInfo *DI) {
119 return DI->getKind() == DK_MachineOptimizationRemarkAnalysis;
122 /// \see DiagnosticInfoOptimizationBase::isEnabled.
123 bool isEnabled() const override {
124 return OptimizationRemarkAnalysis::isEnabled(getPassName());
128 /// Extend llvm::ore:: with MI-specific helper names.
130 using MNV = DiagnosticInfoMIROptimization::MachineArgument;
133 /// The optimization diagnostic interface.
135 /// It allows reporting when optimizations are performed and when they are not
136 /// along with the reasons for it. Hotness information of the corresponding
137 /// code region can be included in the remark if DiagnosticsHotnessRequested is
138 /// enabled in the LLVM context.
139 class MachineOptimizationRemarkEmitter {
141 MachineOptimizationRemarkEmitter(MachineFunction &MF,
142 MachineBlockFrequencyInfo *MBFI)
143 : MF(MF), MBFI(MBFI) {}
145 /// Emit an optimization remark.
146 void emit(DiagnosticInfoOptimizationBase &OptDiag);
148 /// \brief Whether we allow for extra compile-time budget to perform more
149 /// analysis to be more informative.
151 /// This is useful to enable additional missed optimizations to be reported
152 /// that are normally too noisy. In this mode, we can use the extra analysis
153 /// (1) to filter trivial false positives or (2) to provide more context so
154 /// that non-trivial false positives can be quickly detected by the user.
155 bool allowExtraAnalysis() const {
156 // For now, only allow this with -fsave-optimization-record since the -Rpass
157 // options are handled in the front-end.
158 return MF.getFunction()->getContext().getDiagnosticsOutputFile();
164 /// MBFI is only set if hotness is requested.
165 MachineBlockFrequencyInfo *MBFI;
167 /// Compute hotness from IR value (currently assumed to be a block) if PGO is
169 Optional<uint64_t> computeHotness(const MachineBasicBlock &MBB);
171 /// Similar but use value from \p OptDiag and update hotness there.
172 void computeHotness(DiagnosticInfoMIROptimization &Remark);
174 /// \brief Only allow verbose messages if we know we're filtering by hotness
175 /// (BFI is only set in this case).
176 bool shouldEmitVerbose() { return MBFI != nullptr; }
179 /// The analysis pass
181 /// Note that this pass shouldn't generally be marked as preserved by other
182 /// passes. It's holding onto BFI, so if the pass does not preserve BFI, BFI
184 class MachineOptimizationRemarkEmitterPass : public MachineFunctionPass {
185 std::unique_ptr<MachineOptimizationRemarkEmitter> ORE;
188 MachineOptimizationRemarkEmitterPass();
190 bool runOnMachineFunction(MachineFunction &MF) override;
192 void getAnalysisUsage(AnalysisUsage &AU) const override;
194 MachineOptimizationRemarkEmitter &getORE() {
195 assert(ORE && "pass not run yet");