OSDN Git Service

Use StringRef in Pass/PassManager APIs (NFC)
[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
411   /// \brief This is ctor variant allows a pass to build an optimization remark
412   /// from an existing remark.
413   ///
414   /// This is useful when a transformation pass (e.g LV) wants to emit a remark
415   /// (\p Orig) generated by one of its analyses (e.g. LAA) as its own analysis
416   /// remark.  The string \p Prepend will be emitted before the original
417   /// message.
418   DiagnosticInfoOptimizationBase(const char *PassName, StringRef Prepend,
419                                  const DiagnosticInfoOptimizationBase &Orig)
420       : DiagnosticInfoWithDebugLocBase((DiagnosticKind)Orig.getKind(),
421                                        Orig.getSeverity(), Orig.getFunction(),
422                                        Orig.getDebugLoc()),
423         PassName(PassName), RemarkName(Orig.RemarkName),
424         CodeRegion(Orig.getCodeRegion()) {
425     *this << Prepend;
426     std::copy(Orig.Args.begin(), Orig.Args.end(), std::back_inserter(Args));
427   }
428
429   /// Legacy interface.
430   /// \p PassName is the name of the pass emitting this diagnostic.
431   /// \p Fn is the function where the diagnostic is being emitted. \p DLoc is
432   /// the location information to use in the diagnostic. If line table
433   /// information is available, the diagnostic will include the source code
434   /// location. \p Msg is the message to show. Note that this class does not
435   /// copy this message, so this reference must be valid for the whole life time
436   /// of the diagnostic.
437   DiagnosticInfoOptimizationBase(enum DiagnosticKind Kind,
438                                  enum DiagnosticSeverity Severity,
439                                  const char *PassName, const Function &Fn,
440                                  const DebugLoc &DLoc, const Twine &Msg,
441                                  Optional<uint64_t> Hotness = None)
442       : DiagnosticInfoWithDebugLocBase(Kind, Severity, Fn, DLoc),
443         PassName(PassName), Hotness(Hotness) {
444     Args.push_back(Argument(Msg.str()));
445   }
446
447   DiagnosticInfoOptimizationBase &operator<<(StringRef S);
448   DiagnosticInfoOptimizationBase &operator<<(Argument A);
449   DiagnosticInfoOptimizationBase &operator<<(setIsVerbose V);
450
451   /// \see DiagnosticInfo::print.
452   void print(DiagnosticPrinter &DP) const override;
453
454   /// Return true if this optimization remark is enabled by one of
455   /// of the LLVM command line flags (-pass-remarks, -pass-remarks-missed,
456   /// or -pass-remarks-analysis). Note that this only handles the LLVM
457   /// flags. We cannot access Clang flags from here (they are handled
458   /// in BackendConsumer::OptimizationRemarkHandler).
459   virtual bool isEnabled() const = 0;
460
461   StringRef getPassName() const { return PassName; }
462   std::string getMsg() const;
463   Optional<uint64_t> getHotness() const { return Hotness; }
464   void setHotness(Optional<uint64_t> H) { Hotness = H; }
465
466   Value *getCodeRegion() const { return CodeRegion; }
467
468   bool isVerbose() const { return IsVerbose; }
469
470   static bool classof(const DiagnosticInfo *DI) {
471     return DI->getKind() >= DK_FirstRemark &&
472            DI->getKind() <= DK_LastRemark;
473   }
474
475 private:
476   /// Name of the pass that triggers this report. If this matches the
477   /// regular expression given in -Rpass=regexp, then the remark will
478   /// be emitted.
479   const char *PassName;
480
481   /// Textual identifier for the remark.  Can be used by external tools reading
482   /// the YAML output file for optimization remarks to identify the remark.
483   StringRef RemarkName;
484
485   /// If profile information is available, this is the number of times the
486   /// corresponding code was executed in a profile instrumentation run.
487   Optional<uint64_t> Hotness;
488
489   /// The IR value (currently basic block) that the optimization operates on.
490   /// This is currently used to provide run-time hotness information with PGO.
491   Value *CodeRegion;
492
493   /// Arguments collected via the streaming interface.
494   SmallVector<Argument, 4> Args;
495
496   /// The remark is expected to be noisy.
497   bool IsVerbose = false;
498
499   friend struct yaml::MappingTraits<DiagnosticInfoOptimizationBase *>;
500 };
501
502 /// Diagnostic information for applied optimization remarks.
503 class OptimizationRemark : public DiagnosticInfoOptimizationBase {
504 public:
505   /// \p PassName is the name of the pass emitting this diagnostic. If
506   /// this name matches the regular expression given in -Rpass=, then the
507   /// diagnostic will be emitted. \p Fn is the function where the diagnostic
508   /// is being emitted. \p DLoc is the location information to use in the
509   /// diagnostic. If line table information is available, the diagnostic
510   /// will include the source code location. \p Msg is the message to show.
511   /// Note that this class does not copy this message, so this reference
512   /// must be valid for the whole life time of the diagnostic.
513   OptimizationRemark(const char *PassName, const Function &Fn,
514                      const DebugLoc &DLoc, const Twine &Msg,
515                      Optional<uint64_t> Hotness = None)
516       : DiagnosticInfoOptimizationBase(DK_OptimizationRemark, DS_Remark,
517                                        PassName, Fn, DLoc, Msg, Hotness) {}
518
519   /// \p PassName is the name of the pass emitting this diagnostic. If this name
520   /// matches the regular expression given in -Rpass=, then the diagnostic will
521   /// be emitted.  \p RemarkName is a textual identifier for the remark.  \p
522   /// DLoc is the debug location and \p CodeRegion is the region that the
523   /// optimization operates on (currently on block is supported).
524   OptimizationRemark(const char *PassName, StringRef RemarkName,
525                      const DebugLoc &DLoc, Value *CodeRegion);
526
527   /// Same as above but the debug location and code region is derived from \p
528   /// Instr.
529   OptimizationRemark(const char *PassName, StringRef RemarkName,
530                      Instruction *Inst);
531
532   static bool classof(const DiagnosticInfo *DI) {
533     return DI->getKind() == DK_OptimizationRemark;
534   }
535
536   /// \see DiagnosticInfoOptimizationBase::isEnabled.
537   bool isEnabled() const override;
538 };
539
540 /// Diagnostic information for missed-optimization remarks.
541 class OptimizationRemarkMissed : public DiagnosticInfoOptimizationBase {
542 public:
543   /// \p PassName is the name of the pass emitting this diagnostic. If
544   /// this name matches the regular expression given in -Rpass-missed=, then the
545   /// diagnostic will be emitted. \p Fn is the function where the diagnostic
546   /// is being emitted. \p DLoc is the location information to use in the
547   /// diagnostic. If line table information is available, the diagnostic
548   /// will include the source code location. \p Msg is the message to show.
549   /// Note that this class does not copy this message, so this reference
550   /// must be valid for the whole life time of the diagnostic.
551   OptimizationRemarkMissed(const char *PassName, const Function &Fn,
552                            const DebugLoc &DLoc, const Twine &Msg,
553                            Optional<uint64_t> Hotness = None)
554       : DiagnosticInfoOptimizationBase(DK_OptimizationRemarkMissed, DS_Remark,
555                                        PassName, Fn, DLoc, Msg, Hotness) {}
556
557   /// \p PassName is the name of the pass emitting this diagnostic. If this name
558   /// matches the regular expression given in -Rpass-missed=, then the
559   /// diagnostic will be emitted.  \p RemarkName is a textual identifier for the
560   /// remark.  \p DLoc is the debug location and \p CodeRegion is the region
561   /// that the optimization operates on (currently on block is supported).
562   OptimizationRemarkMissed(const char *PassName, StringRef RemarkName,
563                            const DebugLoc &DLoc, Value *CodeRegion);
564
565   /// \brief Same as above but \p Inst is used to derive code region and debug
566   /// location.
567   OptimizationRemarkMissed(const char *PassName, StringRef RemarkName,
568                            Instruction *Inst);
569
570   static bool classof(const DiagnosticInfo *DI) {
571     return DI->getKind() == DK_OptimizationRemarkMissed;
572   }
573
574   /// \see DiagnosticInfoOptimizationBase::isEnabled.
575   bool isEnabled() const override;
576 };
577
578 /// Diagnostic information for optimization analysis remarks.
579 class OptimizationRemarkAnalysis : public DiagnosticInfoOptimizationBase {
580 public:
581   /// \p PassName is the name of the pass emitting this diagnostic. If
582   /// this name matches the regular expression given in -Rpass-analysis=, then
583   /// the diagnostic will be emitted. \p Fn is the function where the diagnostic
584   /// is being emitted. \p DLoc is the location information to use in the
585   /// diagnostic. If line table information is available, the diagnostic will
586   /// include the source code location. \p Msg is the message to show. Note that
587   /// this class does not copy this message, so this reference must be valid for
588   /// the whole life time of the diagnostic.
589   OptimizationRemarkAnalysis(const char *PassName, const Function &Fn,
590                              const DebugLoc &DLoc, const Twine &Msg,
591                              Optional<uint64_t> Hotness = None)
592       : DiagnosticInfoOptimizationBase(DK_OptimizationRemarkAnalysis, DS_Remark,
593                                        PassName, Fn, DLoc, Msg, Hotness) {}
594
595   /// \p PassName is the name of the pass emitting this diagnostic. If this name
596   /// matches the regular expression given in -Rpass-analysis=, then the
597   /// diagnostic will be emitted.  \p RemarkName is a textual identifier for the
598   /// remark.  \p DLoc is the debug location and \p CodeRegion is the region
599   /// that the optimization operates on (currently on block is supported).
600   OptimizationRemarkAnalysis(const char *PassName, StringRef RemarkName,
601                              const DebugLoc &DLoc, Value *CodeRegion);
602
603   /// \brief This is ctor variant allows a pass to build an optimization remark
604   /// from an existing remark.
605   ///
606   /// This is useful when a transformation pass (e.g LV) wants to emit a remark
607   /// (\p Orig) generated by one of its analyses (e.g. LAA) as its own analysis
608   /// remark.  The string \p Prepend will be emitted before the original
609   /// message.
610   OptimizationRemarkAnalysis(const char *PassName, StringRef Prepend,
611                              const OptimizationRemarkAnalysis &Orig)
612       : DiagnosticInfoOptimizationBase(PassName, Prepend, Orig) {}
613
614   /// \brief Same as above but \p Inst is used to derive code region and debug
615   /// location.
616   OptimizationRemarkAnalysis(const char *PassName, StringRef RemarkName,
617                              Instruction *Inst);
618
619   static bool classof(const DiagnosticInfo *DI) {
620     return DI->getKind() == DK_OptimizationRemarkAnalysis;
621   }
622
623   /// \see DiagnosticInfoOptimizationBase::isEnabled.
624   bool isEnabled() const override;
625
626   static const char *AlwaysPrint;
627
628   bool shouldAlwaysPrint() const { return getPassName() == AlwaysPrint; }
629
630 protected:
631   OptimizationRemarkAnalysis(enum DiagnosticKind Kind, const char *PassName,
632                              const Function &Fn, const DebugLoc &DLoc,
633                              const Twine &Msg, Optional<uint64_t> Hotness)
634       : DiagnosticInfoOptimizationBase(Kind, DS_Remark, PassName, Fn, DLoc, Msg,
635                                        Hotness) {}
636
637   OptimizationRemarkAnalysis(enum DiagnosticKind Kind, const char *PassName,
638                              StringRef RemarkName, const DebugLoc &DLoc,
639                              Value *CodeRegion);
640 };
641
642 /// Diagnostic information for optimization analysis remarks related to
643 /// floating-point non-commutativity.
644 class OptimizationRemarkAnalysisFPCommute : public OptimizationRemarkAnalysis {
645 public:
646   /// \p PassName is the name of the pass emitting this diagnostic. If
647   /// this name matches the regular expression given in -Rpass-analysis=, then
648   /// the diagnostic will be emitted. \p Fn is the function where the diagnostic
649   /// is being emitted. \p DLoc is the location information to use in the
650   /// diagnostic. If line table information is available, the diagnostic will
651   /// include the source code location. \p Msg is the message to show. The
652   /// front-end will append its own message related to options that address
653   /// floating-point non-commutativity. Note that this class does not copy this
654   /// message, so this reference must be valid for the whole life time of the
655   /// diagnostic.
656   OptimizationRemarkAnalysisFPCommute(const char *PassName, const Function &Fn,
657                                       const DebugLoc &DLoc, const Twine &Msg,
658                                       Optional<uint64_t> Hotness = None)
659       : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisFPCommute,
660                                    PassName, Fn, DLoc, Msg, Hotness) {}
661
662   /// \p PassName is the name of the pass emitting this diagnostic. If this name
663   /// matches the regular expression given in -Rpass-analysis=, then the
664   /// diagnostic will be emitted.  \p RemarkName is a textual identifier for the
665   /// remark.  \p DLoc is the debug location and \p CodeRegion is the region
666   /// that the optimization operates on (currently on block is supported). The
667   /// front-end will append its own message related to options that address
668   /// floating-point non-commutativity.
669   OptimizationRemarkAnalysisFPCommute(const char *PassName,
670                                       StringRef RemarkName,
671                                       const DebugLoc &DLoc, Value *CodeRegion)
672       : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisFPCommute,
673                                    PassName, RemarkName, DLoc, CodeRegion) {}
674
675   static bool classof(const DiagnosticInfo *DI) {
676     return DI->getKind() == DK_OptimizationRemarkAnalysisFPCommute;
677   }
678 };
679
680 /// Diagnostic information for optimization analysis remarks related to
681 /// pointer aliasing.
682 class OptimizationRemarkAnalysisAliasing : public OptimizationRemarkAnalysis {
683 public:
684   /// \p PassName is the name of the pass emitting this diagnostic. If
685   /// this name matches the regular expression given in -Rpass-analysis=, then
686   /// the diagnostic will be emitted. \p Fn is the function where the diagnostic
687   /// is being emitted. \p DLoc is the location information to use in the
688   /// diagnostic. If line table information is available, the diagnostic will
689   /// include the source code location. \p Msg is the message to show. The
690   /// front-end will append its own message related to options that address
691   /// pointer aliasing legality. Note that this class does not copy this
692   /// message, so this reference must be valid for the whole life time of the
693   /// diagnostic.
694   OptimizationRemarkAnalysisAliasing(const char *PassName, const Function &Fn,
695                                      const DebugLoc &DLoc, const Twine &Msg,
696                                      Optional<uint64_t> Hotness = None)
697       : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisAliasing,
698                                    PassName, Fn, DLoc, Msg, Hotness) {}
699
700   /// \p PassName is the name of the pass emitting this diagnostic. If this name
701   /// matches the regular expression given in -Rpass-analysis=, then the
702   /// diagnostic will be emitted.  \p RemarkName is a textual identifier for the
703   /// remark.  \p DLoc is the debug location and \p CodeRegion is the region
704   /// that the optimization operates on (currently on block is supported). The
705   /// front-end will append its own message related to options that address
706   /// pointer aliasing legality.
707   OptimizationRemarkAnalysisAliasing(const char *PassName, StringRef RemarkName,
708                                      const DebugLoc &DLoc, Value *CodeRegion)
709       : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisAliasing,
710                                    PassName, RemarkName, DLoc, CodeRegion) {}
711
712   static bool classof(const DiagnosticInfo *DI) {
713     return DI->getKind() == DK_OptimizationRemarkAnalysisAliasing;
714   }
715 };
716
717 /// Diagnostic information for machine IR parser.
718 class DiagnosticInfoMIRParser : public DiagnosticInfo {
719   const SMDiagnostic &Diagnostic;
720
721 public:
722   DiagnosticInfoMIRParser(DiagnosticSeverity Severity,
723                           const SMDiagnostic &Diagnostic)
724       : DiagnosticInfo(DK_MIRParser, Severity), Diagnostic(Diagnostic) {}
725
726   const SMDiagnostic &getDiagnostic() const { return Diagnostic; }
727
728   void print(DiagnosticPrinter &DP) const override;
729
730   static bool classof(const DiagnosticInfo *DI) {
731     return DI->getKind() == DK_MIRParser;
732   }
733 };
734
735 /// Diagnostic information for ISel fallback path.
736 class DiagnosticInfoISelFallback : public DiagnosticInfo {
737   /// The function that is concerned by this diagnostic.
738   const Function &Fn;
739
740 public:
741   DiagnosticInfoISelFallback(const Function &Fn,
742                              DiagnosticSeverity Severity = DS_Warning)
743       : DiagnosticInfo(DK_ISelFallback, Severity), Fn(Fn) {}
744
745   const Function &getFunction() const { return Fn; }
746
747   void print(DiagnosticPrinter &DP) const override;
748
749   static bool classof(const DiagnosticInfo *DI) {
750     return DI->getKind() == DK_ISelFallback;
751   }
752 };
753
754 // Create wrappers for C Binding types (see CBindingWrapping.h).
755 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DiagnosticInfo, LLVMDiagnosticInfoRef)
756
757 /// Emit an optimization-applied message. \p PassName is the name of the pass
758 /// emitting the message. If -Rpass= is given and \p PassName matches the
759 /// regular expression in -Rpass, then the remark will be emitted. \p Fn is
760 /// the function triggering the remark, \p DLoc is the debug location where
761 /// the diagnostic is generated. \p Msg is the message string to use.
762 void emitOptimizationRemark(LLVMContext &Ctx, const char *PassName,
763                             const Function &Fn, const DebugLoc &DLoc,
764                             const Twine &Msg);
765
766 /// Emit an optimization-missed message. \p PassName is the name of the
767 /// pass emitting the message. If -Rpass-missed= is given and \p PassName
768 /// matches the regular expression in -Rpass, then the remark will be
769 /// emitted. \p Fn is the function triggering the remark, \p DLoc is the
770 /// debug location where the diagnostic is generated. \p Msg is the
771 /// message string to use.
772 void emitOptimizationRemarkMissed(LLVMContext &Ctx, const char *PassName,
773                                   const Function &Fn, const DebugLoc &DLoc,
774                                   const Twine &Msg);
775
776 /// Emit an optimization analysis remark message. \p PassName is the name of
777 /// the pass emitting the message. If -Rpass-analysis= is given and \p
778 /// PassName matches the regular expression in -Rpass, then the remark will be
779 /// emitted. \p Fn is the function triggering the remark, \p DLoc is the debug
780 /// location where the diagnostic is generated. \p Msg is the message string
781 /// to use.
782 void emitOptimizationRemarkAnalysis(LLVMContext &Ctx, const char *PassName,
783                                     const Function &Fn, const DebugLoc &DLoc,
784                                     const Twine &Msg);
785
786 /// Emit an optimization analysis remark related to messages about
787 /// floating-point non-commutativity. \p PassName is the name of the pass
788 /// emitting the message. If -Rpass-analysis= is given and \p PassName matches
789 /// the regular expression in -Rpass, then the remark will be emitted. \p Fn is
790 /// the function triggering the remark, \p DLoc is the debug location where the
791 /// diagnostic is generated. \p Msg is the message string to use.
792 void emitOptimizationRemarkAnalysisFPCommute(LLVMContext &Ctx,
793                                              const char *PassName,
794                                              const Function &Fn,
795                                              const DebugLoc &DLoc,
796                                              const Twine &Msg);
797
798 /// Emit an optimization analysis remark related to messages about
799 /// pointer aliasing. \p PassName is the name of the pass emitting the message.
800 /// If -Rpass-analysis= is given and \p PassName matches the regular expression
801 /// in -Rpass, then the remark will be emitted. \p Fn is the function triggering
802 /// the remark, \p DLoc is the debug location where the diagnostic is generated.
803 /// \p Msg is the message string to use.
804 void emitOptimizationRemarkAnalysisAliasing(LLVMContext &Ctx,
805                                             const char *PassName,
806                                             const Function &Fn,
807                                             const DebugLoc &DLoc,
808                                             const Twine &Msg);
809
810 /// Diagnostic information for optimization failures.
811 class DiagnosticInfoOptimizationFailure
812     : public DiagnosticInfoOptimizationBase {
813 public:
814   /// \p Fn is the function where the diagnostic is being emitted. \p DLoc is
815   /// the location information to use in the diagnostic. If line table
816   /// information is available, the diagnostic will include the source code
817   /// location. \p Msg is the message to show. Note that this class does not
818   /// copy this message, so this reference must be valid for the whole life time
819   /// of the diagnostic.
820   DiagnosticInfoOptimizationFailure(const Function &Fn, const DebugLoc &DLoc,
821                                     const Twine &Msg)
822       : DiagnosticInfoOptimizationBase(DK_OptimizationFailure, DS_Warning,
823                                        nullptr, Fn, DLoc, Msg) {}
824
825   static bool classof(const DiagnosticInfo *DI) {
826     return DI->getKind() == DK_OptimizationFailure;
827   }
828
829   /// \see DiagnosticInfoOptimizationBase::isEnabled.
830   bool isEnabled() const override;
831 };
832
833 /// Diagnostic information for unsupported feature in backend.
834 class DiagnosticInfoUnsupported
835     : public DiagnosticInfoWithDebugLocBase {
836 private:
837   Twine Msg;
838
839 public:
840   /// \p Fn is the function where the diagnostic is being emitted. \p DLoc is
841   /// the location information to use in the diagnostic. If line table
842   /// information is available, the diagnostic will include the source code
843   /// location. \p Msg is the message to show. Note that this class does not
844   /// copy this message, so this reference must be valid for the whole life time
845   /// of the diagnostic.
846   DiagnosticInfoUnsupported(const Function &Fn, const Twine &Msg,
847                             DebugLoc DLoc = DebugLoc(),
848                             DiagnosticSeverity Severity = DS_Error)
849       : DiagnosticInfoWithDebugLocBase(DK_Unsupported, Severity, Fn, DLoc),
850         Msg(Msg) {}
851
852   static bool classof(const DiagnosticInfo *DI) {
853     return DI->getKind() == DK_Unsupported;
854   }
855
856   const Twine &getMessage() const { return Msg; }
857
858   void print(DiagnosticPrinter &DP) const override;
859 };
860
861 /// Emit a warning when loop vectorization is specified but fails. \p Fn is the
862 /// function triggering the warning, \p DLoc is the debug location where the
863 /// diagnostic is generated. \p Msg is the message string to use.
864 void emitLoopVectorizeWarning(LLVMContext &Ctx, const Function &Fn,
865                               const DebugLoc &DLoc, const Twine &Msg);
866
867 /// Emit a warning when loop interleaving is specified but fails. \p Fn is the
868 /// function triggering the warning, \p DLoc is the debug location where the
869 /// diagnostic is generated. \p Msg is the message string to use.
870 void emitLoopInterleaveWarning(LLVMContext &Ctx, const Function &Fn,
871                                const DebugLoc &DLoc, const Twine &Msg);
872
873 } // end namespace llvm
874
875 #endif // LLVM_IR_DIAGNOSTICINFO_H