1 //===- llvm/IR/DiagnosticInfo.h - Diagnostic Declaration --------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file declares the different classes involved in low level diagnostics.
11 // Diagnostics reporting is still done as part of the LLVMContext.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_IR_DIAGNOSTICINFO_H
15 #define LLVM_IR_DIAGNOSTICINFO_H
17 #include "llvm-c/Types.h"
18 #include "llvm/ADT/Optional.h"
19 #include "llvm/ADT/SmallVector.h"
20 #include "llvm/ADT/StringRef.h"
21 #include "llvm/ADT/Twine.h"
22 #include "llvm/IR/DebugLoc.h"
23 #include "llvm/Support/CBindingWrapping.h"
24 #include "llvm/Support/YAMLTraits.h"
33 // Forward declarations.
34 class DiagnosticPrinter
;
41 /// Defines the different supported severity of a diagnostic.
42 enum DiagnosticSeverity
: char {
46 // A note attaches additional information to one of the previous diagnostic
51 /// Defines the different supported kind of a diagnostic.
52 /// This enum should be extended with a new ID for each added concrete subclass.
58 DK_DebugMetadataVersion
,
59 DK_DebugMetadataInvalid
,
62 DK_OptimizationRemark
,
63 DK_OptimizationRemarkMissed
,
64 DK_OptimizationRemarkAnalysis
,
65 DK_OptimizationRemarkAnalysisFPCommute
,
66 DK_OptimizationRemarkAnalysisAliasing
,
67 DK_OptimizationFailure
,
68 DK_FirstRemark
= DK_OptimizationRemark
,
69 DK_LastRemark
= DK_OptimizationFailure
,
70 DK_MachineOptimizationRemark
,
71 DK_MachineOptimizationRemarkMissed
,
72 DK_MachineOptimizationRemarkAnalysis
,
73 DK_FirstMachineRemark
= DK_MachineOptimizationRemark
,
74 DK_LastMachineRemark
= DK_MachineOptimizationRemarkAnalysis
,
81 /// Get the next available kind ID for a plugin diagnostic.
82 /// Each time this function is called, it returns a different number.
83 /// Therefore, a plugin that wants to "identify" its own classes
84 /// with a dynamic identifier, just have to use this method to get a new ID
85 /// and assign it to each of its classes.
86 /// The returned ID will be greater than or equal to DK_FirstPluginKind.
87 /// Thus, the plugin identifiers will not conflict with the
88 /// DiagnosticKind values.
89 int getNextAvailablePluginDiagnosticKind();
91 /// This is the base abstract class for diagnostic reporting in
93 /// The print method must be overloaded by the subclasses to print a
94 /// user-friendly message in the client of the backend (let us call it a
96 class DiagnosticInfo
{
98 /// Kind defines the kind of report this is about.
99 const /* DiagnosticKind */ int Kind
;
100 /// Severity gives the severity of the diagnostic.
101 const DiagnosticSeverity Severity
;
103 virtual void anchor();
105 DiagnosticInfo(/* DiagnosticKind */ int Kind
, DiagnosticSeverity Severity
)
106 : Kind(Kind
), Severity(Severity
) {}
108 virtual ~DiagnosticInfo() = default;
110 /* DiagnosticKind */ int getKind() const { return Kind
; }
111 DiagnosticSeverity
getSeverity() const { return Severity
; }
113 /// Print using the given \p DP a user-friendly message.
114 /// This is the default message that will be printed to the user.
115 /// It is used when the frontend does not directly take advantage
116 /// of the information contained in fields of the subclasses.
117 /// The printed message must not end with '.' nor start with a severity
119 virtual void print(DiagnosticPrinter
&DP
) const = 0;
122 using DiagnosticHandlerFunction
= std::function
<void(const DiagnosticInfo
&)>;
124 /// Diagnostic information for inline asm reporting.
125 /// This is basically a message and an optional location.
126 class DiagnosticInfoInlineAsm
: public DiagnosticInfo
{
128 /// Optional line information. 0 if not set.
129 unsigned LocCookie
= 0;
130 /// Message to be reported.
132 /// Optional origin of the problem.
133 const Instruction
*Instr
= nullptr;
136 /// \p MsgStr is the message to be reported to the frontend.
137 /// This class does not copy \p MsgStr, therefore the reference must be valid
138 /// for the whole life time of the Diagnostic.
139 DiagnosticInfoInlineAsm(const Twine
&MsgStr
,
140 DiagnosticSeverity Severity
= DS_Error
)
141 : DiagnosticInfo(DK_InlineAsm
, Severity
), MsgStr(MsgStr
) {}
143 /// \p LocCookie if non-zero gives the line number for this report.
144 /// \p MsgStr gives the message.
145 /// This class does not copy \p MsgStr, therefore the reference must be valid
146 /// for the whole life time of the Diagnostic.
147 DiagnosticInfoInlineAsm(unsigned LocCookie
, const Twine
&MsgStr
,
148 DiagnosticSeverity Severity
= DS_Error
)
149 : DiagnosticInfo(DK_InlineAsm
, Severity
), LocCookie(LocCookie
),
152 /// \p Instr gives the original instruction that triggered the diagnostic.
153 /// \p MsgStr gives the message.
154 /// This class does not copy \p MsgStr, therefore the reference must be valid
155 /// for the whole life time of the Diagnostic.
157 DiagnosticInfoInlineAsm(const Instruction
&I
, const Twine
&MsgStr
,
158 DiagnosticSeverity Severity
= DS_Error
);
160 unsigned getLocCookie() const { return LocCookie
; }
161 const Twine
&getMsgStr() const { return MsgStr
; }
162 const Instruction
*getInstruction() const { return Instr
; }
164 /// \see DiagnosticInfo::print.
165 void print(DiagnosticPrinter
&DP
) const override
;
167 static bool classof(const DiagnosticInfo
*DI
) {
168 return DI
->getKind() == DK_InlineAsm
;
172 /// Diagnostic information for stack size etc. reporting.
173 /// This is basically a function and a size.
174 class DiagnosticInfoResourceLimit
: public DiagnosticInfo
{
176 /// The function that is concerned by this resource limit diagnostic.
179 /// Description of the resource type (e.g. stack size)
180 const char *ResourceName
;
182 /// The computed size usage
183 uint64_t ResourceSize
;
186 uint64_t ResourceLimit
;
189 /// \p The function that is concerned by this stack size diagnostic.
190 /// \p The computed stack size.
191 DiagnosticInfoResourceLimit(const Function
&Fn
, const char *ResourceName
,
192 uint64_t ResourceSize
,
193 DiagnosticSeverity Severity
= DS_Warning
,
194 DiagnosticKind Kind
= DK_ResourceLimit
,
195 uint64_t ResourceLimit
= 0)
196 : DiagnosticInfo(Kind
, Severity
), Fn(Fn
), ResourceName(ResourceName
),
197 ResourceSize(ResourceSize
), ResourceLimit(ResourceLimit
) {}
199 const Function
&getFunction() const { return Fn
; }
200 const char *getResourceName() const { return ResourceName
; }
201 uint64_t getResourceSize() const { return ResourceSize
; }
202 uint64_t getResourceLimit() const { return ResourceLimit
; }
204 /// \see DiagnosticInfo::print.
205 void print(DiagnosticPrinter
&DP
) const override
;
207 static bool classof(const DiagnosticInfo
*DI
) {
208 return DI
->getKind() == DK_ResourceLimit
|| DI
->getKind() == DK_StackSize
;
212 class DiagnosticInfoStackSize
: public DiagnosticInfoResourceLimit
{
213 virtual void anchor() override
;
215 DiagnosticInfoStackSize(const Function
&Fn
, uint64_t StackSize
,
216 DiagnosticSeverity Severity
= DS_Warning
,
217 uint64_t StackLimit
= 0)
218 : DiagnosticInfoResourceLimit(Fn
, "stack size", StackSize
, Severity
,
219 DK_StackSize
, StackLimit
) {}
221 uint64_t getStackSize() const { return getResourceSize(); }
222 uint64_t getStackLimit() const { return getResourceLimit(); }
224 static bool classof(const DiagnosticInfo
*DI
) {
225 return DI
->getKind() == DK_StackSize
;
229 /// Diagnostic information for debug metadata version reporting.
230 /// This is basically a module and a version.
231 class DiagnosticInfoDebugMetadataVersion
: public DiagnosticInfo
{
233 /// The module that is concerned by this debug metadata version diagnostic.
235 /// The actual metadata version.
236 unsigned MetadataVersion
;
239 /// \p The module that is concerned by this debug metadata version diagnostic.
240 /// \p The actual metadata version.
241 DiagnosticInfoDebugMetadataVersion(const Module
&M
, unsigned MetadataVersion
,
242 DiagnosticSeverity Severity
= DS_Warning
)
243 : DiagnosticInfo(DK_DebugMetadataVersion
, Severity
), M(M
),
244 MetadataVersion(MetadataVersion
) {}
246 const Module
&getModule() const { return M
; }
247 unsigned getMetadataVersion() const { return MetadataVersion
; }
249 /// \see DiagnosticInfo::print.
250 void print(DiagnosticPrinter
&DP
) const override
;
252 static bool classof(const DiagnosticInfo
*DI
) {
253 return DI
->getKind() == DK_DebugMetadataVersion
;
257 /// Diagnostic information for stripping invalid debug metadata.
258 class DiagnosticInfoIgnoringInvalidDebugMetadata
: public DiagnosticInfo
{
260 /// The module that is concerned by this debug metadata version diagnostic.
264 /// \p The module that is concerned by this debug metadata version diagnostic.
265 DiagnosticInfoIgnoringInvalidDebugMetadata(
266 const Module
&M
, DiagnosticSeverity Severity
= DS_Warning
)
267 : DiagnosticInfo(DK_DebugMetadataVersion
, Severity
), M(M
) {}
269 const Module
&getModule() const { return M
; }
271 /// \see DiagnosticInfo::print.
272 void print(DiagnosticPrinter
&DP
) const override
;
274 static bool classof(const DiagnosticInfo
*DI
) {
275 return DI
->getKind() == DK_DebugMetadataInvalid
;
279 /// Diagnostic information for the sample profiler.
280 class DiagnosticInfoSampleProfile
: public DiagnosticInfo
{
282 DiagnosticInfoSampleProfile(StringRef FileName
, unsigned LineNum
,
284 DiagnosticSeverity Severity
= DS_Error
)
285 : DiagnosticInfo(DK_SampleProfile
, Severity
), FileName(FileName
),
286 LineNum(LineNum
), Msg(Msg
) {}
287 DiagnosticInfoSampleProfile(StringRef FileName
, const Twine
&Msg
,
288 DiagnosticSeverity Severity
= DS_Error
)
289 : DiagnosticInfo(DK_SampleProfile
, Severity
), FileName(FileName
),
291 DiagnosticInfoSampleProfile(const Twine
&Msg
,
292 DiagnosticSeverity Severity
= DS_Error
)
293 : DiagnosticInfo(DK_SampleProfile
, Severity
), Msg(Msg
) {}
295 /// \see DiagnosticInfo::print.
296 void print(DiagnosticPrinter
&DP
) const override
;
298 static bool classof(const DiagnosticInfo
*DI
) {
299 return DI
->getKind() == DK_SampleProfile
;
302 StringRef
getFileName() const { return FileName
; }
303 unsigned getLineNum() const { return LineNum
; }
304 const Twine
&getMsg() const { return Msg
; }
307 /// Name of the input file associated with this diagnostic.
310 /// Line number where the diagnostic occurred. If 0, no line number will
311 /// be emitted in the message.
312 unsigned LineNum
= 0;
314 /// Message to report.
318 /// Diagnostic information for the PGO profiler.
319 class DiagnosticInfoPGOProfile
: public DiagnosticInfo
{
321 DiagnosticInfoPGOProfile(const char *FileName
, const Twine
&Msg
,
322 DiagnosticSeverity Severity
= DS_Error
)
323 : DiagnosticInfo(DK_PGOProfile
, Severity
), FileName(FileName
), Msg(Msg
) {}
325 /// \see DiagnosticInfo::print.
326 void print(DiagnosticPrinter
&DP
) const override
;
328 static bool classof(const DiagnosticInfo
*DI
) {
329 return DI
->getKind() == DK_PGOProfile
;
332 const char *getFileName() const { return FileName
; }
333 const Twine
&getMsg() const { return Msg
; }
336 /// Name of the input file associated with this diagnostic.
337 const char *FileName
;
339 /// Message to report.
343 class DiagnosticLocation
{
344 DIFile
*File
= nullptr;
349 DiagnosticLocation() = default;
350 DiagnosticLocation(const DebugLoc
&DL
);
351 DiagnosticLocation(const DISubprogram
*SP
);
353 bool isValid() const { return File
; }
354 /// Return the full path to the file.
355 std::string
getAbsolutePath() const;
356 /// Return the file name relative to the compilation directory.
357 StringRef
getRelativePath() const;
358 unsigned getLine() const { return Line
; }
359 unsigned getColumn() const { return Column
; }
362 /// Common features for diagnostics with an associated location.
363 class DiagnosticInfoWithLocationBase
: public DiagnosticInfo
{
364 virtual void anchor() override
;
366 /// \p Fn is the function where the diagnostic is being emitted. \p Loc is
367 /// the location information to use in the diagnostic.
368 DiagnosticInfoWithLocationBase(enum DiagnosticKind Kind
,
369 enum DiagnosticSeverity Severity
,
371 const DiagnosticLocation
&Loc
)
372 : DiagnosticInfo(Kind
, Severity
), Fn(Fn
), Loc(Loc
) {}
374 /// Return true if location information is available for this diagnostic.
375 bool isLocationAvailable() const { return Loc
.isValid(); }
377 /// Return a string with the location information for this diagnostic
378 /// in the format "file:line:col". If location information is not available,
379 /// it returns "<unknown>:0:0".
380 const std::string
getLocationStr() const;
382 /// Return location information for this diagnostic in three parts:
383 /// the relative source file path, line number and column.
384 void getLocation(StringRef
&RelativePath
, unsigned &Line
,
385 unsigned &Column
) const;
387 /// Return the absolute path tot the file.
388 std::string
getAbsolutePath() const;
390 const Function
&getFunction() const { return Fn
; }
391 DiagnosticLocation
getLocation() const { return Loc
; }
394 /// Function where this diagnostic is triggered.
397 /// Debug location where this diagnostic is triggered.
398 DiagnosticLocation Loc
;
401 /// Common features for diagnostics dealing with optimization remarks
402 /// that are used by both IR and MIR passes.
403 class DiagnosticInfoOptimizationBase
: public DiagnosticInfoWithLocationBase
{
405 /// Used to set IsVerbose via the stream interface.
406 struct setIsVerbose
{};
408 /// When an instance of this is inserted into the stream, the arguments
409 /// following will not appear in the remark printed in the compiler output
410 /// (-Rpass) but only in the optimization record file
411 /// (-fsave-optimization-record).
412 struct setExtraArgs
{};
414 /// Used in the streaming interface as the general argument type. It
415 /// internally converts everything into a key-value pair.
419 // If set, the debug location corresponding to the value.
420 DiagnosticLocation Loc
;
422 explicit Argument(StringRef Str
= "") : Key("String"), Val(Str
) {}
423 Argument(StringRef Key
, const Value
*V
);
424 Argument(StringRef Key
, const Type
*T
);
425 Argument(StringRef Key
, StringRef S
);
426 Argument(StringRef Key
, const char *S
) : Argument(Key
, StringRef(S
)) {};
427 Argument(StringRef Key
, int N
);
428 Argument(StringRef Key
, float N
);
429 Argument(StringRef Key
, long N
);
430 Argument(StringRef Key
, long long N
);
431 Argument(StringRef Key
, unsigned N
);
432 Argument(StringRef Key
, unsigned long N
);
433 Argument(StringRef Key
, unsigned long long N
);
434 Argument(StringRef Key
, bool B
) : Key(Key
), Val(B
? "true" : "false") {}
435 Argument(StringRef Key
, DebugLoc dl
);
438 /// \p PassName is the name of the pass emitting this diagnostic. \p
439 /// RemarkName is a textual identifier for the remark (single-word,
440 /// camel-case). \p Fn is the function where the diagnostic is being emitted.
441 /// \p Loc is the location information to use in the diagnostic. If line table
442 /// information is available, the diagnostic will include the source code
444 DiagnosticInfoOptimizationBase(enum DiagnosticKind Kind
,
445 enum DiagnosticSeverity Severity
,
446 const char *PassName
, StringRef RemarkName
,
448 const DiagnosticLocation
&Loc
)
449 : DiagnosticInfoWithLocationBase(Kind
, Severity
, Fn
, Loc
),
450 PassName(PassName
), RemarkName(RemarkName
) {}
452 void insert(StringRef S
);
453 void insert(Argument A
);
454 void insert(setIsVerbose V
);
455 void insert(setExtraArgs EA
);
457 /// \see DiagnosticInfo::print.
458 void print(DiagnosticPrinter
&DP
) const override
;
460 /// Return true if this optimization remark is enabled by one of
461 /// of the LLVM command line flags (-pass-remarks, -pass-remarks-missed,
462 /// or -pass-remarks-analysis). Note that this only handles the LLVM
463 /// flags. We cannot access Clang flags from here (they are handled
464 /// in BackendConsumer::OptimizationRemarkHandler).
465 virtual bool isEnabled() const = 0;
467 StringRef
getPassName() const { return PassName
; }
468 std::string
getMsg() const;
469 Optional
<uint64_t> getHotness() const { return Hotness
; }
470 void setHotness(Optional
<uint64_t> H
) { Hotness
= H
; }
472 bool isVerbose() const { return IsVerbose
; }
474 static bool classof(const DiagnosticInfo
*DI
) {
475 return (DI
->getKind() >= DK_FirstRemark
&&
476 DI
->getKind() <= DK_LastRemark
) ||
477 (DI
->getKind() >= DK_FirstMachineRemark
&&
478 DI
->getKind() <= DK_LastMachineRemark
);
481 bool isPassed() const {
482 return (getKind() == DK_OptimizationRemark
||
483 getKind() == DK_MachineOptimizationRemark
);
486 bool isMissed() const {
487 return (getKind() == DK_OptimizationRemarkMissed
||
488 getKind() == DK_MachineOptimizationRemarkMissed
);
491 bool isAnalysis() const {
492 return (getKind() == DK_OptimizationRemarkAnalysis
||
493 getKind() == DK_MachineOptimizationRemarkAnalysis
);
497 /// Name of the pass that triggers this report. If this matches the
498 /// regular expression given in -Rpass=regexp, then the remark will
500 const char *PassName
;
502 /// Textual identifier for the remark (single-word, camel-case). Can be used
503 /// by external tools reading the YAML output file for optimization remarks to
504 /// identify the remark.
505 StringRef RemarkName
;
507 /// If profile information is available, this is the number of times the
508 /// corresponding code was executed in a profile instrumentation run.
509 Optional
<uint64_t> Hotness
;
511 /// Arguments collected via the streaming interface.
512 SmallVector
<Argument
, 4> Args
;
514 /// The remark is expected to be noisy.
515 bool IsVerbose
= false;
517 /// If positive, the index of the first argument that only appear in
518 /// the optimization records and not in the remark printed in the compiler
520 int FirstExtraArgIndex
= -1;
522 friend struct yaml::MappingTraits
<DiagnosticInfoOptimizationBase
*>;
525 /// Allow the insertion operator to return the actual remark type rather than a
526 /// common base class. This allows returning the result of the insertion
527 /// directly by value, e.g. return OptimizationRemarkAnalysis(...) << "blah".
528 template <class RemarkT
>
530 operator<<(RemarkT
&R
,
531 typename
std::enable_if
<
532 std::is_base_of
<DiagnosticInfoOptimizationBase
, RemarkT
>::value
,
533 StringRef
>::type S
) {
538 /// Also allow r-value for the remark to allow insertion into a
539 /// temporarily-constructed remark.
540 template <class RemarkT
>
542 operator<<(RemarkT
&&R
,
543 typename
std::enable_if
<
544 std::is_base_of
<DiagnosticInfoOptimizationBase
, RemarkT
>::value
,
545 StringRef
>::type S
) {
550 template <class RemarkT
>
552 operator<<(RemarkT
&R
,
553 typename
std::enable_if
<
554 std::is_base_of
<DiagnosticInfoOptimizationBase
, RemarkT
>::value
,
555 DiagnosticInfoOptimizationBase::Argument
>::type A
) {
560 template <class RemarkT
>
562 operator<<(RemarkT
&&R
,
563 typename
std::enable_if
<
564 std::is_base_of
<DiagnosticInfoOptimizationBase
, RemarkT
>::value
,
565 DiagnosticInfoOptimizationBase::Argument
>::type A
) {
570 template <class RemarkT
>
572 operator<<(RemarkT
&R
,
573 typename
std::enable_if
<
574 std::is_base_of
<DiagnosticInfoOptimizationBase
, RemarkT
>::value
,
575 DiagnosticInfoOptimizationBase::setIsVerbose
>::type V
) {
580 template <class RemarkT
>
582 operator<<(RemarkT
&&R
,
583 typename
std::enable_if
<
584 std::is_base_of
<DiagnosticInfoOptimizationBase
, RemarkT
>::value
,
585 DiagnosticInfoOptimizationBase::setIsVerbose
>::type V
) {
590 template <class RemarkT
>
592 operator<<(RemarkT
&R
,
593 typename
std::enable_if
<
594 std::is_base_of
<DiagnosticInfoOptimizationBase
, RemarkT
>::value
,
595 DiagnosticInfoOptimizationBase::setExtraArgs
>::type EA
) {
600 /// Common features for diagnostics dealing with optimization remarks
601 /// that are used by IR passes.
602 class DiagnosticInfoIROptimization
: public DiagnosticInfoOptimizationBase
{
603 virtual void anchor() override
;
605 /// \p PassName is the name of the pass emitting this diagnostic. \p
606 /// RemarkName is a textual identifier for the remark (single-word,
607 /// camel-case). \p Fn is the function where the diagnostic is being emitted.
608 /// \p Loc is the location information to use in the diagnostic. If line table
609 /// information is available, the diagnostic will include the source code
610 /// location. \p CodeRegion is IR value (currently basic block) that the
611 /// optimization operates on. This is currently used to provide run-time
612 /// hotness information with PGO.
613 DiagnosticInfoIROptimization(enum DiagnosticKind Kind
,
614 enum DiagnosticSeverity Severity
,
615 const char *PassName
, StringRef RemarkName
,
617 const DiagnosticLocation
&Loc
,
618 const Value
*CodeRegion
= nullptr)
619 : DiagnosticInfoOptimizationBase(Kind
, Severity
, PassName
, RemarkName
, Fn
,
621 CodeRegion(CodeRegion
) {}
623 /// This is ctor variant allows a pass to build an optimization remark
624 /// from an existing remark.
626 /// This is useful when a transformation pass (e.g LV) wants to emit a remark
627 /// (\p Orig) generated by one of its analyses (e.g. LAA) as its own analysis
628 /// remark. The string \p Prepend will be emitted before the original
630 DiagnosticInfoIROptimization(const char *PassName
, StringRef Prepend
,
631 const DiagnosticInfoIROptimization
&Orig
)
632 : DiagnosticInfoOptimizationBase(
633 (DiagnosticKind
)Orig
.getKind(), Orig
.getSeverity(), PassName
,
634 Orig
.RemarkName
, Orig
.getFunction(), Orig
.getLocation()),
635 CodeRegion(Orig
.getCodeRegion()) {
637 std::copy(Orig
.Args
.begin(), Orig
.Args
.end(), std::back_inserter(Args
));
640 /// Legacy interface.
641 /// \p PassName is the name of the pass emitting this diagnostic.
642 /// \p Fn is the function where the diagnostic is being emitted. \p Loc is
643 /// the location information to use in the diagnostic. If line table
644 /// information is available, the diagnostic will include the source code
645 /// location. \p Msg is the message to show. Note that this class does not
646 /// copy this message, so this reference must be valid for the whole life time
647 /// of the diagnostic.
648 DiagnosticInfoIROptimization(enum DiagnosticKind Kind
,
649 enum DiagnosticSeverity Severity
,
650 const char *PassName
, const Function
&Fn
,
651 const DiagnosticLocation
&Loc
, const Twine
&Msg
)
652 : DiagnosticInfoOptimizationBase(Kind
, Severity
, PassName
, "", Fn
, Loc
) {
656 const Value
*getCodeRegion() const { return CodeRegion
; }
658 static bool classof(const DiagnosticInfo
*DI
) {
659 return DI
->getKind() >= DK_FirstRemark
&& DI
->getKind() <= DK_LastRemark
;
663 /// The IR value (currently basic block) that the optimization operates on.
664 /// This is currently used to provide run-time hotness information with PGO.
665 const Value
*CodeRegion
;
668 /// Diagnostic information for applied optimization remarks.
669 class OptimizationRemark
: public DiagnosticInfoIROptimization
{
671 /// \p PassName is the name of the pass emitting this diagnostic. If this name
672 /// matches the regular expression given in -Rpass=, then the diagnostic will
673 /// be emitted. \p RemarkName is a textual identifier for the remark (single-
674 /// word, camel-case). \p Loc is the debug location and \p CodeRegion is the
675 /// region that the optimization operates on (currently only block is
677 OptimizationRemark(const char *PassName
, StringRef RemarkName
,
678 const DiagnosticLocation
&Loc
, const Value
*CodeRegion
);
680 /// Same as above, but the debug location and code region are derived from \p
682 OptimizationRemark(const char *PassName
, StringRef RemarkName
,
683 const Instruction
*Inst
);
685 /// Same as above, but the debug location and code region are derived from \p
687 OptimizationRemark(const char *PassName
, StringRef RemarkName
,
688 const Function
*Func
);
690 static bool classof(const DiagnosticInfo
*DI
) {
691 return DI
->getKind() == DK_OptimizationRemark
;
694 /// \see DiagnosticInfoOptimizationBase::isEnabled.
695 bool isEnabled() const override
;
698 /// This is deprecated now and only used by the function API below.
699 /// \p PassName is the name of the pass emitting this diagnostic. If
700 /// this name matches the regular expression given in -Rpass=, then the
701 /// diagnostic will be emitted. \p Fn is the function where the diagnostic
702 /// is being emitted. \p Loc is the location information to use in the
703 /// diagnostic. If line table information is available, the diagnostic
704 /// will include the source code location. \p Msg is the message to show.
705 /// Note that this class does not copy this message, so this reference
706 /// must be valid for the whole life time of the diagnostic.
707 OptimizationRemark(const char *PassName
, const Function
&Fn
,
708 const DiagnosticLocation
&Loc
, const Twine
&Msg
)
709 : DiagnosticInfoIROptimization(DK_OptimizationRemark
, DS_Remark
, PassName
,
713 /// Diagnostic information for missed-optimization remarks.
714 class OptimizationRemarkMissed
: public DiagnosticInfoIROptimization
{
716 /// \p PassName is the name of the pass emitting this diagnostic. If this name
717 /// matches the regular expression given in -Rpass-missed=, then the
718 /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
719 /// remark (single-word, camel-case). \p Loc is the debug location and \p
720 /// CodeRegion is the region that the optimization operates on (currently only
721 /// block is supported).
722 OptimizationRemarkMissed(const char *PassName
, StringRef RemarkName
,
723 const DiagnosticLocation
&Loc
,
724 const Value
*CodeRegion
);
726 /// Same as above but \p Inst is used to derive code region and debug
728 OptimizationRemarkMissed(const char *PassName
, StringRef RemarkName
,
729 const Instruction
*Inst
);
731 static bool classof(const DiagnosticInfo
*DI
) {
732 return DI
->getKind() == DK_OptimizationRemarkMissed
;
735 /// \see DiagnosticInfoOptimizationBase::isEnabled.
736 bool isEnabled() const override
;
739 /// This is deprecated now and only used by the function API below.
740 /// \p PassName is the name of the pass emitting this diagnostic. If
741 /// this name matches the regular expression given in -Rpass-missed=, then the
742 /// diagnostic will be emitted. \p Fn is the function where the diagnostic
743 /// is being emitted. \p Loc is the location information to use in the
744 /// diagnostic. If line table information is available, the diagnostic
745 /// will include the source code location. \p Msg is the message to show.
746 /// Note that this class does not copy this message, so this reference
747 /// must be valid for the whole life time of the diagnostic.
748 OptimizationRemarkMissed(const char *PassName
, const Function
&Fn
,
749 const DiagnosticLocation
&Loc
, const Twine
&Msg
)
750 : DiagnosticInfoIROptimization(DK_OptimizationRemarkMissed
, DS_Remark
,
751 PassName
, Fn
, Loc
, Msg
) {}
754 /// Diagnostic information for optimization analysis remarks.
755 class OptimizationRemarkAnalysis
: public DiagnosticInfoIROptimization
{
757 /// \p PassName is the name of the pass emitting this diagnostic. If this name
758 /// matches the regular expression given in -Rpass-analysis=, then the
759 /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
760 /// remark (single-word, camel-case). \p Loc is the debug location and \p
761 /// CodeRegion is the region that the optimization operates on (currently only
762 /// block is supported).
763 OptimizationRemarkAnalysis(const char *PassName
, StringRef RemarkName
,
764 const DiagnosticLocation
&Loc
,
765 const Value
*CodeRegion
);
767 /// This is ctor variant allows a pass to build an optimization remark
768 /// from an existing remark.
770 /// This is useful when a transformation pass (e.g LV) wants to emit a remark
771 /// (\p Orig) generated by one of its analyses (e.g. LAA) as its own analysis
772 /// remark. The string \p Prepend will be emitted before the original
774 OptimizationRemarkAnalysis(const char *PassName
, StringRef Prepend
,
775 const OptimizationRemarkAnalysis
&Orig
)
776 : DiagnosticInfoIROptimization(PassName
, Prepend
, Orig
) {}
778 /// Same as above but \p Inst is used to derive code region and debug
780 OptimizationRemarkAnalysis(const char *PassName
, StringRef RemarkName
,
781 const Instruction
*Inst
);
783 static bool classof(const DiagnosticInfo
*DI
) {
784 return DI
->getKind() == DK_OptimizationRemarkAnalysis
;
787 /// \see DiagnosticInfoOptimizationBase::isEnabled.
788 bool isEnabled() const override
;
790 static const char *AlwaysPrint
;
792 bool shouldAlwaysPrint() const { return getPassName() == AlwaysPrint
; }
795 OptimizationRemarkAnalysis(enum DiagnosticKind Kind
, const char *PassName
,
796 const Function
&Fn
, const DiagnosticLocation
&Loc
,
798 : DiagnosticInfoIROptimization(Kind
, DS_Remark
, PassName
, Fn
, Loc
, Msg
) {}
800 OptimizationRemarkAnalysis(enum DiagnosticKind Kind
, const char *PassName
,
801 StringRef RemarkName
,
802 const DiagnosticLocation
&Loc
,
803 const Value
*CodeRegion
);
806 /// This is deprecated now and only used by the function API below.
807 /// \p PassName is the name of the pass emitting this diagnostic. If
808 /// this name matches the regular expression given in -Rpass-analysis=, then
809 /// the diagnostic will be emitted. \p Fn is the function where the diagnostic
810 /// is being emitted. \p Loc is the location information to use in the
811 /// diagnostic. If line table information is available, the diagnostic will
812 /// include the source code location. \p Msg is the message to show. Note that
813 /// this class does not copy this message, so this reference must be valid for
814 /// the whole life time of the diagnostic.
815 OptimizationRemarkAnalysis(const char *PassName
, const Function
&Fn
,
816 const DiagnosticLocation
&Loc
, const Twine
&Msg
)
817 : DiagnosticInfoIROptimization(DK_OptimizationRemarkAnalysis
, DS_Remark
,
818 PassName
, Fn
, Loc
, Msg
) {}
821 /// Diagnostic information for optimization analysis remarks related to
822 /// floating-point non-commutativity.
823 class OptimizationRemarkAnalysisFPCommute
: public OptimizationRemarkAnalysis
{
824 virtual void anchor();
826 /// \p PassName is the name of the pass emitting this diagnostic. If this name
827 /// matches the regular expression given in -Rpass-analysis=, then the
828 /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
829 /// remark (single-word, camel-case). \p Loc is the debug location and \p
830 /// CodeRegion is the region that the optimization operates on (currently only
831 /// block is supported). The front-end will append its own message related to
832 /// options that address floating-point non-commutativity.
833 OptimizationRemarkAnalysisFPCommute(const char *PassName
,
834 StringRef RemarkName
,
835 const DiagnosticLocation
&Loc
,
836 const Value
*CodeRegion
)
837 : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisFPCommute
,
838 PassName
, RemarkName
, Loc
, CodeRegion
) {}
840 static bool classof(const DiagnosticInfo
*DI
) {
841 return DI
->getKind() == DK_OptimizationRemarkAnalysisFPCommute
;
845 /// This is deprecated now and only used by the function API below.
846 /// \p PassName is the name of the pass emitting this diagnostic. If
847 /// this name matches the regular expression given in -Rpass-analysis=, then
848 /// the diagnostic will be emitted. \p Fn is the function where the diagnostic
849 /// is being emitted. \p Loc is the location information to use in the
850 /// diagnostic. If line table information is available, the diagnostic will
851 /// include the source code location. \p Msg is the message to show. The
852 /// front-end will append its own message related to options that address
853 /// floating-point non-commutativity. Note that this class does not copy this
854 /// message, so this reference must be valid for the whole life time of the
856 OptimizationRemarkAnalysisFPCommute(const char *PassName
, const Function
&Fn
,
857 const DiagnosticLocation
&Loc
,
859 : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisFPCommute
,
860 PassName
, Fn
, Loc
, Msg
) {}
863 /// Diagnostic information for optimization analysis remarks related to
864 /// pointer aliasing.
865 class OptimizationRemarkAnalysisAliasing
: public OptimizationRemarkAnalysis
{
866 virtual void anchor();
868 /// \p PassName is the name of the pass emitting this diagnostic. If this name
869 /// matches the regular expression given in -Rpass-analysis=, then the
870 /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
871 /// remark (single-word, camel-case). \p Loc is the debug location and \p
872 /// CodeRegion is the region that the optimization operates on (currently only
873 /// block is supported). The front-end will append its own message related to
874 /// options that address pointer aliasing legality.
875 OptimizationRemarkAnalysisAliasing(const char *PassName
, StringRef RemarkName
,
876 const DiagnosticLocation
&Loc
,
877 const Value
*CodeRegion
)
878 : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisAliasing
,
879 PassName
, RemarkName
, Loc
, CodeRegion
) {}
881 static bool classof(const DiagnosticInfo
*DI
) {
882 return DI
->getKind() == DK_OptimizationRemarkAnalysisAliasing
;
886 /// This is deprecated now and only used by the function API below.
887 /// \p PassName is the name of the pass emitting this diagnostic. If
888 /// this name matches the regular expression given in -Rpass-analysis=, then
889 /// the diagnostic will be emitted. \p Fn is the function where the diagnostic
890 /// is being emitted. \p Loc is the location information to use in the
891 /// diagnostic. If line table information is available, the diagnostic will
892 /// include the source code location. \p Msg is the message to show. The
893 /// front-end will append its own message related to options that address
894 /// pointer aliasing legality. Note that this class does not copy this
895 /// message, so this reference must be valid for the whole life time of the
897 OptimizationRemarkAnalysisAliasing(const char *PassName
, const Function
&Fn
,
898 const DiagnosticLocation
&Loc
,
900 : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisAliasing
,
901 PassName
, Fn
, Loc
, Msg
) {}
904 /// Diagnostic information for machine IR parser.
905 class DiagnosticInfoMIRParser
: public DiagnosticInfo
{
906 const SMDiagnostic
&Diagnostic
;
909 DiagnosticInfoMIRParser(DiagnosticSeverity Severity
,
910 const SMDiagnostic
&Diagnostic
)
911 : DiagnosticInfo(DK_MIRParser
, Severity
), Diagnostic(Diagnostic
) {}
913 const SMDiagnostic
&getDiagnostic() const { return Diagnostic
; }
915 void print(DiagnosticPrinter
&DP
) const override
;
917 static bool classof(const DiagnosticInfo
*DI
) {
918 return DI
->getKind() == DK_MIRParser
;
922 /// Diagnostic information for ISel fallback path.
923 class DiagnosticInfoISelFallback
: public DiagnosticInfo
{
924 /// The function that is concerned by this diagnostic.
928 DiagnosticInfoISelFallback(const Function
&Fn
,
929 DiagnosticSeverity Severity
= DS_Warning
)
930 : DiagnosticInfo(DK_ISelFallback
, Severity
), Fn(Fn
) {}
932 const Function
&getFunction() const { return Fn
; }
934 void print(DiagnosticPrinter
&DP
) const override
;
936 static bool classof(const DiagnosticInfo
*DI
) {
937 return DI
->getKind() == DK_ISelFallback
;
941 // Create wrappers for C Binding types (see CBindingWrapping.h).
942 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DiagnosticInfo
, LLVMDiagnosticInfoRef
)
944 /// Diagnostic information for optimization failures.
945 class DiagnosticInfoOptimizationFailure
: public DiagnosticInfoIROptimization
{
947 /// \p Fn is the function where the diagnostic is being emitted. \p Loc is
948 /// the location information to use in the diagnostic. If line table
949 /// information is available, the diagnostic will include the source code
950 /// location. \p Msg is the message to show. Note that this class does not
951 /// copy this message, so this reference must be valid for the whole life time
952 /// of the diagnostic.
953 DiagnosticInfoOptimizationFailure(const Function
&Fn
,
954 const DiagnosticLocation
&Loc
,
956 : DiagnosticInfoIROptimization(DK_OptimizationFailure
, DS_Warning
,
957 nullptr, Fn
, Loc
, Msg
) {}
959 /// \p PassName is the name of the pass emitting this diagnostic. \p
960 /// RemarkName is a textual identifier for the remark (single-word,
961 /// camel-case). \p Loc is the debug location and \p CodeRegion is the
962 /// region that the optimization operates on (currently basic block is
964 DiagnosticInfoOptimizationFailure(const char *PassName
, StringRef RemarkName
,
965 const DiagnosticLocation
&Loc
,
966 const Value
*CodeRegion
);
968 static bool classof(const DiagnosticInfo
*DI
) {
969 return DI
->getKind() == DK_OptimizationFailure
;
972 /// \see DiagnosticInfoOptimizationBase::isEnabled.
973 bool isEnabled() const override
;
976 /// Diagnostic information for unsupported feature in backend.
977 class DiagnosticInfoUnsupported
: public DiagnosticInfoWithLocationBase
{
982 /// \p Fn is the function where the diagnostic is being emitted. \p Loc is
983 /// the location information to use in the diagnostic. If line table
984 /// information is available, the diagnostic will include the source code
985 /// location. \p Msg is the message to show. Note that this class does not
986 /// copy this message, so this reference must be valid for the whole life time
987 /// of the diagnostic.
988 DiagnosticInfoUnsupported(
989 const Function
&Fn
, const Twine
&Msg
,
990 const DiagnosticLocation
&Loc
= DiagnosticLocation(),
991 DiagnosticSeverity Severity
= DS_Error
)
992 : DiagnosticInfoWithLocationBase(DK_Unsupported
, Severity
, Fn
, Loc
),
995 static bool classof(const DiagnosticInfo
*DI
) {
996 return DI
->getKind() == DK_Unsupported
;
999 const Twine
&getMessage() const { return Msg
; }
1001 void print(DiagnosticPrinter
&DP
) const override
;
1005 template <> struct MappingTraits
<DiagnosticInfoOptimizationBase
*> {
1006 static void mapping(IO
&io
, DiagnosticInfoOptimizationBase
*&OptDiag
);
1010 } // end namespace llvm
1012 #endif // LLVM_IR_DIAGNOSTICINFO_H