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,
78 /// \brief Get the next available kind ID for a plugin diagnostic.
79 /// Each time this function is called, it returns a different number.
80 /// Therefore, a plugin that wants to "identify" its own classes
81 /// with a dynamic identifier, just have to use this method to get a new ID
82 /// and assign it to each of its classes.
83 /// The returned ID will be greater than or equal to DK_FirstPluginKind.
84 /// Thus, the plugin identifiers will not conflict with the
85 /// DiagnosticKind values.
86 int getNextAvailablePluginDiagnosticKind();
88 /// \brief This is the base abstract class for diagnostic reporting in
90 /// The print method must be overloaded by the subclasses to print a
91 /// user-friendly message in the client of the backend (let us call it a
93 class DiagnosticInfo {
95 /// Kind defines the kind of report this is about.
96 const /* DiagnosticKind */ int Kind;
97 /// Severity gives the severity of the diagnostic.
98 const DiagnosticSeverity Severity;
101 DiagnosticInfo(/* DiagnosticKind */ int Kind, DiagnosticSeverity Severity)
102 : Kind(Kind), Severity(Severity) {}
104 virtual ~DiagnosticInfo() = default;
106 /* DiagnosticKind */ int getKind() const { return Kind; }
107 DiagnosticSeverity getSeverity() const { return Severity; }
109 /// Print using the given \p DP a user-friendly message.
110 /// This is the default message that will be printed to the user.
111 /// It is used when the frontend does not directly take advantage
112 /// of the information contained in fields of the subclasses.
113 /// The printed message must not end with '.' nor start with a severity
115 virtual void print(DiagnosticPrinter &DP) const = 0;
118 typedef std::function<void(const DiagnosticInfo &)> DiagnosticHandlerFunction;
120 /// Diagnostic information for inline asm reporting.
121 /// This is basically a message and an optional location.
122 class DiagnosticInfoInlineAsm : public DiagnosticInfo {
124 /// Optional line information. 0 if not set.
126 /// Message to be reported.
128 /// Optional origin of the problem.
129 const Instruction *Instr;
132 /// \p MsgStr is the message to be reported to the frontend.
133 /// This class does not copy \p MsgStr, therefore the reference must be valid
134 /// for the whole life time of the Diagnostic.
135 DiagnosticInfoInlineAsm(const Twine &MsgStr,
136 DiagnosticSeverity Severity = DS_Error)
137 : DiagnosticInfo(DK_InlineAsm, Severity), LocCookie(0), MsgStr(MsgStr),
140 /// \p LocCookie if non-zero gives the line number for this report.
141 /// \p MsgStr gives the message.
142 /// This class does not copy \p MsgStr, therefore the reference must be valid
143 /// for the whole life time of the Diagnostic.
144 DiagnosticInfoInlineAsm(unsigned LocCookie, const Twine &MsgStr,
145 DiagnosticSeverity Severity = DS_Error)
146 : DiagnosticInfo(DK_InlineAsm, Severity), LocCookie(LocCookie),
147 MsgStr(MsgStr), Instr(nullptr) {}
149 /// \p Instr gives the original instruction that triggered the diagnostic.
150 /// \p MsgStr gives the message.
151 /// This class does not copy \p MsgStr, therefore the reference must be valid
152 /// for the whole life time of the Diagnostic.
154 DiagnosticInfoInlineAsm(const Instruction &I, const Twine &MsgStr,
155 DiagnosticSeverity Severity = DS_Error);
157 unsigned getLocCookie() const { return LocCookie; }
158 const Twine &getMsgStr() const { return MsgStr; }
159 const Instruction *getInstruction() const { return Instr; }
161 /// \see DiagnosticInfo::print.
162 void print(DiagnosticPrinter &DP) const override;
164 static bool classof(const DiagnosticInfo *DI) {
165 return DI->getKind() == DK_InlineAsm;
169 /// Diagnostic information for stack size etc. reporting.
170 /// This is basically a function and a size.
171 class DiagnosticInfoResourceLimit : public DiagnosticInfo {
173 /// The function that is concerned by this resource limit diagnostic.
176 /// Description of the resource type (e.g. stack size)
177 const char *ResourceName;
179 /// The computed size usage
180 uint64_t ResourceSize;
183 uint64_t ResourceLimit;
186 /// \p The function that is concerned by this stack size diagnostic.
187 /// \p The computed stack size.
188 DiagnosticInfoResourceLimit(const Function &Fn,
189 const char *ResourceName,
190 uint64_t ResourceSize,
191 DiagnosticSeverity Severity = DS_Warning,
192 DiagnosticKind Kind = DK_ResourceLimit,
193 uint64_t ResourceLimit = 0)
194 : DiagnosticInfo(Kind, Severity),
196 ResourceName(ResourceName),
197 ResourceSize(ResourceSize),
198 ResourceLimit(ResourceLimit) {}
200 const Function &getFunction() const { return Fn; }
201 const char *getResourceName() const { return ResourceName; }
202 uint64_t getResourceSize() const { return ResourceSize; }
203 uint64_t getResourceLimit() const { return ResourceLimit; }
205 /// \see DiagnosticInfo::print.
206 void print(DiagnosticPrinter &DP) const override;
208 static bool classof(const DiagnosticInfo *DI) {
209 return DI->getKind() == DK_ResourceLimit ||
210 DI->getKind() == DK_StackSize;
214 class DiagnosticInfoStackSize : public DiagnosticInfoResourceLimit {
216 DiagnosticInfoStackSize(const Function &Fn,
218 DiagnosticSeverity Severity = DS_Warning,
219 uint64_t StackLimit = 0)
220 : DiagnosticInfoResourceLimit(Fn, "stack size", StackSize,
221 Severity, DK_StackSize, StackLimit) {}
223 uint64_t getStackSize() const { return getResourceSize(); }
224 uint64_t getStackLimit() const { return getResourceLimit(); }
226 static bool classof(const DiagnosticInfo *DI) {
227 return DI->getKind() == DK_StackSize;
231 /// Diagnostic information for debug metadata version reporting.
232 /// This is basically a module and a version.
233 class DiagnosticInfoDebugMetadataVersion : public DiagnosticInfo {
235 /// The module that is concerned by this debug metadata version diagnostic.
237 /// The actual metadata version.
238 unsigned MetadataVersion;
241 /// \p The module that is concerned by this debug metadata version diagnostic.
242 /// \p The actual metadata version.
243 DiagnosticInfoDebugMetadataVersion(const Module &M, unsigned MetadataVersion,
244 DiagnosticSeverity Severity = DS_Warning)
245 : DiagnosticInfo(DK_DebugMetadataVersion, Severity), M(M),
246 MetadataVersion(MetadataVersion) {}
248 const Module &getModule() const { return M; }
249 unsigned getMetadataVersion() const { return MetadataVersion; }
251 /// \see DiagnosticInfo::print.
252 void print(DiagnosticPrinter &DP) const override;
254 static bool classof(const DiagnosticInfo *DI) {
255 return DI->getKind() == DK_DebugMetadataVersion;
259 /// Diagnostic information for stripping invalid debug metadata.
260 class DiagnosticInfoIgnoringInvalidDebugMetadata : public DiagnosticInfo {
262 /// The module that is concerned by this debug metadata version diagnostic.
266 /// \p The module that is concerned by this debug metadata version diagnostic.
267 DiagnosticInfoIgnoringInvalidDebugMetadata(
268 const Module &M, DiagnosticSeverity Severity = DS_Warning)
269 : DiagnosticInfo(DK_DebugMetadataVersion, Severity), M(M) {}
271 const Module &getModule() const { return M; }
273 /// \see DiagnosticInfo::print.
274 void print(DiagnosticPrinter &DP) const override;
276 static bool classof(const DiagnosticInfo *DI) {
277 return DI->getKind() == DK_DebugMetadataInvalid;
281 /// Diagnostic information for the sample profiler.
282 class DiagnosticInfoSampleProfile : public DiagnosticInfo {
284 DiagnosticInfoSampleProfile(StringRef FileName, unsigned LineNum,
286 DiagnosticSeverity Severity = DS_Error)
287 : DiagnosticInfo(DK_SampleProfile, Severity), FileName(FileName),
288 LineNum(LineNum), Msg(Msg) {}
289 DiagnosticInfoSampleProfile(StringRef FileName, const Twine &Msg,
290 DiagnosticSeverity Severity = DS_Error)
291 : DiagnosticInfo(DK_SampleProfile, Severity), FileName(FileName),
292 LineNum(0), Msg(Msg) {}
293 DiagnosticInfoSampleProfile(const Twine &Msg,
294 DiagnosticSeverity Severity = DS_Error)
295 : DiagnosticInfo(DK_SampleProfile, Severity), LineNum(0), Msg(Msg) {}
297 /// \see DiagnosticInfo::print.
298 void print(DiagnosticPrinter &DP) const override;
300 static bool classof(const DiagnosticInfo *DI) {
301 return DI->getKind() == DK_SampleProfile;
304 StringRef getFileName() const { return FileName; }
305 unsigned getLineNum() const { return LineNum; }
306 const Twine &getMsg() const { return Msg; }
309 /// Name of the input file associated with this diagnostic.
312 /// Line number where the diagnostic occurred. If 0, no line number will
313 /// be emitted in the message.
316 /// Message to report.
320 /// Diagnostic information for the PGO profiler.
321 class DiagnosticInfoPGOProfile : public DiagnosticInfo {
323 DiagnosticInfoPGOProfile(const char *FileName, const Twine &Msg,
324 DiagnosticSeverity Severity = DS_Error)
325 : DiagnosticInfo(DK_PGOProfile, Severity), FileName(FileName), Msg(Msg) {}
327 /// \see DiagnosticInfo::print.
328 void print(DiagnosticPrinter &DP) const override;
330 static bool classof(const DiagnosticInfo *DI) {
331 return DI->getKind() == DK_PGOProfile;
334 const char *getFileName() const { return FileName; }
335 const Twine &getMsg() const { return Msg; }
338 /// Name of the input file associated with this diagnostic.
339 const char *FileName;
341 /// Message to report.
345 /// Common features for diagnostics with an associated DebugLoc
346 class DiagnosticInfoWithDebugLocBase : public DiagnosticInfo {
348 /// \p Fn is the function where the diagnostic is being emitted. \p DLoc is
349 /// the location information to use in the diagnostic.
350 DiagnosticInfoWithDebugLocBase(enum DiagnosticKind Kind,
351 enum DiagnosticSeverity Severity,
353 const DebugLoc &DLoc)
354 : DiagnosticInfo(Kind, Severity), Fn(Fn), DLoc(DLoc) {}
356 /// Return true if location information is available for this diagnostic.
357 bool isLocationAvailable() const;
359 /// Return a string with the location information for this diagnostic
360 /// in the format "file:line:col". If location information is not available,
361 /// it returns "<unknown>:0:0".
362 const std::string getLocationStr() const;
364 /// Return location information for this diagnostic in three parts:
365 /// the source file name, line number and column.
366 void getLocation(StringRef *Filename, unsigned *Line, unsigned *Column) const;
368 const Function &getFunction() const { return Fn; }
369 const DebugLoc &getDebugLoc() const { return DLoc; }
372 /// Function where this diagnostic is triggered.
375 /// Debug location where this diagnostic is triggered.
379 /// Common features for diagnostics dealing with optimization remarks.
380 class DiagnosticInfoOptimizationBase : public DiagnosticInfoWithDebugLocBase {
382 /// \brief Used to set IsVerbose via the stream interface.
383 struct setIsVerbose {};
385 /// \brief When an instance of this is inserted into the stream, the arguments
386 /// following will not appear in the remark printed in the compiler output
387 /// (-Rpass) but only in the optimization record file
388 /// (-fsave-optimization-record).
389 struct setExtraArgs {};
391 /// \brief Used in the streaming interface as the general argument type. It
392 /// internally converts everything into a key-value pair.
396 // If set, the debug location corresponding to the value.
399 explicit Argument(StringRef Str = "") : Key("String"), Val(Str) {}
400 Argument(StringRef Key, Value *V);
401 Argument(StringRef Key, Type *T);
402 Argument(StringRef Key, int N);
403 Argument(StringRef Key, unsigned N);
404 Argument(StringRef Key, bool B) : Key(Key), Val(B ? "true" : "false") {}
407 /// \p PassName is the name of the pass emitting this diagnostic. \p
408 /// RemarkName is a textual identifier for the remark. \p Fn is the function
409 /// where the diagnostic is being emitted. \p DLoc is the location information
410 /// to use in the diagnostic. If line table information is available, the
411 /// diagnostic will include the source code location. \p CodeRegion is IR
412 /// value (currently basic block) that the optimization operates on. This is
413 /// currently used to provide run-time hotness information with PGO.
414 DiagnosticInfoOptimizationBase(enum DiagnosticKind Kind,
415 enum DiagnosticSeverity Severity,
416 const char *PassName, StringRef RemarkName,
417 const Function &Fn, const DebugLoc &DLoc,
418 Value *CodeRegion = nullptr)
419 : DiagnosticInfoWithDebugLocBase(Kind, Severity, Fn, DLoc),
420 PassName(PassName), RemarkName(RemarkName), CodeRegion(CodeRegion) {}
422 /// \brief This is ctor variant allows a pass to build an optimization remark
423 /// from an existing remark.
425 /// This is useful when a transformation pass (e.g LV) wants to emit a remark
426 /// (\p Orig) generated by one of its analyses (e.g. LAA) as its own analysis
427 /// remark. The string \p Prepend will be emitted before the original
429 DiagnosticInfoOptimizationBase(const char *PassName, StringRef Prepend,
430 const DiagnosticInfoOptimizationBase &Orig)
431 : DiagnosticInfoWithDebugLocBase((DiagnosticKind)Orig.getKind(),
432 Orig.getSeverity(), Orig.getFunction(),
434 PassName(PassName), RemarkName(Orig.RemarkName),
435 CodeRegion(Orig.getCodeRegion()) {
437 std::copy(Orig.Args.begin(), Orig.Args.end(), std::back_inserter(Args));
440 /// Legacy interface.
441 /// \p PassName is the name of the pass emitting this diagnostic.
442 /// \p Fn is the function where the diagnostic is being emitted. \p DLoc is
443 /// the location information to use in the diagnostic. If line table
444 /// information is available, the diagnostic will include the source code
445 /// location. \p Msg is the message to show. Note that this class does not
446 /// copy this message, so this reference must be valid for the whole life time
447 /// of the diagnostic.
448 DiagnosticInfoOptimizationBase(enum DiagnosticKind Kind,
449 enum DiagnosticSeverity Severity,
450 const char *PassName, const Function &Fn,
451 const DebugLoc &DLoc, const Twine &Msg,
452 Optional<uint64_t> Hotness = None)
453 : DiagnosticInfoWithDebugLocBase(Kind, Severity, Fn, DLoc),
454 PassName(PassName), Hotness(Hotness) {
455 Args.push_back(Argument(Msg.str()));
458 DiagnosticInfoOptimizationBase &operator<<(StringRef S);
459 DiagnosticInfoOptimizationBase &operator<<(Argument A);
460 DiagnosticInfoOptimizationBase &operator<<(setIsVerbose V);
461 DiagnosticInfoOptimizationBase &operator<<(setExtraArgs EA);
463 /// \see DiagnosticInfo::print.
464 void print(DiagnosticPrinter &DP) const override;
466 /// Return true if this optimization remark is enabled by one of
467 /// of the LLVM command line flags (-pass-remarks, -pass-remarks-missed,
468 /// or -pass-remarks-analysis). Note that this only handles the LLVM
469 /// flags. We cannot access Clang flags from here (they are handled
470 /// in BackendConsumer::OptimizationRemarkHandler).
471 virtual bool isEnabled() const = 0;
473 StringRef getPassName() const { return PassName; }
474 std::string getMsg() const;
475 Optional<uint64_t> getHotness() const { return Hotness; }
476 void setHotness(Optional<uint64_t> H) { Hotness = H; }
478 Value *getCodeRegion() const { return CodeRegion; }
480 bool isVerbose() const { return IsVerbose; }
482 static bool classof(const DiagnosticInfo *DI) {
483 return DI->getKind() >= DK_FirstRemark &&
484 DI->getKind() <= DK_LastRemark;
488 /// Name of the pass that triggers this report. If this matches the
489 /// regular expression given in -Rpass=regexp, then the remark will
491 const char *PassName;
493 /// Textual identifier for the remark. Can be used by external tools reading
494 /// the YAML output file for optimization remarks to identify the remark.
495 StringRef RemarkName;
497 /// If profile information is available, this is the number of times the
498 /// corresponding code was executed in a profile instrumentation run.
499 Optional<uint64_t> Hotness;
501 /// The IR value (currently basic block) that the optimization operates on.
502 /// This is currently used to provide run-time hotness information with PGO.
505 /// Arguments collected via the streaming interface.
506 SmallVector<Argument, 4> Args;
508 /// The remark is expected to be noisy.
509 bool IsVerbose = false;
511 /// \brief If positive, the index of the first argument that only appear in
512 /// the optimization records and not in the remark printed in the compiler
514 int FirstExtraArgIndex = -1;
516 friend struct yaml::MappingTraits<DiagnosticInfoOptimizationBase *>;
519 /// Diagnostic information for applied optimization remarks.
520 class OptimizationRemark : public DiagnosticInfoOptimizationBase {
522 /// \p PassName is the name of the pass emitting this diagnostic. If
523 /// this name matches the regular expression given in -Rpass=, then the
524 /// diagnostic will be emitted. \p Fn is the function where the diagnostic
525 /// is being emitted. \p DLoc is the location information to use in the
526 /// diagnostic. If line table information is available, the diagnostic
527 /// will include the source code location. \p Msg is the message to show.
528 /// Note that this class does not copy this message, so this reference
529 /// must be valid for the whole life time of the diagnostic.
530 OptimizationRemark(const char *PassName, const Function &Fn,
531 const DebugLoc &DLoc, const Twine &Msg,
532 Optional<uint64_t> Hotness = None)
533 : DiagnosticInfoOptimizationBase(DK_OptimizationRemark, DS_Remark,
534 PassName, Fn, DLoc, Msg, Hotness) {}
536 /// \p PassName is the name of the pass emitting this diagnostic. If this name
537 /// matches the regular expression given in -Rpass=, then the diagnostic will
538 /// be emitted. \p RemarkName is a textual identifier for the remark. \p
539 /// DLoc is the debug location and \p CodeRegion is the region that the
540 /// optimization operates on (currently on block is supported).
541 OptimizationRemark(const char *PassName, StringRef RemarkName,
542 const DebugLoc &DLoc, Value *CodeRegion);
544 /// Same as above but the debug location and code region is derived from \p
546 OptimizationRemark(const char *PassName, StringRef RemarkName,
549 static bool classof(const DiagnosticInfo *DI) {
550 return DI->getKind() == DK_OptimizationRemark;
553 /// \see DiagnosticInfoOptimizationBase::isEnabled.
554 bool isEnabled() const override;
557 /// Diagnostic information for missed-optimization remarks.
558 class OptimizationRemarkMissed : public DiagnosticInfoOptimizationBase {
560 /// \p PassName is the name of the pass emitting this diagnostic. If
561 /// this name matches the regular expression given in -Rpass-missed=, then the
562 /// diagnostic will be emitted. \p Fn is the function where the diagnostic
563 /// is being emitted. \p DLoc is the location information to use in the
564 /// diagnostic. If line table information is available, the diagnostic
565 /// will include the source code location. \p Msg is the message to show.
566 /// Note that this class does not copy this message, so this reference
567 /// must be valid for the whole life time of the diagnostic.
568 OptimizationRemarkMissed(const char *PassName, const Function &Fn,
569 const DebugLoc &DLoc, const Twine &Msg,
570 Optional<uint64_t> Hotness = None)
571 : DiagnosticInfoOptimizationBase(DK_OptimizationRemarkMissed, DS_Remark,
572 PassName, Fn, DLoc, Msg, Hotness) {}
574 /// \p PassName is the name of the pass emitting this diagnostic. If this name
575 /// matches the regular expression given in -Rpass-missed=, then the
576 /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
577 /// remark. \p DLoc is the debug location and \p CodeRegion is the region
578 /// that the optimization operates on (currently on block is supported).
579 OptimizationRemarkMissed(const char *PassName, StringRef RemarkName,
580 const DebugLoc &DLoc, Value *CodeRegion);
582 /// \brief Same as above but \p Inst is used to derive code region and debug
584 OptimizationRemarkMissed(const char *PassName, StringRef RemarkName,
587 static bool classof(const DiagnosticInfo *DI) {
588 return DI->getKind() == DK_OptimizationRemarkMissed;
591 /// \see DiagnosticInfoOptimizationBase::isEnabled.
592 bool isEnabled() const override;
595 /// Diagnostic information for optimization analysis remarks.
596 class OptimizationRemarkAnalysis : public DiagnosticInfoOptimizationBase {
598 /// \p PassName is the name of the pass emitting this diagnostic. If
599 /// this name matches the regular expression given in -Rpass-analysis=, then
600 /// the diagnostic will be emitted. \p Fn is the function where the diagnostic
601 /// is being emitted. \p DLoc is the location information to use in the
602 /// diagnostic. If line table information is available, the diagnostic will
603 /// include the source code location. \p Msg is the message to show. Note that
604 /// this class does not copy this message, so this reference must be valid for
605 /// the whole life time of the diagnostic.
606 OptimizationRemarkAnalysis(const char *PassName, const Function &Fn,
607 const DebugLoc &DLoc, const Twine &Msg,
608 Optional<uint64_t> Hotness = None)
609 : DiagnosticInfoOptimizationBase(DK_OptimizationRemarkAnalysis, DS_Remark,
610 PassName, Fn, DLoc, Msg, Hotness) {}
612 /// \p PassName is the name of the pass emitting this diagnostic. If this name
613 /// matches the regular expression given in -Rpass-analysis=, then the
614 /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
615 /// remark. \p DLoc is the debug location and \p CodeRegion is the region
616 /// that the optimization operates on (currently on block is supported).
617 OptimizationRemarkAnalysis(const char *PassName, StringRef RemarkName,
618 const DebugLoc &DLoc, Value *CodeRegion);
620 /// \brief This is ctor variant allows a pass to build an optimization remark
621 /// from an existing remark.
623 /// This is useful when a transformation pass (e.g LV) wants to emit a remark
624 /// (\p Orig) generated by one of its analyses (e.g. LAA) as its own analysis
625 /// remark. The string \p Prepend will be emitted before the original
627 OptimizationRemarkAnalysis(const char *PassName, StringRef Prepend,
628 const OptimizationRemarkAnalysis &Orig)
629 : DiagnosticInfoOptimizationBase(PassName, Prepend, Orig) {}
631 /// \brief Same as above but \p Inst is used to derive code region and debug
633 OptimizationRemarkAnalysis(const char *PassName, StringRef RemarkName,
636 static bool classof(const DiagnosticInfo *DI) {
637 return DI->getKind() == DK_OptimizationRemarkAnalysis;
640 /// \see DiagnosticInfoOptimizationBase::isEnabled.
641 bool isEnabled() const override;
643 static const char *AlwaysPrint;
645 bool shouldAlwaysPrint() const { return getPassName() == AlwaysPrint; }
648 OptimizationRemarkAnalysis(enum DiagnosticKind Kind, const char *PassName,
649 const Function &Fn, const DebugLoc &DLoc,
650 const Twine &Msg, Optional<uint64_t> Hotness)
651 : DiagnosticInfoOptimizationBase(Kind, DS_Remark, PassName, Fn, DLoc, Msg,
654 OptimizationRemarkAnalysis(enum DiagnosticKind Kind, const char *PassName,
655 StringRef RemarkName, const DebugLoc &DLoc,
659 /// Diagnostic information for optimization analysis remarks related to
660 /// floating-point non-commutativity.
661 class OptimizationRemarkAnalysisFPCommute : public OptimizationRemarkAnalysis {
663 /// \p PassName is the name of the pass emitting this diagnostic. If
664 /// this name matches the regular expression given in -Rpass-analysis=, then
665 /// the diagnostic will be emitted. \p Fn is the function where the diagnostic
666 /// is being emitted. \p DLoc is the location information to use in the
667 /// diagnostic. If line table information is available, the diagnostic will
668 /// include the source code location. \p Msg is the message to show. The
669 /// front-end will append its own message related to options that address
670 /// floating-point non-commutativity. Note that this class does not copy this
671 /// message, so this reference must be valid for the whole life time of the
673 OptimizationRemarkAnalysisFPCommute(const char *PassName, const Function &Fn,
674 const DebugLoc &DLoc, const Twine &Msg,
675 Optional<uint64_t> Hotness = None)
676 : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisFPCommute,
677 PassName, Fn, DLoc, Msg, Hotness) {}
679 /// \p PassName is the name of the pass emitting this diagnostic. If this name
680 /// matches the regular expression given in -Rpass-analysis=, then the
681 /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
682 /// remark. \p DLoc is the debug location and \p CodeRegion is the region
683 /// that the optimization operates on (currently on block is supported). The
684 /// front-end will append its own message related to options that address
685 /// floating-point non-commutativity.
686 OptimizationRemarkAnalysisFPCommute(const char *PassName,
687 StringRef RemarkName,
688 const DebugLoc &DLoc, Value *CodeRegion)
689 : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisFPCommute,
690 PassName, RemarkName, DLoc, CodeRegion) {}
692 static bool classof(const DiagnosticInfo *DI) {
693 return DI->getKind() == DK_OptimizationRemarkAnalysisFPCommute;
697 /// Diagnostic information for optimization analysis remarks related to
698 /// pointer aliasing.
699 class OptimizationRemarkAnalysisAliasing : public OptimizationRemarkAnalysis {
701 /// \p PassName is the name of the pass emitting this diagnostic. If
702 /// this name matches the regular expression given in -Rpass-analysis=, then
703 /// the diagnostic will be emitted. \p Fn is the function where the diagnostic
704 /// is being emitted. \p DLoc is the location information to use in the
705 /// diagnostic. If line table information is available, the diagnostic will
706 /// include the source code location. \p Msg is the message to show. The
707 /// front-end will append its own message related to options that address
708 /// pointer aliasing legality. Note that this class does not copy this
709 /// message, so this reference must be valid for the whole life time of the
711 OptimizationRemarkAnalysisAliasing(const char *PassName, const Function &Fn,
712 const DebugLoc &DLoc, const Twine &Msg,
713 Optional<uint64_t> Hotness = None)
714 : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisAliasing,
715 PassName, Fn, DLoc, Msg, Hotness) {}
717 /// \p PassName is the name of the pass emitting this diagnostic. If this name
718 /// matches the regular expression given in -Rpass-analysis=, then the
719 /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
720 /// remark. \p DLoc is the debug location and \p CodeRegion is the region
721 /// that the optimization operates on (currently on block is supported). The
722 /// front-end will append its own message related to options that address
723 /// pointer aliasing legality.
724 OptimizationRemarkAnalysisAliasing(const char *PassName, StringRef RemarkName,
725 const DebugLoc &DLoc, Value *CodeRegion)
726 : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisAliasing,
727 PassName, RemarkName, DLoc, CodeRegion) {}
729 static bool classof(const DiagnosticInfo *DI) {
730 return DI->getKind() == DK_OptimizationRemarkAnalysisAliasing;
734 /// Diagnostic information for machine IR parser.
735 class DiagnosticInfoMIRParser : public DiagnosticInfo {
736 const SMDiagnostic &Diagnostic;
739 DiagnosticInfoMIRParser(DiagnosticSeverity Severity,
740 const SMDiagnostic &Diagnostic)
741 : DiagnosticInfo(DK_MIRParser, Severity), Diagnostic(Diagnostic) {}
743 const SMDiagnostic &getDiagnostic() const { return Diagnostic; }
745 void print(DiagnosticPrinter &DP) const override;
747 static bool classof(const DiagnosticInfo *DI) {
748 return DI->getKind() == DK_MIRParser;
752 /// Diagnostic information for ISel fallback path.
753 class DiagnosticInfoISelFallback : public DiagnosticInfo {
754 /// The function that is concerned by this diagnostic.
758 DiagnosticInfoISelFallback(const Function &Fn,
759 DiagnosticSeverity Severity = DS_Warning)
760 : DiagnosticInfo(DK_ISelFallback, Severity), Fn(Fn) {}
762 const Function &getFunction() const { return Fn; }
764 void print(DiagnosticPrinter &DP) const override;
766 static bool classof(const DiagnosticInfo *DI) {
767 return DI->getKind() == DK_ISelFallback;
771 // Create wrappers for C Binding types (see CBindingWrapping.h).
772 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DiagnosticInfo, LLVMDiagnosticInfoRef)
774 /// Emit an optimization-applied message. \p PassName is the name of the pass
775 /// emitting the message. If -Rpass= is given and \p PassName matches the
776 /// regular expression in -Rpass, then the remark will be emitted. \p Fn is
777 /// the function triggering the remark, \p DLoc is the debug location where
778 /// the diagnostic is generated. \p Msg is the message string to use.
779 void emitOptimizationRemark(LLVMContext &Ctx, const char *PassName,
780 const Function &Fn, const DebugLoc &DLoc,
783 /// Emit an optimization-missed message. \p PassName is the name of the
784 /// pass emitting the message. If -Rpass-missed= is given and \p PassName
785 /// matches the regular expression in -Rpass, then the remark will be
786 /// emitted. \p Fn is the function triggering the remark, \p DLoc is the
787 /// debug location where the diagnostic is generated. \p Msg is the
788 /// message string to use.
789 void emitOptimizationRemarkMissed(LLVMContext &Ctx, const char *PassName,
790 const Function &Fn, const DebugLoc &DLoc,
793 /// Emit an optimization analysis remark message. \p PassName is the name of
794 /// the pass emitting the message. If -Rpass-analysis= is given and \p
795 /// PassName matches the regular expression in -Rpass, then the remark will be
796 /// emitted. \p Fn is the function triggering the remark, \p DLoc is the debug
797 /// location where the diagnostic is generated. \p Msg is the message string
799 void emitOptimizationRemarkAnalysis(LLVMContext &Ctx, const char *PassName,
800 const Function &Fn, const DebugLoc &DLoc,
803 /// Emit an optimization analysis remark related to messages about
804 /// floating-point non-commutativity. \p PassName is the name of the pass
805 /// emitting the message. If -Rpass-analysis= is given and \p PassName matches
806 /// the regular expression in -Rpass, then the remark will be emitted. \p Fn is
807 /// the function triggering the remark, \p DLoc is the debug location where the
808 /// diagnostic is generated. \p Msg is the message string to use.
809 void emitOptimizationRemarkAnalysisFPCommute(LLVMContext &Ctx,
810 const char *PassName,
812 const DebugLoc &DLoc,
815 /// Emit an optimization analysis remark related to messages about
816 /// pointer aliasing. \p PassName is the name of the pass emitting the message.
817 /// If -Rpass-analysis= is given and \p PassName matches the regular expression
818 /// in -Rpass, then the remark will be emitted. \p Fn is the function triggering
819 /// the remark, \p DLoc is the debug location where the diagnostic is generated.
820 /// \p Msg is the message string to use.
821 void emitOptimizationRemarkAnalysisAliasing(LLVMContext &Ctx,
822 const char *PassName,
824 const DebugLoc &DLoc,
827 /// Diagnostic information for optimization failures.
828 class DiagnosticInfoOptimizationFailure
829 : public DiagnosticInfoOptimizationBase {
831 /// \p Fn is the function where the diagnostic is being emitted. \p DLoc is
832 /// the location information to use in the diagnostic. If line table
833 /// information is available, the diagnostic will include the source code
834 /// location. \p Msg is the message to show. Note that this class does not
835 /// copy this message, so this reference must be valid for the whole life time
836 /// of the diagnostic.
837 DiagnosticInfoOptimizationFailure(const Function &Fn, const DebugLoc &DLoc,
839 : DiagnosticInfoOptimizationBase(DK_OptimizationFailure, DS_Warning,
840 nullptr, Fn, DLoc, Msg) {}
842 static bool classof(const DiagnosticInfo *DI) {
843 return DI->getKind() == DK_OptimizationFailure;
846 /// \see DiagnosticInfoOptimizationBase::isEnabled.
847 bool isEnabled() const override;
850 /// Diagnostic information for unsupported feature in backend.
851 class DiagnosticInfoUnsupported
852 : public DiagnosticInfoWithDebugLocBase {
857 /// \p Fn is the function where the diagnostic is being emitted. \p DLoc is
858 /// the location information to use in the diagnostic. If line table
859 /// information is available, the diagnostic will include the source code
860 /// location. \p Msg is the message to show. Note that this class does not
861 /// copy this message, so this reference must be valid for the whole life time
862 /// of the diagnostic.
863 DiagnosticInfoUnsupported(const Function &Fn, const Twine &Msg,
864 DebugLoc DLoc = DebugLoc(),
865 DiagnosticSeverity Severity = DS_Error)
866 : DiagnosticInfoWithDebugLocBase(DK_Unsupported, Severity, Fn, DLoc),
869 static bool classof(const DiagnosticInfo *DI) {
870 return DI->getKind() == DK_Unsupported;
873 const Twine &getMessage() const { return Msg; }
875 void print(DiagnosticPrinter &DP) const override;
878 /// Emit a warning when loop vectorization is specified but fails. \p Fn is the
879 /// function triggering the warning, \p DLoc is the debug location where the
880 /// diagnostic is generated. \p Msg is the message string to use.
881 void emitLoopVectorizeWarning(LLVMContext &Ctx, const Function &Fn,
882 const DebugLoc &DLoc, const Twine &Msg);
884 /// Emit a warning when loop interleaving is specified but fails. \p Fn is the
885 /// function triggering the warning, \p DLoc is the debug location where the
886 /// diagnostic is generated. \p Msg is the message string to use.
887 void emitLoopInterleaveWarning(LLVMContext &Ctx, const Function &Fn,
888 const DebugLoc &DLoc, const Twine &Msg);
890 } // end namespace llvm
892 #endif // LLVM_IR_DIAGNOSTICINFO_H