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