LLVM  10.0.0svn
DiagnosticInfo.h
Go to the documentation of this file.
1 //===- llvm/IR/DiagnosticInfo.h - Diagnostic Declaration --------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file declares the different classes involved in low level diagnostics.
10 //
11 // Diagnostics reporting is still done as part of the LLVMContext.
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_IR_DIAGNOSTICINFO_H
15 #define LLVM_IR_DIAGNOSTICINFO_H
16 
17 #include "llvm-c/Types.h"
18 #include "llvm/ADT/Optional.h"
19 #include "llvm/ADT/SmallVector.h"
20 #include "llvm/ADT/StringRef.h"
21 #include "llvm/ADT/Twine.h"
22 #include "llvm/IR/DebugLoc.h"
25 #include <algorithm>
26 #include <cstdint>
27 #include <functional>
28 #include <iterator>
29 #include <string>
30 
31 namespace llvm {
32 
33 // Forward declarations.
34 class DiagnosticPrinter;
35 class Function;
36 class Instruction;
37 class LLVMContext;
38 class Module;
39 class SMDiagnostic;
40 
41 /// Defines the different supported severity of a diagnostic.
42 enum DiagnosticSeverity : char {
46  // A note attaches additional information to one of the previous diagnostic
47  // types.
49 };
50 
51 /// Defines the different supported kind of a diagnostic.
52 /// This enum should be extended with a new ID for each added concrete subclass.
79  DK_FirstPluginKind // Must be last value to work with
80  // getNextAvailablePluginDiagnosticKind
81 };
82 
83 /// Get the next available kind ID for a plugin diagnostic.
84 /// Each time this function is called, it returns a different number.
85 /// Therefore, a plugin that wants to "identify" its own classes
86 /// with a dynamic identifier, just have to use this method to get a new ID
87 /// and assign it to each of its classes.
88 /// The returned ID will be greater than or equal to DK_FirstPluginKind.
89 /// Thus, the plugin identifiers will not conflict with the
90 /// DiagnosticKind values.
92 
93 /// This is the base abstract class for diagnostic reporting in
94 /// the backend.
95 /// The print method must be overloaded by the subclasses to print a
96 /// user-friendly message in the client of the backend (let us call it a
97 /// frontend).
99 private:
100  /// Kind defines the kind of report this is about.
101  const /* DiagnosticKind */ int Kind;
102  /// Severity gives the severity of the diagnostic.
103  const DiagnosticSeverity Severity;
104 
105  virtual void anchor();
106 public:
107  DiagnosticInfo(/* DiagnosticKind */ int Kind, DiagnosticSeverity Severity)
108  : Kind(Kind), Severity(Severity) {}
109 
110  virtual ~DiagnosticInfo() = default;
111 
112  /* DiagnosticKind */ int getKind() const { return Kind; }
113  DiagnosticSeverity getSeverity() const { return Severity; }
114 
115  /// Print using the given \p DP a user-friendly message.
116  /// This is the default message that will be printed to the user.
117  /// It is used when the frontend does not directly take advantage
118  /// of the information contained in fields of the subclasses.
119  /// The printed message must not end with '.' nor start with a severity
120  /// keyword.
121  virtual void print(DiagnosticPrinter &DP) const = 0;
122 };
123 
124 using DiagnosticHandlerFunction = std::function<void(const DiagnosticInfo &)>;
125 
126 /// Diagnostic information for inline asm reporting.
127 /// This is basically a message and an optional location.
129 private:
130  /// Optional line information. 0 if not set.
131  unsigned LocCookie = 0;
132  /// Message to be reported.
133  const Twine &MsgStr;
134  /// Optional origin of the problem.
135  const Instruction *Instr = nullptr;
136 
137 public:
138  /// \p MsgStr is the message to be reported to the frontend.
139  /// This class does not copy \p MsgStr, therefore the reference must be valid
140  /// for the whole life time of the Diagnostic.
142  DiagnosticSeverity Severity = DS_Error)
143  : DiagnosticInfo(DK_InlineAsm, Severity), MsgStr(MsgStr) {}
144 
145  /// \p LocCookie if non-zero gives the line number for this report.
146  /// \p MsgStr gives the message.
147  /// This class does not copy \p MsgStr, therefore the reference must be valid
148  /// for the whole life time of the Diagnostic.
149  DiagnosticInfoInlineAsm(unsigned LocCookie, const Twine &MsgStr,
150  DiagnosticSeverity Severity = DS_Error)
151  : DiagnosticInfo(DK_InlineAsm, Severity), LocCookie(LocCookie),
152  MsgStr(MsgStr) {}
153 
154  /// \p Instr gives the original instruction that triggered the diagnostic.
155  /// \p MsgStr gives the message.
156  /// This class does not copy \p MsgStr, therefore the reference must be valid
157  /// for the whole life time of the Diagnostic.
158  /// Same for \p I.
159  DiagnosticInfoInlineAsm(const Instruction &I, const Twine &MsgStr,
160  DiagnosticSeverity Severity = DS_Error);
161 
162  unsigned getLocCookie() const { return LocCookie; }
163  const Twine &getMsgStr() const { return MsgStr; }
164  const Instruction *getInstruction() const { return Instr; }
165 
166  /// \see DiagnosticInfo::print.
167  void print(DiagnosticPrinter &DP) const override;
168 
169  static bool classof(const DiagnosticInfo *DI) {
170  return DI->getKind() == DK_InlineAsm;
171  }
172 };
173 
174 /// Diagnostic information for stack size etc. reporting.
175 /// This is basically a function and a size.
177 private:
178  /// The function that is concerned by this resource limit diagnostic.
179  const Function &Fn;
180 
181  /// Description of the resource type (e.g. stack size)
182  const char *ResourceName;
183 
184  /// The computed size usage
185  uint64_t ResourceSize;
186 
187  // Threshould passed
188  uint64_t ResourceLimit;
189 
190 public:
191  /// \p The function that is concerned by this stack size diagnostic.
192  /// \p The computed stack size.
193  DiagnosticInfoResourceLimit(const Function &Fn, const char *ResourceName,
194  uint64_t ResourceSize,
195  DiagnosticSeverity Severity = DS_Warning,
197  uint64_t ResourceLimit = 0)
198  : DiagnosticInfo(Kind, Severity), Fn(Fn), ResourceName(ResourceName),
199  ResourceSize(ResourceSize), ResourceLimit(ResourceLimit) {}
200 
201  const Function &getFunction() const { return Fn; }
202  const char *getResourceName() const { return ResourceName; }
203  uint64_t getResourceSize() const { return ResourceSize; }
204  uint64_t getResourceLimit() const { return ResourceLimit; }
205 
206  /// \see DiagnosticInfo::print.
207  void print(DiagnosticPrinter &DP) const override;
208 
209  static bool classof(const DiagnosticInfo *DI) {
210  return DI->getKind() == DK_ResourceLimit || DI->getKind() == DK_StackSize;
211  }
212 };
213 
215  virtual void anchor() override;
216 public:
217  DiagnosticInfoStackSize(const Function &Fn, uint64_t StackSize,
218  DiagnosticSeverity Severity = DS_Warning,
219  uint64_t StackLimit = 0)
220  : DiagnosticInfoResourceLimit(Fn, "stack size", StackSize, Severity,
221  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.
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.
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.
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.
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) {}
290  DiagnosticSeverity Severity = DS_Error)
291  : DiagnosticInfo(DK_SampleProfile, Severity), FileName(FileName),
292  Msg(Msg) {}
294  DiagnosticSeverity Severity = DS_Error)
295  : DiagnosticInfo(DK_SampleProfile, Severity), 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 = 0;
315 
316  /// Message to report.
317  const Twine &Msg;
318 };
319 
320 /// Diagnostic information for the PGO profiler.
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 
346  DIFile *File = nullptr;
347  unsigned Line = 0;
348  unsigned Column = 0;
349 
350 public:
351  DiagnosticLocation() = default;
352  DiagnosticLocation(const DebugLoc &DL);
354 
355  bool isValid() const { return File; }
356  /// Return the full path to the file.
357  std::string getAbsolutePath() const;
358  /// Return the file name relative to the compilation directory.
359  StringRef getRelativePath() const;
360  unsigned getLine() const { return Line; }
361  unsigned getColumn() const { return Column; }
362 };
363 
364 /// Common features for diagnostics with an associated location.
366  virtual void anchor() override;
367 public:
368  /// \p Fn is the function where the diagnostic is being emitted. \p Loc is
369  /// the location information to use in the diagnostic.
371  enum DiagnosticSeverity Severity,
372  const Function &Fn,
373  const DiagnosticLocation &Loc)
374  : DiagnosticInfo(Kind, Severity), Fn(Fn), Loc(Loc) {}
375 
376  /// Return true if location information is available for this diagnostic.
377  bool isLocationAvailable() const { return Loc.isValid(); }
378 
379  /// Return a string with the location information for this diagnostic
380  /// in the format "file:line:col". If location information is not available,
381  /// it returns "<unknown>:0:0".
382  const std::string getLocationStr() const;
383 
384  /// Return location information for this diagnostic in three parts:
385  /// the relative source file path, line number and column.
386  void getLocation(StringRef &RelativePath, unsigned &Line,
387  unsigned &Column) const;
388 
389  /// Return the absolute path tot the file.
390  std::string getAbsolutePath() const;
391 
392  const Function &getFunction() const { return Fn; }
393  DiagnosticLocation getLocation() const { return Loc; }
394 
395 private:
396  /// Function where this diagnostic is triggered.
397  const Function &Fn;
398 
399  /// Debug location where this diagnostic is triggered.
400  DiagnosticLocation Loc;
401 };
402 
403 /// Common features for diagnostics dealing with optimization remarks
404 /// that are used by both IR and MIR passes.
406 public:
407  /// Used to set IsVerbose via the stream interface.
408  struct setIsVerbose {};
409 
410  /// When an instance of this is inserted into the stream, the arguments
411  /// following will not appear in the remark printed in the compiler output
412  /// (-Rpass) but only in the optimization record file
413  /// (-fsave-optimization-record).
414  struct setExtraArgs {};
415 
416  /// Used in the streaming interface as the general argument type. It
417  /// internally converts everything into a key-value pair.
418  struct Argument {
419  std::string Key;
420  std::string Val;
421  // If set, the debug location corresponding to the value.
423 
424  explicit Argument(StringRef Str = "") : Key("String"), Val(Str) {}
425  Argument(StringRef Key, const Value *V);
426  Argument(StringRef Key, const Type *T);
427  Argument(StringRef Key, StringRef S);
428  Argument(StringRef Key, const char *S) : Argument(Key, StringRef(S)) {};
429  Argument(StringRef Key, int N);
430  Argument(StringRef Key, float N);
431  Argument(StringRef Key, long N);
432  Argument(StringRef Key, long long N);
433  Argument(StringRef Key, unsigned N);
434  Argument(StringRef Key, unsigned long N);
435  Argument(StringRef Key, unsigned long long N);
436  Argument(StringRef Key, bool B) : Key(Key), Val(B ? "true" : "false") {}
437  Argument(StringRef Key, DebugLoc dl);
438  };
439 
440  /// \p PassName is the name of the pass emitting this diagnostic. \p
441  /// RemarkName is a textual identifier for the remark (single-word,
442  /// camel-case). \p Fn is the function where the diagnostic is being emitted.
443  /// \p Loc is the location information to use in the diagnostic. If line table
444  /// information is available, the diagnostic will include the source code
445  /// location.
447  enum DiagnosticSeverity Severity,
448  const char *PassName, StringRef RemarkName,
449  const Function &Fn,
450  const DiagnosticLocation &Loc)
451  : DiagnosticInfoWithLocationBase(Kind, Severity, Fn, Loc),
452  PassName(PassName), RemarkName(RemarkName) {}
453 
454  void insert(StringRef S);
455  void insert(Argument A);
456  void insert(setIsVerbose V);
457  void insert(setExtraArgs EA);
458 
459  /// \see DiagnosticInfo::print.
460  void print(DiagnosticPrinter &DP) const override;
461 
462  /// Return true if this optimization remark is enabled by one of
463  /// of the LLVM command line flags (-pass-remarks, -pass-remarks-missed,
464  /// or -pass-remarks-analysis). Note that this only handles the LLVM
465  /// flags. We cannot access Clang flags from here (they are handled
466  /// in BackendConsumer::OptimizationRemarkHandler).
467  virtual bool isEnabled() const = 0;
468 
469  StringRef getPassName() const { return PassName; }
470  StringRef getRemarkName() const { return RemarkName; }
471  std::string getMsg() const;
472  Optional<uint64_t> getHotness() const { return Hotness; }
473  void setHotness(Optional<uint64_t> H) { Hotness = H; }
474 
475  bool isVerbose() const { return IsVerbose; }
476 
477  ArrayRef<Argument> getArgs() const { return Args; }
478 
479  static bool classof(const DiagnosticInfo *DI) {
480  return (DI->getKind() >= DK_FirstRemark &&
481  DI->getKind() <= DK_LastRemark) ||
482  (DI->getKind() >= DK_FirstMachineRemark &&
483  DI->getKind() <= DK_LastMachineRemark);
484  }
485 
486  bool isPassed() const {
487  return (getKind() == DK_OptimizationRemark ||
489  }
490 
491  bool isMissed() const {
492  return (getKind() == DK_OptimizationRemarkMissed ||
494  }
495 
496  bool isAnalysis() const {
497  return (getKind() == DK_OptimizationRemarkAnalysis ||
499  }
500 
501 protected:
502  /// Name of the pass that triggers this report. If this matches the
503  /// regular expression given in -Rpass=regexp, then the remark will
504  /// be emitted.
505  const char *PassName;
506 
507  /// Textual identifier for the remark (single-word, camel-case). Can be used
508  /// by external tools reading the output file for optimization remarks to
509  /// identify the remark.
511 
512  /// If profile information is available, this is the number of times the
513  /// corresponding code was executed in a profile instrumentation run.
515 
516  /// Arguments collected via the streaming interface.
518 
519  /// The remark is expected to be noisy.
520  bool IsVerbose = false;
521 
522  /// If positive, the index of the first argument that only appear in
523  /// the optimization records and not in the remark printed in the compiler
524  /// output.
525  int FirstExtraArgIndex = -1;
526 };
527 
528 /// Allow the insertion operator to return the actual remark type rather than a
529 /// common base class. This allows returning the result of the insertion
530 /// directly by value, e.g. return OptimizationRemarkAnalysis(...) << "blah".
531 template <class RemarkT>
532 RemarkT &
533 operator<<(RemarkT &R,
534  typename std::enable_if<
535  std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
536  StringRef>::type S) {
537  R.insert(S);
538  return R;
539 }
540 
541 /// Also allow r-value for the remark to allow insertion into a
542 /// temporarily-constructed remark.
543 template <class RemarkT>
544 RemarkT &
545 operator<<(RemarkT &&R,
546  typename std::enable_if<
547  std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
548  StringRef>::type S) {
549  R.insert(S);
550  return R;
551 }
552 
553 template <class RemarkT>
554 RemarkT &
555 operator<<(RemarkT &R,
556  typename std::enable_if<
557  std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
559  R.insert(A);
560  return R;
561 }
562 
563 template <class RemarkT>
564 RemarkT &
565 operator<<(RemarkT &&R,
566  typename std::enable_if<
567  std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
569  R.insert(A);
570  return R;
571 }
572 
573 template <class RemarkT>
574 RemarkT &
575 operator<<(RemarkT &R,
576  typename std::enable_if<
577  std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
579  R.insert(V);
580  return R;
581 }
582 
583 template <class RemarkT>
584 RemarkT &
585 operator<<(RemarkT &&R,
586  typename std::enable_if<
587  std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
589  R.insert(V);
590  return R;
591 }
592 
593 template <class RemarkT>
594 RemarkT &
595 operator<<(RemarkT &R,
596  typename std::enable_if<
597  std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
599  R.insert(EA);
600  return R;
601 }
602 
603 /// Common features for diagnostics dealing with optimization remarks
604 /// that are used by IR passes.
606  virtual void anchor() override;
607 public:
608  /// \p PassName is the name of the pass emitting this diagnostic. \p
609  /// RemarkName is a textual identifier for the remark (single-word,
610  /// camel-case). \p Fn is the function where the diagnostic is being emitted.
611  /// \p Loc is the location information to use in the diagnostic. If line table
612  /// information is available, the diagnostic will include the source code
613  /// location. \p CodeRegion is IR value (currently basic block) that the
614  /// optimization operates on. This is currently used to provide run-time
615  /// hotness information with PGO.
617  enum DiagnosticSeverity Severity,
618  const char *PassName, StringRef RemarkName,
619  const Function &Fn,
620  const DiagnosticLocation &Loc,
621  const Value *CodeRegion = nullptr)
622  : DiagnosticInfoOptimizationBase(Kind, Severity, PassName, RemarkName, Fn,
623  Loc),
624  CodeRegion(CodeRegion) {}
625 
626  /// This is ctor variant allows a pass to build an optimization remark
627  /// from an existing remark.
628  ///
629  /// This is useful when a transformation pass (e.g LV) wants to emit a remark
630  /// (\p Orig) generated by one of its analyses (e.g. LAA) as its own analysis
631  /// remark. The string \p Prepend will be emitted before the original
632  /// message.
633  DiagnosticInfoIROptimization(const char *PassName, StringRef Prepend,
634  const DiagnosticInfoIROptimization &Orig)
636  (DiagnosticKind)Orig.getKind(), Orig.getSeverity(), PassName,
637  Orig.RemarkName, Orig.getFunction(), Orig.getLocation()),
638  CodeRegion(Orig.getCodeRegion()) {
639  *this << Prepend;
640  std::copy(Orig.Args.begin(), Orig.Args.end(), std::back_inserter(Args));
641  }
642 
643  /// Legacy interface.
644  /// \p PassName is the name of the pass emitting this diagnostic.
645  /// \p Fn is the function where the diagnostic is being emitted. \p Loc is
646  /// the location information to use in the diagnostic. If line table
647  /// information is available, the diagnostic will include the source code
648  /// location. \p Msg is the message to show. Note that this class does not
649  /// copy this message, so this reference must be valid for the whole life time
650  /// of the diagnostic.
652  enum DiagnosticSeverity Severity,
653  const char *PassName, const Function &Fn,
654  const DiagnosticLocation &Loc, const Twine &Msg)
655  : DiagnosticInfoOptimizationBase(Kind, Severity, PassName, "", Fn, Loc) {
656  *this << Msg.str();
657  }
658 
659  const Value *getCodeRegion() const { return CodeRegion; }
660 
661  static bool classof(const DiagnosticInfo *DI) {
662  return DI->getKind() >= DK_FirstRemark && DI->getKind() <= DK_LastRemark;
663  }
664 
665 private:
666  /// The IR value (currently basic block) that the optimization operates on.
667  /// This is currently used to provide run-time hotness information with PGO.
668  const Value *CodeRegion = nullptr;
669 };
670 
671 /// Diagnostic information for applied optimization remarks.
673 public:
674  /// \p PassName is the name of the pass emitting this diagnostic. If this name
675  /// matches the regular expression given in -Rpass=, then the diagnostic will
676  /// be emitted. \p RemarkName is a textual identifier for the remark (single-
677  /// word, camel-case). \p Loc is the debug location and \p CodeRegion is the
678  /// region that the optimization operates on (currently only block is
679  /// supported).
680  OptimizationRemark(const char *PassName, StringRef RemarkName,
681  const DiagnosticLocation &Loc, const Value *CodeRegion);
682 
683  /// Same as above, but the debug location and code region are derived from \p
684  /// Instr.
685  OptimizationRemark(const char *PassName, StringRef RemarkName,
686  const Instruction *Inst);
687 
688  /// Same as above, but the debug location and code region are derived from \p
689  /// Func.
690  OptimizationRemark(const char *PassName, StringRef RemarkName,
691  const Function *Func);
692 
693  static bool classof(const DiagnosticInfo *DI) {
694  return DI->getKind() == DK_OptimizationRemark;
695  }
696 
697  /// \see DiagnosticInfoOptimizationBase::isEnabled.
698  bool isEnabled() const override;
699 
700 private:
701  /// This is deprecated now and only used by the function API below.
702  /// \p PassName is the name of the pass emitting this diagnostic. If
703  /// this name matches the regular expression given in -Rpass=, then the
704  /// diagnostic will be emitted. \p Fn is the function where the diagnostic
705  /// is being emitted. \p Loc is the location information to use in the
706  /// diagnostic. If line table information is available, the diagnostic
707  /// will include the source code location. \p Msg is the message to show.
708  /// Note that this class does not copy this message, so this reference
709  /// must be valid for the whole life time of the diagnostic.
710  OptimizationRemark(const char *PassName, const Function &Fn,
711  const DiagnosticLocation &Loc, const Twine &Msg)
713  Fn, Loc, Msg) {}
714 };
715 
716 /// Diagnostic information for missed-optimization remarks.
718 public:
719  /// \p PassName is the name of the pass emitting this diagnostic. If this name
720  /// matches the regular expression given in -Rpass-missed=, then the
721  /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
722  /// remark (single-word, camel-case). \p Loc is the debug location and \p
723  /// CodeRegion is the region that the optimization operates on (currently only
724  /// block is supported).
725  OptimizationRemarkMissed(const char *PassName, StringRef RemarkName,
726  const DiagnosticLocation &Loc,
727  const Value *CodeRegion);
728 
729  /// Same as above but \p Inst is used to derive code region and debug
730  /// location.
731  OptimizationRemarkMissed(const char *PassName, StringRef RemarkName,
732  const Instruction *Inst);
733 
734  static bool classof(const DiagnosticInfo *DI) {
735  return DI->getKind() == DK_OptimizationRemarkMissed;
736  }
737 
738  /// \see DiagnosticInfoOptimizationBase::isEnabled.
739  bool isEnabled() const override;
740 
741 private:
742  /// This is deprecated now and only used by the function API below.
743  /// \p PassName is the name of the pass emitting this diagnostic. If
744  /// this name matches the regular expression given in -Rpass-missed=, then the
745  /// diagnostic will be emitted. \p Fn is the function where the diagnostic
746  /// is being emitted. \p Loc is the location information to use in the
747  /// diagnostic. If line table information is available, the diagnostic
748  /// will include the source code location. \p Msg is the message to show.
749  /// Note that this class does not copy this message, so this reference
750  /// must be valid for the whole life time of the diagnostic.
751  OptimizationRemarkMissed(const char *PassName, const Function &Fn,
752  const DiagnosticLocation &Loc, const Twine &Msg)
754  PassName, Fn, Loc, Msg) {}
755 };
756 
757 /// Diagnostic information for optimization analysis remarks.
759 public:
760  /// \p PassName is the name of the pass emitting this diagnostic. If this name
761  /// matches the regular expression given in -Rpass-analysis=, then the
762  /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
763  /// remark (single-word, camel-case). \p Loc is the debug location and \p
764  /// CodeRegion is the region that the optimization operates on (currently only
765  /// block is supported).
766  OptimizationRemarkAnalysis(const char *PassName, StringRef RemarkName,
767  const DiagnosticLocation &Loc,
768  const Value *CodeRegion);
769 
770  /// This is ctor variant allows a pass to build an optimization remark
771  /// from an existing remark.
772  ///
773  /// This is useful when a transformation pass (e.g LV) wants to emit a remark
774  /// (\p Orig) generated by one of its analyses (e.g. LAA) as its own analysis
775  /// remark. The string \p Prepend will be emitted before the original
776  /// message.
777  OptimizationRemarkAnalysis(const char *PassName, StringRef Prepend,
778  const OptimizationRemarkAnalysis &Orig)
779  : DiagnosticInfoIROptimization(PassName, Prepend, Orig) {}
780 
781  /// Same as above but \p Inst is used to derive code region and debug
782  /// location.
783  OptimizationRemarkAnalysis(const char *PassName, StringRef RemarkName,
784  const Instruction *Inst);
785 
786  static bool classof(const DiagnosticInfo *DI) {
787  return DI->getKind() == DK_OptimizationRemarkAnalysis;
788  }
789 
790  /// \see DiagnosticInfoOptimizationBase::isEnabled.
791  bool isEnabled() const override;
792 
793  static const char *AlwaysPrint;
794 
795  bool shouldAlwaysPrint() const { return getPassName() == AlwaysPrint; }
796 
797 protected:
798  OptimizationRemarkAnalysis(enum DiagnosticKind Kind, const char *PassName,
799  const Function &Fn, const DiagnosticLocation &Loc,
800  const Twine &Msg)
801  : DiagnosticInfoIROptimization(Kind, DS_Remark, PassName, Fn, Loc, Msg) {}
802 
803  OptimizationRemarkAnalysis(enum DiagnosticKind Kind, const char *PassName,
804  StringRef RemarkName,
805  const DiagnosticLocation &Loc,
806  const Value *CodeRegion);
807 
808 private:
809  /// This is deprecated now and only used by the function API below.
810  /// \p PassName is the name of the pass emitting this diagnostic. If
811  /// this name matches the regular expression given in -Rpass-analysis=, then
812  /// the diagnostic will be emitted. \p Fn is the function where the diagnostic
813  /// is being emitted. \p Loc is the location information to use in the
814  /// diagnostic. If line table information is available, the diagnostic will
815  /// include the source code location. \p Msg is the message to show. Note that
816  /// this class does not copy this message, so this reference must be valid for
817  /// the whole life time of the diagnostic.
818  OptimizationRemarkAnalysis(const char *PassName, const Function &Fn,
819  const DiagnosticLocation &Loc, const Twine &Msg)
821  PassName, Fn, Loc, Msg) {}
822 };
823 
824 /// Diagnostic information for optimization analysis remarks related to
825 /// floating-point non-commutativity.
827  virtual void anchor();
828 public:
829  /// \p PassName is the name of the pass emitting this diagnostic. If this name
830  /// matches the regular expression given in -Rpass-analysis=, then the
831  /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
832  /// remark (single-word, camel-case). \p Loc is the debug location and \p
833  /// CodeRegion is the region that the optimization operates on (currently only
834  /// block is supported). The front-end will append its own message related to
835  /// options that address floating-point non-commutativity.
837  StringRef RemarkName,
838  const DiagnosticLocation &Loc,
839  const Value *CodeRegion)
841  PassName, RemarkName, Loc, CodeRegion) {}
842 
843  static bool classof(const DiagnosticInfo *DI) {
845  }
846 
847 private:
848  /// This is deprecated now and only used by the function API below.
849  /// \p PassName is the name of the pass emitting this diagnostic. If
850  /// this name matches the regular expression given in -Rpass-analysis=, then
851  /// the diagnostic will be emitted. \p Fn is the function where the diagnostic
852  /// is being emitted. \p Loc is the location information to use in the
853  /// diagnostic. If line table information is available, the diagnostic will
854  /// include the source code location. \p Msg is the message to show. The
855  /// front-end will append its own message related to options that address
856  /// floating-point non-commutativity. Note that this class does not copy this
857  /// message, so this reference must be valid for the whole life time of the
858  /// diagnostic.
859  OptimizationRemarkAnalysisFPCommute(const char *PassName, const Function &Fn,
860  const DiagnosticLocation &Loc,
861  const Twine &Msg)
863  PassName, Fn, Loc, Msg) {}
864 };
865 
866 /// Diagnostic information for optimization analysis remarks related to
867 /// pointer aliasing.
869  virtual void anchor();
870 public:
871  /// \p PassName is the name of the pass emitting this diagnostic. If this name
872  /// matches the regular expression given in -Rpass-analysis=, then the
873  /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
874  /// remark (single-word, camel-case). \p Loc is the debug location and \p
875  /// CodeRegion is the region that the optimization operates on (currently only
876  /// block is supported). The front-end will append its own message related to
877  /// options that address pointer aliasing legality.
878  OptimizationRemarkAnalysisAliasing(const char *PassName, StringRef RemarkName,
879  const DiagnosticLocation &Loc,
880  const Value *CodeRegion)
882  PassName, RemarkName, Loc, CodeRegion) {}
883 
884  static bool classof(const DiagnosticInfo *DI) {
886  }
887 
888 private:
889  /// This is deprecated now and only used by the function API below.
890  /// \p PassName is the name of the pass emitting this diagnostic. If
891  /// this name matches the regular expression given in -Rpass-analysis=, then
892  /// the diagnostic will be emitted. \p Fn is the function where the diagnostic
893  /// is being emitted. \p Loc is the location information to use in the
894  /// diagnostic. If line table information is available, the diagnostic will
895  /// include the source code location. \p Msg is the message to show. The
896  /// front-end will append its own message related to options that address
897  /// pointer aliasing legality. Note that this class does not copy this
898  /// message, so this reference must be valid for the whole life time of the
899  /// diagnostic.
900  OptimizationRemarkAnalysisAliasing(const char *PassName, const Function &Fn,
901  const DiagnosticLocation &Loc,
902  const Twine &Msg)
904  PassName, Fn, Loc, Msg) {}
905 };
906 
907 /// Diagnostic information for machine IR parser.
909  const SMDiagnostic &Diagnostic;
910 
911 public:
913  const SMDiagnostic &Diagnostic)
914  : DiagnosticInfo(DK_MIRParser, Severity), Diagnostic(Diagnostic) {}
915 
916  const SMDiagnostic &getDiagnostic() const { return Diagnostic; }
917 
918  void print(DiagnosticPrinter &DP) const override;
919 
920  static bool classof(const DiagnosticInfo *DI) {
921  return DI->getKind() == DK_MIRParser;
922  }
923 };
924 
925 /// Diagnostic information for ISel fallback path.
927  /// The function that is concerned by this diagnostic.
928  const Function &Fn;
929 
930 public:
932  DiagnosticSeverity Severity = DS_Warning)
933  : DiagnosticInfo(DK_ISelFallback, Severity), Fn(Fn) {}
934 
935  const Function &getFunction() const { return Fn; }
936 
937  void print(DiagnosticPrinter &DP) const override;
938 
939  static bool classof(const DiagnosticInfo *DI) {
940  return DI->getKind() == DK_ISelFallback;
941  }
942 };
943 
944 // Create wrappers for C Binding types (see CBindingWrapping.h).
946 
947 /// Diagnostic information for optimization failures.
949 public:
950  /// \p Fn is the function where the diagnostic is being emitted. \p Loc is
951  /// the location information to use in the diagnostic. If line table
952  /// information is available, the diagnostic will include the source code
953  /// location. \p Msg is the message to show. Note that this class does not
954  /// copy this message, so this reference must be valid for the whole life time
955  /// of the diagnostic.
957  const DiagnosticLocation &Loc,
958  const Twine &Msg)
959  : DiagnosticInfoIROptimization(DK_OptimizationFailure, DS_Warning,
960  nullptr, Fn, Loc, Msg) {}
961 
962  /// \p PassName is the name of the pass emitting this diagnostic. \p
963  /// RemarkName is a textual identifier for the remark (single-word,
964  /// camel-case). \p Loc is the debug location and \p CodeRegion is the
965  /// region that the optimization operates on (currently basic block is
966  /// supported).
967  DiagnosticInfoOptimizationFailure(const char *PassName, StringRef RemarkName,
968  const DiagnosticLocation &Loc,
969  const Value *CodeRegion);
970 
971  static bool classof(const DiagnosticInfo *DI) {
972  return DI->getKind() == DK_OptimizationFailure;
973  }
974 
975  /// \see DiagnosticInfoOptimizationBase::isEnabled.
976  bool isEnabled() const override;
977 };
978 
979 /// Diagnostic information for unsupported feature in backend.
981 private:
982  Twine Msg;
983 
984 public:
985  /// \p Fn is the function where the diagnostic is being emitted. \p Loc is
986  /// the location information to use in the diagnostic. If line table
987  /// information is available, the diagnostic will include the source code
988  /// location. \p Msg is the message to show. Note that this class does not
989  /// copy this message, so this reference must be valid for the whole life time
990  /// of the diagnostic.
992  const Function &Fn, const Twine &Msg,
993  const DiagnosticLocation &Loc = DiagnosticLocation(),
994  DiagnosticSeverity Severity = DS_Error)
995  : DiagnosticInfoWithLocationBase(DK_Unsupported, Severity, Fn, Loc),
996  Msg(Msg) {}
997 
998  static bool classof(const DiagnosticInfo *DI) {
999  return DI->getKind() == DK_Unsupported;
1000  }
1001 
1002  const Twine &getMessage() const { return Msg; }
1003 
1004  void print(DiagnosticPrinter &DP) const override;
1005 };
1006 
1007 /// Diagnostic information for MisExpect analysis.
1009 public:
1010  DiagnosticInfoMisExpect(const Instruction *Inst, Twine &Msg);
1011 
1012  /// \see DiagnosticInfo::print.
1013  void print(DiagnosticPrinter &DP) const override;
1014 
1015  static bool classof(const DiagnosticInfo *DI) {
1016  return DI->getKind() == DK_MisExpect;
1017  }
1018 
1019  const Twine &getMsg() const { return Msg; }
1020 
1021 private:
1022  /// Message to report.
1023  const Twine &Msg;
1024 };
1025 
1026 } // end namespace llvm
1027 
1028 #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:23
const Function & getFunction() const
A Module instance is used to store all the information related to an LLVM module. ...
Definition: Module.h:66
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:33
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
const Twine & getMsg() 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:80
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
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: APInt.h:32
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:258
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
Instrumentation for Order File
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)
Diagnostic information for MisExpect analysis.
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:837
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.
ArrayRef< Argument > getArgs() const
static bool classof(const DiagnosticInfo *DI)
#define I(x, y, z)
Definition: MD5.cpp:58
#define N
Diagnostic information for debug metadata version reporting.
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:2047
std::string str() const
Return the twine contents as a std::string.
Definition: Twine.cpp:17
static bool classof(const DiagnosticInfo *DI)
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:74
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:48
Diagnostic information for the sample profiler.
OutputIt copy(R &&Range, OutputIt Out)
Definition: STLExtras.h:1217
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:261