[Alignment][NFC] Use Align with TargetLowering::setPrefLoopAlignment
[llvm-complete.git] / include / llvm / IR / DiagnosticInfo.h
blob2dce5ec1be1166c60871b1e23b0fbc8ddbf3c8b5
1 //===- llvm/IR/DiagnosticInfo.h - Diagnostic Declaration --------*- C++ -*-===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 //
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"
25 #include <algorithm>
26 #include <cstdint>
27 #include <functional>
28 #include <iterator>
29 #include <string>
31 namespace llvm {
33 // Forward declarations.
34 class DiagnosticPrinter;
35 class Function;
36 class Instruction;
37 class LLVMContext;
38 class Module;
39 class SMDiagnostic;
41 /// Defines the different supported severity of a diagnostic.
42 enum DiagnosticSeverity : char {
43 DS_Error,
44 DS_Warning,
45 DS_Remark,
46 // A note attaches additional information to one of the previous diagnostic
47 // types.
48 DS_Note
51 /// Defines the different supported kind of a diagnostic.
52 /// This enum should be extended with a new ID for each added concrete subclass.
53 enum DiagnosticKind {
54 DK_InlineAsm,
55 DK_ResourceLimit,
56 DK_StackSize,
57 DK_Linker,
58 DK_DebugMetadataVersion,
59 DK_DebugMetadataInvalid,
60 DK_ISelFallback,
61 DK_SampleProfile,
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,
75 DK_MIRParser,
76 DK_PGOProfile,
77 DK_Unsupported,
78 DK_FirstPluginKind
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
92 /// the backend.
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
95 /// frontend).
96 class DiagnosticInfo {
97 private:
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();
104 public:
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
118 /// keyword.
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 {
127 private:
128 /// Optional line information. 0 if not set.
129 unsigned LocCookie = 0;
130 /// Message to be reported.
131 const Twine &MsgStr;
132 /// Optional origin of the problem.
133 const Instruction *Instr = nullptr;
135 public:
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),
150 MsgStr(MsgStr) {}
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.
156 /// Same for \p I.
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 {
175 private:
176 /// The function that is concerned by this resource limit diagnostic.
177 const Function &Fn;
179 /// Description of the resource type (e.g. stack size)
180 const char *ResourceName;
182 /// The computed size usage
183 uint64_t ResourceSize;
185 // Threshould passed
186 uint64_t ResourceLimit;
188 public:
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;
214 public:
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 {
232 private:
233 /// The module that is concerned by this debug metadata version diagnostic.
234 const Module &M;
235 /// The actual metadata version.
236 unsigned MetadataVersion;
238 public:
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 {
259 private:
260 /// The module that is concerned by this debug metadata version diagnostic.
261 const Module &M;
263 public:
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 {
281 public:
282 DiagnosticInfoSampleProfile(StringRef FileName, unsigned LineNum,
283 const Twine &Msg,
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),
290 Msg(Msg) {}
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; }
306 private:
307 /// Name of the input file associated with this diagnostic.
308 StringRef FileName;
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.
315 const Twine &Msg;
318 /// Diagnostic information for the PGO profiler.
319 class DiagnosticInfoPGOProfile : public DiagnosticInfo {
320 public:
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; }
335 private:
336 /// Name of the input file associated with this diagnostic.
337 const char *FileName;
339 /// Message to report.
340 const Twine &Msg;
343 class DiagnosticLocation {
344 DIFile *File = nullptr;
345 unsigned Line = 0;
346 unsigned Column = 0;
348 public:
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;
365 public:
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,
370 const Function &Fn,
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; }
393 private:
394 /// Function where this diagnostic is triggered.
395 const Function &Fn;
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 {
404 public:
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.
416 struct Argument {
417 std::string Key;
418 std::string Val;
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
443 /// location.
444 DiagnosticInfoOptimizationBase(enum DiagnosticKind Kind,
445 enum DiagnosticSeverity Severity,
446 const char *PassName, StringRef RemarkName,
447 const Function &Fn,
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 StringRef getRemarkName() const { return RemarkName; }
469 std::string getMsg() const;
470 Optional<uint64_t> getHotness() const { return Hotness; }
471 void setHotness(Optional<uint64_t> H) { Hotness = H; }
473 bool isVerbose() const { return IsVerbose; }
475 ArrayRef<Argument> getArgs() const { return Args; }
477 static bool classof(const DiagnosticInfo *DI) {
478 return (DI->getKind() >= DK_FirstRemark &&
479 DI->getKind() <= DK_LastRemark) ||
480 (DI->getKind() >= DK_FirstMachineRemark &&
481 DI->getKind() <= DK_LastMachineRemark);
484 bool isPassed() const {
485 return (getKind() == DK_OptimizationRemark ||
486 getKind() == DK_MachineOptimizationRemark);
489 bool isMissed() const {
490 return (getKind() == DK_OptimizationRemarkMissed ||
491 getKind() == DK_MachineOptimizationRemarkMissed);
494 bool isAnalysis() const {
495 return (getKind() == DK_OptimizationRemarkAnalysis ||
496 getKind() == DK_MachineOptimizationRemarkAnalysis);
499 protected:
500 /// Name of the pass that triggers this report. If this matches the
501 /// regular expression given in -Rpass=regexp, then the remark will
502 /// be emitted.
503 const char *PassName;
505 /// Textual identifier for the remark (single-word, camel-case). Can be used
506 /// by external tools reading the output file for optimization remarks to
507 /// identify the remark.
508 StringRef RemarkName;
510 /// If profile information is available, this is the number of times the
511 /// corresponding code was executed in a profile instrumentation run.
512 Optional<uint64_t> Hotness;
514 /// Arguments collected via the streaming interface.
515 SmallVector<Argument, 4> Args;
517 /// The remark is expected to be noisy.
518 bool IsVerbose = false;
520 /// If positive, the index of the first argument that only appear in
521 /// the optimization records and not in the remark printed in the compiler
522 /// output.
523 int FirstExtraArgIndex = -1;
526 /// Allow the insertion operator to return the actual remark type rather than a
527 /// common base class. This allows returning the result of the insertion
528 /// directly by value, e.g. return OptimizationRemarkAnalysis(...) << "blah".
529 template <class RemarkT>
530 RemarkT &
531 operator<<(RemarkT &R,
532 typename std::enable_if<
533 std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
534 StringRef>::type S) {
535 R.insert(S);
536 return R;
539 /// Also allow r-value for the remark to allow insertion into a
540 /// temporarily-constructed remark.
541 template <class RemarkT>
542 RemarkT &
543 operator<<(RemarkT &&R,
544 typename std::enable_if<
545 std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
546 StringRef>::type S) {
547 R.insert(S);
548 return R;
551 template <class RemarkT>
552 RemarkT &
553 operator<<(RemarkT &R,
554 typename std::enable_if<
555 std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
556 DiagnosticInfoOptimizationBase::Argument>::type A) {
557 R.insert(A);
558 return R;
561 template <class RemarkT>
562 RemarkT &
563 operator<<(RemarkT &&R,
564 typename std::enable_if<
565 std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
566 DiagnosticInfoOptimizationBase::Argument>::type A) {
567 R.insert(A);
568 return R;
571 template <class RemarkT>
572 RemarkT &
573 operator<<(RemarkT &R,
574 typename std::enable_if<
575 std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
576 DiagnosticInfoOptimizationBase::setIsVerbose>::type V) {
577 R.insert(V);
578 return R;
581 template <class RemarkT>
582 RemarkT &
583 operator<<(RemarkT &&R,
584 typename std::enable_if<
585 std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
586 DiagnosticInfoOptimizationBase::setIsVerbose>::type V) {
587 R.insert(V);
588 return R;
591 template <class RemarkT>
592 RemarkT &
593 operator<<(RemarkT &R,
594 typename std::enable_if<
595 std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
596 DiagnosticInfoOptimizationBase::setExtraArgs>::type EA) {
597 R.insert(EA);
598 return R;
601 /// Common features for diagnostics dealing with optimization remarks
602 /// that are used by IR passes.
603 class DiagnosticInfoIROptimization : public DiagnosticInfoOptimizationBase {
604 virtual void anchor() override;
605 public:
606 /// \p PassName is the name of the pass emitting this diagnostic. \p
607 /// RemarkName is a textual identifier for the remark (single-word,
608 /// camel-case). \p Fn is the function where the diagnostic is being emitted.
609 /// \p Loc is the location information to use in the diagnostic. If line table
610 /// information is available, the diagnostic will include the source code
611 /// location. \p CodeRegion is IR value (currently basic block) that the
612 /// optimization operates on. This is currently used to provide run-time
613 /// hotness information with PGO.
614 DiagnosticInfoIROptimization(enum DiagnosticKind Kind,
615 enum DiagnosticSeverity Severity,
616 const char *PassName, StringRef RemarkName,
617 const Function &Fn,
618 const DiagnosticLocation &Loc,
619 const Value *CodeRegion = nullptr)
620 : DiagnosticInfoOptimizationBase(Kind, Severity, PassName, RemarkName, Fn,
621 Loc),
622 CodeRegion(CodeRegion) {}
624 /// This is ctor variant allows a pass to build an optimization remark
625 /// from an existing remark.
627 /// This is useful when a transformation pass (e.g LV) wants to emit a remark
628 /// (\p Orig) generated by one of its analyses (e.g. LAA) as its own analysis
629 /// remark. The string \p Prepend will be emitted before the original
630 /// message.
631 DiagnosticInfoIROptimization(const char *PassName, StringRef Prepend,
632 const DiagnosticInfoIROptimization &Orig)
633 : DiagnosticInfoOptimizationBase(
634 (DiagnosticKind)Orig.getKind(), Orig.getSeverity(), PassName,
635 Orig.RemarkName, Orig.getFunction(), Orig.getLocation()),
636 CodeRegion(Orig.getCodeRegion()) {
637 *this << Prepend;
638 std::copy(Orig.Args.begin(), Orig.Args.end(), std::back_inserter(Args));
641 /// Legacy interface.
642 /// \p PassName is the name of the pass emitting this diagnostic.
643 /// \p Fn is the function where the diagnostic is being emitted. \p Loc is
644 /// the location information to use in the diagnostic. If line table
645 /// information is available, the diagnostic will include the source code
646 /// location. \p Msg is the message to show. Note that this class does not
647 /// copy this message, so this reference must be valid for the whole life time
648 /// of the diagnostic.
649 DiagnosticInfoIROptimization(enum DiagnosticKind Kind,
650 enum DiagnosticSeverity Severity,
651 const char *PassName, const Function &Fn,
652 const DiagnosticLocation &Loc, const Twine &Msg)
653 : DiagnosticInfoOptimizationBase(Kind, Severity, PassName, "", Fn, Loc) {
654 *this << Msg.str();
657 const Value *getCodeRegion() const { return CodeRegion; }
659 static bool classof(const DiagnosticInfo *DI) {
660 return DI->getKind() >= DK_FirstRemark && DI->getKind() <= DK_LastRemark;
663 private:
664 /// The IR value (currently basic block) that the optimization operates on.
665 /// This is currently used to provide run-time hotness information with PGO.
666 const Value *CodeRegion = nullptr;
669 /// Diagnostic information for applied optimization remarks.
670 class OptimizationRemark : public DiagnosticInfoIROptimization {
671 public:
672 /// \p PassName is the name of the pass emitting this diagnostic. If this name
673 /// matches the regular expression given in -Rpass=, then the diagnostic will
674 /// be emitted. \p RemarkName is a textual identifier for the remark (single-
675 /// word, camel-case). \p Loc is the debug location and \p CodeRegion is the
676 /// region that the optimization operates on (currently only block is
677 /// supported).
678 OptimizationRemark(const char *PassName, StringRef RemarkName,
679 const DiagnosticLocation &Loc, const Value *CodeRegion);
681 /// Same as above, but the debug location and code region are derived from \p
682 /// Instr.
683 OptimizationRemark(const char *PassName, StringRef RemarkName,
684 const Instruction *Inst);
686 /// Same as above, but the debug location and code region are derived from \p
687 /// Func.
688 OptimizationRemark(const char *PassName, StringRef RemarkName,
689 const Function *Func);
691 static bool classof(const DiagnosticInfo *DI) {
692 return DI->getKind() == DK_OptimizationRemark;
695 /// \see DiagnosticInfoOptimizationBase::isEnabled.
696 bool isEnabled() const override;
698 private:
699 /// This is deprecated now and only used by the function API below.
700 /// \p PassName is the name of the pass emitting this diagnostic. If
701 /// this name matches the regular expression given in -Rpass=, then the
702 /// diagnostic will be emitted. \p Fn is the function where the diagnostic
703 /// is being emitted. \p Loc is the location information to use in the
704 /// diagnostic. If line table information is available, the diagnostic
705 /// will include the source code location. \p Msg is the message to show.
706 /// Note that this class does not copy this message, so this reference
707 /// must be valid for the whole life time of the diagnostic.
708 OptimizationRemark(const char *PassName, const Function &Fn,
709 const DiagnosticLocation &Loc, const Twine &Msg)
710 : DiagnosticInfoIROptimization(DK_OptimizationRemark, DS_Remark, PassName,
711 Fn, Loc, Msg) {}
714 /// Diagnostic information for missed-optimization remarks.
715 class OptimizationRemarkMissed : public DiagnosticInfoIROptimization {
716 public:
717 /// \p PassName is the name of the pass emitting this diagnostic. If this name
718 /// matches the regular expression given in -Rpass-missed=, then the
719 /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
720 /// remark (single-word, camel-case). \p Loc is the debug location and \p
721 /// CodeRegion is the region that the optimization operates on (currently only
722 /// block is supported).
723 OptimizationRemarkMissed(const char *PassName, StringRef RemarkName,
724 const DiagnosticLocation &Loc,
725 const Value *CodeRegion);
727 /// Same as above but \p Inst is used to derive code region and debug
728 /// location.
729 OptimizationRemarkMissed(const char *PassName, StringRef RemarkName,
730 const Instruction *Inst);
732 static bool classof(const DiagnosticInfo *DI) {
733 return DI->getKind() == DK_OptimizationRemarkMissed;
736 /// \see DiagnosticInfoOptimizationBase::isEnabled.
737 bool isEnabled() const override;
739 private:
740 /// This is deprecated now and only used by the function API below.
741 /// \p PassName is the name of the pass emitting this diagnostic. If
742 /// this name matches the regular expression given in -Rpass-missed=, then the
743 /// diagnostic will be emitted. \p Fn is the function where the diagnostic
744 /// is being emitted. \p Loc is the location information to use in the
745 /// diagnostic. If line table information is available, the diagnostic
746 /// will include the source code location. \p Msg is the message to show.
747 /// Note that this class does not copy this message, so this reference
748 /// must be valid for the whole life time of the diagnostic.
749 OptimizationRemarkMissed(const char *PassName, const Function &Fn,
750 const DiagnosticLocation &Loc, const Twine &Msg)
751 : DiagnosticInfoIROptimization(DK_OptimizationRemarkMissed, DS_Remark,
752 PassName, Fn, Loc, Msg) {}
755 /// Diagnostic information for optimization analysis remarks.
756 class OptimizationRemarkAnalysis : public DiagnosticInfoIROptimization {
757 public:
758 /// \p PassName is the name of the pass emitting this diagnostic. If this name
759 /// matches the regular expression given in -Rpass-analysis=, then the
760 /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
761 /// remark (single-word, camel-case). \p Loc is the debug location and \p
762 /// CodeRegion is the region that the optimization operates on (currently only
763 /// block is supported).
764 OptimizationRemarkAnalysis(const char *PassName, StringRef RemarkName,
765 const DiagnosticLocation &Loc,
766 const Value *CodeRegion);
768 /// This is ctor variant allows a pass to build an optimization remark
769 /// from an existing remark.
771 /// This is useful when a transformation pass (e.g LV) wants to emit a remark
772 /// (\p Orig) generated by one of its analyses (e.g. LAA) as its own analysis
773 /// remark. The string \p Prepend will be emitted before the original
774 /// message.
775 OptimizationRemarkAnalysis(const char *PassName, StringRef Prepend,
776 const OptimizationRemarkAnalysis &Orig)
777 : DiagnosticInfoIROptimization(PassName, Prepend, Orig) {}
779 /// Same as above but \p Inst is used to derive code region and debug
780 /// location.
781 OptimizationRemarkAnalysis(const char *PassName, StringRef RemarkName,
782 const Instruction *Inst);
784 static bool classof(const DiagnosticInfo *DI) {
785 return DI->getKind() == DK_OptimizationRemarkAnalysis;
788 /// \see DiagnosticInfoOptimizationBase::isEnabled.
789 bool isEnabled() const override;
791 static const char *AlwaysPrint;
793 bool shouldAlwaysPrint() const { return getPassName() == AlwaysPrint; }
795 protected:
796 OptimizationRemarkAnalysis(enum DiagnosticKind Kind, const char *PassName,
797 const Function &Fn, const DiagnosticLocation &Loc,
798 const Twine &Msg)
799 : DiagnosticInfoIROptimization(Kind, DS_Remark, PassName, Fn, Loc, Msg) {}
801 OptimizationRemarkAnalysis(enum DiagnosticKind Kind, const char *PassName,
802 StringRef RemarkName,
803 const DiagnosticLocation &Loc,
804 const Value *CodeRegion);
806 private:
807 /// This is deprecated now and only used by the function API below.
808 /// \p PassName is the name of the pass emitting this diagnostic. If
809 /// this name matches the regular expression given in -Rpass-analysis=, then
810 /// the diagnostic will be emitted. \p Fn is the function where the diagnostic
811 /// is being emitted. \p Loc is the location information to use in the
812 /// diagnostic. If line table information is available, the diagnostic will
813 /// include the source code location. \p Msg is the message to show. Note that
814 /// this class does not copy this message, so this reference must be valid for
815 /// the whole life time of the diagnostic.
816 OptimizationRemarkAnalysis(const char *PassName, const Function &Fn,
817 const DiagnosticLocation &Loc, const Twine &Msg)
818 : DiagnosticInfoIROptimization(DK_OptimizationRemarkAnalysis, DS_Remark,
819 PassName, Fn, Loc, Msg) {}
822 /// Diagnostic information for optimization analysis remarks related to
823 /// floating-point non-commutativity.
824 class OptimizationRemarkAnalysisFPCommute : public OptimizationRemarkAnalysis {
825 virtual void anchor();
826 public:
827 /// \p PassName is the name of the pass emitting this diagnostic. If this name
828 /// matches the regular expression given in -Rpass-analysis=, then the
829 /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
830 /// remark (single-word, camel-case). \p Loc is the debug location and \p
831 /// CodeRegion is the region that the optimization operates on (currently only
832 /// block is supported). The front-end will append its own message related to
833 /// options that address floating-point non-commutativity.
834 OptimizationRemarkAnalysisFPCommute(const char *PassName,
835 StringRef RemarkName,
836 const DiagnosticLocation &Loc,
837 const Value *CodeRegion)
838 : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisFPCommute,
839 PassName, RemarkName, Loc, CodeRegion) {}
841 static bool classof(const DiagnosticInfo *DI) {
842 return DI->getKind() == DK_OptimizationRemarkAnalysisFPCommute;
845 private:
846 /// This is deprecated now and only used by the function API below.
847 /// \p PassName is the name of the pass emitting this diagnostic. If
848 /// this name matches the regular expression given in -Rpass-analysis=, then
849 /// the diagnostic will be emitted. \p Fn is the function where the diagnostic
850 /// is being emitted. \p Loc is the location information to use in the
851 /// diagnostic. If line table information is available, the diagnostic will
852 /// include the source code location. \p Msg is the message to show. The
853 /// front-end will append its own message related to options that address
854 /// floating-point non-commutativity. Note that this class does not copy this
855 /// message, so this reference must be valid for the whole life time of the
856 /// diagnostic.
857 OptimizationRemarkAnalysisFPCommute(const char *PassName, const Function &Fn,
858 const DiagnosticLocation &Loc,
859 const Twine &Msg)
860 : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisFPCommute,
861 PassName, Fn, Loc, Msg) {}
864 /// Diagnostic information for optimization analysis remarks related to
865 /// pointer aliasing.
866 class OptimizationRemarkAnalysisAliasing : public OptimizationRemarkAnalysis {
867 virtual void anchor();
868 public:
869 /// \p PassName is the name of the pass emitting this diagnostic. If this name
870 /// matches the regular expression given in -Rpass-analysis=, then the
871 /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
872 /// remark (single-word, camel-case). \p Loc is the debug location and \p
873 /// CodeRegion is the region that the optimization operates on (currently only
874 /// block is supported). The front-end will append its own message related to
875 /// options that address pointer aliasing legality.
876 OptimizationRemarkAnalysisAliasing(const char *PassName, StringRef RemarkName,
877 const DiagnosticLocation &Loc,
878 const Value *CodeRegion)
879 : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisAliasing,
880 PassName, RemarkName, Loc, CodeRegion) {}
882 static bool classof(const DiagnosticInfo *DI) {
883 return DI->getKind() == DK_OptimizationRemarkAnalysisAliasing;
886 private:
887 /// This is deprecated now and only used by the function API below.
888 /// \p PassName is the name of the pass emitting this diagnostic. If
889 /// this name matches the regular expression given in -Rpass-analysis=, then
890 /// the diagnostic will be emitted. \p Fn is the function where the diagnostic
891 /// is being emitted. \p Loc is the location information to use in the
892 /// diagnostic. If line table information is available, the diagnostic will
893 /// include the source code location. \p Msg is the message to show. The
894 /// front-end will append its own message related to options that address
895 /// pointer aliasing legality. Note that this class does not copy this
896 /// message, so this reference must be valid for the whole life time of the
897 /// diagnostic.
898 OptimizationRemarkAnalysisAliasing(const char *PassName, const Function &Fn,
899 const DiagnosticLocation &Loc,
900 const Twine &Msg)
901 : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisAliasing,
902 PassName, Fn, Loc, Msg) {}
905 /// Diagnostic information for machine IR parser.
906 class DiagnosticInfoMIRParser : public DiagnosticInfo {
907 const SMDiagnostic &Diagnostic;
909 public:
910 DiagnosticInfoMIRParser(DiagnosticSeverity Severity,
911 const SMDiagnostic &Diagnostic)
912 : DiagnosticInfo(DK_MIRParser, Severity), Diagnostic(Diagnostic) {}
914 const SMDiagnostic &getDiagnostic() const { return Diagnostic; }
916 void print(DiagnosticPrinter &DP) const override;
918 static bool classof(const DiagnosticInfo *DI) {
919 return DI->getKind() == DK_MIRParser;
923 /// Diagnostic information for ISel fallback path.
924 class DiagnosticInfoISelFallback : public DiagnosticInfo {
925 /// The function that is concerned by this diagnostic.
926 const Function &Fn;
928 public:
929 DiagnosticInfoISelFallback(const Function &Fn,
930 DiagnosticSeverity Severity = DS_Warning)
931 : DiagnosticInfo(DK_ISelFallback, Severity), Fn(Fn) {}
933 const Function &getFunction() const { return Fn; }
935 void print(DiagnosticPrinter &DP) const override;
937 static bool classof(const DiagnosticInfo *DI) {
938 return DI->getKind() == DK_ISelFallback;
942 // Create wrappers for C Binding types (see CBindingWrapping.h).
943 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DiagnosticInfo, LLVMDiagnosticInfoRef)
945 /// Diagnostic information for optimization failures.
946 class DiagnosticInfoOptimizationFailure : public DiagnosticInfoIROptimization {
947 public:
948 /// \p Fn is the function where the diagnostic is being emitted. \p Loc is
949 /// the location information to use in the diagnostic. If line table
950 /// information is available, the diagnostic will include the source code
951 /// location. \p Msg is the message to show. Note that this class does not
952 /// copy this message, so this reference must be valid for the whole life time
953 /// of the diagnostic.
954 DiagnosticInfoOptimizationFailure(const Function &Fn,
955 const DiagnosticLocation &Loc,
956 const Twine &Msg)
957 : DiagnosticInfoIROptimization(DK_OptimizationFailure, DS_Warning,
958 nullptr, Fn, Loc, Msg) {}
960 /// \p PassName is the name of the pass emitting this diagnostic. \p
961 /// RemarkName is a textual identifier for the remark (single-word,
962 /// camel-case). \p Loc is the debug location and \p CodeRegion is the
963 /// region that the optimization operates on (currently basic block is
964 /// supported).
965 DiagnosticInfoOptimizationFailure(const char *PassName, StringRef RemarkName,
966 const DiagnosticLocation &Loc,
967 const Value *CodeRegion);
969 static bool classof(const DiagnosticInfo *DI) {
970 return DI->getKind() == DK_OptimizationFailure;
973 /// \see DiagnosticInfoOptimizationBase::isEnabled.
974 bool isEnabled() const override;
977 /// Diagnostic information for unsupported feature in backend.
978 class DiagnosticInfoUnsupported : public DiagnosticInfoWithLocationBase {
979 private:
980 Twine Msg;
982 public:
983 /// \p Fn is the function where the diagnostic is being emitted. \p Loc is
984 /// the location information to use in the diagnostic. If line table
985 /// information is available, the diagnostic will include the source code
986 /// location. \p Msg is the message to show. Note that this class does not
987 /// copy this message, so this reference must be valid for the whole life time
988 /// of the diagnostic.
989 DiagnosticInfoUnsupported(
990 const Function &Fn, const Twine &Msg,
991 const DiagnosticLocation &Loc = DiagnosticLocation(),
992 DiagnosticSeverity Severity = DS_Error)
993 : DiagnosticInfoWithLocationBase(DK_Unsupported, Severity, Fn, Loc),
994 Msg(Msg) {}
996 static bool classof(const DiagnosticInfo *DI) {
997 return DI->getKind() == DK_Unsupported;
1000 const Twine &getMessage() const { return Msg; }
1002 void print(DiagnosticPrinter &DP) const override;
1005 } // end namespace llvm
1007 #endif // LLVM_IR_DIAGNOSTICINFO_H