OSDN Git Service

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