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
,
79 DK_FirstPluginKind
// Must be last value to work with
80 // getNextAvailablePluginDiagnosticKind
83 /// 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 /// 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
;
105 virtual void anchor();
107 DiagnosticInfo(/* DiagnosticKind */ int Kind
, DiagnosticSeverity Severity
)
108 : Kind(Kind
), Severity(Severity
) {}
110 virtual ~DiagnosticInfo() = default;
112 /* DiagnosticKind */ int getKind() const { return Kind
; }
113 DiagnosticSeverity
getSeverity() const { return Severity
; }
115 /// Print using the given \p DP a user-friendly message.
116 /// This is the default message that will be printed to the user.
117 /// It is used when the frontend does not directly take advantage
118 /// of the information contained in fields of the subclasses.
119 /// The printed message must not end with '.' nor start with a severity
121 virtual void print(DiagnosticPrinter
&DP
) const = 0;
124 using DiagnosticHandlerFunction
= std::function
<void(const DiagnosticInfo
&)>;
126 /// Diagnostic information for inline asm reporting.
127 /// This is basically a message and an optional location.
128 class DiagnosticInfoInlineAsm
: public DiagnosticInfo
{
130 /// Optional line information. 0 if not set.
131 unsigned LocCookie
= 0;
132 /// Message to be reported.
134 /// Optional origin of the problem.
135 const Instruction
*Instr
= nullptr;
138 /// \p MsgStr is the message to be reported to the frontend.
139 /// This class does not copy \p MsgStr, therefore the reference must be valid
140 /// for the whole life time of the Diagnostic.
141 DiagnosticInfoInlineAsm(const Twine
&MsgStr
,
142 DiagnosticSeverity Severity
= DS_Error
)
143 : DiagnosticInfo(DK_InlineAsm
, Severity
), 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
),
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
, const char *ResourceName
,
194 uint64_t ResourceSize
,
195 DiagnosticSeverity Severity
= DS_Warning
,
196 DiagnosticKind Kind
= DK_ResourceLimit
,
197 uint64_t ResourceLimit
= 0)
198 : DiagnosticInfo(Kind
, Severity
), Fn(Fn
), ResourceName(ResourceName
),
199 ResourceSize(ResourceSize
), ResourceLimit(ResourceLimit
) {}
201 const Function
&getFunction() const { return Fn
; }
202 const char *getResourceName() const { return ResourceName
; }
203 uint64_t getResourceSize() const { return ResourceSize
; }
204 uint64_t getResourceLimit() const { return ResourceLimit
; }
206 /// \see DiagnosticInfo::print.
207 void print(DiagnosticPrinter
&DP
) const override
;
209 static bool classof(const DiagnosticInfo
*DI
) {
210 return DI
->getKind() == DK_ResourceLimit
|| DI
->getKind() == DK_StackSize
;
214 class DiagnosticInfoStackSize
: public DiagnosticInfoResourceLimit
{
215 virtual void anchor() override
;
217 DiagnosticInfoStackSize(const Function
&Fn
, uint64_t StackSize
,
218 DiagnosticSeverity Severity
= DS_Warning
,
219 uint64_t StackLimit
= 0)
220 : DiagnosticInfoResourceLimit(Fn
, "stack size", StackSize
, Severity
,
221 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
),
293 DiagnosticInfoSampleProfile(const Twine
&Msg
,
294 DiagnosticSeverity Severity
= DS_Error
)
295 : DiagnosticInfo(DK_SampleProfile
, Severity
), 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.
314 unsigned LineNum
= 0;
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 class DiagnosticLocation
{
346 DIFile
*File
= nullptr;
351 DiagnosticLocation() = default;
352 DiagnosticLocation(const DebugLoc
&DL
);
353 DiagnosticLocation(const DISubprogram
*SP
);
355 bool isValid() const { return File
; }
356 /// Return the full path to the file.
357 std::string
getAbsolutePath() const;
358 /// Return the file name relative to the compilation directory.
359 StringRef
getRelativePath() const;
360 unsigned getLine() const { return Line
; }
361 unsigned getColumn() const { return Column
; }
364 /// Common features for diagnostics with an associated location.
365 class DiagnosticInfoWithLocationBase
: public DiagnosticInfo
{
366 virtual void anchor() override
;
368 /// \p Fn is the function where the diagnostic is being emitted. \p Loc is
369 /// the location information to use in the diagnostic.
370 DiagnosticInfoWithLocationBase(enum DiagnosticKind Kind
,
371 enum DiagnosticSeverity Severity
,
373 const DiagnosticLocation
&Loc
)
374 : DiagnosticInfo(Kind
, Severity
), Fn(Fn
), Loc(Loc
) {}
376 /// Return true if location information is available for this diagnostic.
377 bool isLocationAvailable() const { return Loc
.isValid(); }
379 /// Return a string with the location information for this diagnostic
380 /// in the format "file:line:col". If location information is not available,
381 /// it returns "<unknown>:0:0".
382 const std::string
getLocationStr() const;
384 /// Return location information for this diagnostic in three parts:
385 /// the relative source file path, line number and column.
386 void getLocation(StringRef
&RelativePath
, unsigned &Line
,
387 unsigned &Column
) const;
389 /// Return the absolute path tot the file.
390 std::string
getAbsolutePath() const;
392 const Function
&getFunction() const { return Fn
; }
393 DiagnosticLocation
getLocation() const { return Loc
; }
396 /// Function where this diagnostic is triggered.
399 /// Debug location where this diagnostic is triggered.
400 DiagnosticLocation Loc
;
403 /// Common features for diagnostics dealing with optimization remarks
404 /// that are used by both IR and MIR passes.
405 class DiagnosticInfoOptimizationBase
: public DiagnosticInfoWithLocationBase
{
407 /// Used to set IsVerbose via the stream interface.
408 struct setIsVerbose
{};
410 /// When an instance of this is inserted into the stream, the arguments
411 /// following will not appear in the remark printed in the compiler output
412 /// (-Rpass) but only in the optimization record file
413 /// (-fsave-optimization-record).
414 struct setExtraArgs
{};
416 /// Used in the streaming interface as the general argument type. It
417 /// internally converts everything into a key-value pair.
421 // If set, the debug location corresponding to the value.
422 DiagnosticLocation Loc
;
424 explicit Argument(StringRef Str
= "") : Key("String"), Val(Str
) {}
425 Argument(StringRef Key
, const Value
*V
);
426 Argument(StringRef Key
, const Type
*T
);
427 Argument(StringRef Key
, StringRef S
);
428 Argument(StringRef Key
, const char *S
) : Argument(Key
, StringRef(S
)) {};
429 Argument(StringRef Key
, int N
);
430 Argument(StringRef Key
, float N
);
431 Argument(StringRef Key
, long N
);
432 Argument(StringRef Key
, long long N
);
433 Argument(StringRef Key
, unsigned N
);
434 Argument(StringRef Key
, unsigned long N
);
435 Argument(StringRef Key
, unsigned long long N
);
436 Argument(StringRef Key
, bool B
) : Key(Key
), Val(B
? "true" : "false") {}
437 Argument(StringRef Key
, DebugLoc dl
);
440 /// \p PassName is the name of the pass emitting this diagnostic. \p
441 /// RemarkName is a textual identifier for the remark (single-word,
442 /// camel-case). \p Fn is the function where the diagnostic is being emitted.
443 /// \p Loc is the location information to use in the diagnostic. If line table
444 /// information is available, the diagnostic will include the source code
446 DiagnosticInfoOptimizationBase(enum DiagnosticKind Kind
,
447 enum DiagnosticSeverity Severity
,
448 const char *PassName
, StringRef RemarkName
,
450 const DiagnosticLocation
&Loc
)
451 : DiagnosticInfoWithLocationBase(Kind
, Severity
, Fn
, Loc
),
452 PassName(PassName
), RemarkName(RemarkName
) {}
454 void insert(StringRef S
);
455 void insert(Argument A
);
456 void insert(setIsVerbose V
);
457 void insert(setExtraArgs EA
);
459 /// \see DiagnosticInfo::print.
460 void print(DiagnosticPrinter
&DP
) const override
;
462 /// Return true if this optimization remark is enabled by one of
463 /// of the LLVM command line flags (-pass-remarks, -pass-remarks-missed,
464 /// or -pass-remarks-analysis). Note that this only handles the LLVM
465 /// flags. We cannot access Clang flags from here (they are handled
466 /// in BackendConsumer::OptimizationRemarkHandler).
467 virtual bool isEnabled() const = 0;
469 StringRef
getPassName() const { return PassName
; }
470 StringRef
getRemarkName() const { return RemarkName
; }
471 std::string
getMsg() const;
472 Optional
<uint64_t> getHotness() const { return Hotness
; }
473 void setHotness(Optional
<uint64_t> H
) { Hotness
= H
; }
475 bool isVerbose() const { return IsVerbose
; }
477 ArrayRef
<Argument
> getArgs() const { return Args
; }
479 static bool classof(const DiagnosticInfo
*DI
) {
480 return (DI
->getKind() >= DK_FirstRemark
&&
481 DI
->getKind() <= DK_LastRemark
) ||
482 (DI
->getKind() >= DK_FirstMachineRemark
&&
483 DI
->getKind() <= DK_LastMachineRemark
);
486 bool isPassed() const {
487 return (getKind() == DK_OptimizationRemark
||
488 getKind() == DK_MachineOptimizationRemark
);
491 bool isMissed() const {
492 return (getKind() == DK_OptimizationRemarkMissed
||
493 getKind() == DK_MachineOptimizationRemarkMissed
);
496 bool isAnalysis() const {
497 return (getKind() == DK_OptimizationRemarkAnalysis
||
498 getKind() == DK_MachineOptimizationRemarkAnalysis
);
502 /// Name of the pass that triggers this report. If this matches the
503 /// regular expression given in -Rpass=regexp, then the remark will
505 const char *PassName
;
507 /// Textual identifier for the remark (single-word, camel-case). Can be used
508 /// by external tools reading the output file for optimization remarks to
509 /// identify the remark.
510 StringRef RemarkName
;
512 /// If profile information is available, this is the number of times the
513 /// corresponding code was executed in a profile instrumentation run.
514 Optional
<uint64_t> Hotness
;
516 /// Arguments collected via the streaming interface.
517 SmallVector
<Argument
, 4> Args
;
519 /// The remark is expected to be noisy.
520 bool IsVerbose
= false;
522 /// If positive, the index of the first argument that only appear in
523 /// the optimization records and not in the remark printed in the compiler
525 int FirstExtraArgIndex
= -1;
528 /// Allow the insertion operator to return the actual remark type rather than a
529 /// common base class. This allows returning the result of the insertion
530 /// directly by value, e.g. return OptimizationRemarkAnalysis(...) << "blah".
531 template <class RemarkT
>
533 operator<<(RemarkT
&R
,
534 typename
std::enable_if
<
535 std::is_base_of
<DiagnosticInfoOptimizationBase
, RemarkT
>::value
,
536 StringRef
>::type S
) {
541 /// Also allow r-value for the remark to allow insertion into a
542 /// temporarily-constructed remark.
543 template <class RemarkT
>
545 operator<<(RemarkT
&&R
,
546 typename
std::enable_if
<
547 std::is_base_of
<DiagnosticInfoOptimizationBase
, RemarkT
>::value
,
548 StringRef
>::type S
) {
553 template <class RemarkT
>
555 operator<<(RemarkT
&R
,
556 typename
std::enable_if
<
557 std::is_base_of
<DiagnosticInfoOptimizationBase
, RemarkT
>::value
,
558 DiagnosticInfoOptimizationBase::Argument
>::type A
) {
563 template <class RemarkT
>
565 operator<<(RemarkT
&&R
,
566 typename
std::enable_if
<
567 std::is_base_of
<DiagnosticInfoOptimizationBase
, RemarkT
>::value
,
568 DiagnosticInfoOptimizationBase::Argument
>::type A
) {
573 template <class RemarkT
>
575 operator<<(RemarkT
&R
,
576 typename
std::enable_if
<
577 std::is_base_of
<DiagnosticInfoOptimizationBase
, RemarkT
>::value
,
578 DiagnosticInfoOptimizationBase::setIsVerbose
>::type V
) {
583 template <class RemarkT
>
585 operator<<(RemarkT
&&R
,
586 typename
std::enable_if
<
587 std::is_base_of
<DiagnosticInfoOptimizationBase
, RemarkT
>::value
,
588 DiagnosticInfoOptimizationBase::setIsVerbose
>::type V
) {
593 template <class RemarkT
>
595 operator<<(RemarkT
&R
,
596 typename
std::enable_if
<
597 std::is_base_of
<DiagnosticInfoOptimizationBase
, RemarkT
>::value
,
598 DiagnosticInfoOptimizationBase::setExtraArgs
>::type EA
) {
603 /// Common features for diagnostics dealing with optimization remarks
604 /// that are used by IR passes.
605 class DiagnosticInfoIROptimization
: public DiagnosticInfoOptimizationBase
{
606 virtual void anchor() override
;
608 /// \p PassName is the name of the pass emitting this diagnostic. \p
609 /// RemarkName is a textual identifier for the remark (single-word,
610 /// camel-case). \p Fn is the function where the diagnostic is being emitted.
611 /// \p Loc is the location information to use in the diagnostic. If line table
612 /// information is available, the diagnostic will include the source code
613 /// location. \p CodeRegion is IR value (currently basic block) that the
614 /// optimization operates on. This is currently used to provide run-time
615 /// hotness information with PGO.
616 DiagnosticInfoIROptimization(enum DiagnosticKind Kind
,
617 enum DiagnosticSeverity Severity
,
618 const char *PassName
, StringRef RemarkName
,
620 const DiagnosticLocation
&Loc
,
621 const Value
*CodeRegion
= nullptr)
622 : DiagnosticInfoOptimizationBase(Kind
, Severity
, PassName
, RemarkName
, Fn
,
624 CodeRegion(CodeRegion
) {}
626 /// This is ctor variant allows a pass to build an optimization remark
627 /// from an existing remark.
629 /// This is useful when a transformation pass (e.g LV) wants to emit a remark
630 /// (\p Orig) generated by one of its analyses (e.g. LAA) as its own analysis
631 /// remark. The string \p Prepend will be emitted before the original
633 DiagnosticInfoIROptimization(const char *PassName
, StringRef Prepend
,
634 const DiagnosticInfoIROptimization
&Orig
)
635 : DiagnosticInfoOptimizationBase(
636 (DiagnosticKind
)Orig
.getKind(), Orig
.getSeverity(), PassName
,
637 Orig
.RemarkName
, Orig
.getFunction(), Orig
.getLocation()),
638 CodeRegion(Orig
.getCodeRegion()) {
640 std::copy(Orig
.Args
.begin(), Orig
.Args
.end(), std::back_inserter(Args
));
643 /// Legacy interface.
644 /// \p PassName is the name of the pass emitting this diagnostic.
645 /// \p Fn is the function where the diagnostic is being emitted. \p Loc is
646 /// the location information to use in the diagnostic. If line table
647 /// information is available, the diagnostic will include the source code
648 /// location. \p Msg is the message to show. Note that this class does not
649 /// copy this message, so this reference must be valid for the whole life time
650 /// of the diagnostic.
651 DiagnosticInfoIROptimization(enum DiagnosticKind Kind
,
652 enum DiagnosticSeverity Severity
,
653 const char *PassName
, const Function
&Fn
,
654 const DiagnosticLocation
&Loc
, const Twine
&Msg
)
655 : DiagnosticInfoOptimizationBase(Kind
, Severity
, PassName
, "", Fn
, Loc
) {
659 const Value
*getCodeRegion() const { return CodeRegion
; }
661 static bool classof(const DiagnosticInfo
*DI
) {
662 return DI
->getKind() >= DK_FirstRemark
&& DI
->getKind() <= DK_LastRemark
;
666 /// The IR value (currently basic block) that the optimization operates on.
667 /// This is currently used to provide run-time hotness information with PGO.
668 const Value
*CodeRegion
= nullptr;
671 /// Diagnostic information for applied optimization remarks.
672 class OptimizationRemark
: public DiagnosticInfoIROptimization
{
674 /// \p PassName is the name of the pass emitting this diagnostic. If this name
675 /// matches the regular expression given in -Rpass=, then the diagnostic will
676 /// be emitted. \p RemarkName is a textual identifier for the remark (single-
677 /// word, camel-case). \p Loc is the debug location and \p CodeRegion is the
678 /// region that the optimization operates on (currently only block is
680 OptimizationRemark(const char *PassName
, StringRef RemarkName
,
681 const DiagnosticLocation
&Loc
, const Value
*CodeRegion
);
683 /// Same as above, but the debug location and code region are derived from \p
685 OptimizationRemark(const char *PassName
, StringRef RemarkName
,
686 const Instruction
*Inst
);
688 /// Same as above, but the debug location and code region are derived from \p
690 OptimizationRemark(const char *PassName
, StringRef RemarkName
,
691 const Function
*Func
);
693 static bool classof(const DiagnosticInfo
*DI
) {
694 return DI
->getKind() == DK_OptimizationRemark
;
697 /// \see DiagnosticInfoOptimizationBase::isEnabled.
698 bool isEnabled() const override
;
701 /// This is deprecated now and only used by the function API below.
702 /// \p PassName is the name of the pass emitting this diagnostic. If
703 /// this name matches the regular expression given in -Rpass=, then the
704 /// diagnostic will be emitted. \p Fn is the function where the diagnostic
705 /// is being emitted. \p Loc is the location information to use in the
706 /// diagnostic. If line table information is available, the diagnostic
707 /// will include the source code location. \p Msg is the message to show.
708 /// Note that this class does not copy this message, so this reference
709 /// must be valid for the whole life time of the diagnostic.
710 OptimizationRemark(const char *PassName
, const Function
&Fn
,
711 const DiagnosticLocation
&Loc
, const Twine
&Msg
)
712 : DiagnosticInfoIROptimization(DK_OptimizationRemark
, DS_Remark
, PassName
,
716 /// Diagnostic information for missed-optimization remarks.
717 class OptimizationRemarkMissed
: public DiagnosticInfoIROptimization
{
719 /// \p PassName is the name of the pass emitting this diagnostic. If this name
720 /// matches the regular expression given in -Rpass-missed=, then the
721 /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
722 /// remark (single-word, camel-case). \p Loc is the debug location and \p
723 /// CodeRegion is the region that the optimization operates on (currently only
724 /// block is supported).
725 OptimizationRemarkMissed(const char *PassName
, StringRef RemarkName
,
726 const DiagnosticLocation
&Loc
,
727 const Value
*CodeRegion
);
729 /// Same as above but \p Inst is used to derive code region and debug
731 OptimizationRemarkMissed(const char *PassName
, StringRef RemarkName
,
732 const Instruction
*Inst
);
734 static bool classof(const DiagnosticInfo
*DI
) {
735 return DI
->getKind() == DK_OptimizationRemarkMissed
;
738 /// \see DiagnosticInfoOptimizationBase::isEnabled.
739 bool isEnabled() const override
;
742 /// This is deprecated now and only used by the function API below.
743 /// \p PassName is the name of the pass emitting this diagnostic. If
744 /// this name matches the regular expression given in -Rpass-missed=, then the
745 /// diagnostic will be emitted. \p Fn is the function where the diagnostic
746 /// is being emitted. \p Loc is the location information to use in the
747 /// diagnostic. If line table information is available, the diagnostic
748 /// will include the source code location. \p Msg is the message to show.
749 /// Note that this class does not copy this message, so this reference
750 /// must be valid for the whole life time of the diagnostic.
751 OptimizationRemarkMissed(const char *PassName
, const Function
&Fn
,
752 const DiagnosticLocation
&Loc
, const Twine
&Msg
)
753 : DiagnosticInfoIROptimization(DK_OptimizationRemarkMissed
, DS_Remark
,
754 PassName
, Fn
, Loc
, Msg
) {}
757 /// Diagnostic information for optimization analysis remarks.
758 class OptimizationRemarkAnalysis
: public DiagnosticInfoIROptimization
{
760 /// \p PassName is the name of the pass emitting this diagnostic. If this name
761 /// matches the regular expression given in -Rpass-analysis=, then the
762 /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
763 /// remark (single-word, camel-case). \p Loc is the debug location and \p
764 /// CodeRegion is the region that the optimization operates on (currently only
765 /// block is supported).
766 OptimizationRemarkAnalysis(const char *PassName
, StringRef RemarkName
,
767 const DiagnosticLocation
&Loc
,
768 const Value
*CodeRegion
);
770 /// This is ctor variant allows a pass to build an optimization remark
771 /// from an existing remark.
773 /// This is useful when a transformation pass (e.g LV) wants to emit a remark
774 /// (\p Orig) generated by one of its analyses (e.g. LAA) as its own analysis
775 /// remark. The string \p Prepend will be emitted before the original
777 OptimizationRemarkAnalysis(const char *PassName
, StringRef Prepend
,
778 const OptimizationRemarkAnalysis
&Orig
)
779 : DiagnosticInfoIROptimization(PassName
, Prepend
, Orig
) {}
781 /// Same as above but \p Inst is used to derive code region and debug
783 OptimizationRemarkAnalysis(const char *PassName
, StringRef RemarkName
,
784 const Instruction
*Inst
);
786 static bool classof(const DiagnosticInfo
*DI
) {
787 return DI
->getKind() == DK_OptimizationRemarkAnalysis
;
790 /// \see DiagnosticInfoOptimizationBase::isEnabled.
791 bool isEnabled() const override
;
793 static const char *AlwaysPrint
;
795 bool shouldAlwaysPrint() const { return getPassName() == AlwaysPrint
; }
798 OptimizationRemarkAnalysis(enum DiagnosticKind Kind
, const char *PassName
,
799 const Function
&Fn
, const DiagnosticLocation
&Loc
,
801 : DiagnosticInfoIROptimization(Kind
, DS_Remark
, PassName
, Fn
, Loc
, Msg
) {}
803 OptimizationRemarkAnalysis(enum DiagnosticKind Kind
, const char *PassName
,
804 StringRef RemarkName
,
805 const DiagnosticLocation
&Loc
,
806 const Value
*CodeRegion
);
809 /// This is deprecated now and only used by the function API below.
810 /// \p PassName is the name of the pass emitting this diagnostic. If
811 /// this name matches the regular expression given in -Rpass-analysis=, then
812 /// the diagnostic will be emitted. \p Fn is the function where the diagnostic
813 /// is being emitted. \p Loc is the location information to use in the
814 /// diagnostic. If line table information is available, the diagnostic will
815 /// include the source code location. \p Msg is the message to show. Note that
816 /// this class does not copy this message, so this reference must be valid for
817 /// the whole life time of the diagnostic.
818 OptimizationRemarkAnalysis(const char *PassName
, const Function
&Fn
,
819 const DiagnosticLocation
&Loc
, const Twine
&Msg
)
820 : DiagnosticInfoIROptimization(DK_OptimizationRemarkAnalysis
, DS_Remark
,
821 PassName
, Fn
, Loc
, Msg
) {}
824 /// Diagnostic information for optimization analysis remarks related to
825 /// floating-point non-commutativity.
826 class OptimizationRemarkAnalysisFPCommute
: public OptimizationRemarkAnalysis
{
827 virtual void anchor();
829 /// \p PassName is the name of the pass emitting this diagnostic. If this name
830 /// matches the regular expression given in -Rpass-analysis=, then the
831 /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
832 /// remark (single-word, camel-case). \p Loc is the debug location and \p
833 /// CodeRegion is the region that the optimization operates on (currently only
834 /// block is supported). The front-end will append its own message related to
835 /// options that address floating-point non-commutativity.
836 OptimizationRemarkAnalysisFPCommute(const char *PassName
,
837 StringRef RemarkName
,
838 const DiagnosticLocation
&Loc
,
839 const Value
*CodeRegion
)
840 : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisFPCommute
,
841 PassName
, RemarkName
, Loc
, CodeRegion
) {}
843 static bool classof(const DiagnosticInfo
*DI
) {
844 return DI
->getKind() == DK_OptimizationRemarkAnalysisFPCommute
;
848 /// This is deprecated now and only used by the function API below.
849 /// \p PassName is the name of the pass emitting this diagnostic. If
850 /// this name matches the regular expression given in -Rpass-analysis=, then
851 /// the diagnostic will be emitted. \p Fn is the function where the diagnostic
852 /// is being emitted. \p Loc is the location information to use in the
853 /// diagnostic. If line table information is available, the diagnostic will
854 /// include the source code location. \p Msg is the message to show. The
855 /// front-end will append its own message related to options that address
856 /// floating-point non-commutativity. Note that this class does not copy this
857 /// message, so this reference must be valid for the whole life time of the
859 OptimizationRemarkAnalysisFPCommute(const char *PassName
, const Function
&Fn
,
860 const DiagnosticLocation
&Loc
,
862 : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisFPCommute
,
863 PassName
, Fn
, Loc
, Msg
) {}
866 /// Diagnostic information for optimization analysis remarks related to
867 /// pointer aliasing.
868 class OptimizationRemarkAnalysisAliasing
: public OptimizationRemarkAnalysis
{
869 virtual void anchor();
871 /// \p PassName is the name of the pass emitting this diagnostic. If this name
872 /// matches the regular expression given in -Rpass-analysis=, then the
873 /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
874 /// remark (single-word, camel-case). \p Loc is the debug location and \p
875 /// CodeRegion is the region that the optimization operates on (currently only
876 /// block is supported). The front-end will append its own message related to
877 /// options that address pointer aliasing legality.
878 OptimizationRemarkAnalysisAliasing(const char *PassName
, StringRef RemarkName
,
879 const DiagnosticLocation
&Loc
,
880 const Value
*CodeRegion
)
881 : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisAliasing
,
882 PassName
, RemarkName
, Loc
, CodeRegion
) {}
884 static bool classof(const DiagnosticInfo
*DI
) {
885 return DI
->getKind() == DK_OptimizationRemarkAnalysisAliasing
;
889 /// This is deprecated now and only used by the function API below.
890 /// \p PassName is the name of the pass emitting this diagnostic. If
891 /// this name matches the regular expression given in -Rpass-analysis=, then
892 /// the diagnostic will be emitted. \p Fn is the function where the diagnostic
893 /// is being emitted. \p Loc is the location information to use in the
894 /// diagnostic. If line table information is available, the diagnostic will
895 /// include the source code location. \p Msg is the message to show. The
896 /// front-end will append its own message related to options that address
897 /// pointer aliasing legality. Note that this class does not copy this
898 /// message, so this reference must be valid for the whole life time of the
900 OptimizationRemarkAnalysisAliasing(const char *PassName
, const Function
&Fn
,
901 const DiagnosticLocation
&Loc
,
903 : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisAliasing
,
904 PassName
, Fn
, Loc
, Msg
) {}
907 /// Diagnostic information for machine IR parser.
908 class DiagnosticInfoMIRParser
: public DiagnosticInfo
{
909 const SMDiagnostic
&Diagnostic
;
912 DiagnosticInfoMIRParser(DiagnosticSeverity Severity
,
913 const SMDiagnostic
&Diagnostic
)
914 : DiagnosticInfo(DK_MIRParser
, Severity
), Diagnostic(Diagnostic
) {}
916 const SMDiagnostic
&getDiagnostic() const { return Diagnostic
; }
918 void print(DiagnosticPrinter
&DP
) const override
;
920 static bool classof(const DiagnosticInfo
*DI
) {
921 return DI
->getKind() == DK_MIRParser
;
925 /// Diagnostic information for ISel fallback path.
926 class DiagnosticInfoISelFallback
: public DiagnosticInfo
{
927 /// The function that is concerned by this diagnostic.
931 DiagnosticInfoISelFallback(const Function
&Fn
,
932 DiagnosticSeverity Severity
= DS_Warning
)
933 : DiagnosticInfo(DK_ISelFallback
, Severity
), Fn(Fn
) {}
935 const Function
&getFunction() const { return Fn
; }
937 void print(DiagnosticPrinter
&DP
) const override
;
939 static bool classof(const DiagnosticInfo
*DI
) {
940 return DI
->getKind() == DK_ISelFallback
;
944 // Create wrappers for C Binding types (see CBindingWrapping.h).
945 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DiagnosticInfo
, LLVMDiagnosticInfoRef
)
947 /// Diagnostic information for optimization failures.
948 class DiagnosticInfoOptimizationFailure
: public DiagnosticInfoIROptimization
{
950 /// \p Fn is the function where the diagnostic is being emitted. \p Loc is
951 /// the location information to use in the diagnostic. If line table
952 /// information is available, the diagnostic will include the source code
953 /// location. \p Msg is the message to show. Note that this class does not
954 /// copy this message, so this reference must be valid for the whole life time
955 /// of the diagnostic.
956 DiagnosticInfoOptimizationFailure(const Function
&Fn
,
957 const DiagnosticLocation
&Loc
,
959 : DiagnosticInfoIROptimization(DK_OptimizationFailure
, DS_Warning
,
960 nullptr, Fn
, Loc
, Msg
) {}
962 /// \p PassName is the name of the pass emitting this diagnostic. \p
963 /// RemarkName is a textual identifier for the remark (single-word,
964 /// camel-case). \p Loc is the debug location and \p CodeRegion is the
965 /// region that the optimization operates on (currently basic block is
967 DiagnosticInfoOptimizationFailure(const char *PassName
, StringRef RemarkName
,
968 const DiagnosticLocation
&Loc
,
969 const Value
*CodeRegion
);
971 static bool classof(const DiagnosticInfo
*DI
) {
972 return DI
->getKind() == DK_OptimizationFailure
;
975 /// \see DiagnosticInfoOptimizationBase::isEnabled.
976 bool isEnabled() const override
;
979 /// Diagnostic information for unsupported feature in backend.
980 class DiagnosticInfoUnsupported
: public DiagnosticInfoWithLocationBase
{
985 /// \p Fn is the function where the diagnostic is being emitted. \p Loc is
986 /// the location information to use in the diagnostic. If line table
987 /// information is available, the diagnostic will include the source code
988 /// location. \p Msg is the message to show. Note that this class does not
989 /// copy this message, so this reference must be valid for the whole life time
990 /// of the diagnostic.
991 DiagnosticInfoUnsupported(
992 const Function
&Fn
, const Twine
&Msg
,
993 const DiagnosticLocation
&Loc
= DiagnosticLocation(),
994 DiagnosticSeverity Severity
= DS_Error
)
995 : DiagnosticInfoWithLocationBase(DK_Unsupported
, Severity
, Fn
, Loc
),
998 static bool classof(const DiagnosticInfo
*DI
) {
999 return DI
->getKind() == DK_Unsupported
;
1002 const Twine
&getMessage() const { return Msg
; }
1004 void print(DiagnosticPrinter
&DP
) const override
;
1007 /// Diagnostic information for MisExpect analysis.
1008 class DiagnosticInfoMisExpect
: public DiagnosticInfoWithLocationBase
{
1010 DiagnosticInfoMisExpect(const Instruction
*Inst
, Twine
&Msg
);
1012 /// \see DiagnosticInfo::print.
1013 void print(DiagnosticPrinter
&DP
) const override
;
1015 static bool classof(const DiagnosticInfo
*DI
) {
1016 return DI
->getKind() == DK_MisExpect
;
1019 const Twine
&getMsg() const { return Msg
; }
1022 /// Message to report.
1026 } // end namespace llvm
1028 #endif // LLVM_IR_DIAGNOSTICINFO_H