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/ADT/None.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"
26 #include "llvm-c/Types.h"
35 // Forward declarations.
36 class DiagnosticPrinter;
43 /// \brief Defines the different supported severity of a diagnostic.
44 enum DiagnosticSeverity : char {
48 // A note attaches additional information to one of the previous diagnostic
53 /// \brief Defines the different supported kind of a diagnostic.
54 /// This enum should be extended with a new ID for each added concrete subclass.
60 DK_DebugMetadataVersion,
61 DK_DebugMetadataInvalid,
64 DK_OptimizationRemark,
65 DK_OptimizationRemarkMissed,
66 DK_OptimizationRemarkAnalysis,
67 DK_OptimizationRemarkAnalysisFPCommute,
68 DK_OptimizationRemarkAnalysisAliasing,
69 DK_OptimizationFailure,
70 DK_FirstRemark = DK_OptimizationRemark,
71 DK_LastRemark = DK_OptimizationFailure,
72 DK_MachineOptimizationRemark,
73 DK_MachineOptimizationRemarkMissed,
74 DK_MachineOptimizationRemarkAnalysis,
75 DK_FirstMachineRemark = DK_MachineOptimizationRemark,
76 DK_LastMachineRemark = DK_MachineOptimizationRemarkAnalysis,
83 /// \brief Get the next available kind ID for a plugin diagnostic.
84 /// Each time this function is called, it returns a different number.
85 /// Therefore, a plugin that wants to "identify" its own classes
86 /// with a dynamic identifier, just have to use this method to get a new ID
87 /// and assign it to each of its classes.
88 /// The returned ID will be greater than or equal to DK_FirstPluginKind.
89 /// Thus, the plugin identifiers will not conflict with the
90 /// DiagnosticKind values.
91 int getNextAvailablePluginDiagnosticKind();
93 /// \brief This is the base abstract class for diagnostic reporting in
95 /// The print method must be overloaded by the subclasses to print a
96 /// user-friendly message in the client of the backend (let us call it a
98 class DiagnosticInfo {
100 /// Kind defines the kind of report this is about.
101 const /* DiagnosticKind */ int Kind;
102 /// Severity gives the severity of the diagnostic.
103 const DiagnosticSeverity Severity;
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 typedef std::function<void(const DiagnosticInfo &)> DiagnosticHandlerFunction;
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.
131 /// Message to be reported.
133 /// Optional origin of the problem.
134 const Instruction *Instr;
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), LocCookie(0), MsgStr(MsgStr),
145 /// \p LocCookie if non-zero gives the line number for this report.
146 /// \p MsgStr gives the message.
147 /// This class does not copy \p MsgStr, therefore the reference must be valid
148 /// for the whole life time of the Diagnostic.
149 DiagnosticInfoInlineAsm(unsigned LocCookie, const Twine &MsgStr,
150 DiagnosticSeverity Severity = DS_Error)
151 : DiagnosticInfo(DK_InlineAsm, Severity), LocCookie(LocCookie),
152 MsgStr(MsgStr), Instr(nullptr) {}
154 /// \p Instr gives the original instruction that triggered the diagnostic.
155 /// \p MsgStr gives the message.
156 /// This class does not copy \p MsgStr, therefore the reference must be valid
157 /// for the whole life time of the Diagnostic.
159 DiagnosticInfoInlineAsm(const Instruction &I, const Twine &MsgStr,
160 DiagnosticSeverity Severity = DS_Error);
162 unsigned getLocCookie() const { return LocCookie; }
163 const Twine &getMsgStr() const { return MsgStr; }
164 const Instruction *getInstruction() const { return Instr; }
166 /// \see DiagnosticInfo::print.
167 void print(DiagnosticPrinter &DP) const override;
169 static bool classof(const DiagnosticInfo *DI) {
170 return DI->getKind() == DK_InlineAsm;
174 /// Diagnostic information for stack size etc. reporting.
175 /// This is basically a function and a size.
176 class DiagnosticInfoResourceLimit : public DiagnosticInfo {
178 /// The function that is concerned by this resource limit diagnostic.
181 /// Description of the resource type (e.g. stack size)
182 const char *ResourceName;
184 /// The computed size usage
185 uint64_t ResourceSize;
188 uint64_t ResourceLimit;
191 /// \p The function that is concerned by this stack size diagnostic.
192 /// \p The computed stack size.
193 DiagnosticInfoResourceLimit(const Function &Fn,
194 const char *ResourceName,
195 uint64_t ResourceSize,
196 DiagnosticSeverity Severity = DS_Warning,
197 DiagnosticKind Kind = DK_ResourceLimit,
198 uint64_t ResourceLimit = 0)
199 : DiagnosticInfo(Kind, Severity),
201 ResourceName(ResourceName),
202 ResourceSize(ResourceSize),
203 ResourceLimit(ResourceLimit) {}
205 const Function &getFunction() const { return Fn; }
206 const char *getResourceName() const { return ResourceName; }
207 uint64_t getResourceSize() const { return ResourceSize; }
208 uint64_t getResourceLimit() const { return ResourceLimit; }
210 /// \see DiagnosticInfo::print.
211 void print(DiagnosticPrinter &DP) const override;
213 static bool classof(const DiagnosticInfo *DI) {
214 return DI->getKind() == DK_ResourceLimit ||
215 DI->getKind() == DK_StackSize;
219 class DiagnosticInfoStackSize : public DiagnosticInfoResourceLimit {
221 DiagnosticInfoStackSize(const Function &Fn,
223 DiagnosticSeverity Severity = DS_Warning,
224 uint64_t StackLimit = 0)
225 : DiagnosticInfoResourceLimit(Fn, "stack size", StackSize,
226 Severity, DK_StackSize, StackLimit) {}
228 uint64_t getStackSize() const { return getResourceSize(); }
229 uint64_t getStackLimit() const { return getResourceLimit(); }
231 static bool classof(const DiagnosticInfo *DI) {
232 return DI->getKind() == DK_StackSize;
236 /// Diagnostic information for debug metadata version reporting.
237 /// This is basically a module and a version.
238 class DiagnosticInfoDebugMetadataVersion : public DiagnosticInfo {
240 /// The module that is concerned by this debug metadata version diagnostic.
242 /// The actual metadata version.
243 unsigned MetadataVersion;
246 /// \p The module that is concerned by this debug metadata version diagnostic.
247 /// \p The actual metadata version.
248 DiagnosticInfoDebugMetadataVersion(const Module &M, unsigned MetadataVersion,
249 DiagnosticSeverity Severity = DS_Warning)
250 : DiagnosticInfo(DK_DebugMetadataVersion, Severity), M(M),
251 MetadataVersion(MetadataVersion) {}
253 const Module &getModule() const { return M; }
254 unsigned getMetadataVersion() const { return MetadataVersion; }
256 /// \see DiagnosticInfo::print.
257 void print(DiagnosticPrinter &DP) const override;
259 static bool classof(const DiagnosticInfo *DI) {
260 return DI->getKind() == DK_DebugMetadataVersion;
264 /// Diagnostic information for stripping invalid debug metadata.
265 class DiagnosticInfoIgnoringInvalidDebugMetadata : public DiagnosticInfo {
267 /// The module that is concerned by this debug metadata version diagnostic.
271 /// \p The module that is concerned by this debug metadata version diagnostic.
272 DiagnosticInfoIgnoringInvalidDebugMetadata(
273 const Module &M, DiagnosticSeverity Severity = DS_Warning)
274 : DiagnosticInfo(DK_DebugMetadataVersion, Severity), M(M) {}
276 const Module &getModule() const { return M; }
278 /// \see DiagnosticInfo::print.
279 void print(DiagnosticPrinter &DP) const override;
281 static bool classof(const DiagnosticInfo *DI) {
282 return DI->getKind() == DK_DebugMetadataInvalid;
286 /// Diagnostic information for the sample profiler.
287 class DiagnosticInfoSampleProfile : public DiagnosticInfo {
289 DiagnosticInfoSampleProfile(StringRef FileName, unsigned LineNum,
291 DiagnosticSeverity Severity = DS_Error)
292 : DiagnosticInfo(DK_SampleProfile, Severity), FileName(FileName),
293 LineNum(LineNum), Msg(Msg) {}
294 DiagnosticInfoSampleProfile(StringRef FileName, const Twine &Msg,
295 DiagnosticSeverity Severity = DS_Error)
296 : DiagnosticInfo(DK_SampleProfile, Severity), FileName(FileName),
297 LineNum(0), Msg(Msg) {}
298 DiagnosticInfoSampleProfile(const Twine &Msg,
299 DiagnosticSeverity Severity = DS_Error)
300 : DiagnosticInfo(DK_SampleProfile, Severity), LineNum(0), Msg(Msg) {}
302 /// \see DiagnosticInfo::print.
303 void print(DiagnosticPrinter &DP) const override;
305 static bool classof(const DiagnosticInfo *DI) {
306 return DI->getKind() == DK_SampleProfile;
309 StringRef getFileName() const { return FileName; }
310 unsigned getLineNum() const { return LineNum; }
311 const Twine &getMsg() const { return Msg; }
314 /// Name of the input file associated with this diagnostic.
317 /// Line number where the diagnostic occurred. If 0, no line number will
318 /// be emitted in the message.
321 /// Message to report.
325 /// Diagnostic information for the PGO profiler.
326 class DiagnosticInfoPGOProfile : public DiagnosticInfo {
328 DiagnosticInfoPGOProfile(const char *FileName, const Twine &Msg,
329 DiagnosticSeverity Severity = DS_Error)
330 : DiagnosticInfo(DK_PGOProfile, Severity), FileName(FileName), Msg(Msg) {}
332 /// \see DiagnosticInfo::print.
333 void print(DiagnosticPrinter &DP) const override;
335 static bool classof(const DiagnosticInfo *DI) {
336 return DI->getKind() == DK_PGOProfile;
339 const char *getFileName() const { return FileName; }
340 const Twine &getMsg() const { return Msg; }
343 /// Name of the input file associated with this diagnostic.
344 const char *FileName;
346 /// Message to report.
350 class DiagnosticLocation {
355 DiagnosticLocation() {}
356 DiagnosticLocation(const DebugLoc &DL);
357 DiagnosticLocation(const DISubprogram *SP);
359 bool isValid() const { return !Filename.empty(); }
360 StringRef getFilename() const { return Filename; }
361 unsigned getLine() const { return Line; }
362 unsigned getColumn() const { return Column; }
365 /// Common features for diagnostics with an associated location.
366 class DiagnosticInfoWithLocationBase : public DiagnosticInfo {
368 /// \p Fn is the function where the diagnostic is being emitted. \p Loc is
369 /// the location information to use in the diagnostic.
370 DiagnosticInfoWithLocationBase(enum DiagnosticKind Kind,
371 enum DiagnosticSeverity Severity,
373 const DiagnosticLocation &Loc)
374 : DiagnosticInfo(Kind, Severity), Fn(Fn), Loc(Loc) {}
376 /// Return true if location information is available for this diagnostic.
377 bool isLocationAvailable() const { return Loc.isValid(); }
379 /// Return a string with the location information for this diagnostic
380 /// in the format "file:line:col". If location information is not available,
381 /// it returns "<unknown>:0:0".
382 const std::string getLocationStr() const;
384 /// Return location information for this diagnostic in three parts:
385 /// the source file name, line number and column.
386 void getLocation(StringRef *Filename, unsigned *Line, unsigned *Column) const;
388 const Function &getFunction() const { return Fn; }
389 DiagnosticLocation getLocation() const { return Loc; }
392 /// Function where this diagnostic is triggered.
395 /// Debug location where this diagnostic is triggered.
396 DiagnosticLocation Loc;
399 /// \brief Common features for diagnostics dealing with optimization remarks
400 /// that are used by both IR and MIR passes.
401 class DiagnosticInfoOptimizationBase : public DiagnosticInfoWithLocationBase {
403 /// \brief Used to set IsVerbose via the stream interface.
404 struct setIsVerbose {};
406 /// \brief When an instance of this is inserted into the stream, the arguments
407 /// following will not appear in the remark printed in the compiler output
408 /// (-Rpass) but only in the optimization record file
409 /// (-fsave-optimization-record).
410 struct setExtraArgs {};
412 /// \brief Used in the streaming interface as the general argument type. It
413 /// internally converts everything into a key-value pair.
417 // If set, the debug location corresponding to the value.
418 DiagnosticLocation Loc;
420 explicit Argument(StringRef Str = "") : Key("String"), Val(Str) {}
421 Argument(StringRef Key, const Value *V);
422 Argument(StringRef Key, const Type *T);
423 Argument(StringRef Key, int N);
424 Argument(StringRef Key, unsigned N);
425 Argument(StringRef Key, bool B) : Key(Key), Val(B ? "true" : "false") {}
428 /// \p PassName is the name of the pass emitting this diagnostic. \p
429 /// RemarkName is a textual identifier for the remark. \p Fn is the function
430 /// where the diagnostic is being emitted. \p Loc is the location information
431 /// to use in the diagnostic. If line table information is available, the
432 /// diagnostic will include the source code location.
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 DiagnosticInfoOptimizationBase &operator<<(StringRef S);
442 DiagnosticInfoOptimizationBase &operator<<(Argument A);
443 DiagnosticInfoOptimizationBase &operator<<(setIsVerbose V);
444 DiagnosticInfoOptimizationBase &operator<<(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. Can be used by external tools reading
492 /// the YAML output file for optimization remarks to identify the remark.
493 StringRef RemarkName;
495 /// If profile information is available, this is the number of times the
496 /// corresponding code was executed in a profile instrumentation run.
497 Optional<uint64_t> Hotness;
499 /// Arguments collected via the streaming interface.
500 SmallVector<Argument, 4> Args;
502 /// The remark is expected to be noisy.
503 bool IsVerbose = false;
505 /// \brief If positive, the index of the first argument that only appear in
506 /// the optimization records and not in the remark printed in the compiler
508 int FirstExtraArgIndex = -1;
510 friend struct yaml::MappingTraits<DiagnosticInfoOptimizationBase *>;
513 /// \brief Common features for diagnostics dealing with optimization remarks
514 /// that are used by IR passes.
515 class DiagnosticInfoIROptimization : public DiagnosticInfoOptimizationBase {
517 /// \p PassName is the name of the pass emitting this diagnostic. \p
518 /// RemarkName is a textual identifier for the remark. \p Fn is the function
519 /// where the diagnostic is being emitted. \p Loc is the location information
520 /// to use in the diagnostic. If line table information is available, the
521 /// diagnostic will include the source code location. \p CodeRegion is IR
522 /// value (currently basic block) that the optimization operates on. This is
523 /// currently used to provide run-time hotness information with PGO.
524 DiagnosticInfoIROptimization(enum DiagnosticKind Kind,
525 enum DiagnosticSeverity Severity,
526 const char *PassName, StringRef RemarkName,
528 const DiagnosticLocation &Loc,
529 const Value *CodeRegion = nullptr)
530 : DiagnosticInfoOptimizationBase(Kind, Severity, PassName, RemarkName, Fn,
532 CodeRegion(CodeRegion) {}
534 /// \brief This is ctor variant allows a pass to build an optimization remark
535 /// from an existing remark.
537 /// This is useful when a transformation pass (e.g LV) wants to emit a remark
538 /// (\p Orig) generated by one of its analyses (e.g. LAA) as its own analysis
539 /// remark. The string \p Prepend will be emitted before the original
541 DiagnosticInfoIROptimization(const char *PassName, StringRef Prepend,
542 const DiagnosticInfoIROptimization &Orig)
543 : DiagnosticInfoOptimizationBase(
544 (DiagnosticKind)Orig.getKind(), Orig.getSeverity(), PassName,
545 Orig.RemarkName, Orig.getFunction(), Orig.getLocation()),
546 CodeRegion(Orig.getCodeRegion()) {
548 std::copy(Orig.Args.begin(), Orig.Args.end(), std::back_inserter(Args));
551 /// Legacy interface.
552 /// \p PassName is the name of the pass emitting this diagnostic.
553 /// \p Fn is the function where the diagnostic is being emitted. \p Loc is
554 /// the location information to use in the diagnostic. If line table
555 /// information is available, the diagnostic will include the source code
556 /// location. \p Msg is the message to show. Note that this class does not
557 /// copy this message, so this reference must be valid for the whole life time
558 /// of the diagnostic.
559 DiagnosticInfoIROptimization(enum DiagnosticKind Kind,
560 enum DiagnosticSeverity Severity,
561 const char *PassName, const Function &Fn,
562 const DiagnosticLocation &Loc, const Twine &Msg)
563 : DiagnosticInfoOptimizationBase(Kind, Severity, PassName, "", Fn, Loc) {
567 const Value *getCodeRegion() const { return CodeRegion; }
569 static bool classof(const DiagnosticInfo *DI) {
570 return DI->getKind() >= DK_FirstRemark && DI->getKind() <= DK_LastRemark;
574 /// The IR value (currently basic block) that the optimization operates on.
575 /// This is currently used to provide run-time hotness information with PGO.
576 const Value *CodeRegion;
579 /// Diagnostic information for applied optimization remarks.
580 class OptimizationRemark : public DiagnosticInfoIROptimization {
582 /// \p PassName is the name of the pass emitting this diagnostic. If this name
583 /// matches the regular expression given in -Rpass=, then the diagnostic will
584 /// be emitted. \p RemarkName is a textual identifier for the remark. \p
585 /// Loc is the debug location and \p CodeRegion is the region that the
586 /// optimization operates on (currently on block is supported).
587 OptimizationRemark(const char *PassName, StringRef RemarkName,
588 const DiagnosticLocation &Loc, const Value *CodeRegion);
590 /// Same as above but the debug location and code region is derived from \p
592 OptimizationRemark(const char *PassName, StringRef RemarkName,
595 static bool classof(const DiagnosticInfo *DI) {
596 return DI->getKind() == DK_OptimizationRemark;
599 static bool isEnabled(StringRef PassName);
601 /// \see DiagnosticInfoOptimizationBase::isEnabled.
602 bool isEnabled() const override { return isEnabled(getPassName()); }
605 /// This is deprecated now and only used by the function API below.
606 /// \p PassName is the name of the pass emitting this diagnostic. If
607 /// this name matches the regular expression given in -Rpass=, then the
608 /// diagnostic will be emitted. \p Fn is the function where the diagnostic
609 /// is being emitted. \p Loc is the location information to use in the
610 /// diagnostic. If line table information is available, the diagnostic
611 /// will include the source code location. \p Msg is the message to show.
612 /// Note that this class does not copy this message, so this reference
613 /// must be valid for the whole life time of the diagnostic.
614 OptimizationRemark(const char *PassName, const Function &Fn,
615 const DiagnosticLocation &Loc, const Twine &Msg)
616 : DiagnosticInfoIROptimization(DK_OptimizationRemark, DS_Remark, PassName,
619 friend void emitOptimizationRemark(LLVMContext &Ctx, const char *PassName,
621 const DiagnosticLocation &Loc,
625 /// Diagnostic information for missed-optimization remarks.
626 class OptimizationRemarkMissed : public DiagnosticInfoIROptimization {
628 /// \p PassName is the name of the pass emitting this diagnostic. If this name
629 /// matches the regular expression given in -Rpass-missed=, then the
630 /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
631 /// remark. \p Loc is the debug location and \p CodeRegion is the region
632 /// that the optimization operates on (currently on block is supported).
633 OptimizationRemarkMissed(const char *PassName, StringRef RemarkName,
634 const DiagnosticLocation &Loc,
635 const Value *CodeRegion);
637 /// \brief Same as above but \p Inst is used to derive code region and debug
639 OptimizationRemarkMissed(const char *PassName, StringRef RemarkName,
640 const Instruction *Inst);
642 static bool classof(const DiagnosticInfo *DI) {
643 return DI->getKind() == DK_OptimizationRemarkMissed;
646 static bool isEnabled(StringRef PassName);
648 /// \see DiagnosticInfoOptimizationBase::isEnabled.
649 bool isEnabled() const override { return isEnabled(getPassName()); }
652 /// This is deprecated now and only used by the function API below.
653 /// \p PassName is the name of the pass emitting this diagnostic. If
654 /// this name matches the regular expression given in -Rpass-missed=, then the
655 /// diagnostic will be emitted. \p Fn is the function where the diagnostic
656 /// is being emitted. \p Loc is the location information to use in the
657 /// diagnostic. If line table information is available, the diagnostic
658 /// will include the source code location. \p Msg is the message to show.
659 /// Note that this class does not copy this message, so this reference
660 /// must be valid for the whole life time of the diagnostic.
661 OptimizationRemarkMissed(const char *PassName, const Function &Fn,
662 const DiagnosticLocation &Loc, const Twine &Msg)
663 : DiagnosticInfoIROptimization(DK_OptimizationRemarkMissed, DS_Remark,
664 PassName, Fn, Loc, Msg) {}
666 friend void emitOptimizationRemarkMissed(LLVMContext &Ctx,
667 const char *PassName,
669 const DiagnosticLocation &Loc,
673 /// Diagnostic information for optimization analysis remarks.
674 class OptimizationRemarkAnalysis : public DiagnosticInfoIROptimization {
676 /// \p PassName is the name of the pass emitting this diagnostic. If this name
677 /// matches the regular expression given in -Rpass-analysis=, then the
678 /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
679 /// remark. \p Loc is the debug location and \p CodeRegion is the region
680 /// that the optimization operates on (currently on block is supported).
681 OptimizationRemarkAnalysis(const char *PassName, StringRef RemarkName,
682 const DiagnosticLocation &Loc,
683 const Value *CodeRegion);
685 /// \brief This is ctor variant allows a pass to build an optimization remark
686 /// from an existing remark.
688 /// This is useful when a transformation pass (e.g LV) wants to emit a remark
689 /// (\p Orig) generated by one of its analyses (e.g. LAA) as its own analysis
690 /// remark. The string \p Prepend will be emitted before the original
692 OptimizationRemarkAnalysis(const char *PassName, StringRef Prepend,
693 const OptimizationRemarkAnalysis &Orig)
694 : DiagnosticInfoIROptimization(PassName, Prepend, Orig) {}
696 /// \brief Same as above but \p Inst is used to derive code region and debug
698 OptimizationRemarkAnalysis(const char *PassName, StringRef RemarkName,
699 const Instruction *Inst);
701 static bool classof(const DiagnosticInfo *DI) {
702 return DI->getKind() == DK_OptimizationRemarkAnalysis;
705 static bool isEnabled(StringRef PassName);
707 /// \see DiagnosticInfoOptimizationBase::isEnabled.
708 bool isEnabled() const override {
709 return shouldAlwaysPrint() || isEnabled(getPassName());
712 static const char *AlwaysPrint;
714 bool shouldAlwaysPrint() const { return getPassName() == AlwaysPrint; }
717 OptimizationRemarkAnalysis(enum DiagnosticKind Kind, const char *PassName,
718 const Function &Fn, const DiagnosticLocation &Loc,
720 : DiagnosticInfoIROptimization(Kind, DS_Remark, PassName, Fn, Loc, Msg) {}
722 OptimizationRemarkAnalysis(enum DiagnosticKind Kind, const char *PassName,
723 StringRef RemarkName,
724 const DiagnosticLocation &Loc,
725 const Value *CodeRegion);
728 /// This is deprecated now and only used by the function API below.
729 /// \p PassName is the name of the pass emitting this diagnostic. If
730 /// this name matches the regular expression given in -Rpass-analysis=, then
731 /// the diagnostic will be emitted. \p Fn is the function where the diagnostic
732 /// is being emitted. \p Loc is the location information to use in the
733 /// diagnostic. If line table information is available, the diagnostic will
734 /// include the source code location. \p Msg is the message to show. Note that
735 /// this class does not copy this message, so this reference must be valid for
736 /// the whole life time of the diagnostic.
737 OptimizationRemarkAnalysis(const char *PassName, const Function &Fn,
738 const DiagnosticLocation &Loc, const Twine &Msg)
739 : DiagnosticInfoIROptimization(DK_OptimizationRemarkAnalysis, DS_Remark,
740 PassName, Fn, Loc, Msg) {}
742 friend void emitOptimizationRemarkAnalysis(LLVMContext &Ctx,
743 const char *PassName,
745 const DiagnosticLocation &Loc,
749 /// Diagnostic information for optimization analysis remarks related to
750 /// floating-point non-commutativity.
751 class OptimizationRemarkAnalysisFPCommute : public OptimizationRemarkAnalysis {
753 /// \p PassName is the name of the pass emitting this diagnostic. If this name
754 /// matches the regular expression given in -Rpass-analysis=, then the
755 /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
756 /// remark. \p Loc is the debug location and \p CodeRegion is the region
757 /// that the optimization operates on (currently on block is supported). The
758 /// front-end will append its own message related to options that address
759 /// floating-point non-commutativity.
760 OptimizationRemarkAnalysisFPCommute(const char *PassName,
761 StringRef RemarkName,
762 const DiagnosticLocation &Loc,
763 const Value *CodeRegion)
764 : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisFPCommute,
765 PassName, RemarkName, Loc, CodeRegion) {}
767 static bool classof(const DiagnosticInfo *DI) {
768 return DI->getKind() == DK_OptimizationRemarkAnalysisFPCommute;
772 /// This is deprecated now and only used by the function API below.
773 /// \p PassName is the name of the pass emitting this diagnostic. If
774 /// this name matches the regular expression given in -Rpass-analysis=, then
775 /// the diagnostic will be emitted. \p Fn is the function where the diagnostic
776 /// is being emitted. \p Loc is the location information to use in the
777 /// diagnostic. If line table information is available, the diagnostic will
778 /// include the source code location. \p Msg is the message to show. The
779 /// front-end will append its own message related to options that address
780 /// floating-point non-commutativity. Note that this class does not copy this
781 /// message, so this reference must be valid for the whole life time of the
783 OptimizationRemarkAnalysisFPCommute(const char *PassName, const Function &Fn,
784 const DiagnosticLocation &Loc,
786 : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisFPCommute,
787 PassName, Fn, Loc, Msg) {}
788 friend void emitOptimizationRemarkAnalysisFPCommute(
789 LLVMContext &Ctx, const char *PassName, const Function &Fn,
790 const DiagnosticLocation &Loc, const Twine &Msg);
793 /// Diagnostic information for optimization analysis remarks related to
794 /// pointer aliasing.
795 class OptimizationRemarkAnalysisAliasing : public OptimizationRemarkAnalysis {
797 /// \p PassName is the name of the pass emitting this diagnostic. If this name
798 /// matches the regular expression given in -Rpass-analysis=, then the
799 /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
800 /// remark. \p Loc is the debug location and \p CodeRegion is the region
801 /// that the optimization operates on (currently on block is supported). The
802 /// front-end will append its own message related to options that address
803 /// pointer aliasing legality.
804 OptimizationRemarkAnalysisAliasing(const char *PassName, StringRef RemarkName,
805 const DiagnosticLocation &Loc,
806 const Value *CodeRegion)
807 : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisAliasing,
808 PassName, RemarkName, Loc, CodeRegion) {}
810 static bool classof(const DiagnosticInfo *DI) {
811 return DI->getKind() == DK_OptimizationRemarkAnalysisAliasing;
815 /// This is deprecated now and only used by the function API below.
816 /// \p PassName is the name of the pass emitting this diagnostic. If
817 /// this name matches the regular expression given in -Rpass-analysis=, then
818 /// the diagnostic will be emitted. \p Fn is the function where the diagnostic
819 /// is being emitted. \p Loc is the location information to use in the
820 /// diagnostic. If line table information is available, the diagnostic will
821 /// include the source code location. \p Msg is the message to show. The
822 /// front-end will append its own message related to options that address
823 /// pointer aliasing legality. Note that this class does not copy this
824 /// message, so this reference must be valid for the whole life time of the
826 OptimizationRemarkAnalysisAliasing(const char *PassName, const Function &Fn,
827 const DiagnosticLocation &Loc,
829 : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisAliasing,
830 PassName, Fn, Loc, Msg) {}
832 friend void emitOptimizationRemarkAnalysisAliasing(
833 LLVMContext &Ctx, const char *PassName, const Function &Fn,
834 const DiagnosticLocation &Loc, const Twine &Msg);
837 /// Diagnostic information for machine IR parser.
838 class DiagnosticInfoMIRParser : public DiagnosticInfo {
839 const SMDiagnostic &Diagnostic;
842 DiagnosticInfoMIRParser(DiagnosticSeverity Severity,
843 const SMDiagnostic &Diagnostic)
844 : DiagnosticInfo(DK_MIRParser, Severity), Diagnostic(Diagnostic) {}
846 const SMDiagnostic &getDiagnostic() const { return Diagnostic; }
848 void print(DiagnosticPrinter &DP) const override;
850 static bool classof(const DiagnosticInfo *DI) {
851 return DI->getKind() == DK_MIRParser;
855 /// Diagnostic information for ISel fallback path.
856 class DiagnosticInfoISelFallback : public DiagnosticInfo {
857 /// The function that is concerned by this diagnostic.
861 DiagnosticInfoISelFallback(const Function &Fn,
862 DiagnosticSeverity Severity = DS_Warning)
863 : DiagnosticInfo(DK_ISelFallback, Severity), Fn(Fn) {}
865 const Function &getFunction() const { return Fn; }
867 void print(DiagnosticPrinter &DP) const override;
869 static bool classof(const DiagnosticInfo *DI) {
870 return DI->getKind() == DK_ISelFallback;
874 // Create wrappers for C Binding types (see CBindingWrapping.h).
875 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DiagnosticInfo, LLVMDiagnosticInfoRef)
877 /// Emit an optimization-applied message. \p PassName is the name of the pass
878 /// emitting the message. If -Rpass= is given and \p PassName matches the
879 /// regular expression in -Rpass, then the remark will be emitted. \p Fn is
880 /// the function triggering the remark, \p Loc is the debug location where
881 /// the diagnostic is generated. \p Msg is the message string to use.
882 void emitOptimizationRemark(LLVMContext &Ctx, const char *PassName,
883 const Function &Fn, const DiagnosticLocation &Loc,
886 /// Emit an optimization-missed message. \p PassName is the name of the
887 /// pass emitting the message. If -Rpass-missed= is given and \p PassName
888 /// matches the regular expression in -Rpass, then the remark will be
889 /// emitted. \p Fn is the function triggering the remark, \p Loc is the
890 /// debug location where the diagnostic is generated. \p Msg is the
891 /// message string to use.
892 void emitOptimizationRemarkMissed(LLVMContext &Ctx, const char *PassName,
894 const DiagnosticLocation &Loc,
897 /// Emit an optimization analysis remark message. \p PassName is the name of
898 /// the pass emitting the message. If -Rpass-analysis= is given and \p
899 /// PassName matches the regular expression in -Rpass, then the remark will be
900 /// emitted. \p Fn is the function triggering the remark, \p Loc is the debug
901 /// location where the diagnostic is generated. \p Msg is the message string
903 void emitOptimizationRemarkAnalysis(LLVMContext &Ctx, const char *PassName,
905 const DiagnosticLocation &Loc,
908 /// Emit an optimization analysis remark related to messages about
909 /// floating-point non-commutativity. \p PassName is the name of the pass
910 /// emitting the message. If -Rpass-analysis= is given and \p PassName matches
911 /// the regular expression in -Rpass, then the remark will be emitted. \p Fn is
912 /// the function triggering the remark, \p Loc is the debug location where the
913 /// diagnostic is generated. \p Msg is the message string to use.
914 void emitOptimizationRemarkAnalysisFPCommute(LLVMContext &Ctx,
915 const char *PassName,
917 const DiagnosticLocation &Loc,
920 /// Emit an optimization analysis remark related to messages about
921 /// pointer aliasing. \p PassName is the name of the pass emitting the message.
922 /// If -Rpass-analysis= is given and \p PassName matches the regular expression
923 /// in -Rpass, then the remark will be emitted. \p Fn is the function triggering
924 /// the remark, \p Loc is the debug location where the diagnostic is generated.
925 /// \p Msg is the message string to use.
926 void emitOptimizationRemarkAnalysisAliasing(LLVMContext &Ctx,
927 const char *PassName,
929 const DiagnosticLocation &Loc,
932 /// Diagnostic information for optimization failures.
933 class DiagnosticInfoOptimizationFailure : public DiagnosticInfoIROptimization {
935 /// \p Fn is the function where the diagnostic is being emitted. \p Loc is
936 /// the location information to use in the diagnostic. If line table
937 /// information is available, the diagnostic will include the source code
938 /// location. \p Msg is the message to show. Note that this class does not
939 /// copy this message, so this reference must be valid for the whole life time
940 /// of the diagnostic.
941 DiagnosticInfoOptimizationFailure(const Function &Fn,
942 const DiagnosticLocation &Loc,
944 : DiagnosticInfoIROptimization(DK_OptimizationFailure, DS_Warning,
945 nullptr, Fn, Loc, Msg) {}
947 /// \p PassName is the name of the pass emitting this diagnostic. \p
948 /// RemarkName is a textual identifier for the remark (single-word,
949 /// camel-case). \p Loc is the debug location and \p CodeRegion is the
950 /// region that the optimization operates on (currently basic block is
952 DiagnosticInfoOptimizationFailure(const char *PassName, StringRef RemarkName,
953 const DiagnosticLocation &Loc,
954 const Value *CodeRegion);
956 static bool classof(const DiagnosticInfo *DI) {
957 return DI->getKind() == DK_OptimizationFailure;
960 /// \see DiagnosticInfoOptimizationBase::isEnabled.
961 bool isEnabled() const override;
964 /// Diagnostic information for unsupported feature in backend.
965 class DiagnosticInfoUnsupported : public DiagnosticInfoWithLocationBase {
970 /// \p Fn is the function where the diagnostic is being emitted. \p Loc is
971 /// the location information to use in the diagnostic. If line table
972 /// information is available, the diagnostic will include the source code
973 /// location. \p Msg is the message to show. Note that this class does not
974 /// copy this message, so this reference must be valid for the whole life time
975 /// of the diagnostic.
976 DiagnosticInfoUnsupported(
977 const Function &Fn, const Twine &Msg,
978 const DiagnosticLocation &Loc = DiagnosticLocation(),
979 DiagnosticSeverity Severity = DS_Error)
980 : DiagnosticInfoWithLocationBase(DK_Unsupported, Severity, Fn, Loc),
983 static bool classof(const DiagnosticInfo *DI) {
984 return DI->getKind() == DK_Unsupported;
987 const Twine &getMessage() const { return Msg; }
989 void print(DiagnosticPrinter &DP) const override;
991 } // end namespace llvm
993 #endif // LLVM_IR_DIAGNOSTICINFO_H