OSDN Git Service

Migrate PGOMemOptSizeOpt to use new OptimizationRemarkEmitter Pass
[android-x86/external-llvm.git] / include / llvm / IR / DiagnosticInfo.h
1 //===- llvm/IR/DiagnosticInfo.h - Diagnostic Declaration --------*- 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 //
10 // This file declares the different classes involved in low level diagnostics.
11 //
12 // Diagnostics reporting is still done as part of the LLVMContext.
13 //===----------------------------------------------------------------------===//
14
15 #ifndef LLVM_IR_DIAGNOSTICINFO_H
16 #define LLVM_IR_DIAGNOSTICINFO_H
17
18 #include "llvm-c/Types.h"
19 #include "llvm/ADT/Optional.h"
20 #include "llvm/ADT/SmallVector.h"
21 #include "llvm/ADT/StringRef.h"
22 #include "llvm/ADT/Twine.h"
23 #include "llvm/IR/DebugLoc.h"
24 #include "llvm/Support/CBindingWrapping.h"
25 #include "llvm/Support/YAMLTraits.h"
26 #include <algorithm>
27 #include <cstdint>
28 #include <functional>
29 #include <iterator>
30 #include <string>
31
32 namespace llvm {
33
34 // Forward declarations.
35 class DiagnosticPrinter;
36 class Function;
37 class Instruction;
38 class LLVMContext;
39 class Module;
40 class SMDiagnostic;
41
42 /// \brief Defines the different supported severity of a diagnostic.
43 enum DiagnosticSeverity : char {
44   DS_Error,
45   DS_Warning,
46   DS_Remark,
47   // A note attaches additional information to one of the previous diagnostic
48   // types.
49   DS_Note
50 };
51
52 /// \brief Defines the different supported kind of a diagnostic.
53 /// This enum should be extended with a new ID for each added concrete subclass.
54 enum DiagnosticKind {
55   DK_InlineAsm,
56   DK_ResourceLimit,
57   DK_StackSize,
58   DK_Linker,
59   DK_DebugMetadataVersion,
60   DK_DebugMetadataInvalid,
61   DK_ISelFallback,
62   DK_SampleProfile,
63   DK_OptimizationRemark,
64   DK_OptimizationRemarkMissed,
65   DK_OptimizationRemarkAnalysis,
66   DK_OptimizationRemarkAnalysisFPCommute,
67   DK_OptimizationRemarkAnalysisAliasing,
68   DK_OptimizationFailure,
69   DK_FirstRemark = DK_OptimizationRemark,
70   DK_LastRemark = DK_OptimizationFailure,
71   DK_MachineOptimizationRemark,
72   DK_MachineOptimizationRemarkMissed,
73   DK_MachineOptimizationRemarkAnalysis,
74   DK_FirstMachineRemark = DK_MachineOptimizationRemark,
75   DK_LastMachineRemark = DK_MachineOptimizationRemarkAnalysis,
76   DK_MIRParser,
77   DK_PGOProfile,
78   DK_Unsupported,
79   DK_FirstPluginKind
80 };
81
82 /// \brief Get the next available kind ID for a plugin diagnostic.
83 /// Each time this function is called, it returns a different number.
84 /// Therefore, a plugin that wants to "identify" its own classes
85 /// with a dynamic identifier, just have to use this method to get a new ID
86 /// and assign it to each of its classes.
87 /// The returned ID will be greater than or equal to DK_FirstPluginKind.
88 /// Thus, the plugin identifiers will not conflict with the
89 /// DiagnosticKind values.
90 int getNextAvailablePluginDiagnosticKind();
91
92 /// \brief This is the base abstract class for diagnostic reporting in
93 /// the backend.
94 /// The print method must be overloaded by the subclasses to print a
95 /// user-friendly message in the client of the backend (let us call it a
96 /// frontend).
97 class DiagnosticInfo {
98 private:
99   /// Kind defines the kind of report this is about.
100   const /* DiagnosticKind */ int Kind;
101   /// Severity gives the severity of the diagnostic.
102   const DiagnosticSeverity Severity;
103
104 public:
105   DiagnosticInfo(/* DiagnosticKind */ int Kind, DiagnosticSeverity Severity)
106       : Kind(Kind), Severity(Severity) {}
107
108   virtual ~DiagnosticInfo() = default;
109
110   /* DiagnosticKind */ int getKind() const { return Kind; }
111   DiagnosticSeverity getSeverity() const { return Severity; }
112
113   /// Print using the given \p DP a user-friendly message.
114   /// This is the default message that will be printed to the user.
115   /// It is used when the frontend does not directly take advantage
116   /// of the information contained in fields of the subclasses.
117   /// The printed message must not end with '.' nor start with a severity
118   /// keyword.
119   virtual void print(DiagnosticPrinter &DP) const = 0;
120 };
121
122 using DiagnosticHandlerFunction = std::function<void(const DiagnosticInfo &)>;
123
124 /// Diagnostic information for inline asm reporting.
125 /// This is basically a message and an optional location.
126 class DiagnosticInfoInlineAsm : public DiagnosticInfo {
127 private:
128   /// Optional line information. 0 if not set.
129   unsigned LocCookie = 0;
130   /// Message to be reported.
131   const Twine &MsgStr;
132   /// Optional origin of the problem.
133   const Instruction *Instr = nullptr;
134
135 public:
136   /// \p MsgStr is the message to be reported to the frontend.
137   /// This class does not copy \p MsgStr, therefore the reference must be valid
138   /// for the whole life time of the Diagnostic.
139   DiagnosticInfoInlineAsm(const Twine &MsgStr,
140                           DiagnosticSeverity Severity = DS_Error)
141       : DiagnosticInfo(DK_InlineAsm, Severity), MsgStr(MsgStr) {}
142
143   /// \p LocCookie if non-zero gives the line number for this report.
144   /// \p MsgStr gives the message.
145   /// This class does not copy \p MsgStr, therefore the reference must be valid
146   /// for the whole life time of the Diagnostic.
147   DiagnosticInfoInlineAsm(unsigned LocCookie, const Twine &MsgStr,
148                           DiagnosticSeverity Severity = DS_Error)
149       : DiagnosticInfo(DK_InlineAsm, Severity), LocCookie(LocCookie),
150         MsgStr(MsgStr) {}
151
152   /// \p Instr gives the original instruction that triggered the diagnostic.
153   /// \p MsgStr gives the message.
154   /// This class does not copy \p MsgStr, therefore the reference must be valid
155   /// for the whole life time of the Diagnostic.
156   /// Same for \p I.
157   DiagnosticInfoInlineAsm(const Instruction &I, const Twine &MsgStr,
158                           DiagnosticSeverity Severity = DS_Error);
159
160   unsigned getLocCookie() const { return LocCookie; }
161   const Twine &getMsgStr() const { return MsgStr; }
162   const Instruction *getInstruction() const { return Instr; }
163
164   /// \see DiagnosticInfo::print.
165   void print(DiagnosticPrinter &DP) const override;
166
167   static bool classof(const DiagnosticInfo *DI) {
168     return DI->getKind() == DK_InlineAsm;
169   }
170 };
171
172 /// Diagnostic information for stack size etc. reporting.
173 /// This is basically a function and a size.
174 class DiagnosticInfoResourceLimit : public DiagnosticInfo {
175 private:
176   /// The function that is concerned by this resource limit diagnostic.
177   const Function &Fn;
178
179   /// Description of the resource type (e.g. stack size)
180   const char *ResourceName;
181
182   /// The computed size usage
183   uint64_t ResourceSize;
184
185   // Threshould passed
186   uint64_t ResourceLimit;
187
188 public:
189   /// \p The function that is concerned by this stack size diagnostic.
190   /// \p The computed stack size.
191   DiagnosticInfoResourceLimit(const Function &Fn,
192                               const char *ResourceName,
193                               uint64_t ResourceSize,
194                               DiagnosticSeverity Severity = DS_Warning,
195                               DiagnosticKind Kind = DK_ResourceLimit,
196                               uint64_t ResourceLimit = 0)
197       : DiagnosticInfo(Kind, Severity),
198         Fn(Fn),
199         ResourceName(ResourceName),
200         ResourceSize(ResourceSize),
201         ResourceLimit(ResourceLimit) {}
202
203   const Function &getFunction() const { return Fn; }
204   const char *getResourceName() const { return ResourceName; }
205   uint64_t getResourceSize() const { return ResourceSize; }
206   uint64_t getResourceLimit() const { return ResourceLimit; }
207
208   /// \see DiagnosticInfo::print.
209   void print(DiagnosticPrinter &DP) const override;
210
211   static bool classof(const DiagnosticInfo *DI) {
212     return DI->getKind() == DK_ResourceLimit ||
213            DI->getKind() == DK_StackSize;
214   }
215 };
216
217 class DiagnosticInfoStackSize : public DiagnosticInfoResourceLimit {
218 public:
219   DiagnosticInfoStackSize(const Function &Fn,
220                           uint64_t StackSize,
221                           DiagnosticSeverity Severity = DS_Warning,
222                           uint64_t StackLimit = 0)
223     : DiagnosticInfoResourceLimit(Fn, "stack size", StackSize,
224                                   Severity, DK_StackSize, StackLimit) {}
225
226   uint64_t getStackSize() const { return getResourceSize(); }
227   uint64_t getStackLimit() const { return getResourceLimit(); }
228
229   static bool classof(const DiagnosticInfo *DI) {
230     return DI->getKind() == DK_StackSize;
231   }
232 };
233
234 /// Diagnostic information for debug metadata version reporting.
235 /// This is basically a module and a version.
236 class DiagnosticInfoDebugMetadataVersion : public DiagnosticInfo {
237 private:
238   /// The module that is concerned by this debug metadata version diagnostic.
239   const Module &M;
240   /// The actual metadata version.
241   unsigned MetadataVersion;
242
243 public:
244   /// \p The module that is concerned by this debug metadata version diagnostic.
245   /// \p The actual metadata version.
246   DiagnosticInfoDebugMetadataVersion(const Module &M, unsigned MetadataVersion,
247                           DiagnosticSeverity Severity = DS_Warning)
248       : DiagnosticInfo(DK_DebugMetadataVersion, Severity), M(M),
249         MetadataVersion(MetadataVersion) {}
250
251   const Module &getModule() const { return M; }
252   unsigned getMetadataVersion() const { return MetadataVersion; }
253
254   /// \see DiagnosticInfo::print.
255   void print(DiagnosticPrinter &DP) const override;
256
257   static bool classof(const DiagnosticInfo *DI) {
258     return DI->getKind() == DK_DebugMetadataVersion;
259   }
260 };
261
262 /// Diagnostic information for stripping invalid debug metadata.
263 class DiagnosticInfoIgnoringInvalidDebugMetadata : public DiagnosticInfo {
264 private:
265   /// The module that is concerned by this debug metadata version diagnostic.
266   const Module &M;
267
268 public:
269   /// \p The module that is concerned by this debug metadata version diagnostic.
270   DiagnosticInfoIgnoringInvalidDebugMetadata(
271       const Module &M, DiagnosticSeverity Severity = DS_Warning)
272       : DiagnosticInfo(DK_DebugMetadataVersion, Severity), M(M) {}
273
274   const Module &getModule() const { return M; }
275
276   /// \see DiagnosticInfo::print.
277   void print(DiagnosticPrinter &DP) const override;
278
279   static bool classof(const DiagnosticInfo *DI) {
280     return DI->getKind() == DK_DebugMetadataInvalid;
281   }
282 };
283
284 /// Diagnostic information for the sample profiler.
285 class DiagnosticInfoSampleProfile : public DiagnosticInfo {
286 public:
287   DiagnosticInfoSampleProfile(StringRef FileName, unsigned LineNum,
288                               const Twine &Msg,
289                               DiagnosticSeverity Severity = DS_Error)
290       : DiagnosticInfo(DK_SampleProfile, Severity), FileName(FileName),
291         LineNum(LineNum), Msg(Msg) {}
292   DiagnosticInfoSampleProfile(StringRef FileName, const Twine &Msg,
293                               DiagnosticSeverity Severity = DS_Error)
294       : DiagnosticInfo(DK_SampleProfile, Severity), FileName(FileName),
295         Msg(Msg) {}
296   DiagnosticInfoSampleProfile(const Twine &Msg,
297                               DiagnosticSeverity Severity = DS_Error)
298       : DiagnosticInfo(DK_SampleProfile, Severity), Msg(Msg) {}
299
300   /// \see DiagnosticInfo::print.
301   void print(DiagnosticPrinter &DP) const override;
302
303   static bool classof(const DiagnosticInfo *DI) {
304     return DI->getKind() == DK_SampleProfile;
305   }
306
307   StringRef getFileName() const { return FileName; }
308   unsigned getLineNum() const { return LineNum; }
309   const Twine &getMsg() const { return Msg; }
310
311 private:
312   /// Name of the input file associated with this diagnostic.
313   StringRef FileName;
314
315   /// Line number where the diagnostic occurred. If 0, no line number will
316   /// be emitted in the message.
317   unsigned LineNum = 0;
318
319   /// Message to report.
320   const Twine &Msg;
321 };
322
323 /// Diagnostic information for the PGO profiler.
324 class DiagnosticInfoPGOProfile : public DiagnosticInfo {
325 public:
326   DiagnosticInfoPGOProfile(const char *FileName, const Twine &Msg,
327                            DiagnosticSeverity Severity = DS_Error)
328       : DiagnosticInfo(DK_PGOProfile, Severity), FileName(FileName), Msg(Msg) {}
329
330   /// \see DiagnosticInfo::print.
331   void print(DiagnosticPrinter &DP) const override;
332
333   static bool classof(const DiagnosticInfo *DI) {
334     return DI->getKind() == DK_PGOProfile;
335   }
336
337   const char *getFileName() const { return FileName; }
338   const Twine &getMsg() const { return Msg; }
339
340 private:
341   /// Name of the input file associated with this diagnostic.
342   const char *FileName;
343
344   /// Message to report.
345   const Twine &Msg;
346 };
347
348 class DiagnosticLocation {
349   StringRef Filename;
350   unsigned Line = 0;
351   unsigned Column = 0;
352
353 public:
354   DiagnosticLocation() = default;
355   DiagnosticLocation(const DebugLoc &DL);
356   DiagnosticLocation(const DISubprogram *SP);
357
358   bool isValid() const { return !Filename.empty(); }
359   StringRef getFilename() const { return Filename; }
360   unsigned getLine() const { return Line; }
361   unsigned getColumn() const { return Column; }
362 };
363
364 /// Common features for diagnostics with an associated location.
365 class DiagnosticInfoWithLocationBase : public DiagnosticInfo {
366 public:
367   /// \p Fn is the function where the diagnostic is being emitted. \p Loc is
368   /// the location information to use in the diagnostic.
369   DiagnosticInfoWithLocationBase(enum DiagnosticKind Kind,
370                                  enum DiagnosticSeverity Severity,
371                                  const Function &Fn,
372                                  const DiagnosticLocation &Loc)
373       : DiagnosticInfo(Kind, Severity), Fn(Fn), Loc(Loc) {}
374
375   /// Return true if location information is available for this diagnostic.
376   bool isLocationAvailable() const { return Loc.isValid(); }
377
378   /// Return a string with the location information for this diagnostic
379   /// in the format "file:line:col". If location information is not available,
380   /// it returns "<unknown>:0:0".
381   const std::string getLocationStr() const;
382
383   /// Return location information for this diagnostic in three parts:
384   /// the source file name, line number and column.
385   void getLocation(StringRef *Filename, unsigned *Line, unsigned *Column) const;
386
387   const Function &getFunction() const { return Fn; }
388   DiagnosticLocation getLocation() const { return Loc; }
389
390 private:
391   /// Function where this diagnostic is triggered.
392   const Function &Fn;
393
394   /// Debug location where this diagnostic is triggered.
395   DiagnosticLocation Loc;
396 };
397
398 /// \brief Common features for diagnostics dealing with optimization remarks
399 /// that are used by both IR and MIR passes.
400 class DiagnosticInfoOptimizationBase : public DiagnosticInfoWithLocationBase {
401 public:
402   /// \brief Used to set IsVerbose via the stream interface.
403   struct setIsVerbose {};
404
405   /// \brief When an instance of this is inserted into the stream, the arguments
406   /// following will not appear in the remark printed in the compiler output
407   /// (-Rpass) but only in the optimization record file
408   /// (-fsave-optimization-record).
409   struct setExtraArgs {};
410
411   /// \brief Used in the streaming interface as the general argument type.  It
412   /// internally converts everything into a key-value pair.
413   struct Argument {
414     StringRef Key;
415     std::string Val;
416     // If set, the debug location corresponding to the value.
417     DiagnosticLocation Loc;
418
419     explicit Argument(StringRef Str = "") : Key("String"), Val(Str) {}
420     Argument(StringRef Key, const Value *V);
421     Argument(StringRef Key, const Type *T);
422     Argument(StringRef Key, StringRef S);
423     Argument(StringRef Key, int N);
424     Argument(StringRef Key, int64_t N);
425     Argument(StringRef Key, unsigned N);
426     Argument(StringRef Key, uint64_t N);
427     Argument(StringRef Key, bool B) : Key(Key), Val(B ? "true" : "false") {}
428   };
429
430   /// \p PassName is the name of the pass emitting this diagnostic. \p
431   /// RemarkName is a textual identifier for the remark (single-word,
432   /// camel-case). \p Fn is the function where the diagnostic is being emitted.
433   /// \p Loc is the location information to use in the diagnostic. If line table
434   /// information is available, the diagnostic will include the source code
435   /// location.
436   DiagnosticInfoOptimizationBase(enum DiagnosticKind Kind,
437                                  enum DiagnosticSeverity Severity,
438                                  const char *PassName, StringRef RemarkName,
439                                  const Function &Fn,
440                                  const DiagnosticLocation &Loc)
441       : DiagnosticInfoWithLocationBase(Kind, Severity, Fn, Loc),
442         PassName(PassName), RemarkName(RemarkName) {}
443
444   DiagnosticInfoOptimizationBase &operator<<(StringRef S);
445   DiagnosticInfoOptimizationBase &operator<<(Argument A);
446   DiagnosticInfoOptimizationBase &operator<<(setIsVerbose V);
447   DiagnosticInfoOptimizationBase &operator<<(setExtraArgs EA);
448
449   /// \see DiagnosticInfo::print.
450   void print(DiagnosticPrinter &DP) const override;
451
452   /// Return true if this optimization remark is enabled by one of
453   /// of the LLVM command line flags (-pass-remarks, -pass-remarks-missed,
454   /// or -pass-remarks-analysis). Note that this only handles the LLVM
455   /// flags. We cannot access Clang flags from here (they are handled
456   /// in BackendConsumer::OptimizationRemarkHandler).
457   virtual bool isEnabled() const = 0;
458
459   StringRef getPassName() const { return PassName; }
460   std::string getMsg() const;
461   Optional<uint64_t> getHotness() const { return Hotness; }
462   void setHotness(Optional<uint64_t> H) { Hotness = H; }
463
464   bool isVerbose() const { return IsVerbose; }
465
466   static bool classof(const DiagnosticInfo *DI) {
467     return (DI->getKind() >= DK_FirstRemark &&
468             DI->getKind() <= DK_LastRemark) ||
469            (DI->getKind() >= DK_FirstMachineRemark &&
470             DI->getKind() <= DK_LastMachineRemark);
471   }
472
473   bool isPassed() const {
474     return (getKind() == DK_OptimizationRemark ||
475             getKind() == DK_MachineOptimizationRemark);
476   }
477
478   bool isMissed() const {
479     return (getKind() == DK_OptimizationRemarkMissed ||
480             getKind() == DK_MachineOptimizationRemarkMissed);
481   }
482
483   bool isAnalysis() const {
484     return (getKind() == DK_OptimizationRemarkAnalysis ||
485             getKind() == DK_MachineOptimizationRemarkAnalysis);
486   }
487
488 protected:
489   /// Name of the pass that triggers this report. If this matches the
490   /// regular expression given in -Rpass=regexp, then the remark will
491   /// be emitted.
492   const char *PassName;
493
494   /// Textual identifier for the remark (single-word, camel-case). Can be used
495   /// by external tools reading the YAML output file for optimization remarks to
496   /// identify the remark.
497   StringRef RemarkName;
498
499   /// If profile information is available, this is the number of times the
500   /// corresponding code was executed in a profile instrumentation run.
501   Optional<uint64_t> Hotness;
502
503   /// Arguments collected via the streaming interface.
504   SmallVector<Argument, 4> Args;
505
506   /// The remark is expected to be noisy.
507   bool IsVerbose = false;
508
509   /// \brief If positive, the index of the first argument that only appear in
510   /// the optimization records and not in the remark printed in the compiler
511   /// output.
512   int FirstExtraArgIndex = -1;
513
514   friend struct yaml::MappingTraits<DiagnosticInfoOptimizationBase *>;
515 };
516
517 /// \brief Common features for diagnostics dealing with optimization remarks
518 /// that are used by IR passes.
519 class DiagnosticInfoIROptimization : public DiagnosticInfoOptimizationBase {
520 public:
521   /// \p PassName is the name of the pass emitting this diagnostic. \p
522   /// RemarkName is a textual identifier for the remark (single-word,
523   /// camel-case). \p Fn is the function where the diagnostic is being emitted.
524   /// \p Loc is the location information to use in the diagnostic. If line table
525   /// information is available, the diagnostic will include the source code
526   /// location. \p CodeRegion is IR value (currently basic block) that the
527   /// optimization operates on. This is currently used to provide run-time
528   /// hotness information with PGO.
529   DiagnosticInfoIROptimization(enum DiagnosticKind Kind,
530                                enum DiagnosticSeverity Severity,
531                                const char *PassName, StringRef RemarkName,
532                                const Function &Fn,
533                                const DiagnosticLocation &Loc,
534                                const Value *CodeRegion = nullptr)
535       : DiagnosticInfoOptimizationBase(Kind, Severity, PassName, RemarkName, Fn,
536                                        Loc),
537         CodeRegion(CodeRegion) {}
538
539   /// \brief This is ctor variant allows a pass to build an optimization remark
540   /// from an existing remark.
541   ///
542   /// This is useful when a transformation pass (e.g LV) wants to emit a remark
543   /// (\p Orig) generated by one of its analyses (e.g. LAA) as its own analysis
544   /// remark.  The string \p Prepend will be emitted before the original
545   /// message.
546   DiagnosticInfoIROptimization(const char *PassName, StringRef Prepend,
547                                const DiagnosticInfoIROptimization &Orig)
548       : DiagnosticInfoOptimizationBase(
549             (DiagnosticKind)Orig.getKind(), Orig.getSeverity(), PassName,
550             Orig.RemarkName, Orig.getFunction(), Orig.getLocation()),
551         CodeRegion(Orig.getCodeRegion()) {
552     *this << Prepend;
553     std::copy(Orig.Args.begin(), Orig.Args.end(), std::back_inserter(Args));
554   }
555
556   /// Legacy interface.
557   /// \p PassName is the name of the pass emitting this diagnostic.
558   /// \p Fn is the function where the diagnostic is being emitted. \p Loc is
559   /// the location information to use in the diagnostic. If line table
560   /// information is available, the diagnostic will include the source code
561   /// location. \p Msg is the message to show. Note that this class does not
562   /// copy this message, so this reference must be valid for the whole life time
563   /// of the diagnostic.
564   DiagnosticInfoIROptimization(enum DiagnosticKind Kind,
565                                enum DiagnosticSeverity Severity,
566                                const char *PassName, const Function &Fn,
567                                const DiagnosticLocation &Loc, const Twine &Msg)
568       : DiagnosticInfoOptimizationBase(Kind, Severity, PassName, "", Fn, Loc) {
569     *this << Msg.str();
570   }
571
572   const Value *getCodeRegion() const { return CodeRegion; }
573
574   static bool classof(const DiagnosticInfo *DI) {
575     return DI->getKind() >= DK_FirstRemark && DI->getKind() <= DK_LastRemark;
576   }
577
578 private:
579   /// The IR value (currently basic block) that the optimization operates on.
580   /// This is currently used to provide run-time hotness information with PGO.
581   const Value *CodeRegion;
582 };
583
584 /// Diagnostic information for applied optimization remarks.
585 class OptimizationRemark : public DiagnosticInfoIROptimization {
586 public:
587   /// \p PassName is the name of the pass emitting this diagnostic. If this name
588   /// matches the regular expression given in -Rpass=, then the diagnostic will
589   /// be emitted. \p RemarkName is a textual identifier for the remark (single-
590   /// word, camel-case). \p Loc is the debug location and \p CodeRegion is the
591   /// region that the optimization operates on (currently only block is
592   /// supported).
593   OptimizationRemark(const char *PassName, StringRef RemarkName,
594                      const DiagnosticLocation &Loc, const Value *CodeRegion);
595
596   /// Same as above, but the debug location and code region are derived from \p
597   /// Instr.
598   OptimizationRemark(const char *PassName, StringRef RemarkName,
599                      const Instruction *Inst);
600
601   /// Same as above, but the debug location and code region are derived from \p
602   /// Func.
603   OptimizationRemark(const char *PassName, StringRef RemarkName,
604                      const Function *Func);
605
606   static bool classof(const DiagnosticInfo *DI) {
607     return DI->getKind() == DK_OptimizationRemark;
608   }
609
610   static bool isEnabled(StringRef PassName);
611
612   /// \see DiagnosticInfoOptimizationBase::isEnabled.
613   bool isEnabled() const override { return isEnabled(getPassName()); }
614
615 private:
616   /// This is deprecated now and only used by the function API below.
617   /// \p PassName is the name of the pass emitting this diagnostic. If
618   /// this name matches the regular expression given in -Rpass=, then the
619   /// diagnostic will be emitted. \p Fn is the function where the diagnostic
620   /// is being emitted. \p Loc is the location information to use in the
621   /// diagnostic. If line table information is available, the diagnostic
622   /// will include the source code location. \p Msg is the message to show.
623   /// Note that this class does not copy this message, so this reference
624   /// must be valid for the whole life time of the diagnostic.
625   OptimizationRemark(const char *PassName, const Function &Fn,
626                      const DiagnosticLocation &Loc, const Twine &Msg)
627       : DiagnosticInfoIROptimization(DK_OptimizationRemark, DS_Remark, PassName,
628                                      Fn, Loc, Msg) {}
629
630   friend void emitOptimizationRemark(LLVMContext &Ctx, const char *PassName,
631                                      const Function &Fn,
632                                      const DiagnosticLocation &Loc,
633                                      const Twine &Msg);
634 };
635
636 /// Diagnostic information for missed-optimization remarks.
637 class OptimizationRemarkMissed : public DiagnosticInfoIROptimization {
638 public:
639   /// \p PassName is the name of the pass emitting this diagnostic. If this name
640   /// matches the regular expression given in -Rpass-missed=, then the
641   /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
642   /// remark (single-word, camel-case). \p Loc is the debug location and \p
643   /// CodeRegion is the region that the optimization operates on (currently only
644   /// block is supported).
645   OptimizationRemarkMissed(const char *PassName, StringRef RemarkName,
646                            const DiagnosticLocation &Loc,
647                            const Value *CodeRegion);
648
649   /// \brief Same as above but \p Inst is used to derive code region and debug
650   /// location.
651   OptimizationRemarkMissed(const char *PassName, StringRef RemarkName,
652                            const Instruction *Inst);
653
654   static bool classof(const DiagnosticInfo *DI) {
655     return DI->getKind() == DK_OptimizationRemarkMissed;
656   }
657
658   static bool isEnabled(StringRef PassName);
659
660   /// \see DiagnosticInfoOptimizationBase::isEnabled.
661   bool isEnabled() const override { return isEnabled(getPassName()); }
662
663 private:
664   /// This is deprecated now and only used by the function API below.
665   /// \p PassName is the name of the pass emitting this diagnostic. If
666   /// this name matches the regular expression given in -Rpass-missed=, then the
667   /// diagnostic will be emitted. \p Fn is the function where the diagnostic
668   /// is being emitted. \p Loc is the location information to use in the
669   /// diagnostic. If line table information is available, the diagnostic
670   /// will include the source code location. \p Msg is the message to show.
671   /// Note that this class does not copy this message, so this reference
672   /// must be valid for the whole life time of the diagnostic.
673   OptimizationRemarkMissed(const char *PassName, const Function &Fn,
674                            const DiagnosticLocation &Loc, const Twine &Msg)
675       : DiagnosticInfoIROptimization(DK_OptimizationRemarkMissed, DS_Remark,
676                                      PassName, Fn, Loc, Msg) {}
677
678   friend void emitOptimizationRemarkMissed(LLVMContext &Ctx,
679                                            const char *PassName,
680                                            const Function &Fn,
681                                            const DiagnosticLocation &Loc,
682                                            const Twine &Msg);
683 };
684
685 /// Diagnostic information for optimization analysis remarks.
686 class OptimizationRemarkAnalysis : public DiagnosticInfoIROptimization {
687 public:
688   /// \p PassName is the name of the pass emitting this diagnostic. If this name
689   /// matches the regular expression given in -Rpass-analysis=, then the
690   /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
691   /// remark (single-word, camel-case). \p Loc is the debug location and \p
692   /// CodeRegion is the region that the optimization operates on (currently only
693   /// block is supported).
694   OptimizationRemarkAnalysis(const char *PassName, StringRef RemarkName,
695                              const DiagnosticLocation &Loc,
696                              const Value *CodeRegion);
697
698   /// \brief This is ctor variant allows a pass to build an optimization remark
699   /// from an existing remark.
700   ///
701   /// This is useful when a transformation pass (e.g LV) wants to emit a remark
702   /// (\p Orig) generated by one of its analyses (e.g. LAA) as its own analysis
703   /// remark.  The string \p Prepend will be emitted before the original
704   /// message.
705   OptimizationRemarkAnalysis(const char *PassName, StringRef Prepend,
706                              const OptimizationRemarkAnalysis &Orig)
707       : DiagnosticInfoIROptimization(PassName, Prepend, Orig) {}
708
709   /// \brief Same as above but \p Inst is used to derive code region and debug
710   /// location.
711   OptimizationRemarkAnalysis(const char *PassName, StringRef RemarkName,
712                              const Instruction *Inst);
713
714   static bool classof(const DiagnosticInfo *DI) {
715     return DI->getKind() == DK_OptimizationRemarkAnalysis;
716   }
717
718   static bool isEnabled(StringRef PassName);
719
720   /// \see DiagnosticInfoOptimizationBase::isEnabled.
721   bool isEnabled() const override {
722     return shouldAlwaysPrint() || isEnabled(getPassName());
723   }
724
725   static const char *AlwaysPrint;
726
727   bool shouldAlwaysPrint() const { return getPassName() == AlwaysPrint; }
728
729 protected:
730   OptimizationRemarkAnalysis(enum DiagnosticKind Kind, const char *PassName,
731                              const Function &Fn, const DiagnosticLocation &Loc,
732                              const Twine &Msg)
733       : DiagnosticInfoIROptimization(Kind, DS_Remark, PassName, Fn, Loc, Msg) {}
734
735   OptimizationRemarkAnalysis(enum DiagnosticKind Kind, const char *PassName,
736                              StringRef RemarkName,
737                              const DiagnosticLocation &Loc,
738                              const Value *CodeRegion);
739
740 private:
741   /// This is deprecated now and only used by the function API below.
742   /// \p PassName is the name of the pass emitting this diagnostic. If
743   /// this name matches the regular expression given in -Rpass-analysis=, then
744   /// the diagnostic will be emitted. \p Fn is the function where the diagnostic
745   /// is being emitted. \p Loc is the location information to use in the
746   /// diagnostic. If line table information is available, the diagnostic will
747   /// include the source code location. \p Msg is the message to show. Note that
748   /// this class does not copy this message, so this reference must be valid for
749   /// the whole life time of the diagnostic.
750   OptimizationRemarkAnalysis(const char *PassName, const Function &Fn,
751                              const DiagnosticLocation &Loc, const Twine &Msg)
752       : DiagnosticInfoIROptimization(DK_OptimizationRemarkAnalysis, DS_Remark,
753                                      PassName, Fn, Loc, Msg) {}
754
755   friend void emitOptimizationRemarkAnalysis(LLVMContext &Ctx,
756                                              const char *PassName,
757                                              const Function &Fn,
758                                              const DiagnosticLocation &Loc,
759                                              const Twine &Msg);
760 };
761
762 /// Diagnostic information for optimization analysis remarks related to
763 /// floating-point non-commutativity.
764 class OptimizationRemarkAnalysisFPCommute : public OptimizationRemarkAnalysis {
765 public:
766   /// \p PassName is the name of the pass emitting this diagnostic. If this name
767   /// matches the regular expression given in -Rpass-analysis=, then the
768   /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
769   /// remark (single-word, camel-case). \p Loc is the debug location and \p
770   /// CodeRegion is the region that the optimization operates on (currently only
771   /// block is supported). The front-end will append its own message related to
772   /// options that address floating-point non-commutativity.
773   OptimizationRemarkAnalysisFPCommute(const char *PassName,
774                                       StringRef RemarkName,
775                                       const DiagnosticLocation &Loc,
776                                       const Value *CodeRegion)
777       : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisFPCommute,
778                                    PassName, RemarkName, Loc, CodeRegion) {}
779
780   static bool classof(const DiagnosticInfo *DI) {
781     return DI->getKind() == DK_OptimizationRemarkAnalysisFPCommute;
782   }
783
784 private:
785   /// This is deprecated now and only used by the function API below.
786   /// \p PassName is the name of the pass emitting this diagnostic. If
787   /// this name matches the regular expression given in -Rpass-analysis=, then
788   /// the diagnostic will be emitted. \p Fn is the function where the diagnostic
789   /// is being emitted. \p Loc is the location information to use in the
790   /// diagnostic. If line table information is available, the diagnostic will
791   /// include the source code location. \p Msg is the message to show. The
792   /// front-end will append its own message related to options that address
793   /// floating-point non-commutativity. Note that this class does not copy this
794   /// message, so this reference must be valid for the whole life time of the
795   /// diagnostic.
796   OptimizationRemarkAnalysisFPCommute(const char *PassName, const Function &Fn,
797                                       const DiagnosticLocation &Loc,
798                                       const Twine &Msg)
799       : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisFPCommute,
800                                    PassName, Fn, Loc, Msg) {}
801
802   friend void emitOptimizationRemarkAnalysisFPCommute(
803       LLVMContext &Ctx, const char *PassName, const Function &Fn,
804       const DiagnosticLocation &Loc, const Twine &Msg);
805 };
806
807 /// Diagnostic information for optimization analysis remarks related to
808 /// pointer aliasing.
809 class OptimizationRemarkAnalysisAliasing : public OptimizationRemarkAnalysis {
810 public:
811   /// \p PassName is the name of the pass emitting this diagnostic. If this name
812   /// matches the regular expression given in -Rpass-analysis=, then the
813   /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
814   /// remark (single-word, camel-case). \p Loc is the debug location and \p
815   /// CodeRegion is the region that the optimization operates on (currently only
816   /// block is supported). The front-end will append its own message related to
817   /// options that address pointer aliasing legality.
818   OptimizationRemarkAnalysisAliasing(const char *PassName, StringRef RemarkName,
819                                      const DiagnosticLocation &Loc,
820                                      const Value *CodeRegion)
821       : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisAliasing,
822                                    PassName, RemarkName, Loc, CodeRegion) {}
823
824   static bool classof(const DiagnosticInfo *DI) {
825     return DI->getKind() == DK_OptimizationRemarkAnalysisAliasing;
826   }
827
828 private:
829   /// This is deprecated now and only used by the function API below.
830   /// \p PassName is the name of the pass emitting this diagnostic. If
831   /// this name matches the regular expression given in -Rpass-analysis=, then
832   /// the diagnostic will be emitted. \p Fn is the function where the diagnostic
833   /// is being emitted. \p Loc is the location information to use in the
834   /// diagnostic. If line table information is available, the diagnostic will
835   /// include the source code location. \p Msg is the message to show. The
836   /// front-end will append its own message related to options that address
837   /// pointer aliasing legality. Note that this class does not copy this
838   /// message, so this reference must be valid for the whole life time of the
839   /// diagnostic.
840   OptimizationRemarkAnalysisAliasing(const char *PassName, const Function &Fn,
841                                      const DiagnosticLocation &Loc,
842                                      const Twine &Msg)
843       : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisAliasing,
844                                    PassName, Fn, Loc, Msg) {}
845
846   friend void emitOptimizationRemarkAnalysisAliasing(
847       LLVMContext &Ctx, const char *PassName, const Function &Fn,
848       const DiagnosticLocation &Loc, const Twine &Msg);
849 };
850
851 /// Diagnostic information for machine IR parser.
852 class DiagnosticInfoMIRParser : public DiagnosticInfo {
853   const SMDiagnostic &Diagnostic;
854
855 public:
856   DiagnosticInfoMIRParser(DiagnosticSeverity Severity,
857                           const SMDiagnostic &Diagnostic)
858       : DiagnosticInfo(DK_MIRParser, Severity), Diagnostic(Diagnostic) {}
859
860   const SMDiagnostic &getDiagnostic() const { return Diagnostic; }
861
862   void print(DiagnosticPrinter &DP) const override;
863
864   static bool classof(const DiagnosticInfo *DI) {
865     return DI->getKind() == DK_MIRParser;
866   }
867 };
868
869 /// Diagnostic information for ISel fallback path.
870 class DiagnosticInfoISelFallback : public DiagnosticInfo {
871   /// The function that is concerned by this diagnostic.
872   const Function &Fn;
873
874 public:
875   DiagnosticInfoISelFallback(const Function &Fn,
876                              DiagnosticSeverity Severity = DS_Warning)
877       : DiagnosticInfo(DK_ISelFallback, Severity), Fn(Fn) {}
878
879   const Function &getFunction() const { return Fn; }
880
881   void print(DiagnosticPrinter &DP) const override;
882
883   static bool classof(const DiagnosticInfo *DI) {
884     return DI->getKind() == DK_ISelFallback;
885   }
886 };
887
888 // Create wrappers for C Binding types (see CBindingWrapping.h).
889 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DiagnosticInfo, LLVMDiagnosticInfoRef)
890
891 /// \brief Legacy interface to emit an optimization-applied message.  Use
892 /// (Machine)OptimizationRemarkEmitter instead.
893 ///
894 /// \p PassName is the name of the pass emitting the message. If -Rpass= is
895 /// given and \p PassName matches the regular expression in -Rpass, then the
896 /// remark will be emitted. \p Fn is the function triggering the remark, \p Loc
897 /// is the debug location where the diagnostic is generated. \p Msg is the
898 /// message string to use.
899 void emitOptimizationRemark(LLVMContext &Ctx, const char *PassName,
900                             const Function &Fn, const DiagnosticLocation &Loc,
901                             const Twine &Msg);
902
903 /// \brief Legacy interface to emit an optimization-missed message.  Use
904 /// (Machine)OptimizationRemarkEmitter instead.
905 ///
906 /// \p PassName is the name of the pass emitting the message. If -Rpass-missed=
907 /// is given and \p PassName matches the regular expression in -Rpass, then the
908 /// remark will be emitted. \p Fn is the function triggering the remark, \p Loc
909 /// is the debug location where the diagnostic is generated. \p Msg is the
910 /// message string to use.
911 void emitOptimizationRemarkMissed(LLVMContext &Ctx, const char *PassName,
912                                   const Function &Fn,
913                                   const DiagnosticLocation &Loc,
914                                   const Twine &Msg);
915
916 /// \brief Legacy interface to emit an optimization analysis remark message.
917 /// Use (Machine)OptimizationRemarkEmitter instead.
918 ///
919 /// \p PassName is the name of the pass emitting the message. If
920 /// -Rpass-analysis= is given and \p PassName matches the regular expression in
921 /// -Rpass, then the remark will be emitted. \p Fn is the function triggering
922 /// the remark, \p Loc is the debug location where the diagnostic is
923 /// generated. \p Msg is the message string to use.
924 void emitOptimizationRemarkAnalysis(LLVMContext &Ctx, const char *PassName,
925                                     const Function &Fn,
926                                     const DiagnosticLocation &Loc,
927                                     const Twine &Msg);
928
929 /// \brief Legacy interface to emit an optimization analysis remark related to
930 /// messages about floating-point non-commutativity.  Use
931 /// (Machine)OptimizationRemarkEmitter instead.
932 ///
933 /// \p PassName is the name of the pass emitting the message. If
934 /// -Rpass-analysis= is given and \p PassName matches the regular expression in
935 /// -Rpass, then the remark will be emitted. \p Fn is the function triggering
936 /// the remark, \p Loc is the debug location where the diagnostic is
937 /// generated. \p Msg is the message string to use.
938 void emitOptimizationRemarkAnalysisFPCommute(LLVMContext &Ctx,
939                                              const char *PassName,
940                                              const Function &Fn,
941                                              const DiagnosticLocation &Loc,
942                                              const Twine &Msg);
943
944 /// \brief Legacy interface to emit an optimization analysis remark related to
945 /// messages about pointer aliasing.  Use (Machine)OptimizationRemarkEmitter
946 /// instead.
947 ///
948 /// \p PassName is the name of the pass emitting the message.
949 /// If -Rpass-analysis= is given and \p PassName matches the regular expression
950 /// in -Rpass, then the remark will be emitted. \p Fn is the function triggering
951 /// the remark, \p Loc is the debug location where the diagnostic is generated.
952 /// \p Msg is the message string to use.
953 void emitOptimizationRemarkAnalysisAliasing(LLVMContext &Ctx,
954                                             const char *PassName,
955                                             const Function &Fn,
956                                             const DiagnosticLocation &Loc,
957                                             const Twine &Msg);
958
959 /// Diagnostic information for optimization failures.
960 class DiagnosticInfoOptimizationFailure : public DiagnosticInfoIROptimization {
961 public:
962   /// \p Fn is the function where the diagnostic is being emitted. \p Loc is
963   /// the location information to use in the diagnostic. If line table
964   /// information is available, the diagnostic will include the source code
965   /// location. \p Msg is the message to show. Note that this class does not
966   /// copy this message, so this reference must be valid for the whole life time
967   /// of the diagnostic.
968   DiagnosticInfoOptimizationFailure(const Function &Fn,
969                                     const DiagnosticLocation &Loc,
970                                     const Twine &Msg)
971       : DiagnosticInfoIROptimization(DK_OptimizationFailure, DS_Warning,
972                                      nullptr, Fn, Loc, Msg) {}
973
974   /// \p PassName is the name of the pass emitting this diagnostic.  \p
975   /// RemarkName is a textual identifier for the remark (single-word,
976   /// camel-case).  \p Loc is the debug location and \p CodeRegion is the
977   /// region that the optimization operates on (currently basic block is
978   /// supported).
979   DiagnosticInfoOptimizationFailure(const char *PassName, StringRef RemarkName,
980                                     const DiagnosticLocation &Loc,
981                                     const Value *CodeRegion);
982
983   static bool classof(const DiagnosticInfo *DI) {
984     return DI->getKind() == DK_OptimizationFailure;
985   }
986
987   /// \see DiagnosticInfoOptimizationBase::isEnabled.
988   bool isEnabled() const override;
989 };
990
991 /// Diagnostic information for unsupported feature in backend.
992 class DiagnosticInfoUnsupported : public DiagnosticInfoWithLocationBase {
993 private:
994   Twine Msg;
995
996 public:
997   /// \p Fn is the function where the diagnostic is being emitted. \p Loc is
998   /// the location information to use in the diagnostic. If line table
999   /// information is available, the diagnostic will include the source code
1000   /// location. \p Msg is the message to show. Note that this class does not
1001   /// copy this message, so this reference must be valid for the whole life time
1002   /// of the diagnostic.
1003   DiagnosticInfoUnsupported(
1004       const Function &Fn, const Twine &Msg,
1005       const DiagnosticLocation &Loc = DiagnosticLocation(),
1006       DiagnosticSeverity Severity = DS_Error)
1007       : DiagnosticInfoWithLocationBase(DK_Unsupported, Severity, Fn, Loc),
1008         Msg(Msg) {}
1009
1010   static bool classof(const DiagnosticInfo *DI) {
1011     return DI->getKind() == DK_Unsupported;
1012   }
1013
1014   const Twine &getMessage() const { return Msg; }
1015
1016   void print(DiagnosticPrinter &DP) const override;
1017 };
1018
1019 } // end namespace llvm
1020
1021 #endif // LLVM_IR_DIAGNOSTICINFO_H