[SimplifyCFG] FoldTwoEntryPHINode(): consider *total* speculation cost, not per-BB...
[llvm-complete.git] / include / llvm / IR / DiagnosticInfo.h
blob4cabadb0e4516563057d9e95f9d0462a34b1e1d6
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,
79 DK_MisExpect
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
93 /// the backend.
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
96 /// frontend).
97 class DiagnosticInfo {
98 private:
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();
105 public:
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
119 /// keyword.
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 {
128 private:
129 /// Optional line information. 0 if not set.
130 unsigned LocCookie = 0;
131 /// Message to be reported.
132 const Twine &MsgStr;
133 /// Optional origin of the problem.
134 const Instruction *Instr = nullptr;
136 public:
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),
151 MsgStr(MsgStr) {}
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.
157 /// Same for \p I.
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 {
176 private:
177 /// The function that is concerned by this resource limit diagnostic.
178 const Function &Fn;
180 /// Description of the resource type (e.g. stack size)
181 const char *ResourceName;
183 /// The computed size usage
184 uint64_t ResourceSize;
186 // Threshould passed
187 uint64_t ResourceLimit;
189 public:
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;
215 public:
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 {
233 private:
234 /// The module that is concerned by this debug metadata version diagnostic.
235 const Module &M;
236 /// The actual metadata version.
237 unsigned MetadataVersion;
239 public:
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 {
260 private:
261 /// The module that is concerned by this debug metadata version diagnostic.
262 const Module &M;
264 public:
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 {
282 public:
283 DiagnosticInfoSampleProfile(StringRef FileName, unsigned LineNum,
284 const Twine &Msg,
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),
291 Msg(Msg) {}
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; }
307 private:
308 /// Name of the input file associated with this diagnostic.
309 StringRef FileName;
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.
316 const Twine &Msg;
319 /// Diagnostic information for the PGO profiler.
320 class DiagnosticInfoPGOProfile : public DiagnosticInfo {
321 public:
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; }
336 private:
337 /// Name of the input file associated with this diagnostic.
338 const char *FileName;
340 /// Message to report.
341 const Twine &Msg;
344 class DiagnosticLocation {
345 DIFile *File = nullptr;
346 unsigned Line = 0;
347 unsigned Column = 0;
349 public:
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;
366 public:
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,
371 const Function &Fn,
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; }
394 private:
395 /// Function where this diagnostic is triggered.
396 const Function &Fn;
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 {
405 public:
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.
417 struct Argument {
418 std::string Key;
419 std::string Val;
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
444 /// location.
445 DiagnosticInfoOptimizationBase(enum DiagnosticKind Kind,
446 enum DiagnosticSeverity Severity,
447 const char *PassName, StringRef RemarkName,
448 const Function &Fn,
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);
500 protected:
501 /// Name of the pass that triggers this report. If this matches the
502 /// regular expression given in -Rpass=regexp, then the remark will
503 /// be emitted.
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
523 /// output.
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>
531 RemarkT &
532 operator<<(RemarkT &R,
533 typename std::enable_if<
534 std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
535 StringRef>::type S) {
536 R.insert(S);
537 return R;
540 /// Also allow r-value for the remark to allow insertion into a
541 /// temporarily-constructed remark.
542 template <class RemarkT>
543 RemarkT &
544 operator<<(RemarkT &&R,
545 typename std::enable_if<
546 std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
547 StringRef>::type S) {
548 R.insert(S);
549 return R;
552 template <class RemarkT>
553 RemarkT &
554 operator<<(RemarkT &R,
555 typename std::enable_if<
556 std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
557 DiagnosticInfoOptimizationBase::Argument>::type A) {
558 R.insert(A);
559 return R;
562 template <class RemarkT>
563 RemarkT &
564 operator<<(RemarkT &&R,
565 typename std::enable_if<
566 std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
567 DiagnosticInfoOptimizationBase::Argument>::type A) {
568 R.insert(A);
569 return R;
572 template <class RemarkT>
573 RemarkT &
574 operator<<(RemarkT &R,
575 typename std::enable_if<
576 std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
577 DiagnosticInfoOptimizationBase::setIsVerbose>::type V) {
578 R.insert(V);
579 return R;
582 template <class RemarkT>
583 RemarkT &
584 operator<<(RemarkT &&R,
585 typename std::enable_if<
586 std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
587 DiagnosticInfoOptimizationBase::setIsVerbose>::type V) {
588 R.insert(V);
589 return R;
592 template <class RemarkT>
593 RemarkT &
594 operator<<(RemarkT &R,
595 typename std::enable_if<
596 std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
597 DiagnosticInfoOptimizationBase::setExtraArgs>::type EA) {
598 R.insert(EA);
599 return R;
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;
606 public:
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,
618 const Function &Fn,
619 const DiagnosticLocation &Loc,
620 const Value *CodeRegion = nullptr)
621 : DiagnosticInfoOptimizationBase(Kind, Severity, PassName, RemarkName, Fn,
622 Loc),
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
631 /// message.
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()) {
638 *this << Prepend;
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) {
655 *this << Msg.str();
658 const Value *getCodeRegion() const { return CodeRegion; }
660 static bool classof(const DiagnosticInfo *DI) {
661 return DI->getKind() >= DK_FirstRemark && DI->getKind() <= DK_LastRemark;
664 private:
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 {
672 public:
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
678 /// supported).
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
683 /// Instr.
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
688 /// Func.
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;
699 private:
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,
712 Fn, Loc, Msg) {}
715 /// Diagnostic information for missed-optimization remarks.
716 class OptimizationRemarkMissed : public DiagnosticInfoIROptimization {
717 public:
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
729 /// location.
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;
740 private:
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 {
758 public:
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
775 /// message.
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
781 /// location.
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; }
796 protected:
797 OptimizationRemarkAnalysis(enum DiagnosticKind Kind, const char *PassName,
798 const Function &Fn, const DiagnosticLocation &Loc,
799 const Twine &Msg)
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);
807 private:
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();
827 public:
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;
846 private:
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
857 /// diagnostic.
858 OptimizationRemarkAnalysisFPCommute(const char *PassName, const Function &Fn,
859 const DiagnosticLocation &Loc,
860 const Twine &Msg)
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();
869 public:
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;
887 private:
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
898 /// diagnostic.
899 OptimizationRemarkAnalysisAliasing(const char *PassName, const Function &Fn,
900 const DiagnosticLocation &Loc,
901 const Twine &Msg)
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;
910 public:
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.
927 const Function &Fn;
929 public:
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 {
948 public:
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,
957 const Twine &Msg)
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
965 /// supported).
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 {
980 private:
981 Twine Msg;
983 public:
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),
995 Msg(Msg) {}
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 {
1008 public:
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; }
1020 private:
1021 /// Message to report.
1022 const Twine &Msg;
1025 } // end namespace llvm
1027 #endif // LLVM_IR_DIAGNOSTICINFO_H