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 /// Common features for diagnostics with an associated DebugLoc
351 class DiagnosticInfoWithDebugLocBase : public DiagnosticInfo {
353 /// \p Fn is the function where the diagnostic is being emitted. \p DLoc is
354 /// the location information to use in the diagnostic.
355 DiagnosticInfoWithDebugLocBase(enum DiagnosticKind Kind,
356 enum DiagnosticSeverity Severity,
358 const DebugLoc &DLoc)
359 : DiagnosticInfo(Kind, Severity), Fn(Fn), DLoc(DLoc) {}
361 /// Return true if location information is available for this diagnostic.
362 bool isLocationAvailable() const;
364 /// Return a string with the location information for this diagnostic
365 /// in the format "file:line:col". If location information is not available,
366 /// it returns "<unknown>:0:0".
367 const std::string getLocationStr() const;
369 /// Return location information for this diagnostic in three parts:
370 /// the source file name, line number and column.
371 void getLocation(StringRef *Filename, unsigned *Line, unsigned *Column) const;
373 const Function &getFunction() const { return Fn; }
374 const DebugLoc &getDebugLoc() const { return DLoc; }
377 /// Function where this diagnostic is triggered.
380 /// Debug location where this diagnostic is triggered.
384 /// \brief Common features for diagnostics dealing with optimization remarks
385 /// that are used by both IR and MIR passes.
386 class DiagnosticInfoOptimizationBase : public DiagnosticInfoWithDebugLocBase {
388 /// \brief Used to set IsVerbose via the stream interface.
389 struct setIsVerbose {};
391 /// \brief When an instance of this is inserted into the stream, the arguments
392 /// following will not appear in the remark printed in the compiler output
393 /// (-Rpass) but only in the optimization record file
394 /// (-fsave-optimization-record).
395 struct setExtraArgs {};
397 /// \brief Used in the streaming interface as the general argument type. It
398 /// internally converts everything into a key-value pair.
402 // If set, the debug location corresponding to the value.
405 explicit Argument(StringRef Str = "") : Key("String"), Val(Str) {}
406 Argument(StringRef Key, Value *V);
407 Argument(StringRef Key, Type *T);
408 Argument(StringRef Key, int N);
409 Argument(StringRef Key, unsigned N);
410 Argument(StringRef Key, bool B) : Key(Key), Val(B ? "true" : "false") {}
413 /// \p PassName is the name of the pass emitting this diagnostic. \p
414 /// RemarkName is a textual identifier for the remark. \p Fn is the function
415 /// where the diagnostic is being emitted. \p DLoc is the location information
416 /// to use in the diagnostic. If line table information is available, the
417 /// diagnostic will include the source code location.
418 DiagnosticInfoOptimizationBase(enum DiagnosticKind Kind,
419 enum DiagnosticSeverity Severity,
420 const char *PassName, StringRef RemarkName,
421 const Function &Fn, const DebugLoc &DLoc)
422 : DiagnosticInfoWithDebugLocBase(Kind, Severity, Fn, DLoc),
423 PassName(PassName), RemarkName(RemarkName) {}
425 DiagnosticInfoOptimizationBase &operator<<(StringRef S);
426 DiagnosticInfoOptimizationBase &operator<<(Argument A);
427 DiagnosticInfoOptimizationBase &operator<<(setIsVerbose V);
428 DiagnosticInfoOptimizationBase &operator<<(setExtraArgs EA);
430 /// \see DiagnosticInfo::print.
431 void print(DiagnosticPrinter &DP) const override;
433 /// Return true if this optimization remark is enabled by one of
434 /// of the LLVM command line flags (-pass-remarks, -pass-remarks-missed,
435 /// or -pass-remarks-analysis). Note that this only handles the LLVM
436 /// flags. We cannot access Clang flags from here (they are handled
437 /// in BackendConsumer::OptimizationRemarkHandler).
438 virtual bool isEnabled() const = 0;
440 StringRef getPassName() const { return PassName; }
441 std::string getMsg() const;
442 Optional<uint64_t> getHotness() const { return Hotness; }
443 void setHotness(Optional<uint64_t> H) { Hotness = H; }
445 bool isVerbose() const { return IsVerbose; }
447 static bool classof(const DiagnosticInfo *DI) {
448 return (DI->getKind() >= DK_FirstRemark &&
449 DI->getKind() <= DK_LastRemark) ||
450 (DI->getKind() >= DK_FirstMachineRemark &&
451 DI->getKind() <= DK_LastMachineRemark);
454 bool isPassed() const {
455 return (getKind() == DK_OptimizationRemark ||
456 getKind() == DK_MachineOptimizationRemark);
459 bool isMissed() const {
460 return (getKind() == DK_OptimizationRemarkMissed ||
461 getKind() == DK_MachineOptimizationRemarkMissed);
464 bool isAnalysis() const {
465 return (getKind() == DK_OptimizationRemarkAnalysis ||
466 getKind() == DK_MachineOptimizationRemarkAnalysis);
470 /// Name of the pass that triggers this report. If this matches the
471 /// regular expression given in -Rpass=regexp, then the remark will
473 const char *PassName;
475 /// Textual identifier for the remark. Can be used by external tools reading
476 /// the YAML output file for optimization remarks to identify the remark.
477 StringRef RemarkName;
479 /// If profile information is available, this is the number of times the
480 /// corresponding code was executed in a profile instrumentation run.
481 Optional<uint64_t> Hotness;
483 /// Arguments collected via the streaming interface.
484 SmallVector<Argument, 4> Args;
486 /// The remark is expected to be noisy.
487 bool IsVerbose = false;
489 /// \brief If positive, the index of the first argument that only appear in
490 /// the optimization records and not in the remark printed in the compiler
492 int FirstExtraArgIndex = -1;
494 friend struct yaml::MappingTraits<DiagnosticInfoOptimizationBase *>;
497 /// \brief Common features for diagnostics dealing with optimization remarks
498 /// that are used by IR passes.
499 class DiagnosticInfoIROptimization : public DiagnosticInfoOptimizationBase {
501 /// \p PassName is the name of the pass emitting this diagnostic. \p
502 /// RemarkName is a textual identifier for the remark. \p Fn is the function
503 /// where the diagnostic is being emitted. \p DLoc is the location information
504 /// to use in the diagnostic. If line table information is available, the
505 /// diagnostic will include the source code location. \p CodeRegion is IR
506 /// value (currently basic block) that the optimization operates on. This is
507 /// currently used to provide run-time hotness information with PGO.
508 DiagnosticInfoIROptimization(enum DiagnosticKind Kind,
509 enum DiagnosticSeverity Severity,
510 const char *PassName, StringRef RemarkName,
511 const Function &Fn, const DebugLoc &DLoc,
512 Value *CodeRegion = nullptr)
513 : DiagnosticInfoOptimizationBase(Kind, Severity, PassName, RemarkName, Fn,
515 CodeRegion(CodeRegion) {}
517 /// \brief This is ctor variant allows a pass to build an optimization remark
518 /// from an existing remark.
520 /// This is useful when a transformation pass (e.g LV) wants to emit a remark
521 /// (\p Orig) generated by one of its analyses (e.g. LAA) as its own analysis
522 /// remark. The string \p Prepend will be emitted before the original
524 DiagnosticInfoIROptimization(const char *PassName, StringRef Prepend,
525 const DiagnosticInfoIROptimization &Orig)
526 : DiagnosticInfoOptimizationBase(
527 (DiagnosticKind)Orig.getKind(), Orig.getSeverity(), PassName,
528 Orig.RemarkName, Orig.getFunction(), Orig.getDebugLoc()),
529 CodeRegion(Orig.getCodeRegion()) {
531 std::copy(Orig.Args.begin(), Orig.Args.end(), std::back_inserter(Args));
534 /// Legacy interface.
535 /// \p PassName is the name of the pass emitting this diagnostic.
536 /// \p Fn is the function where the diagnostic is being emitted. \p DLoc is
537 /// the location information to use in the diagnostic. If line table
538 /// information is available, the diagnostic will include the source code
539 /// location. \p Msg is the message to show. Note that this class does not
540 /// copy this message, so this reference must be valid for the whole life time
541 /// of the diagnostic.
542 DiagnosticInfoIROptimization(enum DiagnosticKind Kind,
543 enum DiagnosticSeverity Severity,
544 const char *PassName, const Function &Fn,
545 const DebugLoc &DLoc, const Twine &Msg,
546 Optional<uint64_t> Hotness = None)
547 : DiagnosticInfoOptimizationBase(Kind, Severity, PassName, "", Fn, DLoc) {
552 Value *getCodeRegion() const { return CodeRegion; }
554 static bool classof(const DiagnosticInfo *DI) {
555 return DI->getKind() >= DK_FirstRemark && DI->getKind() <= DK_LastRemark;
559 /// The IR value (currently basic block) that the optimization operates on.
560 /// This is currently used to provide run-time hotness information with PGO.
564 /// Diagnostic information for applied optimization remarks.
565 class OptimizationRemark : public DiagnosticInfoIROptimization {
567 /// \p PassName is the name of the pass emitting this diagnostic. If
568 /// this name matches the regular expression given in -Rpass=, then the
569 /// diagnostic will be emitted. \p Fn is the function where the diagnostic
570 /// is being emitted. \p DLoc is the location information to use in the
571 /// diagnostic. If line table information is available, the diagnostic
572 /// will include the source code location. \p Msg is the message to show.
573 /// Note that this class does not copy this message, so this reference
574 /// must be valid for the whole life time of the diagnostic.
575 OptimizationRemark(const char *PassName, const Function &Fn,
576 const DebugLoc &DLoc, const Twine &Msg,
577 Optional<uint64_t> Hotness = None)
578 : DiagnosticInfoIROptimization(DK_OptimizationRemark, DS_Remark, PassName,
579 Fn, DLoc, Msg, Hotness) {}
581 /// \p PassName is the name of the pass emitting this diagnostic. If this name
582 /// matches the regular expression given in -Rpass=, then the diagnostic will
583 /// be emitted. \p RemarkName is a textual identifier for the remark. \p
584 /// DLoc is the debug location and \p CodeRegion is the region that the
585 /// optimization operates on (currently on block is supported).
586 OptimizationRemark(const char *PassName, StringRef RemarkName,
587 const DebugLoc &DLoc, Value *CodeRegion);
589 /// Same as above but the debug location and code region is derived from \p
591 OptimizationRemark(const char *PassName, StringRef RemarkName,
594 static bool classof(const DiagnosticInfo *DI) {
595 return DI->getKind() == DK_OptimizationRemark;
598 static bool isEnabled(StringRef PassName);
600 /// \see DiagnosticInfoOptimizationBase::isEnabled.
601 bool isEnabled() const override { return isEnabled(getPassName()); }
604 /// Diagnostic information for missed-optimization remarks.
605 class OptimizationRemarkMissed : public DiagnosticInfoIROptimization {
607 /// \p PassName is the name of the pass emitting this diagnostic. If
608 /// this name matches the regular expression given in -Rpass-missed=, then the
609 /// diagnostic will be emitted. \p Fn is the function where the diagnostic
610 /// is being emitted. \p DLoc is the location information to use in the
611 /// diagnostic. If line table information is available, the diagnostic
612 /// will include the source code location. \p Msg is the message to show.
613 /// Note that this class does not copy this message, so this reference
614 /// must be valid for the whole life time of the diagnostic.
615 OptimizationRemarkMissed(const char *PassName, const Function &Fn,
616 const DebugLoc &DLoc, const Twine &Msg,
617 Optional<uint64_t> Hotness = None)
618 : DiagnosticInfoIROptimization(DK_OptimizationRemarkMissed, DS_Remark,
619 PassName, Fn, DLoc, Msg, Hotness) {}
621 /// \p PassName is the name of the pass emitting this diagnostic. If this name
622 /// matches the regular expression given in -Rpass-missed=, then the
623 /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
624 /// remark. \p DLoc is the debug location and \p CodeRegion is the region
625 /// that the optimization operates on (currently on block is supported).
626 OptimizationRemarkMissed(const char *PassName, StringRef RemarkName,
627 const DebugLoc &DLoc, Value *CodeRegion);
629 /// \brief Same as above but \p Inst is used to derive code region and debug
631 OptimizationRemarkMissed(const char *PassName, StringRef RemarkName,
634 static bool classof(const DiagnosticInfo *DI) {
635 return DI->getKind() == DK_OptimizationRemarkMissed;
638 static bool isEnabled(StringRef PassName);
640 /// \see DiagnosticInfoOptimizationBase::isEnabled.
641 bool isEnabled() const override { return isEnabled(getPassName()); }
644 /// Diagnostic information for optimization analysis remarks.
645 class OptimizationRemarkAnalysis : public DiagnosticInfoIROptimization {
647 /// \p PassName is the name of the pass emitting this diagnostic. If
648 /// this name matches the regular expression given in -Rpass-analysis=, then
649 /// the diagnostic will be emitted. \p Fn is the function where the diagnostic
650 /// is being emitted. \p DLoc is the location information to use in the
651 /// diagnostic. If line table information is available, the diagnostic will
652 /// include the source code location. \p Msg is the message to show. Note that
653 /// this class does not copy this message, so this reference must be valid for
654 /// the whole life time of the diagnostic.
655 OptimizationRemarkAnalysis(const char *PassName, const Function &Fn,
656 const DebugLoc &DLoc, const Twine &Msg,
657 Optional<uint64_t> Hotness = None)
658 : DiagnosticInfoIROptimization(DK_OptimizationRemarkAnalysis, DS_Remark,
659 PassName, Fn, DLoc, Msg, Hotness) {}
661 /// \p PassName is the name of the pass emitting this diagnostic. If this name
662 /// matches the regular expression given in -Rpass-analysis=, then the
663 /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
664 /// remark. \p DLoc is the debug location and \p CodeRegion is the region
665 /// that the optimization operates on (currently on block is supported).
666 OptimizationRemarkAnalysis(const char *PassName, StringRef RemarkName,
667 const DebugLoc &DLoc, Value *CodeRegion);
669 /// \brief This is ctor variant allows a pass to build an optimization remark
670 /// from an existing remark.
672 /// This is useful when a transformation pass (e.g LV) wants to emit a remark
673 /// (\p Orig) generated by one of its analyses (e.g. LAA) as its own analysis
674 /// remark. The string \p Prepend will be emitted before the original
676 OptimizationRemarkAnalysis(const char *PassName, StringRef Prepend,
677 const OptimizationRemarkAnalysis &Orig)
678 : DiagnosticInfoIROptimization(PassName, Prepend, Orig) {}
680 /// \brief Same as above but \p Inst is used to derive code region and debug
682 OptimizationRemarkAnalysis(const char *PassName, StringRef RemarkName,
685 static bool classof(const DiagnosticInfo *DI) {
686 return DI->getKind() == DK_OptimizationRemarkAnalysis;
689 static bool isEnabled(StringRef PassName);
691 /// \see DiagnosticInfoOptimizationBase::isEnabled.
692 bool isEnabled() const override {
693 return shouldAlwaysPrint() || isEnabled(getPassName());
696 static const char *AlwaysPrint;
698 bool shouldAlwaysPrint() const { return getPassName() == AlwaysPrint; }
701 OptimizationRemarkAnalysis(enum DiagnosticKind Kind, const char *PassName,
702 const Function &Fn, const DebugLoc &DLoc,
703 const Twine &Msg, Optional<uint64_t> Hotness)
704 : DiagnosticInfoIROptimization(Kind, DS_Remark, PassName, Fn, DLoc, Msg,
707 OptimizationRemarkAnalysis(enum DiagnosticKind Kind, const char *PassName,
708 StringRef RemarkName, const DebugLoc &DLoc,
712 /// Diagnostic information for optimization analysis remarks related to
713 /// floating-point non-commutativity.
714 class OptimizationRemarkAnalysisFPCommute : public OptimizationRemarkAnalysis {
716 /// \p PassName is the name of the pass emitting this diagnostic. If
717 /// this name matches the regular expression given in -Rpass-analysis=, then
718 /// the diagnostic will be emitted. \p Fn is the function where the diagnostic
719 /// is being emitted. \p DLoc is the location information to use in the
720 /// diagnostic. If line table information is available, the diagnostic will
721 /// include the source code location. \p Msg is the message to show. The
722 /// front-end will append its own message related to options that address
723 /// floating-point non-commutativity. Note that this class does not copy this
724 /// message, so this reference must be valid for the whole life time of the
726 OptimizationRemarkAnalysisFPCommute(const char *PassName, const Function &Fn,
727 const DebugLoc &DLoc, const Twine &Msg,
728 Optional<uint64_t> Hotness = None)
729 : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisFPCommute,
730 PassName, Fn, DLoc, Msg, Hotness) {}
732 /// \p PassName is the name of the pass emitting this diagnostic. If this name
733 /// matches the regular expression given in -Rpass-analysis=, then the
734 /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
735 /// remark. \p DLoc is the debug location and \p CodeRegion is the region
736 /// that the optimization operates on (currently on block is supported). The
737 /// front-end will append its own message related to options that address
738 /// floating-point non-commutativity.
739 OptimizationRemarkAnalysisFPCommute(const char *PassName,
740 StringRef RemarkName,
741 const DebugLoc &DLoc, Value *CodeRegion)
742 : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisFPCommute,
743 PassName, RemarkName, DLoc, CodeRegion) {}
745 static bool classof(const DiagnosticInfo *DI) {
746 return DI->getKind() == DK_OptimizationRemarkAnalysisFPCommute;
750 /// Diagnostic information for optimization analysis remarks related to
751 /// pointer aliasing.
752 class OptimizationRemarkAnalysisAliasing : public OptimizationRemarkAnalysis {
754 /// \p PassName is the name of the pass emitting this diagnostic. If
755 /// this name matches the regular expression given in -Rpass-analysis=, then
756 /// the diagnostic will be emitted. \p Fn is the function where the diagnostic
757 /// is being emitted. \p DLoc is the location information to use in the
758 /// diagnostic. If line table information is available, the diagnostic will
759 /// include the source code location. \p Msg is the message to show. The
760 /// front-end will append its own message related to options that address
761 /// pointer aliasing legality. Note that this class does not copy this
762 /// message, so this reference must be valid for the whole life time of the
764 OptimizationRemarkAnalysisAliasing(const char *PassName, const Function &Fn,
765 const DebugLoc &DLoc, const Twine &Msg,
766 Optional<uint64_t> Hotness = None)
767 : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisAliasing,
768 PassName, Fn, DLoc, Msg, Hotness) {}
770 /// \p PassName is the name of the pass emitting this diagnostic. If this name
771 /// matches the regular expression given in -Rpass-analysis=, then the
772 /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
773 /// remark. \p DLoc is the debug location and \p CodeRegion is the region
774 /// that the optimization operates on (currently on block is supported). The
775 /// front-end will append its own message related to options that address
776 /// pointer aliasing legality.
777 OptimizationRemarkAnalysisAliasing(const char *PassName, StringRef RemarkName,
778 const DebugLoc &DLoc, Value *CodeRegion)
779 : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisAliasing,
780 PassName, RemarkName, DLoc, CodeRegion) {}
782 static bool classof(const DiagnosticInfo *DI) {
783 return DI->getKind() == DK_OptimizationRemarkAnalysisAliasing;
787 /// Diagnostic information for machine IR parser.
788 class DiagnosticInfoMIRParser : public DiagnosticInfo {
789 const SMDiagnostic &Diagnostic;
792 DiagnosticInfoMIRParser(DiagnosticSeverity Severity,
793 const SMDiagnostic &Diagnostic)
794 : DiagnosticInfo(DK_MIRParser, Severity), Diagnostic(Diagnostic) {}
796 const SMDiagnostic &getDiagnostic() const { return Diagnostic; }
798 void print(DiagnosticPrinter &DP) const override;
800 static bool classof(const DiagnosticInfo *DI) {
801 return DI->getKind() == DK_MIRParser;
805 /// Diagnostic information for ISel fallback path.
806 class DiagnosticInfoISelFallback : public DiagnosticInfo {
807 /// The function that is concerned by this diagnostic.
811 DiagnosticInfoISelFallback(const Function &Fn,
812 DiagnosticSeverity Severity = DS_Warning)
813 : DiagnosticInfo(DK_ISelFallback, Severity), Fn(Fn) {}
815 const Function &getFunction() const { return Fn; }
817 void print(DiagnosticPrinter &DP) const override;
819 static bool classof(const DiagnosticInfo *DI) {
820 return DI->getKind() == DK_ISelFallback;
824 // Create wrappers for C Binding types (see CBindingWrapping.h).
825 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DiagnosticInfo, LLVMDiagnosticInfoRef)
827 /// Emit an optimization-applied message. \p PassName is the name of the pass
828 /// emitting the message. If -Rpass= is given and \p PassName matches the
829 /// regular expression in -Rpass, then the remark will be emitted. \p Fn is
830 /// the function triggering the remark, \p DLoc is the debug location where
831 /// the diagnostic is generated. \p Msg is the message string to use.
832 void emitOptimizationRemark(LLVMContext &Ctx, const char *PassName,
833 const Function &Fn, const DebugLoc &DLoc,
836 /// Emit an optimization-missed message. \p PassName is the name of the
837 /// pass emitting the message. If -Rpass-missed= is given and \p PassName
838 /// matches the regular expression in -Rpass, then the remark will be
839 /// emitted. \p Fn is the function triggering the remark, \p DLoc is the
840 /// debug location where the diagnostic is generated. \p Msg is the
841 /// message string to use.
842 void emitOptimizationRemarkMissed(LLVMContext &Ctx, const char *PassName,
843 const Function &Fn, const DebugLoc &DLoc,
846 /// Emit an optimization analysis remark message. \p PassName is the name of
847 /// the pass emitting the message. If -Rpass-analysis= is given and \p
848 /// PassName matches the regular expression in -Rpass, then the remark will be
849 /// emitted. \p Fn is the function triggering the remark, \p DLoc is the debug
850 /// location where the diagnostic is generated. \p Msg is the message string
852 void emitOptimizationRemarkAnalysis(LLVMContext &Ctx, const char *PassName,
853 const Function &Fn, const DebugLoc &DLoc,
856 /// Emit an optimization analysis remark related to messages about
857 /// floating-point non-commutativity. \p PassName is the name of the pass
858 /// emitting the message. If -Rpass-analysis= is given and \p PassName matches
859 /// the regular expression in -Rpass, then the remark will be emitted. \p Fn is
860 /// the function triggering the remark, \p DLoc is the debug location where the
861 /// diagnostic is generated. \p Msg is the message string to use.
862 void emitOptimizationRemarkAnalysisFPCommute(LLVMContext &Ctx,
863 const char *PassName,
865 const DebugLoc &DLoc,
868 /// Emit an optimization analysis remark related to messages about
869 /// pointer aliasing. \p PassName is the name of the pass emitting the message.
870 /// If -Rpass-analysis= is given and \p PassName matches the regular expression
871 /// in -Rpass, then the remark will be emitted. \p Fn is the function triggering
872 /// the remark, \p DLoc is the debug location where the diagnostic is generated.
873 /// \p Msg is the message string to use.
874 void emitOptimizationRemarkAnalysisAliasing(LLVMContext &Ctx,
875 const char *PassName,
877 const DebugLoc &DLoc,
880 /// Diagnostic information for optimization failures.
881 class DiagnosticInfoOptimizationFailure : public DiagnosticInfoIROptimization {
883 /// \p Fn is the function where the diagnostic is being emitted. \p DLoc is
884 /// the location information to use in the diagnostic. If line table
885 /// information is available, the diagnostic will include the source code
886 /// location. \p Msg is the message to show. Note that this class does not
887 /// copy this message, so this reference must be valid for the whole life time
888 /// of the diagnostic.
889 DiagnosticInfoOptimizationFailure(const Function &Fn, const DebugLoc &DLoc,
891 : DiagnosticInfoIROptimization(DK_OptimizationFailure, DS_Warning,
892 nullptr, Fn, DLoc, Msg) {}
894 /// \p PassName is the name of the pass emitting this diagnostic. \p
895 /// RemarkName is a textual identifier for the remark (single-word,
896 /// camel-case). \p DLoc is the debug location and \p CodeRegion is the
897 /// region that the optimization operates on (currently basic block is
899 DiagnosticInfoOptimizationFailure(const char *PassName, StringRef RemarkName,
900 const DebugLoc &DLoc, Value *CodeRegion);
902 static bool classof(const DiagnosticInfo *DI) {
903 return DI->getKind() == DK_OptimizationFailure;
906 /// \see DiagnosticInfoOptimizationBase::isEnabled.
907 bool isEnabled() const override;
910 /// Diagnostic information for unsupported feature in backend.
911 class DiagnosticInfoUnsupported
912 : public DiagnosticInfoWithDebugLocBase {
917 /// \p Fn is the function where the diagnostic is being emitted. \p DLoc is
918 /// the location information to use in the diagnostic. If line table
919 /// information is available, the diagnostic will include the source code
920 /// location. \p Msg is the message to show. Note that this class does not
921 /// copy this message, so this reference must be valid for the whole life time
922 /// of the diagnostic.
923 DiagnosticInfoUnsupported(const Function &Fn, const Twine &Msg,
924 DebugLoc DLoc = DebugLoc(),
925 DiagnosticSeverity Severity = DS_Error)
926 : DiagnosticInfoWithDebugLocBase(DK_Unsupported, Severity, Fn, DLoc),
929 static bool classof(const DiagnosticInfo *DI) {
930 return DI->getKind() == DK_Unsupported;
933 const Twine &getMessage() const { return Msg; }
935 void print(DiagnosticPrinter &DP) const override;
937 } // end namespace llvm
939 #endif // LLVM_IR_DIAGNOSTICINFO_H