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 /// \brief 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 /// \brief 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 /// \brief 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 /// \brief 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;
105 DiagnosticInfo(/* DiagnosticKind */ int Kind, DiagnosticSeverity Severity)
106 : Kind(Kind), Severity(Severity) {}
108 virtual ~DiagnosticInfo() = default;
110 /* DiagnosticKind */ int getKind() const { return Kind; }
111 DiagnosticSeverity getSeverity() const { return Severity; }
113 /// Print using the given \p DP a user-friendly message.
114 /// This is the default message that will be printed to the user.
115 /// It is used when the frontend does not directly take advantage
116 /// of the information contained in fields of the subclasses.
117 /// The printed message must not end with '.' nor start with a severity
119 virtual void print(DiagnosticPrinter &DP) const = 0;
122 using DiagnosticHandlerFunction = std::function<void(const DiagnosticInfo &)>;
124 /// Diagnostic information for inline asm reporting.
125 /// This is basically a message and an optional location.
126 class DiagnosticInfoInlineAsm : public DiagnosticInfo {
128 /// Optional line information. 0 if not set.
129 unsigned LocCookie = 0;
130 /// Message to be reported.
132 /// Optional origin of the problem.
133 const Instruction *Instr = nullptr;
136 /// \p MsgStr is the message to be reported to the frontend.
137 /// This class does not copy \p MsgStr, therefore the reference must be valid
138 /// for the whole life time of the Diagnostic.
139 DiagnosticInfoInlineAsm(const Twine &MsgStr,
140 DiagnosticSeverity Severity = DS_Error)
141 : DiagnosticInfo(DK_InlineAsm, Severity), MsgStr(MsgStr) {}
143 /// \p LocCookie if non-zero gives the line number for this report.
144 /// \p MsgStr gives the message.
145 /// This class does not copy \p MsgStr, therefore the reference must be valid
146 /// for the whole life time of the Diagnostic.
147 DiagnosticInfoInlineAsm(unsigned LocCookie, const Twine &MsgStr,
148 DiagnosticSeverity Severity = DS_Error)
149 : DiagnosticInfo(DK_InlineAsm, Severity), LocCookie(LocCookie),
152 /// \p Instr gives the original instruction that triggered the diagnostic.
153 /// \p MsgStr gives the message.
154 /// This class does not copy \p MsgStr, therefore the reference must be valid
155 /// for the whole life time of the Diagnostic.
157 DiagnosticInfoInlineAsm(const Instruction &I, const Twine &MsgStr,
158 DiagnosticSeverity Severity = DS_Error);
160 unsigned getLocCookie() const { return LocCookie; }
161 const Twine &getMsgStr() const { return MsgStr; }
162 const Instruction *getInstruction() const { return Instr; }
164 /// \see DiagnosticInfo::print.
165 void print(DiagnosticPrinter &DP) const override;
167 static bool classof(const DiagnosticInfo *DI) {
168 return DI->getKind() == DK_InlineAsm;
172 /// Diagnostic information for stack size etc. reporting.
173 /// This is basically a function and a size.
174 class DiagnosticInfoResourceLimit : public DiagnosticInfo {
176 /// The function that is concerned by this resource limit diagnostic.
179 /// Description of the resource type (e.g. stack size)
180 const char *ResourceName;
182 /// The computed size usage
183 uint64_t ResourceSize;
186 uint64_t ResourceLimit;
189 /// \p The function that is concerned by this stack size diagnostic.
190 /// \p The computed stack size.
191 DiagnosticInfoResourceLimit(const Function &Fn, const char *ResourceName,
192 uint64_t ResourceSize,
193 DiagnosticSeverity Severity = DS_Warning,
194 DiagnosticKind Kind = DK_ResourceLimit,
195 uint64_t ResourceLimit = 0)
196 : DiagnosticInfo(Kind, Severity), Fn(Fn), ResourceName(ResourceName),
197 ResourceSize(ResourceSize), ResourceLimit(ResourceLimit) {}
199 const Function &getFunction() const { return Fn; }
200 const char *getResourceName() const { return ResourceName; }
201 uint64_t getResourceSize() const { return ResourceSize; }
202 uint64_t getResourceLimit() const { return ResourceLimit; }
204 /// \see DiagnosticInfo::print.
205 void print(DiagnosticPrinter &DP) const override;
207 static bool classof(const DiagnosticInfo *DI) {
208 return DI->getKind() == DK_ResourceLimit || DI->getKind() == DK_StackSize;
212 class DiagnosticInfoStackSize : public DiagnosticInfoResourceLimit {
214 DiagnosticInfoStackSize(const Function &Fn, uint64_t StackSize,
215 DiagnosticSeverity Severity = DS_Warning,
216 uint64_t StackLimit = 0)
217 : DiagnosticInfoResourceLimit(Fn, "stack size", StackSize, Severity,
218 DK_StackSize, StackLimit) {}
220 uint64_t getStackSize() const { return getResourceSize(); }
221 uint64_t getStackLimit() const { return getResourceLimit(); }
223 static bool classof(const DiagnosticInfo *DI) {
224 return DI->getKind() == DK_StackSize;
228 /// Diagnostic information for debug metadata version reporting.
229 /// This is basically a module and a version.
230 class DiagnosticInfoDebugMetadataVersion : public DiagnosticInfo {
232 /// The module that is concerned by this debug metadata version diagnostic.
234 /// The actual metadata version.
235 unsigned MetadataVersion;
238 /// \p The module that is concerned by this debug metadata version diagnostic.
239 /// \p The actual metadata version.
240 DiagnosticInfoDebugMetadataVersion(const Module &M, unsigned MetadataVersion,
241 DiagnosticSeverity Severity = DS_Warning)
242 : DiagnosticInfo(DK_DebugMetadataVersion, Severity), M(M),
243 MetadataVersion(MetadataVersion) {}
245 const Module &getModule() const { return M; }
246 unsigned getMetadataVersion() const { return MetadataVersion; }
248 /// \see DiagnosticInfo::print.
249 void print(DiagnosticPrinter &DP) const override;
251 static bool classof(const DiagnosticInfo *DI) {
252 return DI->getKind() == DK_DebugMetadataVersion;
256 /// Diagnostic information for stripping invalid debug metadata.
257 class DiagnosticInfoIgnoringInvalidDebugMetadata : public DiagnosticInfo {
259 /// The module that is concerned by this debug metadata version diagnostic.
263 /// \p The module that is concerned by this debug metadata version diagnostic.
264 DiagnosticInfoIgnoringInvalidDebugMetadata(
265 const Module &M, DiagnosticSeverity Severity = DS_Warning)
266 : DiagnosticInfo(DK_DebugMetadataVersion, Severity), M(M) {}
268 const Module &getModule() const { return M; }
270 /// \see DiagnosticInfo::print.
271 void print(DiagnosticPrinter &DP) const override;
273 static bool classof(const DiagnosticInfo *DI) {
274 return DI->getKind() == DK_DebugMetadataInvalid;
278 /// Diagnostic information for the sample profiler.
279 class DiagnosticInfoSampleProfile : public DiagnosticInfo {
281 DiagnosticInfoSampleProfile(StringRef FileName, unsigned LineNum,
283 DiagnosticSeverity Severity = DS_Error)
284 : DiagnosticInfo(DK_SampleProfile, Severity), FileName(FileName),
285 LineNum(LineNum), Msg(Msg) {}
286 DiagnosticInfoSampleProfile(StringRef FileName, const Twine &Msg,
287 DiagnosticSeverity Severity = DS_Error)
288 : DiagnosticInfo(DK_SampleProfile, Severity), FileName(FileName),
290 DiagnosticInfoSampleProfile(const Twine &Msg,
291 DiagnosticSeverity Severity = DS_Error)
292 : DiagnosticInfo(DK_SampleProfile, Severity), Msg(Msg) {}
294 /// \see DiagnosticInfo::print.
295 void print(DiagnosticPrinter &DP) const override;
297 static bool classof(const DiagnosticInfo *DI) {
298 return DI->getKind() == DK_SampleProfile;
301 StringRef getFileName() const { return FileName; }
302 unsigned getLineNum() const { return LineNum; }
303 const Twine &getMsg() const { return Msg; }
306 /// Name of the input file associated with this diagnostic.
309 /// Line number where the diagnostic occurred. If 0, no line number will
310 /// be emitted in the message.
311 unsigned LineNum = 0;
313 /// Message to report.
317 /// Diagnostic information for the PGO profiler.
318 class DiagnosticInfoPGOProfile : public DiagnosticInfo {
320 DiagnosticInfoPGOProfile(const char *FileName, const Twine &Msg,
321 DiagnosticSeverity Severity = DS_Error)
322 : DiagnosticInfo(DK_PGOProfile, Severity), FileName(FileName), Msg(Msg) {}
324 /// \see DiagnosticInfo::print.
325 void print(DiagnosticPrinter &DP) const override;
327 static bool classof(const DiagnosticInfo *DI) {
328 return DI->getKind() == DK_PGOProfile;
331 const char *getFileName() const { return FileName; }
332 const Twine &getMsg() const { return Msg; }
335 /// Name of the input file associated with this diagnostic.
336 const char *FileName;
338 /// Message to report.
342 class DiagnosticLocation {
348 DiagnosticLocation() = default;
349 DiagnosticLocation(const DebugLoc &DL);
350 DiagnosticLocation(const DISubprogram *SP);
352 bool isValid() const { return !Filename.empty(); }
353 StringRef getFilename() const { return Filename; }
354 unsigned getLine() const { return Line; }
355 unsigned getColumn() const { return Column; }
358 /// Common features for diagnostics with an associated location.
359 class DiagnosticInfoWithLocationBase : public DiagnosticInfo {
361 /// \p Fn is the function where the diagnostic is being emitted. \p Loc is
362 /// the location information to use in the diagnostic.
363 DiagnosticInfoWithLocationBase(enum DiagnosticKind Kind,
364 enum DiagnosticSeverity Severity,
366 const DiagnosticLocation &Loc)
367 : DiagnosticInfo(Kind, Severity), Fn(Fn), Loc(Loc) {}
369 /// Return true if location information is available for this diagnostic.
370 bool isLocationAvailable() const { return Loc.isValid(); }
372 /// Return a string with the location information for this diagnostic
373 /// in the format "file:line:col". If location information is not available,
374 /// it returns "<unknown>:0:0".
375 const std::string getLocationStr() const;
377 /// Return location information for this diagnostic in three parts:
378 /// the source file name, line number and column.
379 void getLocation(StringRef *Filename, unsigned *Line, unsigned *Column) const;
381 const Function &getFunction() const { return Fn; }
382 DiagnosticLocation getLocation() const { return Loc; }
385 /// Function where this diagnostic is triggered.
388 /// Debug location where this diagnostic is triggered.
389 DiagnosticLocation Loc;
392 /// \brief Common features for diagnostics dealing with optimization remarks
393 /// that are used by both IR and MIR passes.
394 class DiagnosticInfoOptimizationBase : public DiagnosticInfoWithLocationBase {
396 /// \brief Used to set IsVerbose via the stream interface.
397 struct setIsVerbose {};
399 /// \brief When an instance of this is inserted into the stream, the arguments
400 /// following will not appear in the remark printed in the compiler output
401 /// (-Rpass) but only in the optimization record file
402 /// (-fsave-optimization-record).
403 struct setExtraArgs {};
405 /// \brief Used in the streaming interface as the general argument type. It
406 /// internally converts everything into a key-value pair.
410 // If set, the debug location corresponding to the value.
411 DiagnosticLocation Loc;
413 explicit Argument(StringRef Str = "") : Key("String"), Val(Str) {}
414 Argument(StringRef Key, const Value *V);
415 Argument(StringRef Key, const Type *T);
416 Argument(StringRef Key, StringRef S);
417 Argument(StringRef Key, int N);
418 Argument(StringRef Key, long N);
419 Argument(StringRef Key, long long N);
420 Argument(StringRef Key, unsigned N);
421 Argument(StringRef Key, unsigned long N);
422 Argument(StringRef Key, unsigned long long N);
423 Argument(StringRef Key, bool B) : Key(Key), Val(B ? "true" : "false") {}
424 Argument(StringRef Key, DebugLoc dl);
427 /// \p PassName is the name of the pass emitting this diagnostic. \p
428 /// RemarkName is a textual identifier for the remark (single-word,
429 /// camel-case). \p Fn is the function where the diagnostic is being emitted.
430 /// \p Loc is the location information to use in the diagnostic. If line table
431 /// information is available, the diagnostic will include the source code
433 DiagnosticInfoOptimizationBase(enum DiagnosticKind Kind,
434 enum DiagnosticSeverity Severity,
435 const char *PassName, StringRef RemarkName,
437 const DiagnosticLocation &Loc)
438 : DiagnosticInfoWithLocationBase(Kind, Severity, Fn, Loc),
439 PassName(PassName), RemarkName(RemarkName) {}
441 void insert(StringRef S);
442 void insert(Argument A);
443 void insert(setIsVerbose V);
444 void insert(setExtraArgs EA);
446 /// \see DiagnosticInfo::print.
447 void print(DiagnosticPrinter &DP) const override;
449 /// Return true if this optimization remark is enabled by one of
450 /// of the LLVM command line flags (-pass-remarks, -pass-remarks-missed,
451 /// or -pass-remarks-analysis). Note that this only handles the LLVM
452 /// flags. We cannot access Clang flags from here (they are handled
453 /// in BackendConsumer::OptimizationRemarkHandler).
454 virtual bool isEnabled() const = 0;
456 StringRef getPassName() const { return PassName; }
457 std::string getMsg() const;
458 Optional<uint64_t> getHotness() const { return Hotness; }
459 void setHotness(Optional<uint64_t> H) { Hotness = H; }
461 bool isVerbose() const { return IsVerbose; }
463 static bool classof(const DiagnosticInfo *DI) {
464 return (DI->getKind() >= DK_FirstRemark &&
465 DI->getKind() <= DK_LastRemark) ||
466 (DI->getKind() >= DK_FirstMachineRemark &&
467 DI->getKind() <= DK_LastMachineRemark);
470 bool isPassed() const {
471 return (getKind() == DK_OptimizationRemark ||
472 getKind() == DK_MachineOptimizationRemark);
475 bool isMissed() const {
476 return (getKind() == DK_OptimizationRemarkMissed ||
477 getKind() == DK_MachineOptimizationRemarkMissed);
480 bool isAnalysis() const {
481 return (getKind() == DK_OptimizationRemarkAnalysis ||
482 getKind() == DK_MachineOptimizationRemarkAnalysis);
486 /// Name of the pass that triggers this report. If this matches the
487 /// regular expression given in -Rpass=regexp, then the remark will
489 const char *PassName;
491 /// Textual identifier for the remark (single-word, camel-case). Can be used
492 /// by external tools reading the YAML output file for optimization remarks to
493 /// identify the remark.
494 StringRef RemarkName;
496 /// If profile information is available, this is the number of times the
497 /// corresponding code was executed in a profile instrumentation run.
498 Optional<uint64_t> Hotness;
500 /// Arguments collected via the streaming interface.
501 SmallVector<Argument, 4> Args;
503 /// The remark is expected to be noisy.
504 bool IsVerbose = false;
506 /// \brief If positive, the index of the first argument that only appear in
507 /// the optimization records and not in the remark printed in the compiler
509 int FirstExtraArgIndex = -1;
511 friend struct yaml::MappingTraits<DiagnosticInfoOptimizationBase *>;
514 /// Allow the insertion operator to return the actual remark type rather than a
515 /// common base class. This allows returning the result of the insertion
516 /// directly by value, e.g. return OptimizationRemarkAnalysis(...) << "blah".
517 template <class RemarkT>
519 operator<<(RemarkT &R,
520 typename std::enable_if<
521 std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
522 StringRef>::type S) {
527 /// Also allow r-value for the remark to allow insertion into a
528 /// temporarily-constructed remark.
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 template <class RemarkT>
541 operator<<(RemarkT &R,
542 typename std::enable_if<
543 std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
544 DiagnosticInfoOptimizationBase::Argument>::type A) {
549 template <class RemarkT>
551 operator<<(RemarkT &&R,
552 typename std::enable_if<
553 std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
554 DiagnosticInfoOptimizationBase::Argument>::type A) {
559 template <class RemarkT>
561 operator<<(RemarkT &R,
562 typename std::enable_if<
563 std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
564 DiagnosticInfoOptimizationBase::setIsVerbose>::type V) {
569 template <class RemarkT>
571 operator<<(RemarkT &&R,
572 typename std::enable_if<
573 std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
574 DiagnosticInfoOptimizationBase::setIsVerbose>::type V) {
579 template <class RemarkT>
581 operator<<(RemarkT &R,
582 typename std::enable_if<
583 std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
584 DiagnosticInfoOptimizationBase::setExtraArgs>::type EA) {
589 /// \brief Common features for diagnostics dealing with optimization remarks
590 /// that are used by IR passes.
591 class DiagnosticInfoIROptimization : public DiagnosticInfoOptimizationBase {
593 /// \p PassName is the name of the pass emitting this diagnostic. \p
594 /// RemarkName is a textual identifier for the remark (single-word,
595 /// camel-case). \p Fn is the function where the diagnostic is being emitted.
596 /// \p Loc is the location information to use in the diagnostic. If line table
597 /// information is available, the diagnostic will include the source code
598 /// location. \p CodeRegion is IR value (currently basic block) that the
599 /// optimization operates on. This is currently used to provide run-time
600 /// hotness information with PGO.
601 DiagnosticInfoIROptimization(enum DiagnosticKind Kind,
602 enum DiagnosticSeverity Severity,
603 const char *PassName, StringRef RemarkName,
605 const DiagnosticLocation &Loc,
606 const Value *CodeRegion = nullptr)
607 : DiagnosticInfoOptimizationBase(Kind, Severity, PassName, RemarkName, Fn,
609 CodeRegion(CodeRegion) {}
611 /// \brief This is ctor variant allows a pass to build an optimization remark
612 /// from an existing remark.
614 /// This is useful when a transformation pass (e.g LV) wants to emit a remark
615 /// (\p Orig) generated by one of its analyses (e.g. LAA) as its own analysis
616 /// remark. The string \p Prepend will be emitted before the original
618 DiagnosticInfoIROptimization(const char *PassName, StringRef Prepend,
619 const DiagnosticInfoIROptimization &Orig)
620 : DiagnosticInfoOptimizationBase(
621 (DiagnosticKind)Orig.getKind(), Orig.getSeverity(), PassName,
622 Orig.RemarkName, Orig.getFunction(), Orig.getLocation()),
623 CodeRegion(Orig.getCodeRegion()) {
625 std::copy(Orig.Args.begin(), Orig.Args.end(), std::back_inserter(Args));
628 /// Legacy interface.
629 /// \p PassName is the name of the pass emitting this diagnostic.
630 /// \p Fn is the function where the diagnostic is being emitted. \p Loc is
631 /// the location information to use in the diagnostic. If line table
632 /// information is available, the diagnostic will include the source code
633 /// location. \p Msg is the message to show. Note that this class does not
634 /// copy this message, so this reference must be valid for the whole life time
635 /// of the diagnostic.
636 DiagnosticInfoIROptimization(enum DiagnosticKind Kind,
637 enum DiagnosticSeverity Severity,
638 const char *PassName, const Function &Fn,
639 const DiagnosticLocation &Loc, const Twine &Msg)
640 : DiagnosticInfoOptimizationBase(Kind, Severity, PassName, "", Fn, Loc) {
644 const Value *getCodeRegion() const { return CodeRegion; }
646 static bool classof(const DiagnosticInfo *DI) {
647 return DI->getKind() >= DK_FirstRemark && DI->getKind() <= DK_LastRemark;
651 /// The IR value (currently basic block) that the optimization operates on.
652 /// This is currently used to provide run-time hotness information with PGO.
653 const Value *CodeRegion;
656 /// Diagnostic information for applied optimization remarks.
657 class OptimizationRemark : public DiagnosticInfoIROptimization {
659 /// \p PassName is the name of the pass emitting this diagnostic. If this name
660 /// matches the regular expression given in -Rpass=, then the diagnostic will
661 /// be emitted. \p RemarkName is a textual identifier for the remark (single-
662 /// word, camel-case). \p Loc is the debug location and \p CodeRegion is the
663 /// region that the optimization operates on (currently only block is
665 OptimizationRemark(const char *PassName, StringRef RemarkName,
666 const DiagnosticLocation &Loc, const Value *CodeRegion);
668 /// Same as above, but the debug location and code region are derived from \p
670 OptimizationRemark(const char *PassName, StringRef RemarkName,
671 const Instruction *Inst);
673 /// Same as above, but the debug location and code region are derived from \p
675 OptimizationRemark(const char *PassName, StringRef RemarkName,
676 const Function *Func);
678 static bool classof(const DiagnosticInfo *DI) {
679 return DI->getKind() == DK_OptimizationRemark;
682 /// \see DiagnosticInfoOptimizationBase::isEnabled.
683 bool isEnabled() const override;
686 /// This is deprecated now and only used by the function API below.
687 /// \p PassName is the name of the pass emitting this diagnostic. If
688 /// this name matches the regular expression given in -Rpass=, then the
689 /// diagnostic will be emitted. \p Fn is the function where the diagnostic
690 /// is being emitted. \p Loc is the location information to use in the
691 /// diagnostic. If line table information is available, the diagnostic
692 /// will include the source code location. \p Msg is the message to show.
693 /// Note that this class does not copy this message, so this reference
694 /// must be valid for the whole life time of the diagnostic.
695 OptimizationRemark(const char *PassName, const Function &Fn,
696 const DiagnosticLocation &Loc, const Twine &Msg)
697 : DiagnosticInfoIROptimization(DK_OptimizationRemark, DS_Remark, PassName,
701 /// Diagnostic information for missed-optimization remarks.
702 class OptimizationRemarkMissed : public DiagnosticInfoIROptimization {
704 /// \p PassName is the name of the pass emitting this diagnostic. If this name
705 /// matches the regular expression given in -Rpass-missed=, then the
706 /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
707 /// remark (single-word, camel-case). \p Loc is the debug location and \p
708 /// CodeRegion is the region that the optimization operates on (currently only
709 /// block is supported).
710 OptimizationRemarkMissed(const char *PassName, StringRef RemarkName,
711 const DiagnosticLocation &Loc,
712 const Value *CodeRegion);
714 /// \brief Same as above but \p Inst is used to derive code region and debug
716 OptimizationRemarkMissed(const char *PassName, StringRef RemarkName,
717 const Instruction *Inst);
719 static bool classof(const DiagnosticInfo *DI) {
720 return DI->getKind() == DK_OptimizationRemarkMissed;
723 /// \see DiagnosticInfoOptimizationBase::isEnabled.
724 bool isEnabled() const override;
727 /// This is deprecated now and only used by the function API below.
728 /// \p PassName is the name of the pass emitting this diagnostic. If
729 /// this name matches the regular expression given in -Rpass-missed=, then the
730 /// diagnostic will be emitted. \p Fn is the function where the diagnostic
731 /// is being emitted. \p Loc is the location information to use in the
732 /// diagnostic. If line table information is available, the diagnostic
733 /// will include the source code location. \p Msg is the message to show.
734 /// Note that this class does not copy this message, so this reference
735 /// must be valid for the whole life time of the diagnostic.
736 OptimizationRemarkMissed(const char *PassName, const Function &Fn,
737 const DiagnosticLocation &Loc, const Twine &Msg)
738 : DiagnosticInfoIROptimization(DK_OptimizationRemarkMissed, DS_Remark,
739 PassName, Fn, Loc, Msg) {}
742 /// Diagnostic information for optimization analysis remarks.
743 class OptimizationRemarkAnalysis : public DiagnosticInfoIROptimization {
745 /// \p PassName is the name of the pass emitting this diagnostic. If this name
746 /// matches the regular expression given in -Rpass-analysis=, then the
747 /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
748 /// remark (single-word, camel-case). \p Loc is the debug location and \p
749 /// CodeRegion is the region that the optimization operates on (currently only
750 /// block is supported).
751 OptimizationRemarkAnalysis(const char *PassName, StringRef RemarkName,
752 const DiagnosticLocation &Loc,
753 const Value *CodeRegion);
755 /// \brief This is ctor variant allows a pass to build an optimization remark
756 /// from an existing remark.
758 /// This is useful when a transformation pass (e.g LV) wants to emit a remark
759 /// (\p Orig) generated by one of its analyses (e.g. LAA) as its own analysis
760 /// remark. The string \p Prepend will be emitted before the original
762 OptimizationRemarkAnalysis(const char *PassName, StringRef Prepend,
763 const OptimizationRemarkAnalysis &Orig)
764 : DiagnosticInfoIROptimization(PassName, Prepend, Orig) {}
766 /// \brief Same as above but \p Inst is used to derive code region and debug
768 OptimizationRemarkAnalysis(const char *PassName, StringRef RemarkName,
769 const Instruction *Inst);
771 static bool classof(const DiagnosticInfo *DI) {
772 return DI->getKind() == DK_OptimizationRemarkAnalysis;
775 /// \see DiagnosticInfoOptimizationBase::isEnabled.
776 bool isEnabled() const override;
778 static const char *AlwaysPrint;
780 bool shouldAlwaysPrint() const { return getPassName() == AlwaysPrint; }
783 OptimizationRemarkAnalysis(enum DiagnosticKind Kind, const char *PassName,
784 const Function &Fn, const DiagnosticLocation &Loc,
786 : DiagnosticInfoIROptimization(Kind, DS_Remark, PassName, Fn, Loc, Msg) {}
788 OptimizationRemarkAnalysis(enum DiagnosticKind Kind, const char *PassName,
789 StringRef RemarkName,
790 const DiagnosticLocation &Loc,
791 const Value *CodeRegion);
794 /// This is deprecated now and only used by the function API below.
795 /// \p PassName is the name of the pass emitting this diagnostic. If
796 /// this name matches the regular expression given in -Rpass-analysis=, then
797 /// the diagnostic will be emitted. \p Fn is the function where the diagnostic
798 /// is being emitted. \p Loc is the location information to use in the
799 /// diagnostic. If line table information is available, the diagnostic will
800 /// include the source code location. \p Msg is the message to show. Note that
801 /// this class does not copy this message, so this reference must be valid for
802 /// the whole life time of the diagnostic.
803 OptimizationRemarkAnalysis(const char *PassName, const Function &Fn,
804 const DiagnosticLocation &Loc, const Twine &Msg)
805 : DiagnosticInfoIROptimization(DK_OptimizationRemarkAnalysis, DS_Remark,
806 PassName, Fn, Loc, Msg) {}
809 /// Diagnostic information for optimization analysis remarks related to
810 /// floating-point non-commutativity.
811 class OptimizationRemarkAnalysisFPCommute : public OptimizationRemarkAnalysis {
813 /// \p PassName is the name of the pass emitting this diagnostic. If this name
814 /// matches the regular expression given in -Rpass-analysis=, then the
815 /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
816 /// remark (single-word, camel-case). \p Loc is the debug location and \p
817 /// CodeRegion is the region that the optimization operates on (currently only
818 /// block is supported). The front-end will append its own message related to
819 /// options that address floating-point non-commutativity.
820 OptimizationRemarkAnalysisFPCommute(const char *PassName,
821 StringRef RemarkName,
822 const DiagnosticLocation &Loc,
823 const Value *CodeRegion)
824 : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisFPCommute,
825 PassName, RemarkName, Loc, CodeRegion) {}
827 static bool classof(const DiagnosticInfo *DI) {
828 return DI->getKind() == DK_OptimizationRemarkAnalysisFPCommute;
832 /// This is deprecated now and only used by the function API below.
833 /// \p PassName is the name of the pass emitting this diagnostic. If
834 /// this name matches the regular expression given in -Rpass-analysis=, then
835 /// the diagnostic will be emitted. \p Fn is the function where the diagnostic
836 /// is being emitted. \p Loc is the location information to use in the
837 /// diagnostic. If line table information is available, the diagnostic will
838 /// include the source code location. \p Msg is the message to show. The
839 /// front-end will append its own message related to options that address
840 /// floating-point non-commutativity. Note that this class does not copy this
841 /// message, so this reference must be valid for the whole life time of the
843 OptimizationRemarkAnalysisFPCommute(const char *PassName, const Function &Fn,
844 const DiagnosticLocation &Loc,
846 : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisFPCommute,
847 PassName, Fn, Loc, Msg) {}
850 /// Diagnostic information for optimization analysis remarks related to
851 /// pointer aliasing.
852 class OptimizationRemarkAnalysisAliasing : public OptimizationRemarkAnalysis {
854 /// \p PassName is the name of the pass emitting this diagnostic. If this name
855 /// matches the regular expression given in -Rpass-analysis=, then the
856 /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
857 /// remark (single-word, camel-case). \p Loc is the debug location and \p
858 /// CodeRegion is the region that the optimization operates on (currently only
859 /// block is supported). The front-end will append its own message related to
860 /// options that address pointer aliasing legality.
861 OptimizationRemarkAnalysisAliasing(const char *PassName, StringRef RemarkName,
862 const DiagnosticLocation &Loc,
863 const Value *CodeRegion)
864 : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisAliasing,
865 PassName, RemarkName, Loc, CodeRegion) {}
867 static bool classof(const DiagnosticInfo *DI) {
868 return DI->getKind() == DK_OptimizationRemarkAnalysisAliasing;
872 /// This is deprecated now and only used by the function API below.
873 /// \p PassName is the name of the pass emitting this diagnostic. If
874 /// this name matches the regular expression given in -Rpass-analysis=, then
875 /// the diagnostic will be emitted. \p Fn is the function where the diagnostic
876 /// is being emitted. \p Loc is the location information to use in the
877 /// diagnostic. If line table information is available, the diagnostic will
878 /// include the source code location. \p Msg is the message to show. The
879 /// front-end will append its own message related to options that address
880 /// pointer aliasing legality. Note that this class does not copy this
881 /// message, so this reference must be valid for the whole life time of the
883 OptimizationRemarkAnalysisAliasing(const char *PassName, const Function &Fn,
884 const DiagnosticLocation &Loc,
886 : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisAliasing,
887 PassName, Fn, Loc, Msg) {}
890 /// Diagnostic information for machine IR parser.
891 class DiagnosticInfoMIRParser : public DiagnosticInfo {
892 const SMDiagnostic &Diagnostic;
895 DiagnosticInfoMIRParser(DiagnosticSeverity Severity,
896 const SMDiagnostic &Diagnostic)
897 : DiagnosticInfo(DK_MIRParser, Severity), Diagnostic(Diagnostic) {}
899 const SMDiagnostic &getDiagnostic() const { return Diagnostic; }
901 void print(DiagnosticPrinter &DP) const override;
903 static bool classof(const DiagnosticInfo *DI) {
904 return DI->getKind() == DK_MIRParser;
908 /// Diagnostic information for ISel fallback path.
909 class DiagnosticInfoISelFallback : public DiagnosticInfo {
910 /// The function that is concerned by this diagnostic.
914 DiagnosticInfoISelFallback(const Function &Fn,
915 DiagnosticSeverity Severity = DS_Warning)
916 : DiagnosticInfo(DK_ISelFallback, Severity), Fn(Fn) {}
918 const Function &getFunction() const { return Fn; }
920 void print(DiagnosticPrinter &DP) const override;
922 static bool classof(const DiagnosticInfo *DI) {
923 return DI->getKind() == DK_ISelFallback;
927 // Create wrappers for C Binding types (see CBindingWrapping.h).
928 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DiagnosticInfo, LLVMDiagnosticInfoRef)
930 /// Diagnostic information for optimization failures.
931 class DiagnosticInfoOptimizationFailure : public DiagnosticInfoIROptimization {
933 /// \p Fn is the function where the diagnostic is being emitted. \p Loc is
934 /// the location information to use in the diagnostic. If line table
935 /// information is available, the diagnostic will include the source code
936 /// location. \p Msg is the message to show. Note that this class does not
937 /// copy this message, so this reference must be valid for the whole life time
938 /// of the diagnostic.
939 DiagnosticInfoOptimizationFailure(const Function &Fn,
940 const DiagnosticLocation &Loc,
942 : DiagnosticInfoIROptimization(DK_OptimizationFailure, DS_Warning,
943 nullptr, Fn, Loc, Msg) {}
945 /// \p PassName is the name of the pass emitting this diagnostic. \p
946 /// RemarkName is a textual identifier for the remark (single-word,
947 /// camel-case). \p Loc is the debug location and \p CodeRegion is the
948 /// region that the optimization operates on (currently basic block is
950 DiagnosticInfoOptimizationFailure(const char *PassName, StringRef RemarkName,
951 const DiagnosticLocation &Loc,
952 const Value *CodeRegion);
954 static bool classof(const DiagnosticInfo *DI) {
955 return DI->getKind() == DK_OptimizationFailure;
958 /// \see DiagnosticInfoOptimizationBase::isEnabled.
959 bool isEnabled() const override;
962 /// Diagnostic information for unsupported feature in backend.
963 class DiagnosticInfoUnsupported : public DiagnosticInfoWithLocationBase {
968 /// \p Fn is the function where the diagnostic is being emitted. \p Loc is
969 /// the location information to use in the diagnostic. If line table
970 /// information is available, the diagnostic will include the source code
971 /// location. \p Msg is the message to show. Note that this class does not
972 /// copy this message, so this reference must be valid for the whole life time
973 /// of the diagnostic.
974 DiagnosticInfoUnsupported(
975 const Function &Fn, const Twine &Msg,
976 const DiagnosticLocation &Loc = DiagnosticLocation(),
977 DiagnosticSeverity Severity = DS_Error)
978 : DiagnosticInfoWithLocationBase(DK_Unsupported, Severity, Fn, Loc),
981 static bool classof(const DiagnosticInfo *DI) {
982 return DI->getKind() == DK_Unsupported;
985 const Twine &getMessage() const { return Msg; }
987 void print(DiagnosticPrinter &DP) const override;
991 template <> struct MappingTraits<DiagnosticInfoOptimizationBase *> {
992 static void mapping(IO &io, DiagnosticInfoOptimizationBase *&OptDiag);
996 } // end namespace llvm
998 #endif // LLVM_IR_DIAGNOSTICINFO_H