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
,
82 /// Get the next available kind ID for a plugin diagnostic.
83 /// Each time this function is called, it returns a different number.
84 /// Therefore, a plugin that wants to "identify" its own classes
85 /// with a dynamic identifier, just have to use this method to get a new ID
86 /// and assign it to each of its classes.
87 /// The returned ID will be greater than or equal to DK_FirstPluginKind.
88 /// Thus, the plugin identifiers will not conflict with the
89 /// DiagnosticKind values.
90 int getNextAvailablePluginDiagnosticKind();
92 /// This is the base abstract class for diagnostic reporting in
94 /// The print method must be overloaded by the subclasses to print a
95 /// user-friendly message in the client of the backend (let us call it a
97 class DiagnosticInfo
{
99 /// Kind defines the kind of report this is about.
100 const /* DiagnosticKind */ int Kind
;
101 /// Severity gives the severity of the diagnostic.
102 const DiagnosticSeverity Severity
;
104 virtual void anchor();
106 DiagnosticInfo(/* DiagnosticKind */ int Kind
, DiagnosticSeverity Severity
)
107 : Kind(Kind
), Severity(Severity
) {}
109 virtual ~DiagnosticInfo() = default;
111 /* DiagnosticKind */ int getKind() const { return Kind
; }
112 DiagnosticSeverity
getSeverity() const { return Severity
; }
114 /// Print using the given \p DP a user-friendly message.
115 /// This is the default message that will be printed to the user.
116 /// It is used when the frontend does not directly take advantage
117 /// of the information contained in fields of the subclasses.
118 /// The printed message must not end with '.' nor start with a severity
120 virtual void print(DiagnosticPrinter
&DP
) const = 0;
123 using DiagnosticHandlerFunction
= std::function
<void(const DiagnosticInfo
&)>;
125 /// Diagnostic information for inline asm reporting.
126 /// This is basically a message and an optional location.
127 class DiagnosticInfoInlineAsm
: public DiagnosticInfo
{
129 /// Optional line information. 0 if not set.
130 unsigned LocCookie
= 0;
131 /// Message to be reported.
133 /// Optional origin of the problem.
134 const Instruction
*Instr
= nullptr;
137 /// \p MsgStr is the message to be reported to the frontend.
138 /// This class does not copy \p MsgStr, therefore the reference must be valid
139 /// for the whole life time of the Diagnostic.
140 DiagnosticInfoInlineAsm(const Twine
&MsgStr
,
141 DiagnosticSeverity Severity
= DS_Error
)
142 : DiagnosticInfo(DK_InlineAsm
, Severity
), MsgStr(MsgStr
) {}
144 /// \p LocCookie if non-zero gives the line number for this report.
145 /// \p MsgStr gives the message.
146 /// This class does not copy \p MsgStr, therefore the reference must be valid
147 /// for the whole life time of the Diagnostic.
148 DiagnosticInfoInlineAsm(unsigned LocCookie
, const Twine
&MsgStr
,
149 DiagnosticSeverity Severity
= DS_Error
)
150 : DiagnosticInfo(DK_InlineAsm
, Severity
), LocCookie(LocCookie
),
153 /// \p Instr gives the original instruction that triggered the diagnostic.
154 /// \p MsgStr gives the message.
155 /// This class does not copy \p MsgStr, therefore the reference must be valid
156 /// for the whole life time of the Diagnostic.
158 DiagnosticInfoInlineAsm(const Instruction
&I
, const Twine
&MsgStr
,
159 DiagnosticSeverity Severity
= DS_Error
);
161 unsigned getLocCookie() const { return LocCookie
; }
162 const Twine
&getMsgStr() const { return MsgStr
; }
163 const Instruction
*getInstruction() const { return Instr
; }
165 /// \see DiagnosticInfo::print.
166 void print(DiagnosticPrinter
&DP
) const override
;
168 static bool classof(const DiagnosticInfo
*DI
) {
169 return DI
->getKind() == DK_InlineAsm
;
173 /// Diagnostic information for stack size etc. reporting.
174 /// This is basically a function and a size.
175 class DiagnosticInfoResourceLimit
: public DiagnosticInfo
{
177 /// The function that is concerned by this resource limit diagnostic.
180 /// Description of the resource type (e.g. stack size)
181 const char *ResourceName
;
183 /// The computed size usage
184 uint64_t ResourceSize
;
187 uint64_t ResourceLimit
;
190 /// \p The function that is concerned by this stack size diagnostic.
191 /// \p The computed stack size.
192 DiagnosticInfoResourceLimit(const Function
&Fn
, const char *ResourceName
,
193 uint64_t ResourceSize
,
194 DiagnosticSeverity Severity
= DS_Warning
,
195 DiagnosticKind Kind
= DK_ResourceLimit
,
196 uint64_t ResourceLimit
= 0)
197 : DiagnosticInfo(Kind
, Severity
), Fn(Fn
), ResourceName(ResourceName
),
198 ResourceSize(ResourceSize
), 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
|| DI
->getKind() == DK_StackSize
;
213 class DiagnosticInfoStackSize
: public DiagnosticInfoResourceLimit
{
214 virtual void anchor() override
;
216 DiagnosticInfoStackSize(const Function
&Fn
, uint64_t StackSize
,
217 DiagnosticSeverity Severity
= DS_Warning
,
218 uint64_t StackLimit
= 0)
219 : DiagnosticInfoResourceLimit(Fn
, "stack size", StackSize
, Severity
,
220 DK_StackSize
, StackLimit
) {}
222 uint64_t getStackSize() const { return getResourceSize(); }
223 uint64_t getStackLimit() const { return getResourceLimit(); }
225 static bool classof(const DiagnosticInfo
*DI
) {
226 return DI
->getKind() == DK_StackSize
;
230 /// Diagnostic information for debug metadata version reporting.
231 /// This is basically a module and a version.
232 class DiagnosticInfoDebugMetadataVersion
: public DiagnosticInfo
{
234 /// The module that is concerned by this debug metadata version diagnostic.
236 /// The actual metadata version.
237 unsigned MetadataVersion
;
240 /// \p The module that is concerned by this debug metadata version diagnostic.
241 /// \p The actual metadata version.
242 DiagnosticInfoDebugMetadataVersion(const Module
&M
, unsigned MetadataVersion
,
243 DiagnosticSeverity Severity
= DS_Warning
)
244 : DiagnosticInfo(DK_DebugMetadataVersion
, Severity
), M(M
),
245 MetadataVersion(MetadataVersion
) {}
247 const Module
&getModule() const { return M
; }
248 unsigned getMetadataVersion() const { return MetadataVersion
; }
250 /// \see DiagnosticInfo::print.
251 void print(DiagnosticPrinter
&DP
) const override
;
253 static bool classof(const DiagnosticInfo
*DI
) {
254 return DI
->getKind() == DK_DebugMetadataVersion
;
258 /// Diagnostic information for stripping invalid debug metadata.
259 class DiagnosticInfoIgnoringInvalidDebugMetadata
: public DiagnosticInfo
{
261 /// The module that is concerned by this debug metadata version diagnostic.
265 /// \p The module that is concerned by this debug metadata version diagnostic.
266 DiagnosticInfoIgnoringInvalidDebugMetadata(
267 const Module
&M
, DiagnosticSeverity Severity
= DS_Warning
)
268 : DiagnosticInfo(DK_DebugMetadataVersion
, Severity
), M(M
) {}
270 const Module
&getModule() const { return M
; }
272 /// \see DiagnosticInfo::print.
273 void print(DiagnosticPrinter
&DP
) const override
;
275 static bool classof(const DiagnosticInfo
*DI
) {
276 return DI
->getKind() == DK_DebugMetadataInvalid
;
280 /// Diagnostic information for the sample profiler.
281 class DiagnosticInfoSampleProfile
: public DiagnosticInfo
{
283 DiagnosticInfoSampleProfile(StringRef FileName
, unsigned LineNum
,
285 DiagnosticSeverity Severity
= DS_Error
)
286 : DiagnosticInfo(DK_SampleProfile
, Severity
), FileName(FileName
),
287 LineNum(LineNum
), Msg(Msg
) {}
288 DiagnosticInfoSampleProfile(StringRef FileName
, const Twine
&Msg
,
289 DiagnosticSeverity Severity
= DS_Error
)
290 : DiagnosticInfo(DK_SampleProfile
, Severity
), FileName(FileName
),
292 DiagnosticInfoSampleProfile(const Twine
&Msg
,
293 DiagnosticSeverity Severity
= DS_Error
)
294 : DiagnosticInfo(DK_SampleProfile
, Severity
), Msg(Msg
) {}
296 /// \see DiagnosticInfo::print.
297 void print(DiagnosticPrinter
&DP
) const override
;
299 static bool classof(const DiagnosticInfo
*DI
) {
300 return DI
->getKind() == DK_SampleProfile
;
303 StringRef
getFileName() const { return FileName
; }
304 unsigned getLineNum() const { return LineNum
; }
305 const Twine
&getMsg() const { return Msg
; }
308 /// Name of the input file associated with this diagnostic.
311 /// Line number where the diagnostic occurred. If 0, no line number will
312 /// be emitted in the message.
313 unsigned LineNum
= 0;
315 /// Message to report.
319 /// Diagnostic information for the PGO profiler.
320 class DiagnosticInfoPGOProfile
: public DiagnosticInfo
{
322 DiagnosticInfoPGOProfile(const char *FileName
, const Twine
&Msg
,
323 DiagnosticSeverity Severity
= DS_Error
)
324 : DiagnosticInfo(DK_PGOProfile
, Severity
), FileName(FileName
), Msg(Msg
) {}
326 /// \see DiagnosticInfo::print.
327 void print(DiagnosticPrinter
&DP
) const override
;
329 static bool classof(const DiagnosticInfo
*DI
) {
330 return DI
->getKind() == DK_PGOProfile
;
333 const char *getFileName() const { return FileName
; }
334 const Twine
&getMsg() const { return Msg
; }
337 /// Name of the input file associated with this diagnostic.
338 const char *FileName
;
340 /// Message to report.
344 class DiagnosticLocation
{
345 DIFile
*File
= nullptr;
350 DiagnosticLocation() = default;
351 DiagnosticLocation(const DebugLoc
&DL
);
352 DiagnosticLocation(const DISubprogram
*SP
);
354 bool isValid() const { return File
; }
355 /// Return the full path to the file.
356 std::string
getAbsolutePath() const;
357 /// Return the file name relative to the compilation directory.
358 StringRef
getRelativePath() const;
359 unsigned getLine() const { return Line
; }
360 unsigned getColumn() const { return Column
; }
363 /// Common features for diagnostics with an associated location.
364 class DiagnosticInfoWithLocationBase
: public DiagnosticInfo
{
365 virtual void anchor() override
;
367 /// \p Fn is the function where the diagnostic is being emitted. \p Loc is
368 /// the location information to use in the diagnostic.
369 DiagnosticInfoWithLocationBase(enum DiagnosticKind Kind
,
370 enum DiagnosticSeverity Severity
,
372 const DiagnosticLocation
&Loc
)
373 : DiagnosticInfo(Kind
, Severity
), Fn(Fn
), Loc(Loc
) {}
375 /// Return true if location information is available for this diagnostic.
376 bool isLocationAvailable() const { return Loc
.isValid(); }
378 /// Return a string with the location information for this diagnostic
379 /// in the format "file:line:col". If location information is not available,
380 /// it returns "<unknown>:0:0".
381 const std::string
getLocationStr() const;
383 /// Return location information for this diagnostic in three parts:
384 /// the relative source file path, line number and column.
385 void getLocation(StringRef
&RelativePath
, unsigned &Line
,
386 unsigned &Column
) const;
388 /// Return the absolute path tot the file.
389 std::string
getAbsolutePath() const;
391 const Function
&getFunction() const { return Fn
; }
392 DiagnosticLocation
getLocation() const { return Loc
; }
395 /// Function where this diagnostic is triggered.
398 /// Debug location where this diagnostic is triggered.
399 DiagnosticLocation Loc
;
402 /// Common features for diagnostics dealing with optimization remarks
403 /// that are used by both IR and MIR passes.
404 class DiagnosticInfoOptimizationBase
: public DiagnosticInfoWithLocationBase
{
406 /// Used to set IsVerbose via the stream interface.
407 struct setIsVerbose
{};
409 /// When an instance of this is inserted into the stream, the arguments
410 /// following will not appear in the remark printed in the compiler output
411 /// (-Rpass) but only in the optimization record file
412 /// (-fsave-optimization-record).
413 struct setExtraArgs
{};
415 /// Used in the streaming interface as the general argument type. It
416 /// internally converts everything into a key-value pair.
420 // If set, the debug location corresponding to the value.
421 DiagnosticLocation Loc
;
423 explicit Argument(StringRef Str
= "") : Key("String"), Val(Str
) {}
424 Argument(StringRef Key
, const Value
*V
);
425 Argument(StringRef Key
, const Type
*T
);
426 Argument(StringRef Key
, StringRef S
);
427 Argument(StringRef Key
, const char *S
) : Argument(Key
, StringRef(S
)) {};
428 Argument(StringRef Key
, int N
);
429 Argument(StringRef Key
, float N
);
430 Argument(StringRef Key
, long N
);
431 Argument(StringRef Key
, long long N
);
432 Argument(StringRef Key
, unsigned N
);
433 Argument(StringRef Key
, unsigned long N
);
434 Argument(StringRef Key
, unsigned long long N
);
435 Argument(StringRef Key
, bool B
) : Key(Key
), Val(B
? "true" : "false") {}
436 Argument(StringRef Key
, DebugLoc dl
);
439 /// \p PassName is the name of the pass emitting this diagnostic. \p
440 /// RemarkName is a textual identifier for the remark (single-word,
441 /// camel-case). \p Fn is the function where the diagnostic is being emitted.
442 /// \p Loc is the location information to use in the diagnostic. If line table
443 /// information is available, the diagnostic will include the source code
445 DiagnosticInfoOptimizationBase(enum DiagnosticKind Kind
,
446 enum DiagnosticSeverity Severity
,
447 const char *PassName
, StringRef RemarkName
,
449 const DiagnosticLocation
&Loc
)
450 : DiagnosticInfoWithLocationBase(Kind
, Severity
, Fn
, Loc
),
451 PassName(PassName
), RemarkName(RemarkName
) {}
453 void insert(StringRef S
);
454 void insert(Argument A
);
455 void insert(setIsVerbose V
);
456 void insert(setExtraArgs EA
);
458 /// \see DiagnosticInfo::print.
459 void print(DiagnosticPrinter
&DP
) const override
;
461 /// Return true if this optimization remark is enabled by one of
462 /// of the LLVM command line flags (-pass-remarks, -pass-remarks-missed,
463 /// or -pass-remarks-analysis). Note that this only handles the LLVM
464 /// flags. We cannot access Clang flags from here (they are handled
465 /// in BackendConsumer::OptimizationRemarkHandler).
466 virtual bool isEnabled() const = 0;
468 StringRef
getPassName() const { return PassName
; }
469 StringRef
getRemarkName() const { return RemarkName
; }
470 std::string
getMsg() const;
471 Optional
<uint64_t> getHotness() const { return Hotness
; }
472 void setHotness(Optional
<uint64_t> H
) { Hotness
= H
; }
474 bool isVerbose() const { return IsVerbose
; }
476 ArrayRef
<Argument
> getArgs() const { return Args
; }
478 static bool classof(const DiagnosticInfo
*DI
) {
479 return (DI
->getKind() >= DK_FirstRemark
&&
480 DI
->getKind() <= DK_LastRemark
) ||
481 (DI
->getKind() >= DK_FirstMachineRemark
&&
482 DI
->getKind() <= DK_LastMachineRemark
);
485 bool isPassed() const {
486 return (getKind() == DK_OptimizationRemark
||
487 getKind() == DK_MachineOptimizationRemark
);
490 bool isMissed() const {
491 return (getKind() == DK_OptimizationRemarkMissed
||
492 getKind() == DK_MachineOptimizationRemarkMissed
);
495 bool isAnalysis() const {
496 return (getKind() == DK_OptimizationRemarkAnalysis
||
497 getKind() == DK_MachineOptimizationRemarkAnalysis
);
501 /// Name of the pass that triggers this report. If this matches the
502 /// regular expression given in -Rpass=regexp, then the remark will
504 const char *PassName
;
506 /// Textual identifier for the remark (single-word, camel-case). Can be used
507 /// by external tools reading the output file for optimization remarks to
508 /// identify the remark.
509 StringRef RemarkName
;
511 /// If profile information is available, this is the number of times the
512 /// corresponding code was executed in a profile instrumentation run.
513 Optional
<uint64_t> Hotness
;
515 /// Arguments collected via the streaming interface.
516 SmallVector
<Argument
, 4> Args
;
518 /// The remark is expected to be noisy.
519 bool IsVerbose
= false;
521 /// If positive, the index of the first argument that only appear in
522 /// the optimization records and not in the remark printed in the compiler
524 int FirstExtraArgIndex
= -1;
527 /// Allow the insertion operator to return the actual remark type rather than a
528 /// common base class. This allows returning the result of the insertion
529 /// directly by value, e.g. return OptimizationRemarkAnalysis(...) << "blah".
530 template <class RemarkT
>
532 operator<<(RemarkT
&R
,
533 typename
std::enable_if
<
534 std::is_base_of
<DiagnosticInfoOptimizationBase
, RemarkT
>::value
,
535 StringRef
>::type S
) {
540 /// Also allow r-value for the remark to allow insertion into a
541 /// temporarily-constructed remark.
542 template <class RemarkT
>
544 operator<<(RemarkT
&&R
,
545 typename
std::enable_if
<
546 std::is_base_of
<DiagnosticInfoOptimizationBase
, RemarkT
>::value
,
547 StringRef
>::type S
) {
552 template <class RemarkT
>
554 operator<<(RemarkT
&R
,
555 typename
std::enable_if
<
556 std::is_base_of
<DiagnosticInfoOptimizationBase
, RemarkT
>::value
,
557 DiagnosticInfoOptimizationBase::Argument
>::type A
) {
562 template <class RemarkT
>
564 operator<<(RemarkT
&&R
,
565 typename
std::enable_if
<
566 std::is_base_of
<DiagnosticInfoOptimizationBase
, RemarkT
>::value
,
567 DiagnosticInfoOptimizationBase::Argument
>::type A
) {
572 template <class RemarkT
>
574 operator<<(RemarkT
&R
,
575 typename
std::enable_if
<
576 std::is_base_of
<DiagnosticInfoOptimizationBase
, RemarkT
>::value
,
577 DiagnosticInfoOptimizationBase::setIsVerbose
>::type V
) {
582 template <class RemarkT
>
584 operator<<(RemarkT
&&R
,
585 typename
std::enable_if
<
586 std::is_base_of
<DiagnosticInfoOptimizationBase
, RemarkT
>::value
,
587 DiagnosticInfoOptimizationBase::setIsVerbose
>::type V
) {
592 template <class RemarkT
>
594 operator<<(RemarkT
&R
,
595 typename
std::enable_if
<
596 std::is_base_of
<DiagnosticInfoOptimizationBase
, RemarkT
>::value
,
597 DiagnosticInfoOptimizationBase::setExtraArgs
>::type EA
) {
602 /// Common features for diagnostics dealing with optimization remarks
603 /// that are used by IR passes.
604 class DiagnosticInfoIROptimization
: public DiagnosticInfoOptimizationBase
{
605 virtual void anchor() override
;
607 /// \p PassName is the name of the pass emitting this diagnostic. \p
608 /// RemarkName is a textual identifier for the remark (single-word,
609 /// camel-case). \p Fn is the function where the diagnostic is being emitted.
610 /// \p Loc is the location information to use in the diagnostic. If line table
611 /// information is available, the diagnostic will include the source code
612 /// location. \p CodeRegion is IR value (currently basic block) that the
613 /// optimization operates on. This is currently used to provide run-time
614 /// hotness information with PGO.
615 DiagnosticInfoIROptimization(enum DiagnosticKind Kind
,
616 enum DiagnosticSeverity Severity
,
617 const char *PassName
, StringRef RemarkName
,
619 const DiagnosticLocation
&Loc
,
620 const Value
*CodeRegion
= nullptr)
621 : DiagnosticInfoOptimizationBase(Kind
, Severity
, PassName
, RemarkName
, Fn
,
623 CodeRegion(CodeRegion
) {}
625 /// This is ctor variant allows a pass to build an optimization remark
626 /// from an existing remark.
628 /// This is useful when a transformation pass (e.g LV) wants to emit a remark
629 /// (\p Orig) generated by one of its analyses (e.g. LAA) as its own analysis
630 /// remark. The string \p Prepend will be emitted before the original
632 DiagnosticInfoIROptimization(const char *PassName
, StringRef Prepend
,
633 const DiagnosticInfoIROptimization
&Orig
)
634 : DiagnosticInfoOptimizationBase(
635 (DiagnosticKind
)Orig
.getKind(), Orig
.getSeverity(), PassName
,
636 Orig
.RemarkName
, Orig
.getFunction(), Orig
.getLocation()),
637 CodeRegion(Orig
.getCodeRegion()) {
639 std::copy(Orig
.Args
.begin(), Orig
.Args
.end(), std::back_inserter(Args
));
642 /// Legacy interface.
643 /// \p PassName is the name of the pass emitting this diagnostic.
644 /// \p Fn is the function where the diagnostic is being emitted. \p Loc is
645 /// the location information to use in the diagnostic. If line table
646 /// information is available, the diagnostic will include the source code
647 /// location. \p Msg is the message to show. Note that this class does not
648 /// copy this message, so this reference must be valid for the whole life time
649 /// of the diagnostic.
650 DiagnosticInfoIROptimization(enum DiagnosticKind Kind
,
651 enum DiagnosticSeverity Severity
,
652 const char *PassName
, const Function
&Fn
,
653 const DiagnosticLocation
&Loc
, const Twine
&Msg
)
654 : DiagnosticInfoOptimizationBase(Kind
, Severity
, PassName
, "", Fn
, Loc
) {
658 const Value
*getCodeRegion() const { return CodeRegion
; }
660 static bool classof(const DiagnosticInfo
*DI
) {
661 return DI
->getKind() >= DK_FirstRemark
&& DI
->getKind() <= DK_LastRemark
;
665 /// The IR value (currently basic block) that the optimization operates on.
666 /// This is currently used to provide run-time hotness information with PGO.
667 const Value
*CodeRegion
= nullptr;
670 /// Diagnostic information for applied optimization remarks.
671 class OptimizationRemark
: public DiagnosticInfoIROptimization
{
673 /// \p PassName is the name of the pass emitting this diagnostic. If this name
674 /// matches the regular expression given in -Rpass=, then the diagnostic will
675 /// be emitted. \p RemarkName is a textual identifier for the remark (single-
676 /// word, camel-case). \p Loc is the debug location and \p CodeRegion is the
677 /// region that the optimization operates on (currently only block is
679 OptimizationRemark(const char *PassName
, StringRef RemarkName
,
680 const DiagnosticLocation
&Loc
, const Value
*CodeRegion
);
682 /// Same as above, but the debug location and code region are derived from \p
684 OptimizationRemark(const char *PassName
, StringRef RemarkName
,
685 const Instruction
*Inst
);
687 /// Same as above, but the debug location and code region are derived from \p
689 OptimizationRemark(const char *PassName
, StringRef RemarkName
,
690 const Function
*Func
);
692 static bool classof(const DiagnosticInfo
*DI
) {
693 return DI
->getKind() == DK_OptimizationRemark
;
696 /// \see DiagnosticInfoOptimizationBase::isEnabled.
697 bool isEnabled() const override
;
700 /// This is deprecated now and only used by the function API below.
701 /// \p PassName is the name of the pass emitting this diagnostic. If
702 /// this name matches the regular expression given in -Rpass=, then the
703 /// diagnostic will be emitted. \p Fn is the function where the diagnostic
704 /// is being emitted. \p Loc is the location information to use in the
705 /// diagnostic. If line table information is available, the diagnostic
706 /// will include the source code location. \p Msg is the message to show.
707 /// Note that this class does not copy this message, so this reference
708 /// must be valid for the whole life time of the diagnostic.
709 OptimizationRemark(const char *PassName
, const Function
&Fn
,
710 const DiagnosticLocation
&Loc
, const Twine
&Msg
)
711 : DiagnosticInfoIROptimization(DK_OptimizationRemark
, DS_Remark
, PassName
,
715 /// Diagnostic information for missed-optimization remarks.
716 class OptimizationRemarkMissed
: public DiagnosticInfoIROptimization
{
718 /// \p PassName is the name of the pass emitting this diagnostic. If this name
719 /// matches the regular expression given in -Rpass-missed=, then the
720 /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
721 /// remark (single-word, camel-case). \p Loc is the debug location and \p
722 /// CodeRegion is the region that the optimization operates on (currently only
723 /// block is supported).
724 OptimizationRemarkMissed(const char *PassName
, StringRef RemarkName
,
725 const DiagnosticLocation
&Loc
,
726 const Value
*CodeRegion
);
728 /// Same as above but \p Inst is used to derive code region and debug
730 OptimizationRemarkMissed(const char *PassName
, StringRef RemarkName
,
731 const Instruction
*Inst
);
733 static bool classof(const DiagnosticInfo
*DI
) {
734 return DI
->getKind() == DK_OptimizationRemarkMissed
;
737 /// \see DiagnosticInfoOptimizationBase::isEnabled.
738 bool isEnabled() const override
;
741 /// This is deprecated now and only used by the function API below.
742 /// \p PassName is the name of the pass emitting this diagnostic. If
743 /// this name matches the regular expression given in -Rpass-missed=, then the
744 /// diagnostic will be emitted. \p Fn is the function where the diagnostic
745 /// is being emitted. \p Loc is the location information to use in the
746 /// diagnostic. If line table information is available, the diagnostic
747 /// will include the source code location. \p Msg is the message to show.
748 /// Note that this class does not copy this message, so this reference
749 /// must be valid for the whole life time of the diagnostic.
750 OptimizationRemarkMissed(const char *PassName
, const Function
&Fn
,
751 const DiagnosticLocation
&Loc
, const Twine
&Msg
)
752 : DiagnosticInfoIROptimization(DK_OptimizationRemarkMissed
, DS_Remark
,
753 PassName
, Fn
, Loc
, Msg
) {}
756 /// Diagnostic information for optimization analysis remarks.
757 class OptimizationRemarkAnalysis
: public DiagnosticInfoIROptimization
{
759 /// \p PassName is the name of the pass emitting this diagnostic. If this name
760 /// matches the regular expression given in -Rpass-analysis=, then the
761 /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
762 /// remark (single-word, camel-case). \p Loc is the debug location and \p
763 /// CodeRegion is the region that the optimization operates on (currently only
764 /// block is supported).
765 OptimizationRemarkAnalysis(const char *PassName
, StringRef RemarkName
,
766 const DiagnosticLocation
&Loc
,
767 const Value
*CodeRegion
);
769 /// This is ctor variant allows a pass to build an optimization remark
770 /// from an existing remark.
772 /// This is useful when a transformation pass (e.g LV) wants to emit a remark
773 /// (\p Orig) generated by one of its analyses (e.g. LAA) as its own analysis
774 /// remark. The string \p Prepend will be emitted before the original
776 OptimizationRemarkAnalysis(const char *PassName
, StringRef Prepend
,
777 const OptimizationRemarkAnalysis
&Orig
)
778 : DiagnosticInfoIROptimization(PassName
, Prepend
, Orig
) {}
780 /// Same as above but \p Inst is used to derive code region and debug
782 OptimizationRemarkAnalysis(const char *PassName
, StringRef RemarkName
,
783 const Instruction
*Inst
);
785 static bool classof(const DiagnosticInfo
*DI
) {
786 return DI
->getKind() == DK_OptimizationRemarkAnalysis
;
789 /// \see DiagnosticInfoOptimizationBase::isEnabled.
790 bool isEnabled() const override
;
792 static const char *AlwaysPrint
;
794 bool shouldAlwaysPrint() const { return getPassName() == AlwaysPrint
; }
797 OptimizationRemarkAnalysis(enum DiagnosticKind Kind
, const char *PassName
,
798 const Function
&Fn
, const DiagnosticLocation
&Loc
,
800 : DiagnosticInfoIROptimization(Kind
, DS_Remark
, PassName
, Fn
, Loc
, Msg
) {}
802 OptimizationRemarkAnalysis(enum DiagnosticKind Kind
, const char *PassName
,
803 StringRef RemarkName
,
804 const DiagnosticLocation
&Loc
,
805 const Value
*CodeRegion
);
808 /// This is deprecated now and only used by the function API below.
809 /// \p PassName is the name of the pass emitting this diagnostic. If
810 /// this name matches the regular expression given in -Rpass-analysis=, then
811 /// the diagnostic will be emitted. \p Fn is the function where the diagnostic
812 /// is being emitted. \p Loc is the location information to use in the
813 /// diagnostic. If line table information is available, the diagnostic will
814 /// include the source code location. \p Msg is the message to show. Note that
815 /// this class does not copy this message, so this reference must be valid for
816 /// the whole life time of the diagnostic.
817 OptimizationRemarkAnalysis(const char *PassName
, const Function
&Fn
,
818 const DiagnosticLocation
&Loc
, const Twine
&Msg
)
819 : DiagnosticInfoIROptimization(DK_OptimizationRemarkAnalysis
, DS_Remark
,
820 PassName
, Fn
, Loc
, Msg
) {}
823 /// Diagnostic information for optimization analysis remarks related to
824 /// floating-point non-commutativity.
825 class OptimizationRemarkAnalysisFPCommute
: public OptimizationRemarkAnalysis
{
826 virtual void anchor();
828 /// \p PassName is the name of the pass emitting this diagnostic. If this name
829 /// matches the regular expression given in -Rpass-analysis=, then the
830 /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
831 /// remark (single-word, camel-case). \p Loc is the debug location and \p
832 /// CodeRegion is the region that the optimization operates on (currently only
833 /// block is supported). The front-end will append its own message related to
834 /// options that address floating-point non-commutativity.
835 OptimizationRemarkAnalysisFPCommute(const char *PassName
,
836 StringRef RemarkName
,
837 const DiagnosticLocation
&Loc
,
838 const Value
*CodeRegion
)
839 : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisFPCommute
,
840 PassName
, RemarkName
, Loc
, CodeRegion
) {}
842 static bool classof(const DiagnosticInfo
*DI
) {
843 return DI
->getKind() == DK_OptimizationRemarkAnalysisFPCommute
;
847 /// This is deprecated now and only used by the function API below.
848 /// \p PassName is the name of the pass emitting this diagnostic. If
849 /// this name matches the regular expression given in -Rpass-analysis=, then
850 /// the diagnostic will be emitted. \p Fn is the function where the diagnostic
851 /// is being emitted. \p Loc is the location information to use in the
852 /// diagnostic. If line table information is available, the diagnostic will
853 /// include the source code location. \p Msg is the message to show. The
854 /// front-end will append its own message related to options that address
855 /// floating-point non-commutativity. Note that this class does not copy this
856 /// message, so this reference must be valid for the whole life time of the
858 OptimizationRemarkAnalysisFPCommute(const char *PassName
, const Function
&Fn
,
859 const DiagnosticLocation
&Loc
,
861 : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisFPCommute
,
862 PassName
, Fn
, Loc
, Msg
) {}
865 /// Diagnostic information for optimization analysis remarks related to
866 /// pointer aliasing.
867 class OptimizationRemarkAnalysisAliasing
: public OptimizationRemarkAnalysis
{
868 virtual void anchor();
870 /// \p PassName is the name of the pass emitting this diagnostic. If this name
871 /// matches the regular expression given in -Rpass-analysis=, then the
872 /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
873 /// remark (single-word, camel-case). \p Loc is the debug location and \p
874 /// CodeRegion is the region that the optimization operates on (currently only
875 /// block is supported). The front-end will append its own message related to
876 /// options that address pointer aliasing legality.
877 OptimizationRemarkAnalysisAliasing(const char *PassName
, StringRef RemarkName
,
878 const DiagnosticLocation
&Loc
,
879 const Value
*CodeRegion
)
880 : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisAliasing
,
881 PassName
, RemarkName
, Loc
, CodeRegion
) {}
883 static bool classof(const DiagnosticInfo
*DI
) {
884 return DI
->getKind() == DK_OptimizationRemarkAnalysisAliasing
;
888 /// This is deprecated now and only used by the function API below.
889 /// \p PassName is the name of the pass emitting this diagnostic. If
890 /// this name matches the regular expression given in -Rpass-analysis=, then
891 /// the diagnostic will be emitted. \p Fn is the function where the diagnostic
892 /// is being emitted. \p Loc is the location information to use in the
893 /// diagnostic. If line table information is available, the diagnostic will
894 /// include the source code location. \p Msg is the message to show. The
895 /// front-end will append its own message related to options that address
896 /// pointer aliasing legality. Note that this class does not copy this
897 /// message, so this reference must be valid for the whole life time of the
899 OptimizationRemarkAnalysisAliasing(const char *PassName
, const Function
&Fn
,
900 const DiagnosticLocation
&Loc
,
902 : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisAliasing
,
903 PassName
, Fn
, Loc
, Msg
) {}
906 /// Diagnostic information for machine IR parser.
907 class DiagnosticInfoMIRParser
: public DiagnosticInfo
{
908 const SMDiagnostic
&Diagnostic
;
911 DiagnosticInfoMIRParser(DiagnosticSeverity Severity
,
912 const SMDiagnostic
&Diagnostic
)
913 : DiagnosticInfo(DK_MIRParser
, Severity
), Diagnostic(Diagnostic
) {}
915 const SMDiagnostic
&getDiagnostic() const { return Diagnostic
; }
917 void print(DiagnosticPrinter
&DP
) const override
;
919 static bool classof(const DiagnosticInfo
*DI
) {
920 return DI
->getKind() == DK_MIRParser
;
924 /// Diagnostic information for ISel fallback path.
925 class DiagnosticInfoISelFallback
: public DiagnosticInfo
{
926 /// The function that is concerned by this diagnostic.
930 DiagnosticInfoISelFallback(const Function
&Fn
,
931 DiagnosticSeverity Severity
= DS_Warning
)
932 : DiagnosticInfo(DK_ISelFallback
, Severity
), Fn(Fn
) {}
934 const Function
&getFunction() const { return Fn
; }
936 void print(DiagnosticPrinter
&DP
) const override
;
938 static bool classof(const DiagnosticInfo
*DI
) {
939 return DI
->getKind() == DK_ISelFallback
;
943 // Create wrappers for C Binding types (see CBindingWrapping.h).
944 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DiagnosticInfo
, LLVMDiagnosticInfoRef
)
946 /// Diagnostic information for optimization failures.
947 class DiagnosticInfoOptimizationFailure
: public DiagnosticInfoIROptimization
{
949 /// \p Fn is the function where the diagnostic is being emitted. \p Loc is
950 /// the location information to use in the diagnostic. If line table
951 /// information is available, the diagnostic will include the source code
952 /// location. \p Msg is the message to show. Note that this class does not
953 /// copy this message, so this reference must be valid for the whole life time
954 /// of the diagnostic.
955 DiagnosticInfoOptimizationFailure(const Function
&Fn
,
956 const DiagnosticLocation
&Loc
,
958 : DiagnosticInfoIROptimization(DK_OptimizationFailure
, DS_Warning
,
959 nullptr, Fn
, Loc
, Msg
) {}
961 /// \p PassName is the name of the pass emitting this diagnostic. \p
962 /// RemarkName is a textual identifier for the remark (single-word,
963 /// camel-case). \p Loc is the debug location and \p CodeRegion is the
964 /// region that the optimization operates on (currently basic block is
966 DiagnosticInfoOptimizationFailure(const char *PassName
, StringRef RemarkName
,
967 const DiagnosticLocation
&Loc
,
968 const Value
*CodeRegion
);
970 static bool classof(const DiagnosticInfo
*DI
) {
971 return DI
->getKind() == DK_OptimizationFailure
;
974 /// \see DiagnosticInfoOptimizationBase::isEnabled.
975 bool isEnabled() const override
;
978 /// Diagnostic information for unsupported feature in backend.
979 class DiagnosticInfoUnsupported
: public DiagnosticInfoWithLocationBase
{
984 /// \p Fn is the function where the diagnostic is being emitted. \p Loc is
985 /// the location information to use in the diagnostic. If line table
986 /// information is available, the diagnostic will include the source code
987 /// location. \p Msg is the message to show. Note that this class does not
988 /// copy this message, so this reference must be valid for the whole life time
989 /// of the diagnostic.
990 DiagnosticInfoUnsupported(
991 const Function
&Fn
, const Twine
&Msg
,
992 const DiagnosticLocation
&Loc
= DiagnosticLocation(),
993 DiagnosticSeverity Severity
= DS_Error
)
994 : DiagnosticInfoWithLocationBase(DK_Unsupported
, Severity
, Fn
, Loc
),
997 static bool classof(const DiagnosticInfo
*DI
) {
998 return DI
->getKind() == DK_Unsupported
;
1001 const Twine
&getMessage() const { return Msg
; }
1003 void print(DiagnosticPrinter
&DP
) const override
;
1006 /// Diagnostic information for MisExpect analysis.
1007 class DiagnosticInfoMisExpect
: public DiagnosticInfoWithLocationBase
{
1009 DiagnosticInfoMisExpect(const Instruction
*Inst
, Twine
&Msg
);
1011 /// \see DiagnosticInfo::print.
1012 void print(DiagnosticPrinter
&DP
) const override
;
1014 static bool classof(const DiagnosticInfo
*DI
) {
1015 return DI
->getKind() == DK_MisExpect
;
1018 const Twine
&getMsg() const { return Msg
; }
1021 /// Message to report.
1025 } // end namespace llvm
1027 #endif // LLVM_IR_DIAGNOSTICINFO_H