OSDN Git Service

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