]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/include/llvm/CodeGen/MachineOptimizationRemarkEmitter.h
Merge llvm, clang, lld, lldb, compiler-rt and libc++ r306956, and update
[FreeBSD/FreeBSD.git] / contrib / llvm / include / llvm / CodeGen / MachineOptimizationRemarkEmitter.h
1 ///===- MachineOptimizationRemarkEmitter.h - Opt Diagnostics -*- C++ -*----===//
2 ///
3 ///                     The LLVM Compiler Infrastructure
4 ///
5 /// This file is distributed under the University of Illinois Open Source
6 /// License. See LICENSE.TXT for details.
7 ///
8 ///===---------------------------------------------------------------------===//
9 /// \file
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.
13 ///
14 ///===---------------------------------------------------------------------===//
15
16 #ifndef LLVM_CODEGEN_MACHINEOPTIMIZATIONREMARKEMITTER_H
17 #define LLVM_CODEGEN_MACHINEOPTIMIZATIONREMARKEMITTER_H
18
19 #include "llvm/Analysis/OptimizationDiagnosticInfo.h"
20 #include "llvm/CodeGen/MachineFunctionPass.h"
21
22 namespace llvm {
23 class MachineBasicBlock;
24 class MachineBlockFrequencyInfo;
25 class MachineInstr;
26
27 /// \brief Common features for diagnostics dealing with optimization remarks
28 /// that are used by machine passes.
29 class DiagnosticInfoMIROptimization : public DiagnosticInfoOptimizationBase {
30 public:
31   DiagnosticInfoMIROptimization(enum DiagnosticKind Kind, const char *PassName,
32                                 StringRef RemarkName,
33                                 const DiagnosticLocation &Loc,
34                                 const MachineBasicBlock *MBB)
35       : DiagnosticInfoOptimizationBase(Kind, DS_Remark, PassName, RemarkName,
36                                        *MBB->getParent()->getFunction(), Loc),
37         MBB(MBB) {}
38
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);
43   };
44
45   static bool classof(const DiagnosticInfo *DI) {
46     return DI->getKind() >= DK_FirstMachineRemark &&
47            DI->getKind() <= DK_LastMachineRemark;
48   }
49
50   const MachineBasicBlock *getBlock() const { return MBB; }
51
52 private:
53   const MachineBasicBlock *MBB;
54 };
55
56 /// Diagnostic information for applied optimization remarks.
57 class MachineOptimizationRemark : public DiagnosticInfoMIROptimization {
58 public:
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
63   /// operates in.
64   MachineOptimizationRemark(const char *PassName, StringRef RemarkName,
65                             const DiagnosticLocation &Loc,
66                             const MachineBasicBlock *MBB)
67       : DiagnosticInfoMIROptimization(DK_MachineOptimizationRemark, PassName,
68                                       RemarkName, Loc, MBB) {}
69
70   static bool classof(const DiagnosticInfo *DI) {
71     return DI->getKind() == DK_MachineOptimizationRemark;
72   }
73
74   /// \see DiagnosticInfoOptimizationBase::isEnabled.
75   bool isEnabled() const override {
76     return OptimizationRemark::isEnabled(getPassName());
77   }
78 };
79
80 /// Diagnostic information for missed-optimization remarks.
81 class MachineOptimizationRemarkMissed : public DiagnosticInfoMIROptimization {
82 public:
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) {}
93
94   static bool classof(const DiagnosticInfo *DI) {
95     return DI->getKind() == DK_MachineOptimizationRemarkMissed;
96   }
97
98   /// \see DiagnosticInfoOptimizationBase::isEnabled.
99   bool isEnabled() const override {
100     return OptimizationRemarkMissed::isEnabled(getPassName());
101   }
102 };
103
104 /// Diagnostic information for optimization analysis remarks.
105 class MachineOptimizationRemarkAnalysis : public DiagnosticInfoMIROptimization {
106 public:
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) {}
117
118   static bool classof(const DiagnosticInfo *DI) {
119     return DI->getKind() == DK_MachineOptimizationRemarkAnalysis;
120   }
121
122   /// \see DiagnosticInfoOptimizationBase::isEnabled.
123   bool isEnabled() const override {
124     return OptimizationRemarkAnalysis::isEnabled(getPassName());
125   }
126 };
127
128 /// Extend llvm::ore:: with MI-specific helper names.
129 namespace ore {
130 using MNV = DiagnosticInfoMIROptimization::MachineArgument;
131 }
132
133 /// The optimization diagnostic interface.
134 ///
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 {
140 public:
141   MachineOptimizationRemarkEmitter(MachineFunction &MF,
142                                    MachineBlockFrequencyInfo *MBFI)
143       : MF(MF), MBFI(MBFI) {}
144
145   /// Emit an optimization remark.
146   void emit(DiagnosticInfoOptimizationBase &OptDiag);
147
148   /// \brief Whether we allow for extra compile-time budget to perform more
149   /// analysis to be more informative.
150   ///
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();
159   }
160
161 private:
162   MachineFunction &MF;
163
164   /// MBFI is only set if hotness is requested.
165   MachineBlockFrequencyInfo *MBFI;
166
167   /// Compute hotness from IR value (currently assumed to be a block) if PGO is
168   /// available.
169   Optional<uint64_t> computeHotness(const MachineBasicBlock &MBB);
170
171   /// Similar but use value from \p OptDiag and update hotness there.
172   void computeHotness(DiagnosticInfoMIROptimization &Remark);
173
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; }
177 };
178
179 /// The analysis pass
180 ///
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
183 /// could be freed.
184 class MachineOptimizationRemarkEmitterPass : public MachineFunctionPass {
185   std::unique_ptr<MachineOptimizationRemarkEmitter> ORE;
186
187 public:
188   MachineOptimizationRemarkEmitterPass();
189
190   bool runOnMachineFunction(MachineFunction &MF) override;
191
192   void getAnalysisUsage(AnalysisUsage &AU) const override;
193
194   MachineOptimizationRemarkEmitter &getORE() {
195     assert(ORE && "pass not run yet");
196     return *ORE;
197   }
198
199   static char ID;
200 };
201 }
202
203 #endif