1 //===- llvm/IR/DiagnosticInfo.h - Diagnostic Declaration --------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file declares the different classes involved in low level diagnostics.
12 // Diagnostics reporting is still done as part of the LLVMContext.
13 //===----------------------------------------------------------------------===//
15 #ifndef LLVM_IR_DIAGNOSTICINFO_H
16 #define LLVM_IR_DIAGNOSTICINFO_H
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"
24 #include "llvm/Support/CBindingWrapping.h"
25 #include "llvm/Support/YAMLTraits.h"
34 // Forward declarations.
35 class DiagnosticPrinter;
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
52 /// Defines the different supported kind of a diagnostic.
53 /// This enum should be extended with a new ID for each added concrete subclass.
59 DK_DebugMetadataVersion,
60 DK_DebugMetadataInvalid,
63 DK_OptimizationRemark,
64 DK_OptimizationRemarkMissed,
65 DK_OptimizationRemarkAnalysis,
66 DK_OptimizationRemarkAnalysisFPCommute,
67 DK_OptimizationRemarkAnalysisAliasing,
68 DK_OptimizationFailure,
69 DK_FirstRemark = DK_OptimizationRemark,
70 DK_LastRemark = DK_OptimizationFailure,
71 DK_MachineOptimizationRemark,
72 DK_MachineOptimizationRemarkMissed,
73 DK_MachineOptimizationRemarkAnalysis,
74 DK_FirstMachineRemark = DK_MachineOptimizationRemark,
75 DK_LastMachineRemark = DK_MachineOptimizationRemarkAnalysis,
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.
90 int getNextAvailablePluginDiagnosticKind();
92 /// This is the base abstract class for diagnostic reporting in
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
97 class DiagnosticInfo {
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;
104 virtual void anchor();
106 DiagnosticInfo(/* DiagnosticKind */ int Kind, DiagnosticSeverity Severity)
107 : Kind(Kind), Severity(Severity) {}
109 virtual ~DiagnosticInfo() = default;
111 /* DiagnosticKind */ int getKind() const { return Kind; }
112 DiagnosticSeverity getSeverity() const { return Severity; }
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
120 virtual void print(DiagnosticPrinter &DP) const = 0;
123 using DiagnosticHandlerFunction = std::function<void(const DiagnosticInfo &)>;
125 /// Diagnostic information for inline asm reporting.
126 /// This is basically a message and an optional location.
127 class DiagnosticInfoInlineAsm : public DiagnosticInfo {
129 /// Optional line information. 0 if not set.
130 unsigned LocCookie = 0;
131 /// Message to be reported.
133 /// Optional origin of the problem.
134 const Instruction *Instr = nullptr;
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.
140 DiagnosticInfoInlineAsm(const Twine &MsgStr,
141 DiagnosticSeverity Severity = DS_Error)
142 : DiagnosticInfo(DK_InlineAsm, Severity), MsgStr(MsgStr) {}
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),
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.
158 DiagnosticInfoInlineAsm(const Instruction &I, const Twine &MsgStr,
159 DiagnosticSeverity Severity = DS_Error);
161 unsigned getLocCookie() const { return LocCookie; }
162 const Twine &getMsgStr() const { return MsgStr; }
163 const Instruction *getInstruction() const { return Instr; }
165 /// \see DiagnosticInfo::print.
166 void print(DiagnosticPrinter &DP) const override;
168 static bool classof(const DiagnosticInfo *DI) {
169 return DI->getKind() == DK_InlineAsm;
173 /// Diagnostic information for stack size etc. reporting.
174 /// This is basically a function and a size.
175 class DiagnosticInfoResourceLimit : public DiagnosticInfo {
177 /// The function that is concerned by this resource limit diagnostic.
180 /// Description of the resource type (e.g. stack size)
181 const char *ResourceName;
183 /// The computed size usage
184 uint64_t ResourceSize;
187 uint64_t ResourceLimit;
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,
195 DiagnosticKind Kind = DK_ResourceLimit,
196 uint64_t ResourceLimit = 0)
197 : DiagnosticInfo(Kind, Severity), Fn(Fn), ResourceName(ResourceName),
198 ResourceSize(ResourceSize), ResourceLimit(ResourceLimit) {}
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; }
205 /// \see DiagnosticInfo::print.
206 void print(DiagnosticPrinter &DP) const override;
208 static bool classof(const DiagnosticInfo *DI) {
209 return DI->getKind() == DK_ResourceLimit || DI->getKind() == DK_StackSize;
213 class DiagnosticInfoStackSize : public DiagnosticInfoResourceLimit {
214 virtual void anchor() override;
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) {}
222 uint64_t getStackSize() const { return getResourceSize(); }
223 uint64_t getStackLimit() const { return getResourceLimit(); }
225 static bool classof(const DiagnosticInfo *DI) {
226 return DI->getKind() == DK_StackSize;
230 /// Diagnostic information for debug metadata version reporting.
231 /// This is basically a module and a version.
232 class DiagnosticInfoDebugMetadataVersion : public DiagnosticInfo {
234 /// The module that is concerned by this debug metadata version diagnostic.
236 /// The actual metadata version.
237 unsigned MetadataVersion;
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) {}
247 const Module &getModule() const { return M; }
248 unsigned getMetadataVersion() const { return MetadataVersion; }
250 /// \see DiagnosticInfo::print.
251 void print(DiagnosticPrinter &DP) const override;
253 static bool classof(const DiagnosticInfo *DI) {
254 return DI->getKind() == DK_DebugMetadataVersion;
258 /// Diagnostic information for stripping invalid debug metadata.
259 class DiagnosticInfoIgnoringInvalidDebugMetadata : public DiagnosticInfo {
261 /// The module that is concerned by this debug metadata version diagnostic.
265 /// \p The module that is concerned by this debug metadata version diagnostic.
266 DiagnosticInfoIgnoringInvalidDebugMetadata(
267 const Module &M, DiagnosticSeverity Severity = DS_Warning)
268 : DiagnosticInfo(DK_DebugMetadataVersion, Severity), M(M) {}
270 const Module &getModule() const { return M; }
272 /// \see DiagnosticInfo::print.
273 void print(DiagnosticPrinter &DP) const override;
275 static bool classof(const DiagnosticInfo *DI) {
276 return DI->getKind() == DK_DebugMetadataInvalid;
280 /// Diagnostic information for the sample profiler.
281 class DiagnosticInfoSampleProfile : public DiagnosticInfo {
283 DiagnosticInfoSampleProfile(StringRef FileName, unsigned LineNum,
285 DiagnosticSeverity Severity = DS_Error)
286 : DiagnosticInfo(DK_SampleProfile, Severity), FileName(FileName),
287 LineNum(LineNum), Msg(Msg) {}
288 DiagnosticInfoSampleProfile(StringRef FileName, const Twine &Msg,
289 DiagnosticSeverity Severity = DS_Error)
290 : DiagnosticInfo(DK_SampleProfile, Severity), FileName(FileName),
292 DiagnosticInfoSampleProfile(const Twine &Msg,
293 DiagnosticSeverity Severity = DS_Error)
294 : DiagnosticInfo(DK_SampleProfile, Severity), Msg(Msg) {}
296 /// \see DiagnosticInfo::print.
297 void print(DiagnosticPrinter &DP) const override;
299 static bool classof(const DiagnosticInfo *DI) {
300 return DI->getKind() == DK_SampleProfile;
303 StringRef getFileName() const { return FileName; }
304 unsigned getLineNum() const { return LineNum; }
305 const Twine &getMsg() const { return Msg; }
308 /// Name of the input file associated with this diagnostic.
311 /// Line number where the diagnostic occurred. If 0, no line number will
312 /// be emitted in the message.
313 unsigned LineNum = 0;
315 /// Message to report.
319 /// Diagnostic information for the PGO profiler.
320 class DiagnosticInfoPGOProfile : public DiagnosticInfo {
322 DiagnosticInfoPGOProfile(const char *FileName, const Twine &Msg,
323 DiagnosticSeverity Severity = DS_Error)
324 : DiagnosticInfo(DK_PGOProfile, Severity), FileName(FileName), Msg(Msg) {}
326 /// \see DiagnosticInfo::print.
327 void print(DiagnosticPrinter &DP) const override;
329 static bool classof(const DiagnosticInfo *DI) {
330 return DI->getKind() == DK_PGOProfile;
333 const char *getFileName() const { return FileName; }
334 const Twine &getMsg() const { return Msg; }
337 /// Name of the input file associated with this diagnostic.
338 const char *FileName;
340 /// Message to report.
344 class DiagnosticLocation {
345 DIFile *File = nullptr;
350 DiagnosticLocation() = default;
351 DiagnosticLocation(const DebugLoc &DL);
352 DiagnosticLocation(const DISubprogram *SP);
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; }
363 /// Common features for diagnostics with an associated location.
364 class DiagnosticInfoWithLocationBase : public DiagnosticInfo {
365 virtual void anchor() override;
367 /// \p Fn is the function where the diagnostic is being emitted. \p Loc is
368 /// the location information to use in the diagnostic.
369 DiagnosticInfoWithLocationBase(enum DiagnosticKind Kind,
370 enum DiagnosticSeverity Severity,
372 const DiagnosticLocation &Loc)
373 : DiagnosticInfo(Kind, Severity), Fn(Fn), Loc(Loc) {}
375 /// Return true if location information is available for this diagnostic.
376 bool isLocationAvailable() const { return Loc.isValid(); }
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;
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;
388 /// Return the absolute path tot the file.
389 std::string getAbsolutePath() const;
391 const Function &getFunction() const { return Fn; }
392 DiagnosticLocation getLocation() const { return Loc; }
395 /// Function where this diagnostic is triggered.
398 /// Debug location where this diagnostic is triggered.
399 DiagnosticLocation Loc;
402 /// Common features for diagnostics dealing with optimization remarks
403 /// that are used by both IR and MIR passes.
404 class DiagnosticInfoOptimizationBase : public DiagnosticInfoWithLocationBase {
406 /// Used to set IsVerbose via the stream interface.
407 struct setIsVerbose {};
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 {};
415 /// Used in the streaming interface as the general argument type. It
416 /// internally converts everything into a key-value pair.
420 // If set, the debug location corresponding to the value.
421 DiagnosticLocation Loc;
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);
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
445 DiagnosticInfoOptimizationBase(enum DiagnosticKind Kind,
446 enum DiagnosticSeverity Severity,
447 const char *PassName, StringRef RemarkName,
449 const DiagnosticLocation &Loc)
450 : DiagnosticInfoWithLocationBase(Kind, Severity, Fn, Loc),
451 PassName(PassName), RemarkName(RemarkName) {}
453 void insert(StringRef S);
454 void insert(Argument A);
455 void insert(setIsVerbose V);
456 void insert(setExtraArgs EA);
458 /// \see DiagnosticInfo::print.
459 void print(DiagnosticPrinter &DP) const override;
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;
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; }
473 bool isVerbose() const { return IsVerbose; }
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);
482 bool isPassed() const {
483 return (getKind() == DK_OptimizationRemark ||
484 getKind() == DK_MachineOptimizationRemark);
487 bool isMissed() const {
488 return (getKind() == DK_OptimizationRemarkMissed ||
489 getKind() == DK_MachineOptimizationRemarkMissed);
492 bool isAnalysis() const {
493 return (getKind() == DK_OptimizationRemarkAnalysis ||
494 getKind() == DK_MachineOptimizationRemarkAnalysis);
498 /// Name of the pass that triggers this report. If this matches the
499 /// regular expression given in -Rpass=regexp, then the remark will
501 const char *PassName;
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.
506 StringRef RemarkName;
508 /// If profile information is available, this is the number of times the
509 /// corresponding code was executed in a profile instrumentation run.
510 Optional<uint64_t> Hotness;
512 /// Arguments collected via the streaming interface.
513 SmallVector<Argument, 4> Args;
515 /// The remark is expected to be noisy.
516 bool IsVerbose = false;
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
521 int FirstExtraArgIndex = -1;
523 friend struct yaml::MappingTraits<DiagnosticInfoOptimizationBase *>;
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>
531 operator<<(RemarkT &R,
532 typename std::enable_if<
533 std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
534 StringRef>::type S) {
539 /// Also allow r-value for the remark to allow insertion into a
540 /// temporarily-constructed remark.
541 template <class RemarkT>
543 operator<<(RemarkT &&R,
544 typename std::enable_if<
545 std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
546 StringRef>::type S) {
551 template <class RemarkT>
553 operator<<(RemarkT &R,
554 typename std::enable_if<
555 std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
556 DiagnosticInfoOptimizationBase::Argument>::type A) {
561 template <class RemarkT>
563 operator<<(RemarkT &&R,
564 typename std::enable_if<
565 std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
566 DiagnosticInfoOptimizationBase::Argument>::type A) {
571 template <class RemarkT>
573 operator<<(RemarkT &R,
574 typename std::enable_if<
575 std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
576 DiagnosticInfoOptimizationBase::setIsVerbose>::type V) {
581 template <class RemarkT>
583 operator<<(RemarkT &&R,
584 typename std::enable_if<
585 std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
586 DiagnosticInfoOptimizationBase::setIsVerbose>::type V) {
591 template <class RemarkT>
593 operator<<(RemarkT &R,
594 typename std::enable_if<
595 std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
596 DiagnosticInfoOptimizationBase::setExtraArgs>::type EA) {
601 /// Common features for diagnostics dealing with optimization remarks
602 /// that are used by IR passes.
603 class DiagnosticInfoIROptimization : public DiagnosticInfoOptimizationBase {
604 virtual void anchor() override;
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.
614 DiagnosticInfoIROptimization(enum DiagnosticKind Kind,
615 enum DiagnosticSeverity Severity,
616 const char *PassName, StringRef RemarkName,
618 const DiagnosticLocation &Loc,
619 const Value *CodeRegion = nullptr)
620 : DiagnosticInfoOptimizationBase(Kind, Severity, PassName, RemarkName, Fn,
622 CodeRegion(CodeRegion) {}
624 /// This is ctor variant allows a pass to build an optimization remark
625 /// from an existing remark.
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
631 DiagnosticInfoIROptimization(const char *PassName, StringRef Prepend,
632 const DiagnosticInfoIROptimization &Orig)
633 : DiagnosticInfoOptimizationBase(
634 (DiagnosticKind)Orig.getKind(), Orig.getSeverity(), PassName,
635 Orig.RemarkName, Orig.getFunction(), Orig.getLocation()),
636 CodeRegion(Orig.getCodeRegion()) {
638 std::copy(Orig.Args.begin(), Orig.Args.end(), std::back_inserter(Args));
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.
649 DiagnosticInfoIROptimization(enum DiagnosticKind Kind,
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) {
657 const Value *getCodeRegion() const { return CodeRegion; }
659 static bool classof(const DiagnosticInfo *DI) {
660 return DI->getKind() >= DK_FirstRemark && DI->getKind() <= DK_LastRemark;
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;
669 /// Diagnostic information for applied optimization remarks.
670 class OptimizationRemark : public DiagnosticInfoIROptimization {
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
678 OptimizationRemark(const char *PassName, StringRef RemarkName,
679 const DiagnosticLocation &Loc, const Value *CodeRegion);
681 /// Same as above, but the debug location and code region are derived from \p
683 OptimizationRemark(const char *PassName, StringRef RemarkName,
684 const Instruction *Inst);
686 /// Same as above, but the debug location and code region are derived from \p
688 OptimizationRemark(const char *PassName, StringRef RemarkName,
689 const Function *Func);
691 static bool classof(const DiagnosticInfo *DI) {
692 return DI->getKind() == DK_OptimizationRemark;
695 /// \see DiagnosticInfoOptimizationBase::isEnabled.
696 bool isEnabled() const override;
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)
710 : DiagnosticInfoIROptimization(DK_OptimizationRemark, DS_Remark, PassName,
714 /// Diagnostic information for missed-optimization remarks.
715 class OptimizationRemarkMissed : public DiagnosticInfoIROptimization {
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);
727 /// Same as above but \p Inst is used to derive code region and debug
729 OptimizationRemarkMissed(const char *PassName, StringRef RemarkName,
730 const Instruction *Inst);
732 static bool classof(const DiagnosticInfo *DI) {
733 return DI->getKind() == DK_OptimizationRemarkMissed;
736 /// \see DiagnosticInfoOptimizationBase::isEnabled.
737 bool isEnabled() const override;
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)
751 : DiagnosticInfoIROptimization(DK_OptimizationRemarkMissed, DS_Remark,
752 PassName, Fn, Loc, Msg) {}
755 /// Diagnostic information for optimization analysis remarks.
756 class OptimizationRemarkAnalysis : public DiagnosticInfoIROptimization {
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);
768 /// This is ctor variant allows a pass to build an optimization remark
769 /// from an existing remark.
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
775 OptimizationRemarkAnalysis(const char *PassName, StringRef Prepend,
776 const OptimizationRemarkAnalysis &Orig)
777 : DiagnosticInfoIROptimization(PassName, Prepend, Orig) {}
779 /// Same as above but \p Inst is used to derive code region and debug
781 OptimizationRemarkAnalysis(const char *PassName, StringRef RemarkName,
782 const Instruction *Inst);
784 static bool classof(const DiagnosticInfo *DI) {
785 return DI->getKind() == DK_OptimizationRemarkAnalysis;
788 /// \see DiagnosticInfoOptimizationBase::isEnabled.
789 bool isEnabled() const override;
791 static const char *AlwaysPrint;
793 bool shouldAlwaysPrint() const { return getPassName() == AlwaysPrint; }
796 OptimizationRemarkAnalysis(enum DiagnosticKind Kind, const char *PassName,
797 const Function &Fn, const DiagnosticLocation &Loc,
799 : DiagnosticInfoIROptimization(Kind, DS_Remark, PassName, Fn, Loc, Msg) {}
801 OptimizationRemarkAnalysis(enum DiagnosticKind Kind, const char *PassName,
802 StringRef RemarkName,
803 const DiagnosticLocation &Loc,
804 const Value *CodeRegion);
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)
818 : DiagnosticInfoIROptimization(DK_OptimizationRemarkAnalysis, DS_Remark,
819 PassName, Fn, Loc, Msg) {}
822 /// Diagnostic information for optimization analysis remarks related to
823 /// floating-point non-commutativity.
824 class OptimizationRemarkAnalysisFPCommute : public OptimizationRemarkAnalysis {
825 virtual void anchor();
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.
834 OptimizationRemarkAnalysisFPCommute(const char *PassName,
835 StringRef RemarkName,
836 const DiagnosticLocation &Loc,
837 const Value *CodeRegion)
838 : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisFPCommute,
839 PassName, RemarkName, Loc, CodeRegion) {}
841 static bool classof(const DiagnosticInfo *DI) {
842 return DI->getKind() == DK_OptimizationRemarkAnalysisFPCommute;
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
857 OptimizationRemarkAnalysisFPCommute(const char *PassName, const Function &Fn,
858 const DiagnosticLocation &Loc,
860 : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisFPCommute,
861 PassName, Fn, Loc, Msg) {}
864 /// Diagnostic information for optimization analysis remarks related to
865 /// pointer aliasing.
866 class OptimizationRemarkAnalysisAliasing : public OptimizationRemarkAnalysis {
867 virtual void anchor();
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)
879 : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisAliasing,
880 PassName, RemarkName, Loc, CodeRegion) {}
882 static bool classof(const DiagnosticInfo *DI) {
883 return DI->getKind() == DK_OptimizationRemarkAnalysisAliasing;
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
898 OptimizationRemarkAnalysisAliasing(const char *PassName, const Function &Fn,
899 const DiagnosticLocation &Loc,
901 : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisAliasing,
902 PassName, Fn, Loc, Msg) {}
905 /// Diagnostic information for machine IR parser.
906 class DiagnosticInfoMIRParser : public DiagnosticInfo {
907 const SMDiagnostic &Diagnostic;
910 DiagnosticInfoMIRParser(DiagnosticSeverity Severity,
911 const SMDiagnostic &Diagnostic)
912 : DiagnosticInfo(DK_MIRParser, Severity), Diagnostic(Diagnostic) {}
914 const SMDiagnostic &getDiagnostic() const { return Diagnostic; }
916 void print(DiagnosticPrinter &DP) const override;
918 static bool classof(const DiagnosticInfo *DI) {
919 return DI->getKind() == DK_MIRParser;
923 /// Diagnostic information for ISel fallback path.
924 class DiagnosticInfoISelFallback : public DiagnosticInfo {
925 /// The function that is concerned by this diagnostic.
929 DiagnosticInfoISelFallback(const Function &Fn,
930 DiagnosticSeverity Severity = DS_Warning)
931 : DiagnosticInfo(DK_ISelFallback, Severity), Fn(Fn) {}
933 const Function &getFunction() const { return Fn; }
935 void print(DiagnosticPrinter &DP) const override;
937 static bool classof(const DiagnosticInfo *DI) {
938 return DI->getKind() == DK_ISelFallback;
942 // Create wrappers for C Binding types (see CBindingWrapping.h).
943 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DiagnosticInfo, LLVMDiagnosticInfoRef)
945 /// Diagnostic information for optimization failures.
946 class DiagnosticInfoOptimizationFailure : public DiagnosticInfoIROptimization {
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.
954 DiagnosticInfoOptimizationFailure(const Function &Fn,
955 const DiagnosticLocation &Loc,
957 : DiagnosticInfoIROptimization(DK_OptimizationFailure, DS_Warning,
958 nullptr, Fn, Loc, Msg) {}
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
965 DiagnosticInfoOptimizationFailure(const char *PassName, StringRef RemarkName,
966 const DiagnosticLocation &Loc,
967 const Value *CodeRegion);
969 static bool classof(const DiagnosticInfo *DI) {
970 return DI->getKind() == DK_OptimizationFailure;
973 /// \see DiagnosticInfoOptimizationBase::isEnabled.
974 bool isEnabled() const override;
977 /// Diagnostic information for unsupported feature in backend.
978 class DiagnosticInfoUnsupported : public DiagnosticInfoWithLocationBase {
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.
989 DiagnosticInfoUnsupported(
990 const Function &Fn, const Twine &Msg,
991 const DiagnosticLocation &Loc = DiagnosticLocation(),
992 DiagnosticSeverity Severity = DS_Error)
993 : DiagnosticInfoWithLocationBase(DK_Unsupported, Severity, Fn, Loc),
996 static bool classof(const DiagnosticInfo *DI) {
997 return DI->getKind() == DK_Unsupported;
1000 const Twine &getMessage() const { return Msg; }
1002 void print(DiagnosticPrinter &DP) const override;
1006 template <> struct MappingTraits<DiagnosticInfoOptimizationBase *> {
1007 static void mapping(IO &io, DiagnosticInfoOptimizationBase *&OptDiag);
1011 } // end namespace llvm
1013 #endif // LLVM_IR_DIAGNOSTICINFO_H