]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/include/llvm/CodeGen/MachineOptimizationRemarkEmitter.h
Merge clang 7.0.1 and several follow-up changes
[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/OptimizationRemarkEmitter.h"
20 #include "llvm/CodeGen/MachineFunctionPass.h"
21
22 namespace llvm {
23 class MachineBasicBlock;
24 class MachineBlockFrequencyInfo;
25 class MachineInstr;
26
27 /// 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     const Function &Fn = getFunction();
77     LLVMContext &Ctx = Fn.getContext();
78     return Ctx.getDiagHandlerPtr()->isPassedOptRemarkEnabled(getPassName());
79   }
80 };
81
82 /// Diagnostic information for missed-optimization remarks.
83 class MachineOptimizationRemarkMissed : public DiagnosticInfoMIROptimization {
84 public:
85   /// \p PassName is the name of the pass emitting this diagnostic. If this name
86   /// matches the regular expression given in -Rpass-missed=, then the
87   /// diagnostic will be emitted.  \p RemarkName is a textual identifier for the
88   /// remark.  \p Loc is the debug location and \p MBB is the block that the
89   /// optimization operates in.
90   MachineOptimizationRemarkMissed(const char *PassName, StringRef RemarkName,
91                                   const DiagnosticLocation &Loc,
92                                   const MachineBasicBlock *MBB)
93       : DiagnosticInfoMIROptimization(DK_MachineOptimizationRemarkMissed,
94                                       PassName, RemarkName, Loc, MBB) {}
95
96   static bool classof(const DiagnosticInfo *DI) {
97     return DI->getKind() == DK_MachineOptimizationRemarkMissed;
98   }
99
100   /// \see DiagnosticInfoOptimizationBase::isEnabled.
101   bool isEnabled() const override {
102     const Function &Fn = getFunction();
103     LLVMContext &Ctx = Fn.getContext();
104     return Ctx.getDiagHandlerPtr()->isMissedOptRemarkEnabled(getPassName());
105   }
106 };
107
108 /// Diagnostic information for optimization analysis remarks.
109 class MachineOptimizationRemarkAnalysis : public DiagnosticInfoMIROptimization {
110 public:
111   /// \p PassName is the name of the pass emitting this diagnostic. If this name
112   /// matches the regular expression given in -Rpass-analysis=, then the
113   /// diagnostic will be emitted.  \p RemarkName is a textual identifier for the
114   /// remark.  \p Loc is the debug location and \p MBB is the block that the
115   /// optimization operates in.
116   MachineOptimizationRemarkAnalysis(const char *PassName, StringRef RemarkName,
117                                     const DiagnosticLocation &Loc,
118                                     const MachineBasicBlock *MBB)
119       : DiagnosticInfoMIROptimization(DK_MachineOptimizationRemarkAnalysis,
120                                       PassName, RemarkName, Loc, MBB) {}
121
122   static bool classof(const DiagnosticInfo *DI) {
123     return DI->getKind() == DK_MachineOptimizationRemarkAnalysis;
124   }
125
126   /// \see DiagnosticInfoOptimizationBase::isEnabled.
127   bool isEnabled() const override {
128     const Function &Fn = getFunction();
129     LLVMContext &Ctx = Fn.getContext();
130     return Ctx.getDiagHandlerPtr()->isAnalysisRemarkEnabled(getPassName());
131   }
132 };
133
134 /// Extend llvm::ore:: with MI-specific helper names.
135 namespace ore {
136 using MNV = DiagnosticInfoMIROptimization::MachineArgument;
137 }
138
139 /// The optimization diagnostic interface.
140 ///
141 /// It allows reporting when optimizations are performed and when they are not
142 /// along with the reasons for it.  Hotness information of the corresponding
143 /// code region can be included in the remark if DiagnosticsHotnessRequested is
144 /// enabled in the LLVM context.
145 class MachineOptimizationRemarkEmitter {
146 public:
147   MachineOptimizationRemarkEmitter(MachineFunction &MF,
148                                    MachineBlockFrequencyInfo *MBFI)
149       : MF(MF), MBFI(MBFI) {}
150
151   /// Emit an optimization remark.
152   void emit(DiagnosticInfoOptimizationBase &OptDiag);
153
154   /// Whether we allow for extra compile-time budget to perform more
155   /// analysis to be more informative.
156   ///
157   /// This is useful to enable additional missed optimizations to be reported
158   /// that are normally too noisy.  In this mode, we can use the extra analysis
159   /// (1) to filter trivial false positives or (2) to provide more context so
160   /// that non-trivial false positives can be quickly detected by the user.
161   bool allowExtraAnalysis(StringRef PassName) const {
162     return (MF.getFunction().getContext().getDiagnosticsOutputFile() ||
163             MF.getFunction().getContext()
164             .getDiagHandlerPtr()->isAnyRemarkEnabled(PassName));
165   }
166
167   /// Take a lambda that returns a remark which will be emitted.  Second
168   /// argument is only used to restrict this to functions.
169   template <typename T>
170   void emit(T RemarkBuilder, decltype(RemarkBuilder()) * = nullptr) {
171     // Avoid building the remark unless we know there are at least *some*
172     // remarks enabled. We can't currently check whether remarks are requested
173     // for the calling pass since that requires actually building the remark.
174
175     if (MF.getFunction().getContext().getDiagnosticsOutputFile() ||
176         MF.getFunction().getContext().getDiagHandlerPtr()->isAnyRemarkEnabled()) {
177       auto R = RemarkBuilder();
178       emit((DiagnosticInfoOptimizationBase &)R);
179     }
180   }
181
182 private:
183   MachineFunction &MF;
184
185   /// MBFI is only set if hotness is requested.
186   MachineBlockFrequencyInfo *MBFI;
187
188   /// Compute hotness from IR value (currently assumed to be a block) if PGO is
189   /// available.
190   Optional<uint64_t> computeHotness(const MachineBasicBlock &MBB);
191
192   /// Similar but use value from \p OptDiag and update hotness there.
193   void computeHotness(DiagnosticInfoMIROptimization &Remark);
194
195   /// Only allow verbose messages if we know we're filtering by hotness
196   /// (BFI is only set in this case).
197   bool shouldEmitVerbose() { return MBFI != nullptr; }
198 };
199
200 /// The analysis pass
201 ///
202 /// Note that this pass shouldn't generally be marked as preserved by other
203 /// passes.  It's holding onto BFI, so if the pass does not preserve BFI, BFI
204 /// could be freed.
205 class MachineOptimizationRemarkEmitterPass : public MachineFunctionPass {
206   std::unique_ptr<MachineOptimizationRemarkEmitter> ORE;
207
208 public:
209   MachineOptimizationRemarkEmitterPass();
210
211   bool runOnMachineFunction(MachineFunction &MF) override;
212
213   void getAnalysisUsage(AnalysisUsage &AU) const override;
214
215   MachineOptimizationRemarkEmitter &getORE() {
216     assert(ORE && "pass not run yet");
217     return *ORE;
218   }
219
220   static char ID;
221 };
222 }
223
224 #endif