OSDN Git Service

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