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,
192 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),
199 ResourceName(ResourceName),
200 ResourceSize(ResourceSize),
201 ResourceLimit(ResourceLimit) {}
203 const Function &getFunction() const { return Fn; }
204 const char *getResourceName() const { return ResourceName; }
205 uint64_t getResourceSize() const { return ResourceSize; }
206 uint64_t getResourceLimit() const { return ResourceLimit; }
208 /// \see DiagnosticInfo::print.
209 void print(DiagnosticPrinter &DP) const override;
211 static bool classof(const DiagnosticInfo *DI) {
212 return DI->getKind() == DK_ResourceLimit ||
213 DI->getKind() == DK_StackSize;
217 class DiagnosticInfoStackSize : public DiagnosticInfoResourceLimit {
219 DiagnosticInfoStackSize(const Function &Fn,
221 DiagnosticSeverity Severity = DS_Warning,
222 uint64_t StackLimit = 0)
223 : DiagnosticInfoResourceLimit(Fn, "stack size", StackSize,
224 Severity, DK_StackSize, StackLimit) {}
226 uint64_t getStackSize() const { return getResourceSize(); }
227 uint64_t getStackLimit() const { return getResourceLimit(); }
229 static bool classof(const DiagnosticInfo *DI) {
230 return DI->getKind() == DK_StackSize;
234 /// Diagnostic information for debug metadata version reporting.
235 /// This is basically a module and a version.
236 class DiagnosticInfoDebugMetadataVersion : public DiagnosticInfo {
238 /// The module that is concerned by this debug metadata version diagnostic.
240 /// The actual metadata version.
241 unsigned MetadataVersion;
244 /// \p The module that is concerned by this debug metadata version diagnostic.
245 /// \p The actual metadata version.
246 DiagnosticInfoDebugMetadataVersion(const Module &M, unsigned MetadataVersion,
247 DiagnosticSeverity Severity = DS_Warning)
248 : DiagnosticInfo(DK_DebugMetadataVersion, Severity), M(M),
249 MetadataVersion(MetadataVersion) {}
251 const Module &getModule() const { return M; }
252 unsigned getMetadataVersion() const { return MetadataVersion; }
254 /// \see DiagnosticInfo::print.
255 void print(DiagnosticPrinter &DP) const override;
257 static bool classof(const DiagnosticInfo *DI) {
258 return DI->getKind() == DK_DebugMetadataVersion;
262 /// Diagnostic information for stripping invalid debug metadata.
263 class DiagnosticInfoIgnoringInvalidDebugMetadata : public DiagnosticInfo {
265 /// The module that is concerned by this debug metadata version diagnostic.
269 /// \p The module that is concerned by this debug metadata version diagnostic.
270 DiagnosticInfoIgnoringInvalidDebugMetadata(
271 const Module &M, DiagnosticSeverity Severity = DS_Warning)
272 : DiagnosticInfo(DK_DebugMetadataVersion, Severity), M(M) {}
274 const Module &getModule() const { return M; }
276 /// \see DiagnosticInfo::print.
277 void print(DiagnosticPrinter &DP) const override;
279 static bool classof(const DiagnosticInfo *DI) {
280 return DI->getKind() == DK_DebugMetadataInvalid;
284 /// Diagnostic information for the sample profiler.
285 class DiagnosticInfoSampleProfile : public DiagnosticInfo {
287 DiagnosticInfoSampleProfile(StringRef FileName, unsigned LineNum,
289 DiagnosticSeverity Severity = DS_Error)
290 : DiagnosticInfo(DK_SampleProfile, Severity), FileName(FileName),
291 LineNum(LineNum), Msg(Msg) {}
292 DiagnosticInfoSampleProfile(StringRef FileName, const Twine &Msg,
293 DiagnosticSeverity Severity = DS_Error)
294 : DiagnosticInfo(DK_SampleProfile, Severity), FileName(FileName),
296 DiagnosticInfoSampleProfile(const Twine &Msg,
297 DiagnosticSeverity Severity = DS_Error)
298 : DiagnosticInfo(DK_SampleProfile, Severity), Msg(Msg) {}
300 /// \see DiagnosticInfo::print.
301 void print(DiagnosticPrinter &DP) const override;
303 static bool classof(const DiagnosticInfo *DI) {
304 return DI->getKind() == DK_SampleProfile;
307 StringRef getFileName() const { return FileName; }
308 unsigned getLineNum() const { return LineNum; }
309 const Twine &getMsg() const { return Msg; }
312 /// Name of the input file associated with this diagnostic.
315 /// Line number where the diagnostic occurred. If 0, no line number will
316 /// be emitted in the message.
317 unsigned LineNum = 0;
319 /// Message to report.
323 /// Diagnostic information for the PGO profiler.
324 class DiagnosticInfoPGOProfile : public DiagnosticInfo {
326 DiagnosticInfoPGOProfile(const char *FileName, const Twine &Msg,
327 DiagnosticSeverity Severity = DS_Error)
328 : DiagnosticInfo(DK_PGOProfile, Severity), FileName(FileName), Msg(Msg) {}
330 /// \see DiagnosticInfo::print.
331 void print(DiagnosticPrinter &DP) const override;
333 static bool classof(const DiagnosticInfo *DI) {
334 return DI->getKind() == DK_PGOProfile;
337 const char *getFileName() const { return FileName; }
338 const Twine &getMsg() const { return Msg; }
341 /// Name of the input file associated with this diagnostic.
342 const char *FileName;
344 /// Message to report.
348 class DiagnosticLocation {
354 DiagnosticLocation() = default;
355 DiagnosticLocation(const DebugLoc &DL);
356 DiagnosticLocation(const DISubprogram *SP);
358 bool isValid() const { return !Filename.empty(); }
359 StringRef getFilename() const { return Filename; }
360 unsigned getLine() const { return Line; }
361 unsigned getColumn() const { return Column; }
364 /// Common features for diagnostics with an associated location.
365 class DiagnosticInfoWithLocationBase : public DiagnosticInfo {
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 source file name, line number and column.
385 void getLocation(StringRef *Filename, unsigned *Line, unsigned *Column) const;
387 const Function &getFunction() const { return Fn; }
388 DiagnosticLocation getLocation() const { return Loc; }
391 /// Function where this diagnostic is triggered.
394 /// Debug location where this diagnostic is triggered.
395 DiagnosticLocation Loc;
398 /// \brief Common features for diagnostics dealing with optimization remarks
399 /// that are used by both IR and MIR passes.
400 class DiagnosticInfoOptimizationBase : public DiagnosticInfoWithLocationBase {
402 /// \brief Used to set IsVerbose via the stream interface.
403 struct setIsVerbose {};
405 /// \brief When an instance of this is inserted into the stream, the arguments
406 /// following will not appear in the remark printed in the compiler output
407 /// (-Rpass) but only in the optimization record file
408 /// (-fsave-optimization-record).
409 struct setExtraArgs {};
411 /// \brief Used in the streaming interface as the general argument type. It
412 /// internally converts everything into a key-value pair.
416 // If set, the debug location corresponding to the value.
417 DiagnosticLocation Loc;
419 explicit Argument(StringRef Str = "") : Key("String"), Val(Str) {}
420 Argument(StringRef Key, const Value *V);
421 Argument(StringRef Key, const Type *T);
422 Argument(StringRef Key, StringRef S);
423 Argument(StringRef Key, int N);
424 Argument(StringRef Key, int64_t N);
425 Argument(StringRef Key, unsigned N);
426 Argument(StringRef Key, uint64_t N);
427 Argument(StringRef Key, bool B) : Key(Key), Val(B ? "true" : "false") {}
430 /// \p PassName is the name of the pass emitting this diagnostic. \p
431 /// RemarkName is a textual identifier for the remark (single-word,
432 /// camel-case). \p Fn is the function where the diagnostic is being emitted.
433 /// \p Loc is the location information to use in the diagnostic. If line table
434 /// information is available, the diagnostic will include the source code
436 DiagnosticInfoOptimizationBase(enum DiagnosticKind Kind,
437 enum DiagnosticSeverity Severity,
438 const char *PassName, StringRef RemarkName,
440 const DiagnosticLocation &Loc)
441 : DiagnosticInfoWithLocationBase(Kind, Severity, Fn, Loc),
442 PassName(PassName), RemarkName(RemarkName) {}
444 DiagnosticInfoOptimizationBase &operator<<(StringRef S);
445 DiagnosticInfoOptimizationBase &operator<<(Argument A);
446 DiagnosticInfoOptimizationBase &operator<<(setIsVerbose V);
447 DiagnosticInfoOptimizationBase &operator<<(setExtraArgs EA);
449 /// \see DiagnosticInfo::print.
450 void print(DiagnosticPrinter &DP) const override;
452 /// Return true if this optimization remark is enabled by one of
453 /// of the LLVM command line flags (-pass-remarks, -pass-remarks-missed,
454 /// or -pass-remarks-analysis). Note that this only handles the LLVM
455 /// flags. We cannot access Clang flags from here (they are handled
456 /// in BackendConsumer::OptimizationRemarkHandler).
457 virtual bool isEnabled() const = 0;
459 StringRef getPassName() const { return PassName; }
460 std::string getMsg() const;
461 Optional<uint64_t> getHotness() const { return Hotness; }
462 void setHotness(Optional<uint64_t> H) { Hotness = H; }
464 bool isVerbose() const { return IsVerbose; }
466 static bool classof(const DiagnosticInfo *DI) {
467 return (DI->getKind() >= DK_FirstRemark &&
468 DI->getKind() <= DK_LastRemark) ||
469 (DI->getKind() >= DK_FirstMachineRemark &&
470 DI->getKind() <= DK_LastMachineRemark);
473 bool isPassed() const {
474 return (getKind() == DK_OptimizationRemark ||
475 getKind() == DK_MachineOptimizationRemark);
478 bool isMissed() const {
479 return (getKind() == DK_OptimizationRemarkMissed ||
480 getKind() == DK_MachineOptimizationRemarkMissed);
483 bool isAnalysis() const {
484 return (getKind() == DK_OptimizationRemarkAnalysis ||
485 getKind() == DK_MachineOptimizationRemarkAnalysis);
489 /// Name of the pass that triggers this report. If this matches the
490 /// regular expression given in -Rpass=regexp, then the remark will
492 const char *PassName;
494 /// Textual identifier for the remark (single-word, camel-case). Can be used
495 /// by external tools reading the YAML output file for optimization remarks to
496 /// identify the remark.
497 StringRef RemarkName;
499 /// If profile information is available, this is the number of times the
500 /// corresponding code was executed in a profile instrumentation run.
501 Optional<uint64_t> Hotness;
503 /// Arguments collected via the streaming interface.
504 SmallVector<Argument, 4> Args;
506 /// The remark is expected to be noisy.
507 bool IsVerbose = false;
509 /// \brief If positive, the index of the first argument that only appear in
510 /// the optimization records and not in the remark printed in the compiler
512 int FirstExtraArgIndex = -1;
514 friend struct yaml::MappingTraits<DiagnosticInfoOptimizationBase *>;
517 /// \brief Common features for diagnostics dealing with optimization remarks
518 /// that are used by IR passes.
519 class DiagnosticInfoIROptimization : public DiagnosticInfoOptimizationBase {
521 /// \p PassName is the name of the pass emitting this diagnostic. \p
522 /// RemarkName is a textual identifier for the remark (single-word,
523 /// camel-case). \p Fn is the function where the diagnostic is being emitted.
524 /// \p Loc is the location information to use in the diagnostic. If line table
525 /// information is available, the diagnostic will include the source code
526 /// location. \p CodeRegion is IR value (currently basic block) that the
527 /// optimization operates on. This is currently used to provide run-time
528 /// hotness information with PGO.
529 DiagnosticInfoIROptimization(enum DiagnosticKind Kind,
530 enum DiagnosticSeverity Severity,
531 const char *PassName, StringRef RemarkName,
533 const DiagnosticLocation &Loc,
534 const Value *CodeRegion = nullptr)
535 : DiagnosticInfoOptimizationBase(Kind, Severity, PassName, RemarkName, Fn,
537 CodeRegion(CodeRegion) {}
539 /// \brief This is ctor variant allows a pass to build an optimization remark
540 /// from an existing remark.
542 /// This is useful when a transformation pass (e.g LV) wants to emit a remark
543 /// (\p Orig) generated by one of its analyses (e.g. LAA) as its own analysis
544 /// remark. The string \p Prepend will be emitted before the original
546 DiagnosticInfoIROptimization(const char *PassName, StringRef Prepend,
547 const DiagnosticInfoIROptimization &Orig)
548 : DiagnosticInfoOptimizationBase(
549 (DiagnosticKind)Orig.getKind(), Orig.getSeverity(), PassName,
550 Orig.RemarkName, Orig.getFunction(), Orig.getLocation()),
551 CodeRegion(Orig.getCodeRegion()) {
553 std::copy(Orig.Args.begin(), Orig.Args.end(), std::back_inserter(Args));
556 /// Legacy interface.
557 /// \p PassName is the name of the pass emitting this diagnostic.
558 /// \p Fn is the function where the diagnostic is being emitted. \p Loc is
559 /// the location information to use in the diagnostic. If line table
560 /// information is available, the diagnostic will include the source code
561 /// location. \p Msg is the message to show. Note that this class does not
562 /// copy this message, so this reference must be valid for the whole life time
563 /// of the diagnostic.
564 DiagnosticInfoIROptimization(enum DiagnosticKind Kind,
565 enum DiagnosticSeverity Severity,
566 const char *PassName, const Function &Fn,
567 const DiagnosticLocation &Loc, const Twine &Msg)
568 : DiagnosticInfoOptimizationBase(Kind, Severity, PassName, "", Fn, Loc) {
572 const Value *getCodeRegion() const { return CodeRegion; }
574 static bool classof(const DiagnosticInfo *DI) {
575 return DI->getKind() >= DK_FirstRemark && DI->getKind() <= DK_LastRemark;
579 /// The IR value (currently basic block) that the optimization operates on.
580 /// This is currently used to provide run-time hotness information with PGO.
581 const Value *CodeRegion;
584 /// Diagnostic information for applied optimization remarks.
585 class OptimizationRemark : public DiagnosticInfoIROptimization {
587 /// \p PassName is the name of the pass emitting this diagnostic. If this name
588 /// matches the regular expression given in -Rpass=, then the diagnostic will
589 /// be emitted. \p RemarkName is a textual identifier for the remark (single-
590 /// word, camel-case). \p Loc is the debug location and \p CodeRegion is the
591 /// region that the optimization operates on (currently only block is
593 OptimizationRemark(const char *PassName, StringRef RemarkName,
594 const DiagnosticLocation &Loc, const Value *CodeRegion);
596 /// Same as above, but the debug location and code region are derived from \p
598 OptimizationRemark(const char *PassName, StringRef RemarkName,
599 const Instruction *Inst);
601 /// Same as above, but the debug location and code region are derived from \p
603 OptimizationRemark(const char *PassName, StringRef RemarkName,
604 const Function *Func);
606 static bool classof(const DiagnosticInfo *DI) {
607 return DI->getKind() == DK_OptimizationRemark;
610 static bool isEnabled(StringRef PassName);
612 /// \see DiagnosticInfoOptimizationBase::isEnabled.
613 bool isEnabled() const override { return isEnabled(getPassName()); }
616 /// This is deprecated now and only used by the function API below.
617 /// \p PassName is the name of the pass emitting this diagnostic. If
618 /// this name matches the regular expression given in -Rpass=, then the
619 /// diagnostic will be emitted. \p Fn is the function where the diagnostic
620 /// is being emitted. \p Loc is the location information to use in the
621 /// diagnostic. If line table information is available, the diagnostic
622 /// will include the source code location. \p Msg is the message to show.
623 /// Note that this class does not copy this message, so this reference
624 /// must be valid for the whole life time of the diagnostic.
625 OptimizationRemark(const char *PassName, const Function &Fn,
626 const DiagnosticLocation &Loc, const Twine &Msg)
627 : DiagnosticInfoIROptimization(DK_OptimizationRemark, DS_Remark, PassName,
630 friend void emitOptimizationRemark(LLVMContext &Ctx, const char *PassName,
632 const DiagnosticLocation &Loc,
636 /// Diagnostic information for missed-optimization remarks.
637 class OptimizationRemarkMissed : public DiagnosticInfoIROptimization {
639 /// \p PassName is the name of the pass emitting this diagnostic. If this name
640 /// matches the regular expression given in -Rpass-missed=, then the
641 /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
642 /// remark (single-word, camel-case). \p Loc is the debug location and \p
643 /// CodeRegion is the region that the optimization operates on (currently only
644 /// block is supported).
645 OptimizationRemarkMissed(const char *PassName, StringRef RemarkName,
646 const DiagnosticLocation &Loc,
647 const Value *CodeRegion);
649 /// \brief Same as above but \p Inst is used to derive code region and debug
651 OptimizationRemarkMissed(const char *PassName, StringRef RemarkName,
652 const Instruction *Inst);
654 static bool classof(const DiagnosticInfo *DI) {
655 return DI->getKind() == DK_OptimizationRemarkMissed;
658 static bool isEnabled(StringRef PassName);
660 /// \see DiagnosticInfoOptimizationBase::isEnabled.
661 bool isEnabled() const override { return isEnabled(getPassName()); }
664 /// This is deprecated now and only used by the function API below.
665 /// \p PassName is the name of the pass emitting this diagnostic. If
666 /// this name matches the regular expression given in -Rpass-missed=, then the
667 /// diagnostic will be emitted. \p Fn is the function where the diagnostic
668 /// is being emitted. \p Loc is the location information to use in the
669 /// diagnostic. If line table information is available, the diagnostic
670 /// will include the source code location. \p Msg is the message to show.
671 /// Note that this class does not copy this message, so this reference
672 /// must be valid for the whole life time of the diagnostic.
673 OptimizationRemarkMissed(const char *PassName, const Function &Fn,
674 const DiagnosticLocation &Loc, const Twine &Msg)
675 : DiagnosticInfoIROptimization(DK_OptimizationRemarkMissed, DS_Remark,
676 PassName, Fn, Loc, Msg) {}
678 friend void emitOptimizationRemarkMissed(LLVMContext &Ctx,
679 const char *PassName,
681 const DiagnosticLocation &Loc,
685 /// Diagnostic information for optimization analysis remarks.
686 class OptimizationRemarkAnalysis : public DiagnosticInfoIROptimization {
688 /// \p PassName is the name of the pass emitting this diagnostic. If this name
689 /// matches the regular expression given in -Rpass-analysis=, then the
690 /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
691 /// remark (single-word, camel-case). \p Loc is the debug location and \p
692 /// CodeRegion is the region that the optimization operates on (currently only
693 /// block is supported).
694 OptimizationRemarkAnalysis(const char *PassName, StringRef RemarkName,
695 const DiagnosticLocation &Loc,
696 const Value *CodeRegion);
698 /// \brief This is ctor variant allows a pass to build an optimization remark
699 /// from an existing remark.
701 /// This is useful when a transformation pass (e.g LV) wants to emit a remark
702 /// (\p Orig) generated by one of its analyses (e.g. LAA) as its own analysis
703 /// remark. The string \p Prepend will be emitted before the original
705 OptimizationRemarkAnalysis(const char *PassName, StringRef Prepend,
706 const OptimizationRemarkAnalysis &Orig)
707 : DiagnosticInfoIROptimization(PassName, Prepend, Orig) {}
709 /// \brief Same as above but \p Inst is used to derive code region and debug
711 OptimizationRemarkAnalysis(const char *PassName, StringRef RemarkName,
712 const Instruction *Inst);
714 static bool classof(const DiagnosticInfo *DI) {
715 return DI->getKind() == DK_OptimizationRemarkAnalysis;
718 static bool isEnabled(StringRef PassName);
720 /// \see DiagnosticInfoOptimizationBase::isEnabled.
721 bool isEnabled() const override {
722 return shouldAlwaysPrint() || isEnabled(getPassName());
725 static const char *AlwaysPrint;
727 bool shouldAlwaysPrint() const { return getPassName() == AlwaysPrint; }
730 OptimizationRemarkAnalysis(enum DiagnosticKind Kind, const char *PassName,
731 const Function &Fn, const DiagnosticLocation &Loc,
733 : DiagnosticInfoIROptimization(Kind, DS_Remark, PassName, Fn, Loc, Msg) {}
735 OptimizationRemarkAnalysis(enum DiagnosticKind Kind, const char *PassName,
736 StringRef RemarkName,
737 const DiagnosticLocation &Loc,
738 const Value *CodeRegion);
741 /// This is deprecated now and only used by the function API below.
742 /// \p PassName is the name of the pass emitting this diagnostic. If
743 /// this name matches the regular expression given in -Rpass-analysis=, then
744 /// the diagnostic will be emitted. \p Fn is the function where the diagnostic
745 /// is being emitted. \p Loc is the location information to use in the
746 /// diagnostic. If line table information is available, the diagnostic will
747 /// include the source code location. \p Msg is the message to show. Note that
748 /// this class does not copy this message, so this reference must be valid for
749 /// the whole life time of the diagnostic.
750 OptimizationRemarkAnalysis(const char *PassName, const Function &Fn,
751 const DiagnosticLocation &Loc, const Twine &Msg)
752 : DiagnosticInfoIROptimization(DK_OptimizationRemarkAnalysis, DS_Remark,
753 PassName, Fn, Loc, Msg) {}
755 friend void emitOptimizationRemarkAnalysis(LLVMContext &Ctx,
756 const char *PassName,
758 const DiagnosticLocation &Loc,
762 /// Diagnostic information for optimization analysis remarks related to
763 /// floating-point non-commutativity.
764 class OptimizationRemarkAnalysisFPCommute : public OptimizationRemarkAnalysis {
766 /// \p PassName is the name of the pass emitting this diagnostic. If this name
767 /// matches the regular expression given in -Rpass-analysis=, then the
768 /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
769 /// remark (single-word, camel-case). \p Loc is the debug location and \p
770 /// CodeRegion is the region that the optimization operates on (currently only
771 /// block is supported). The front-end will append its own message related to
772 /// options that address floating-point non-commutativity.
773 OptimizationRemarkAnalysisFPCommute(const char *PassName,
774 StringRef RemarkName,
775 const DiagnosticLocation &Loc,
776 const Value *CodeRegion)
777 : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisFPCommute,
778 PassName, RemarkName, Loc, CodeRegion) {}
780 static bool classof(const DiagnosticInfo *DI) {
781 return DI->getKind() == DK_OptimizationRemarkAnalysisFPCommute;
785 /// This is deprecated now and only used by the function API below.
786 /// \p PassName is the name of the pass emitting this diagnostic. If
787 /// this name matches the regular expression given in -Rpass-analysis=, then
788 /// the diagnostic will be emitted. \p Fn is the function where the diagnostic
789 /// is being emitted. \p Loc is the location information to use in the
790 /// diagnostic. If line table information is available, the diagnostic will
791 /// include the source code location. \p Msg is the message to show. The
792 /// front-end will append its own message related to options that address
793 /// floating-point non-commutativity. Note that this class does not copy this
794 /// message, so this reference must be valid for the whole life time of the
796 OptimizationRemarkAnalysisFPCommute(const char *PassName, const Function &Fn,
797 const DiagnosticLocation &Loc,
799 : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisFPCommute,
800 PassName, Fn, Loc, Msg) {}
802 friend void emitOptimizationRemarkAnalysisFPCommute(
803 LLVMContext &Ctx, const char *PassName, const Function &Fn,
804 const DiagnosticLocation &Loc, const Twine &Msg);
807 /// Diagnostic information for optimization analysis remarks related to
808 /// pointer aliasing.
809 class OptimizationRemarkAnalysisAliasing : public OptimizationRemarkAnalysis {
811 /// \p PassName is the name of the pass emitting this diagnostic. If this name
812 /// matches the regular expression given in -Rpass-analysis=, then the
813 /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
814 /// remark (single-word, camel-case). \p Loc is the debug location and \p
815 /// CodeRegion is the region that the optimization operates on (currently only
816 /// block is supported). The front-end will append its own message related to
817 /// options that address pointer aliasing legality.
818 OptimizationRemarkAnalysisAliasing(const char *PassName, StringRef RemarkName,
819 const DiagnosticLocation &Loc,
820 const Value *CodeRegion)
821 : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisAliasing,
822 PassName, RemarkName, Loc, CodeRegion) {}
824 static bool classof(const DiagnosticInfo *DI) {
825 return DI->getKind() == DK_OptimizationRemarkAnalysisAliasing;
829 /// This is deprecated now and only used by the function API below.
830 /// \p PassName is the name of the pass emitting this diagnostic. If
831 /// this name matches the regular expression given in -Rpass-analysis=, then
832 /// the diagnostic will be emitted. \p Fn is the function where the diagnostic
833 /// is being emitted. \p Loc is the location information to use in the
834 /// diagnostic. If line table information is available, the diagnostic will
835 /// include the source code location. \p Msg is the message to show. The
836 /// front-end will append its own message related to options that address
837 /// pointer aliasing legality. Note that this class does not copy this
838 /// message, so this reference must be valid for the whole life time of the
840 OptimizationRemarkAnalysisAliasing(const char *PassName, const Function &Fn,
841 const DiagnosticLocation &Loc,
843 : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisAliasing,
844 PassName, Fn, Loc, Msg) {}
846 friend void emitOptimizationRemarkAnalysisAliasing(
847 LLVMContext &Ctx, const char *PassName, const Function &Fn,
848 const DiagnosticLocation &Loc, const Twine &Msg);
851 /// Diagnostic information for machine IR parser.
852 class DiagnosticInfoMIRParser : public DiagnosticInfo {
853 const SMDiagnostic &Diagnostic;
856 DiagnosticInfoMIRParser(DiagnosticSeverity Severity,
857 const SMDiagnostic &Diagnostic)
858 : DiagnosticInfo(DK_MIRParser, Severity), Diagnostic(Diagnostic) {}
860 const SMDiagnostic &getDiagnostic() const { return Diagnostic; }
862 void print(DiagnosticPrinter &DP) const override;
864 static bool classof(const DiagnosticInfo *DI) {
865 return DI->getKind() == DK_MIRParser;
869 /// Diagnostic information for ISel fallback path.
870 class DiagnosticInfoISelFallback : public DiagnosticInfo {
871 /// The function that is concerned by this diagnostic.
875 DiagnosticInfoISelFallback(const Function &Fn,
876 DiagnosticSeverity Severity = DS_Warning)
877 : DiagnosticInfo(DK_ISelFallback, Severity), Fn(Fn) {}
879 const Function &getFunction() const { return Fn; }
881 void print(DiagnosticPrinter &DP) const override;
883 static bool classof(const DiagnosticInfo *DI) {
884 return DI->getKind() == DK_ISelFallback;
888 // Create wrappers for C Binding types (see CBindingWrapping.h).
889 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DiagnosticInfo, LLVMDiagnosticInfoRef)
891 /// \brief Legacy interface to emit an optimization-applied message. Use
892 /// (Machine)OptimizationRemarkEmitter instead.
894 /// \p PassName is the name of the pass emitting the message. If -Rpass= is
895 /// given and \p PassName matches the regular expression in -Rpass, then the
896 /// remark will be emitted. \p Fn is the function triggering the remark, \p Loc
897 /// is the debug location where the diagnostic is generated. \p Msg is the
898 /// message string to use.
899 void emitOptimizationRemark(LLVMContext &Ctx, const char *PassName,
900 const Function &Fn, const DiagnosticLocation &Loc,
903 /// \brief Legacy interface to emit an optimization-missed message. Use
904 /// (Machine)OptimizationRemarkEmitter instead.
906 /// \p PassName is the name of the pass emitting the message. If -Rpass-missed=
907 /// is given and \p PassName matches the regular expression in -Rpass, then the
908 /// remark will be emitted. \p Fn is the function triggering the remark, \p Loc
909 /// is the debug location where the diagnostic is generated. \p Msg is the
910 /// message string to use.
911 void emitOptimizationRemarkMissed(LLVMContext &Ctx, const char *PassName,
913 const DiagnosticLocation &Loc,
916 /// \brief Legacy interface to emit an optimization analysis remark message.
917 /// Use (Machine)OptimizationRemarkEmitter instead.
919 /// \p PassName is the name of the pass emitting the message. If
920 /// -Rpass-analysis= is given and \p PassName matches the regular expression in
921 /// -Rpass, then the remark will be emitted. \p Fn is the function triggering
922 /// the remark, \p Loc is the debug location where the diagnostic is
923 /// generated. \p Msg is the message string to use.
924 void emitOptimizationRemarkAnalysis(LLVMContext &Ctx, const char *PassName,
926 const DiagnosticLocation &Loc,
929 /// \brief Legacy interface to emit an optimization analysis remark related to
930 /// messages about floating-point non-commutativity. Use
931 /// (Machine)OptimizationRemarkEmitter instead.
933 /// \p PassName is the name of the pass emitting the message. If
934 /// -Rpass-analysis= is given and \p PassName matches the regular expression in
935 /// -Rpass, then the remark will be emitted. \p Fn is the function triggering
936 /// the remark, \p Loc is the debug location where the diagnostic is
937 /// generated. \p Msg is the message string to use.
938 void emitOptimizationRemarkAnalysisFPCommute(LLVMContext &Ctx,
939 const char *PassName,
941 const DiagnosticLocation &Loc,
944 /// \brief Legacy interface to emit an optimization analysis remark related to
945 /// messages about pointer aliasing. Use (Machine)OptimizationRemarkEmitter
948 /// \p PassName is the name of the pass emitting the message.
949 /// If -Rpass-analysis= is given and \p PassName matches the regular expression
950 /// in -Rpass, then the remark will be emitted. \p Fn is the function triggering
951 /// the remark, \p Loc is the debug location where the diagnostic is generated.
952 /// \p Msg is the message string to use.
953 void emitOptimizationRemarkAnalysisAliasing(LLVMContext &Ctx,
954 const char *PassName,
956 const DiagnosticLocation &Loc,
959 /// Diagnostic information for optimization failures.
960 class DiagnosticInfoOptimizationFailure : public DiagnosticInfoIROptimization {
962 /// \p Fn is the function where the diagnostic is being emitted. \p Loc is
963 /// the location information to use in the diagnostic. If line table
964 /// information is available, the diagnostic will include the source code
965 /// location. \p Msg is the message to show. Note that this class does not
966 /// copy this message, so this reference must be valid for the whole life time
967 /// of the diagnostic.
968 DiagnosticInfoOptimizationFailure(const Function &Fn,
969 const DiagnosticLocation &Loc,
971 : DiagnosticInfoIROptimization(DK_OptimizationFailure, DS_Warning,
972 nullptr, Fn, Loc, Msg) {}
974 /// \p PassName is the name of the pass emitting this diagnostic. \p
975 /// RemarkName is a textual identifier for the remark (single-word,
976 /// camel-case). \p Loc is the debug location and \p CodeRegion is the
977 /// region that the optimization operates on (currently basic block is
979 DiagnosticInfoOptimizationFailure(const char *PassName, StringRef RemarkName,
980 const DiagnosticLocation &Loc,
981 const Value *CodeRegion);
983 static bool classof(const DiagnosticInfo *DI) {
984 return DI->getKind() == DK_OptimizationFailure;
987 /// \see DiagnosticInfoOptimizationBase::isEnabled.
988 bool isEnabled() const override;
991 /// Diagnostic information for unsupported feature in backend.
992 class DiagnosticInfoUnsupported : public DiagnosticInfoWithLocationBase {
997 /// \p Fn is the function where the diagnostic is being emitted. \p Loc is
998 /// the location information to use in the diagnostic. If line table
999 /// information is available, the diagnostic will include the source code
1000 /// location. \p Msg is the message to show. Note that this class does not
1001 /// copy this message, so this reference must be valid for the whole life time
1002 /// of the diagnostic.
1003 DiagnosticInfoUnsupported(
1004 const Function &Fn, const Twine &Msg,
1005 const DiagnosticLocation &Loc = DiagnosticLocation(),
1006 DiagnosticSeverity Severity = DS_Error)
1007 : DiagnosticInfoWithLocationBase(DK_Unsupported, Severity, Fn, Loc),
1010 static bool classof(const DiagnosticInfo *DI) {
1011 return DI->getKind() == DK_Unsupported;
1014 const Twine &getMessage() const { return Msg; }
1016 void print(DiagnosticPrinter &DP) const override;
1019 } // end namespace llvm
1021 #endif // LLVM_IR_DIAGNOSTICINFO_H