Home | History | Annotate | Download | only in IR
      1 //===- llvm/IR/DiagnosticInfo.h - Diagnostic Declaration --------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file declares the different classes involved in low level diagnostics.
     11 //
     12 // Diagnostics reporting is still done as part of the LLVMContext.
     13 //===----------------------------------------------------------------------===//
     14 
     15 #ifndef LLVM_IR_DIAGNOSTICINFO_H
     16 #define LLVM_IR_DIAGNOSTICINFO_H
     17 
     18 #include "llvm-c/Types.h"
     19 #include "llvm/ADT/Optional.h"
     20 #include "llvm/ADT/SmallVector.h"
     21 #include "llvm/ADT/StringRef.h"
     22 #include "llvm/ADT/Twine.h"
     23 #include "llvm/IR/DebugLoc.h"
     24 #include "llvm/Support/CBindingWrapping.h"
     25 #include "llvm/Support/YAMLTraits.h"
     26 #include <algorithm>
     27 #include <cstdint>
     28 #include <functional>
     29 #include <iterator>
     30 #include <string>
     31 
     32 namespace llvm {
     33 
     34 // Forward declarations.
     35 class DiagnosticPrinter;
     36 class Function;
     37 class Instruction;
     38 class LLVMContext;
     39 class Module;
     40 class SMDiagnostic;
     41 
     42 /// \brief Defines the different supported severity of a diagnostic.
     43 enum DiagnosticSeverity : char {
     44   DS_Error,
     45   DS_Warning,
     46   DS_Remark,
     47   // A note attaches additional information to one of the previous diagnostic
     48   // types.
     49   DS_Note
     50 };
     51 
     52 /// \brief Defines the different supported kind of a diagnostic.
     53 /// This enum should be extended with a new ID for each added concrete subclass.
     54 enum DiagnosticKind {
     55   DK_InlineAsm,
     56   DK_ResourceLimit,
     57   DK_StackSize,
     58   DK_Linker,
     59   DK_DebugMetadataVersion,
     60   DK_DebugMetadataInvalid,
     61   DK_ISelFallback,
     62   DK_SampleProfile,
     63   DK_OptimizationRemark,
     64   DK_OptimizationRemarkMissed,
     65   DK_OptimizationRemarkAnalysis,
     66   DK_OptimizationRemarkAnalysisFPCommute,
     67   DK_OptimizationRemarkAnalysisAliasing,
     68   DK_OptimizationFailure,
     69   DK_FirstRemark = DK_OptimizationRemark,
     70   DK_LastRemark = DK_OptimizationFailure,
     71   DK_MachineOptimizationRemark,
     72   DK_MachineOptimizationRemarkMissed,
     73   DK_MachineOptimizationRemarkAnalysis,
     74   DK_FirstMachineRemark = DK_MachineOptimizationRemark,
     75   DK_LastMachineRemark = DK_MachineOptimizationRemarkAnalysis,
     76   DK_MIRParser,
     77   DK_PGOProfile,
     78   DK_Unsupported,
     79   DK_FirstPluginKind
     80 };
     81 
     82 /// \brief 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();
     91 
     92 /// \brief 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;
    103 
    104 public:
    105   DiagnosticInfo(/* DiagnosticKind */ int Kind, DiagnosticSeverity Severity)
    106       : Kind(Kind), Severity(Severity) {}
    107 
    108   virtual ~DiagnosticInfo() = default;
    109 
    110   /* DiagnosticKind */ int getKind() const { return Kind; }
    111   DiagnosticSeverity getSeverity() const { return Severity; }
    112 
    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;
    120 };
    121 
    122 using DiagnosticHandlerFunction = std::function<void(const DiagnosticInfo &)>;
    123 
    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;
    134 
    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) {}
    142 
    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) {}
    151 
    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);
    159 
    160   unsigned getLocCookie() const { return LocCookie; }
    161   const Twine &getMsgStr() const { return MsgStr; }
    162   const Instruction *getInstruction() const { return Instr; }
    163 
    164   /// \see DiagnosticInfo::print.
    165   void print(DiagnosticPrinter &DP) const override;
    166 
    167   static bool classof(const DiagnosticInfo *DI) {
    168     return DI->getKind() == DK_InlineAsm;
    169   }
    170 };
    171 
    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;
    178 
    179   /// Description of the resource type (e.g. stack size)
    180   const char *ResourceName;
    181 
    182   /// The computed size usage
    183   uint64_t ResourceSize;
    184 
    185   // Threshould passed
    186   uint64_t ResourceLimit;
    187 
    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,
    192                               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),
    198         Fn(Fn),
    199         ResourceName(ResourceName),
    200         ResourceSize(ResourceSize),
    201         ResourceLimit(ResourceLimit) {}
    202 
    203   const Function &getFunction() const { return Fn; }
    204   const char *getResourceName() const { return ResourceName; }
    205   uint64_t getResourceSize() const { return ResourceSize; }
    206   uint64_t getResourceLimit() const { return ResourceLimit; }
    207 
    208   /// \see DiagnosticInfo::print.
    209   void print(DiagnosticPrinter &DP) const override;
    210 
    211   static bool classof(const DiagnosticInfo *DI) {
    212     return DI->getKind() == DK_ResourceLimit ||
    213            DI->getKind() == DK_StackSize;
    214   }
    215 };
    216 
    217 class DiagnosticInfoStackSize : public DiagnosticInfoResourceLimit {
    218 public:
    219   DiagnosticInfoStackSize(const Function &Fn,
    220                           uint64_t StackSize,
    221                           DiagnosticSeverity Severity = DS_Warning,
    222                           uint64_t StackLimit = 0)
    223     : DiagnosticInfoResourceLimit(Fn, "stack size", StackSize,
    224                                   Severity, DK_StackSize, StackLimit) {}
    225 
    226   uint64_t getStackSize() const { return getResourceSize(); }
    227   uint64_t getStackLimit() const { return getResourceLimit(); }
    228 
    229   static bool classof(const DiagnosticInfo *DI) {
    230     return DI->getKind() == DK_StackSize;
    231   }
    232 };
    233 
    234 /// Diagnostic information for debug metadata version reporting.
    235 /// This is basically a module and a version.
    236 class DiagnosticInfoDebugMetadataVersion : public DiagnosticInfo {
    237 private:
    238   /// The module that is concerned by this debug metadata version diagnostic.
    239   const Module &M;
    240   /// The actual metadata version.
    241   unsigned MetadataVersion;
    242 
    243 public:
    244   /// \p The module that is concerned by this debug metadata version diagnostic.
    245   /// \p The actual metadata version.
    246   DiagnosticInfoDebugMetadataVersion(const Module &M, unsigned MetadataVersion,
    247                           DiagnosticSeverity Severity = DS_Warning)
    248       : DiagnosticInfo(DK_DebugMetadataVersion, Severity), M(M),
    249         MetadataVersion(MetadataVersion) {}
    250 
    251   const Module &getModule() const { return M; }
    252   unsigned getMetadataVersion() const { return MetadataVersion; }
    253 
    254   /// \see DiagnosticInfo::print.
    255   void print(DiagnosticPrinter &DP) const override;
    256 
    257   static bool classof(const DiagnosticInfo *DI) {
    258     return DI->getKind() == DK_DebugMetadataVersion;
    259   }
    260 };
    261 
    262 /// Diagnostic information for stripping invalid debug metadata.
    263 class DiagnosticInfoIgnoringInvalidDebugMetadata : public DiagnosticInfo {
    264 private:
    265   /// The module that is concerned by this debug metadata version diagnostic.
    266   const Module &M;
    267 
    268 public:
    269   /// \p The module that is concerned by this debug metadata version diagnostic.
    270   DiagnosticInfoIgnoringInvalidDebugMetadata(
    271       const Module &M, DiagnosticSeverity Severity = DS_Warning)
    272       : DiagnosticInfo(DK_DebugMetadataVersion, Severity), M(M) {}
    273 
    274   const Module &getModule() const { return M; }
    275 
    276   /// \see DiagnosticInfo::print.
    277   void print(DiagnosticPrinter &DP) const override;
    278 
    279   static bool classof(const DiagnosticInfo *DI) {
    280     return DI->getKind() == DK_DebugMetadataInvalid;
    281   }
    282 };
    283 
    284 /// Diagnostic information for the sample profiler.
    285 class DiagnosticInfoSampleProfile : public DiagnosticInfo {
    286 public:
    287   DiagnosticInfoSampleProfile(StringRef FileName, unsigned LineNum,
    288                               const Twine &Msg,
    289                               DiagnosticSeverity Severity = DS_Error)
    290       : DiagnosticInfo(DK_SampleProfile, Severity), FileName(FileName),
    291         LineNum(LineNum), Msg(Msg) {}
    292   DiagnosticInfoSampleProfile(StringRef FileName, const Twine &Msg,
    293                               DiagnosticSeverity Severity = DS_Error)
    294       : DiagnosticInfo(DK_SampleProfile, Severity), FileName(FileName),
    295         Msg(Msg) {}
    296   DiagnosticInfoSampleProfile(const Twine &Msg,
    297                               DiagnosticSeverity Severity = DS_Error)
    298       : DiagnosticInfo(DK_SampleProfile, Severity), Msg(Msg) {}
    299 
    300   /// \see DiagnosticInfo::print.
    301   void print(DiagnosticPrinter &DP) const override;
    302 
    303   static bool classof(const DiagnosticInfo *DI) {
    304     return DI->getKind() == DK_SampleProfile;
    305   }
    306 
    307   StringRef getFileName() const { return FileName; }
    308   unsigned getLineNum() const { return LineNum; }
    309   const Twine &getMsg() const { return Msg; }
    310 
    311 private:
    312   /// Name of the input file associated with this diagnostic.
    313   StringRef FileName;
    314 
    315   /// Line number where the diagnostic occurred. If 0, no line number will
    316   /// be emitted in the message.
    317   unsigned LineNum = 0;
    318 
    319   /// Message to report.
    320   const Twine &Msg;
    321 };
    322 
    323 /// Diagnostic information for the PGO profiler.
    324 class DiagnosticInfoPGOProfile : public DiagnosticInfo {
    325 public:
    326   DiagnosticInfoPGOProfile(const char *FileName, const Twine &Msg,
    327                            DiagnosticSeverity Severity = DS_Error)
    328       : DiagnosticInfo(DK_PGOProfile, Severity), FileName(FileName), Msg(Msg) {}
    329 
    330   /// \see DiagnosticInfo::print.
    331   void print(DiagnosticPrinter &DP) const override;
    332 
    333   static bool classof(const DiagnosticInfo *DI) {
    334     return DI->getKind() == DK_PGOProfile;
    335   }
    336 
    337   const char *getFileName() const { return FileName; }
    338   const Twine &getMsg() const { return Msg; }
    339 
    340 private:
    341   /// Name of the input file associated with this diagnostic.
    342   const char *FileName;
    343 
    344   /// Message to report.
    345   const Twine &Msg;
    346 };
    347 
    348 class DiagnosticLocation {
    349   StringRef Filename;
    350   unsigned Line = 0;
    351   unsigned Column = 0;
    352 
    353 public:
    354   DiagnosticLocation() = default;
    355   DiagnosticLocation(const DebugLoc &DL);
    356   DiagnosticLocation(const DISubprogram *SP);
    357 
    358   bool isValid() const { return !Filename.empty(); }
    359   StringRef getFilename() const { return Filename; }
    360   unsigned getLine() const { return Line; }
    361   unsigned getColumn() const { return Column; }
    362 };
    363 
    364 /// Common features for diagnostics with an associated location.
    365 class DiagnosticInfoWithLocationBase : public DiagnosticInfo {
    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) {}
    374 
    375   /// Return true if location information is available for this diagnostic.
    376   bool isLocationAvailable() const { return Loc.isValid(); }
    377 
    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;
    382 
    383   /// Return location information for this diagnostic in three parts:
    384   /// the source file name, line number and column.
    385   void getLocation(StringRef *Filename, unsigned *Line, unsigned *Column) const;
    386 
    387   const Function &getFunction() const { return Fn; }
    388   DiagnosticLocation getLocation() const { return Loc; }
    389 
    390 private:
    391   /// Function where this diagnostic is triggered.
    392   const Function &Fn;
    393 
    394   /// Debug location where this diagnostic is triggered.
    395   DiagnosticLocation Loc;
    396 };
    397 
    398 /// \brief Common features for diagnostics dealing with optimization remarks
    399 /// that are used by both IR and MIR passes.
    400 class DiagnosticInfoOptimizationBase : public DiagnosticInfoWithLocationBase {
    401 public:
    402   /// \brief Used to set IsVerbose via the stream interface.
    403   struct setIsVerbose {};
    404 
    405   /// \brief When an instance of this is inserted into the stream, the arguments
    406   /// following will not appear in the remark printed in the compiler output
    407   /// (-Rpass) but only in the optimization record file
    408   /// (-fsave-optimization-record).
    409   struct setExtraArgs {};
    410 
    411   /// \brief Used in the streaming interface as the general argument type.  It
    412   /// internally converts everything into a key-value pair.
    413   struct Argument {
    414     StringRef Key;
    415     std::string Val;
    416     // If set, the debug location corresponding to the value.
    417     DiagnosticLocation Loc;
    418 
    419     explicit Argument(StringRef Str = "") : Key("String"), Val(Str) {}
    420     Argument(StringRef Key, const Value *V);
    421     Argument(StringRef Key, const Type *T);
    422     Argument(StringRef Key, int N);
    423     Argument(StringRef Key, unsigned N);
    424     Argument(StringRef Key, bool B) : Key(Key), Val(B ? "true" : "false") {}
    425   };
    426 
    427   /// \p PassName is the name of the pass emitting this diagnostic. \p
    428   /// RemarkName is a textual identifier for the remark (single-word,
    429   /// camel-case). \p Fn is the function where the diagnostic is being emitted.
    430   /// \p Loc is the location information to use in the diagnostic. If line table
    431   /// information is available, the diagnostic will include the source code
    432   /// location.
    433   DiagnosticInfoOptimizationBase(enum DiagnosticKind Kind,
    434                                  enum DiagnosticSeverity Severity,
    435                                  const char *PassName, StringRef RemarkName,
    436                                  const Function &Fn,
    437                                  const DiagnosticLocation &Loc)
    438       : DiagnosticInfoWithLocationBase(Kind, Severity, Fn, Loc),
    439         PassName(PassName), RemarkName(RemarkName) {}
    440 
    441   DiagnosticInfoOptimizationBase &operator<<(StringRef S);
    442   DiagnosticInfoOptimizationBase &operator<<(Argument A);
    443   DiagnosticInfoOptimizationBase &operator<<(setIsVerbose V);
    444   DiagnosticInfoOptimizationBase &operator<<(setExtraArgs EA);
    445 
    446   /// \see DiagnosticInfo::print.
    447   void print(DiagnosticPrinter &DP) const override;
    448 
    449   /// Return true if this optimization remark is enabled by one of
    450   /// of the LLVM command line flags (-pass-remarks, -pass-remarks-missed,
    451   /// or -pass-remarks-analysis). Note that this only handles the LLVM
    452   /// flags. We cannot access Clang flags from here (they are handled
    453   /// in BackendConsumer::OptimizationRemarkHandler).
    454   virtual bool isEnabled() const = 0;
    455 
    456   StringRef getPassName() const { return PassName; }
    457   std::string getMsg() const;
    458   Optional<uint64_t> getHotness() const { return Hotness; }
    459   void setHotness(Optional<uint64_t> H) { Hotness = H; }
    460 
    461   bool isVerbose() const { return IsVerbose; }
    462 
    463   static bool classof(const DiagnosticInfo *DI) {
    464     return (DI->getKind() >= DK_FirstRemark &&
    465             DI->getKind() <= DK_LastRemark) ||
    466            (DI->getKind() >= DK_FirstMachineRemark &&
    467             DI->getKind() <= DK_LastMachineRemark);
    468   }
    469 
    470   bool isPassed() const {
    471     return (getKind() == DK_OptimizationRemark ||
    472             getKind() == DK_MachineOptimizationRemark);
    473   }
    474 
    475   bool isMissed() const {
    476     return (getKind() == DK_OptimizationRemarkMissed ||
    477             getKind() == DK_MachineOptimizationRemarkMissed);
    478   }
    479 
    480   bool isAnalysis() const {
    481     return (getKind() == DK_OptimizationRemarkAnalysis ||
    482             getKind() == DK_MachineOptimizationRemarkAnalysis);
    483   }
    484 
    485 protected:
    486   /// Name of the pass that triggers this report. If this matches the
    487   /// regular expression given in -Rpass=regexp, then the remark will
    488   /// be emitted.
    489   const char *PassName;
    490 
    491   /// Textual identifier for the remark (single-word, camel-case). Can be used
    492   /// by external tools reading the YAML output file for optimization remarks to
    493   /// identify the remark.
    494   StringRef RemarkName;
    495 
    496   /// If profile information is available, this is the number of times the
    497   /// corresponding code was executed in a profile instrumentation run.
    498   Optional<uint64_t> Hotness;
    499 
    500   /// Arguments collected via the streaming interface.
    501   SmallVector<Argument, 4> Args;
    502 
    503   /// The remark is expected to be noisy.
    504   bool IsVerbose = false;
    505 
    506   /// \brief If positive, the index of the first argument that only appear in
    507   /// the optimization records and not in the remark printed in the compiler
    508   /// output.
    509   int FirstExtraArgIndex = -1;
    510 
    511   friend struct yaml::MappingTraits<DiagnosticInfoOptimizationBase *>;
    512 };
    513 
    514 /// \brief Common features for diagnostics dealing with optimization remarks
    515 /// that are used by IR passes.
    516 class DiagnosticInfoIROptimization : public DiagnosticInfoOptimizationBase {
    517 public:
    518   /// \p PassName is the name of the pass emitting this diagnostic. \p
    519   /// RemarkName is a textual identifier for the remark (single-word,
    520   /// camel-case). \p Fn is the function where the diagnostic is being emitted.
    521   /// \p Loc is the location information to use in the diagnostic. If line table
    522   /// information is available, the diagnostic will include the source code
    523   /// location. \p CodeRegion is IR value (currently basic block) that the
    524   /// optimization operates on. This is currently used to provide run-time
    525   /// hotness information with PGO.
    526   DiagnosticInfoIROptimization(enum DiagnosticKind Kind,
    527                                enum DiagnosticSeverity Severity,
    528                                const char *PassName, StringRef RemarkName,
    529                                const Function &Fn,
    530                                const DiagnosticLocation &Loc,
    531                                const Value *CodeRegion = nullptr)
    532       : DiagnosticInfoOptimizationBase(Kind, Severity, PassName, RemarkName, Fn,
    533                                        Loc),
    534         CodeRegion(CodeRegion) {}
    535 
    536   /// \brief This is ctor variant allows a pass to build an optimization remark
    537   /// from an existing remark.
    538   ///
    539   /// This is useful when a transformation pass (e.g LV) wants to emit a remark
    540   /// (\p Orig) generated by one of its analyses (e.g. LAA) as its own analysis
    541   /// remark.  The string \p Prepend will be emitted before the original
    542   /// message.
    543   DiagnosticInfoIROptimization(const char *PassName, StringRef Prepend,
    544                                const DiagnosticInfoIROptimization &Orig)
    545       : DiagnosticInfoOptimizationBase(
    546             (DiagnosticKind)Orig.getKind(), Orig.getSeverity(), PassName,
    547             Orig.RemarkName, Orig.getFunction(), Orig.getLocation()),
    548         CodeRegion(Orig.getCodeRegion()) {
    549     *this << Prepend;
    550     std::copy(Orig.Args.begin(), Orig.Args.end(), std::back_inserter(Args));
    551   }
    552 
    553   /// Legacy interface.
    554   /// \p PassName is the name of the pass emitting this diagnostic.
    555   /// \p Fn is the function where the diagnostic is being emitted. \p Loc is
    556   /// the location information to use in the diagnostic. If line table
    557   /// information is available, the diagnostic will include the source code
    558   /// location. \p Msg is the message to show. Note that this class does not
    559   /// copy this message, so this reference must be valid for the whole life time
    560   /// of the diagnostic.
    561   DiagnosticInfoIROptimization(enum DiagnosticKind Kind,
    562                                enum DiagnosticSeverity Severity,
    563                                const char *PassName, const Function &Fn,
    564                                const DiagnosticLocation &Loc, const Twine &Msg)
    565       : DiagnosticInfoOptimizationBase(Kind, Severity, PassName, "", Fn, Loc) {
    566     *this << Msg.str();
    567   }
    568 
    569   const Value *getCodeRegion() const { return CodeRegion; }
    570 
    571   static bool classof(const DiagnosticInfo *DI) {
    572     return DI->getKind() >= DK_FirstRemark && DI->getKind() <= DK_LastRemark;
    573   }
    574 
    575 private:
    576   /// The IR value (currently basic block) that the optimization operates on.
    577   /// This is currently used to provide run-time hotness information with PGO.
    578   const Value *CodeRegion;
    579 };
    580 
    581 /// Diagnostic information for applied optimization remarks.
    582 class OptimizationRemark : public DiagnosticInfoIROptimization {
    583 public:
    584   /// \p PassName is the name of the pass emitting this diagnostic. If this name
    585   /// matches the regular expression given in -Rpass=, then the diagnostic will
    586   /// be emitted. \p RemarkName is a textual identifier for the remark (single-
    587   /// word, camel-case). \p Loc is the debug location and \p CodeRegion is the
    588   /// region that the optimization operates on (currently only block is
    589   /// supported).
    590   OptimizationRemark(const char *PassName, StringRef RemarkName,
    591                      const DiagnosticLocation &Loc, const Value *CodeRegion);
    592 
    593   /// Same as above, but the debug location and code region are derived from \p
    594   /// Instr.
    595   OptimizationRemark(const char *PassName, StringRef RemarkName,
    596                      const Instruction *Inst);
    597 
    598   /// Same as above, but the debug location and code region are derived from \p
    599   /// Func.
    600   OptimizationRemark(const char *PassName, StringRef RemarkName,
    601                      const Function *Func);
    602 
    603   static bool classof(const DiagnosticInfo *DI) {
    604     return DI->getKind() == DK_OptimizationRemark;
    605   }
    606 
    607   static bool isEnabled(StringRef PassName);
    608 
    609   /// \see DiagnosticInfoOptimizationBase::isEnabled.
    610   bool isEnabled() const override { return isEnabled(getPassName()); }
    611 
    612 private:
    613   /// This is deprecated now and only used by the function API below.
    614   /// \p PassName is the name of the pass emitting this diagnostic. If
    615   /// this name matches the regular expression given in -Rpass=, then the
    616   /// diagnostic will be emitted. \p Fn is the function where the diagnostic
    617   /// is being emitted. \p Loc is the location information to use in the
    618   /// diagnostic. If line table information is available, the diagnostic
    619   /// will include the source code location. \p Msg is the message to show.
    620   /// Note that this class does not copy this message, so this reference
    621   /// must be valid for the whole life time of the diagnostic.
    622   OptimizationRemark(const char *PassName, const Function &Fn,
    623                      const DiagnosticLocation &Loc, const Twine &Msg)
    624       : DiagnosticInfoIROptimization(DK_OptimizationRemark, DS_Remark, PassName,
    625                                      Fn, Loc, Msg) {}
    626 
    627   friend void emitOptimizationRemark(LLVMContext &Ctx, const char *PassName,
    628                                      const Function &Fn,
    629                                      const DiagnosticLocation &Loc,
    630                                      const Twine &Msg);
    631 };
    632 
    633 /// Diagnostic information for missed-optimization remarks.
    634 class OptimizationRemarkMissed : public DiagnosticInfoIROptimization {
    635 public:
    636   /// \p PassName is the name of the pass emitting this diagnostic. If this name
    637   /// matches the regular expression given in -Rpass-missed=, then the
    638   /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
    639   /// remark (single-word, camel-case). \p Loc is the debug location and \p
    640   /// CodeRegion is the region that the optimization operates on (currently only
    641   /// block is supported).
    642   OptimizationRemarkMissed(const char *PassName, StringRef RemarkName,
    643                            const DiagnosticLocation &Loc,
    644                            const Value *CodeRegion);
    645 
    646   /// \brief Same as above but \p Inst is used to derive code region and debug
    647   /// location.
    648   OptimizationRemarkMissed(const char *PassName, StringRef RemarkName,
    649                            const Instruction *Inst);
    650 
    651   static bool classof(const DiagnosticInfo *DI) {
    652     return DI->getKind() == DK_OptimizationRemarkMissed;
    653   }
    654 
    655   static bool isEnabled(StringRef PassName);
    656 
    657   /// \see DiagnosticInfoOptimizationBase::isEnabled.
    658   bool isEnabled() const override { return isEnabled(getPassName()); }
    659 
    660 private:
    661   /// This is deprecated now and only used by the function API below.
    662   /// \p PassName is the name of the pass emitting this diagnostic. If
    663   /// this name matches the regular expression given in -Rpass-missed=, then the
    664   /// diagnostic will be emitted. \p Fn is the function where the diagnostic
    665   /// is being emitted. \p Loc is the location information to use in the
    666   /// diagnostic. If line table information is available, the diagnostic
    667   /// will include the source code location. \p Msg is the message to show.
    668   /// Note that this class does not copy this message, so this reference
    669   /// must be valid for the whole life time of the diagnostic.
    670   OptimizationRemarkMissed(const char *PassName, const Function &Fn,
    671                            const DiagnosticLocation &Loc, const Twine &Msg)
    672       : DiagnosticInfoIROptimization(DK_OptimizationRemarkMissed, DS_Remark,
    673                                      PassName, Fn, Loc, Msg) {}
    674 
    675   friend void emitOptimizationRemarkMissed(LLVMContext &Ctx,
    676                                            const char *PassName,
    677                                            const Function &Fn,
    678                                            const DiagnosticLocation &Loc,
    679                                            const Twine &Msg);
    680 };
    681 
    682 /// Diagnostic information for optimization analysis remarks.
    683 class OptimizationRemarkAnalysis : public DiagnosticInfoIROptimization {
    684 public:
    685   /// \p PassName is the name of the pass emitting this diagnostic. If this name
    686   /// matches the regular expression given in -Rpass-analysis=, then the
    687   /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
    688   /// remark (single-word, camel-case). \p Loc is the debug location and \p
    689   /// CodeRegion is the region that the optimization operates on (currently only
    690   /// block is supported).
    691   OptimizationRemarkAnalysis(const char *PassName, StringRef RemarkName,
    692                              const DiagnosticLocation &Loc,
    693                              const Value *CodeRegion);
    694 
    695   /// \brief This is ctor variant allows a pass to build an optimization remark
    696   /// from an existing remark.
    697   ///
    698   /// This is useful when a transformation pass (e.g LV) wants to emit a remark
    699   /// (\p Orig) generated by one of its analyses (e.g. LAA) as its own analysis
    700   /// remark.  The string \p Prepend will be emitted before the original
    701   /// message.
    702   OptimizationRemarkAnalysis(const char *PassName, StringRef Prepend,
    703                              const OptimizationRemarkAnalysis &Orig)
    704       : DiagnosticInfoIROptimization(PassName, Prepend, Orig) {}
    705 
    706   /// \brief Same as above but \p Inst is used to derive code region and debug
    707   /// location.
    708   OptimizationRemarkAnalysis(const char *PassName, StringRef RemarkName,
    709                              const Instruction *Inst);
    710 
    711   static bool classof(const DiagnosticInfo *DI) {
    712     return DI->getKind() == DK_OptimizationRemarkAnalysis;
    713   }
    714 
    715   static bool isEnabled(StringRef PassName);
    716 
    717   /// \see DiagnosticInfoOptimizationBase::isEnabled.
    718   bool isEnabled() const override {
    719     return shouldAlwaysPrint() || isEnabled(getPassName());
    720   }
    721 
    722   static const char *AlwaysPrint;
    723 
    724   bool shouldAlwaysPrint() const { return getPassName() == AlwaysPrint; }
    725 
    726 protected:
    727   OptimizationRemarkAnalysis(enum DiagnosticKind Kind, const char *PassName,
    728                              const Function &Fn, const DiagnosticLocation &Loc,
    729                              const Twine &Msg)
    730       : DiagnosticInfoIROptimization(Kind, DS_Remark, PassName, Fn, Loc, Msg) {}
    731 
    732   OptimizationRemarkAnalysis(enum DiagnosticKind Kind, const char *PassName,
    733                              StringRef RemarkName,
    734                              const DiagnosticLocation &Loc,
    735                              const Value *CodeRegion);
    736 
    737 private:
    738   /// This is deprecated now and only used by the function API below.
    739   /// \p PassName is the name of the pass emitting this diagnostic. If
    740   /// this name matches the regular expression given in -Rpass-analysis=, then
    741   /// the diagnostic will be emitted. \p Fn is the function where the diagnostic
    742   /// is being emitted. \p Loc is the location information to use in the
    743   /// diagnostic. If line table information is available, the diagnostic will
    744   /// include the source code location. \p Msg is the message to show. Note that
    745   /// this class does not copy this message, so this reference must be valid for
    746   /// the whole life time of the diagnostic.
    747   OptimizationRemarkAnalysis(const char *PassName, const Function &Fn,
    748                              const DiagnosticLocation &Loc, const Twine &Msg)
    749       : DiagnosticInfoIROptimization(DK_OptimizationRemarkAnalysis, DS_Remark,
    750                                      PassName, Fn, Loc, Msg) {}
    751 
    752   friend void emitOptimizationRemarkAnalysis(LLVMContext &Ctx,
    753                                              const char *PassName,
    754                                              const Function &Fn,
    755                                              const DiagnosticLocation &Loc,
    756                                              const Twine &Msg);
    757 };
    758 
    759 /// Diagnostic information for optimization analysis remarks related to
    760 /// floating-point non-commutativity.
    761 class OptimizationRemarkAnalysisFPCommute : public OptimizationRemarkAnalysis {
    762 public:
    763   /// \p PassName is the name of the pass emitting this diagnostic. If this name
    764   /// matches the regular expression given in -Rpass-analysis=, then the
    765   /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
    766   /// remark (single-word, camel-case). \p Loc is the debug location and \p
    767   /// CodeRegion is the region that the optimization operates on (currently only
    768   /// block is supported). The front-end will append its own message related to
    769   /// options that address floating-point non-commutativity.
    770   OptimizationRemarkAnalysisFPCommute(const char *PassName,
    771                                       StringRef RemarkName,
    772                                       const DiagnosticLocation &Loc,
    773                                       const Value *CodeRegion)
    774       : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisFPCommute,
    775                                    PassName, RemarkName, Loc, CodeRegion) {}
    776 
    777   static bool classof(const DiagnosticInfo *DI) {
    778     return DI->getKind() == DK_OptimizationRemarkAnalysisFPCommute;
    779   }
    780 
    781 private:
    782   /// This is deprecated now and only used by the function API below.
    783   /// \p PassName is the name of the pass emitting this diagnostic. If
    784   /// this name matches the regular expression given in -Rpass-analysis=, then
    785   /// the diagnostic will be emitted. \p Fn is the function where the diagnostic
    786   /// is being emitted. \p Loc is the location information to use in the
    787   /// diagnostic. If line table information is available, the diagnostic will
    788   /// include the source code location. \p Msg is the message to show. The
    789   /// front-end will append its own message related to options that address
    790   /// floating-point non-commutativity. Note that this class does not copy this
    791   /// message, so this reference must be valid for the whole life time of the
    792   /// diagnostic.
    793   OptimizationRemarkAnalysisFPCommute(const char *PassName, const Function &Fn,
    794                                       const DiagnosticLocation &Loc,
    795                                       const Twine &Msg)
    796       : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisFPCommute,
    797                                    PassName, Fn, Loc, Msg) {}
    798 
    799   friend void emitOptimizationRemarkAnalysisFPCommute(
    800       LLVMContext &Ctx, const char *PassName, const Function &Fn,
    801       const DiagnosticLocation &Loc, const Twine &Msg);
    802 };
    803 
    804 /// Diagnostic information for optimization analysis remarks related to
    805 /// pointer aliasing.
    806 class OptimizationRemarkAnalysisAliasing : public OptimizationRemarkAnalysis {
    807 public:
    808   /// \p PassName is the name of the pass emitting this diagnostic. If this name
    809   /// matches the regular expression given in -Rpass-analysis=, then the
    810   /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
    811   /// remark (single-word, camel-case). \p Loc is the debug location and \p
    812   /// CodeRegion is the region that the optimization operates on (currently only
    813   /// block is supported). The front-end will append its own message related to
    814   /// options that address pointer aliasing legality.
    815   OptimizationRemarkAnalysisAliasing(const char *PassName, StringRef RemarkName,
    816                                      const DiagnosticLocation &Loc,
    817                                      const Value *CodeRegion)
    818       : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisAliasing,
    819                                    PassName, RemarkName, Loc, CodeRegion) {}
    820 
    821   static bool classof(const DiagnosticInfo *DI) {
    822     return DI->getKind() == DK_OptimizationRemarkAnalysisAliasing;
    823   }
    824 
    825 private:
    826   /// This is deprecated now and only used by the function API below.
    827   /// \p PassName is the name of the pass emitting this diagnostic. If
    828   /// this name matches the regular expression given in -Rpass-analysis=, then
    829   /// the diagnostic will be emitted. \p Fn is the function where the diagnostic
    830   /// is being emitted. \p Loc is the location information to use in the
    831   /// diagnostic. If line table information is available, the diagnostic will
    832   /// include the source code location. \p Msg is the message to show. The
    833   /// front-end will append its own message related to options that address
    834   /// pointer aliasing legality. Note that this class does not copy this
    835   /// message, so this reference must be valid for the whole life time of the
    836   /// diagnostic.
    837   OptimizationRemarkAnalysisAliasing(const char *PassName, const Function &Fn,
    838                                      const DiagnosticLocation &Loc,
    839                                      const Twine &Msg)
    840       : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisAliasing,
    841                                    PassName, Fn, Loc, Msg) {}
    842 
    843   friend void emitOptimizationRemarkAnalysisAliasing(
    844       LLVMContext &Ctx, const char *PassName, const Function &Fn,
    845       const DiagnosticLocation &Loc, const Twine &Msg);
    846 };
    847 
    848 /// Diagnostic information for machine IR parser.
    849 class DiagnosticInfoMIRParser : public DiagnosticInfo {
    850   const SMDiagnostic &Diagnostic;
    851 
    852 public:
    853   DiagnosticInfoMIRParser(DiagnosticSeverity Severity,
    854                           const SMDiagnostic &Diagnostic)
    855       : DiagnosticInfo(DK_MIRParser, Severity), Diagnostic(Diagnostic) {}
    856 
    857   const SMDiagnostic &getDiagnostic() const { return Diagnostic; }
    858 
    859   void print(DiagnosticPrinter &DP) const override;
    860 
    861   static bool classof(const DiagnosticInfo *DI) {
    862     return DI->getKind() == DK_MIRParser;
    863   }
    864 };
    865 
    866 /// Diagnostic information for ISel fallback path.
    867 class DiagnosticInfoISelFallback : public DiagnosticInfo {
    868   /// The function that is concerned by this diagnostic.
    869   const Function &Fn;
    870 
    871 public:
    872   DiagnosticInfoISelFallback(const Function &Fn,
    873                              DiagnosticSeverity Severity = DS_Warning)
    874       : DiagnosticInfo(DK_ISelFallback, Severity), Fn(Fn) {}
    875 
    876   const Function &getFunction() const { return Fn; }
    877 
    878   void print(DiagnosticPrinter &DP) const override;
    879 
    880   static bool classof(const DiagnosticInfo *DI) {
    881     return DI->getKind() == DK_ISelFallback;
    882   }
    883 };
    884 
    885 // Create wrappers for C Binding types (see CBindingWrapping.h).
    886 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DiagnosticInfo, LLVMDiagnosticInfoRef)
    887 
    888 /// \brief Legacy interface to emit an optimization-applied message.  Use
    889 /// (Machine)OptimizationRemarkEmitter instead.
    890 ///
    891 /// \p PassName is the name of the pass emitting the message. If -Rpass= is
    892 /// given and \p PassName matches the regular expression in -Rpass, then the
    893 /// remark will be emitted. \p Fn is the function triggering the remark, \p Loc
    894 /// is the debug location where the diagnostic is generated. \p Msg is the
    895 /// message string to use.
    896 void emitOptimizationRemark(LLVMContext &Ctx, const char *PassName,
    897                             const Function &Fn, const DiagnosticLocation &Loc,
    898                             const Twine &Msg);
    899 
    900 /// \brief Legacy interface to emit an optimization-missed message.  Use
    901 /// (Machine)OptimizationRemarkEmitter instead.
    902 ///
    903 /// \p PassName is the name of the pass emitting the message. If -Rpass-missed=
    904 /// is given and \p PassName matches the regular expression in -Rpass, then the
    905 /// remark will be emitted. \p Fn is the function triggering the remark, \p Loc
    906 /// is the debug location where the diagnostic is generated. \p Msg is the
    907 /// message string to use.
    908 void emitOptimizationRemarkMissed(LLVMContext &Ctx, const char *PassName,
    909                                   const Function &Fn,
    910                                   const DiagnosticLocation &Loc,
    911                                   const Twine &Msg);
    912 
    913 /// \brief Legacy interface to emit an optimization analysis remark message.
    914 /// Use (Machine)OptimizationRemarkEmitter instead.
    915 ///
    916 /// \p PassName is the name of the pass emitting the message. If
    917 /// -Rpass-analysis= is given and \p PassName matches the regular expression in
    918 /// -Rpass, then the remark will be emitted. \p Fn is the function triggering
    919 /// the remark, \p Loc is the debug location where the diagnostic is
    920 /// generated. \p Msg is the message string to use.
    921 void emitOptimizationRemarkAnalysis(LLVMContext &Ctx, const char *PassName,
    922                                     const Function &Fn,
    923                                     const DiagnosticLocation &Loc,
    924                                     const Twine &Msg);
    925 
    926 /// \brief Legacy interface to emit an optimization analysis remark related to
    927 /// messages about floating-point non-commutativity.  Use
    928 /// (Machine)OptimizationRemarkEmitter instead.
    929 ///
    930 /// \p PassName is the name of the pass emitting the message. If
    931 /// -Rpass-analysis= is given and \p PassName matches the regular expression in
    932 /// -Rpass, then the remark will be emitted. \p Fn is the function triggering
    933 /// the remark, \p Loc is the debug location where the diagnostic is
    934 /// generated. \p Msg is the message string to use.
    935 void emitOptimizationRemarkAnalysisFPCommute(LLVMContext &Ctx,
    936                                              const char *PassName,
    937                                              const Function &Fn,
    938                                              const DiagnosticLocation &Loc,
    939                                              const Twine &Msg);
    940 
    941 /// \brief Legacy interface to emit an optimization analysis remark related to
    942 /// messages about pointer aliasing.  Use (Machine)OptimizationRemarkEmitter
    943 /// instead.
    944 ///
    945 /// \p PassName is the name of the pass emitting the message.
    946 /// If -Rpass-analysis= is given and \p PassName matches the regular expression
    947 /// in -Rpass, then the remark will be emitted. \p Fn is the function triggering
    948 /// the remark, \p Loc is the debug location where the diagnostic is generated.
    949 /// \p Msg is the message string to use.
    950 void emitOptimizationRemarkAnalysisAliasing(LLVMContext &Ctx,
    951                                             const char *PassName,
    952                                             const Function &Fn,
    953                                             const DiagnosticLocation &Loc,
    954                                             const Twine &Msg);
    955 
    956 /// Diagnostic information for optimization failures.
    957 class DiagnosticInfoOptimizationFailure : public DiagnosticInfoIROptimization {
    958 public:
    959   /// \p Fn is the function where the diagnostic is being emitted. \p Loc is
    960   /// the location information to use in the diagnostic. If line table
    961   /// information is available, the diagnostic will include the source code
    962   /// location. \p Msg is the message to show. Note that this class does not
    963   /// copy this message, so this reference must be valid for the whole life time
    964   /// of the diagnostic.
    965   DiagnosticInfoOptimizationFailure(const Function &Fn,
    966                                     const DiagnosticLocation &Loc,
    967                                     const Twine &Msg)
    968       : DiagnosticInfoIROptimization(DK_OptimizationFailure, DS_Warning,
    969                                      nullptr, Fn, Loc, Msg) {}
    970 
    971   /// \p PassName is the name of the pass emitting this diagnostic.  \p
    972   /// RemarkName is a textual identifier for the remark (single-word,
    973   /// camel-case).  \p Loc is the debug location and \p CodeRegion is the
    974   /// region that the optimization operates on (currently basic block is
    975   /// supported).
    976   DiagnosticInfoOptimizationFailure(const char *PassName, StringRef RemarkName,
    977                                     const DiagnosticLocation &Loc,
    978                                     const Value *CodeRegion);
    979 
    980   static bool classof(const DiagnosticInfo *DI) {
    981     return DI->getKind() == DK_OptimizationFailure;
    982   }
    983 
    984   /// \see DiagnosticInfoOptimizationBase::isEnabled.
    985   bool isEnabled() const override;
    986 };
    987 
    988 /// Diagnostic information for unsupported feature in backend.
    989 class DiagnosticInfoUnsupported : public DiagnosticInfoWithLocationBase {
    990 private:
    991   Twine Msg;
    992 
    993 public:
    994   /// \p Fn is the function where the diagnostic is being emitted. \p Loc is
    995   /// the location information to use in the diagnostic. If line table
    996   /// information is available, the diagnostic will include the source code
    997   /// location. \p Msg is the message to show. Note that this class does not
    998   /// copy this message, so this reference must be valid for the whole life time
    999   /// of the diagnostic.
   1000   DiagnosticInfoUnsupported(
   1001       const Function &Fn, const Twine &Msg,
   1002       const DiagnosticLocation &Loc = DiagnosticLocation(),
   1003       DiagnosticSeverity Severity = DS_Error)
   1004       : DiagnosticInfoWithLocationBase(DK_Unsupported, Severity, Fn, Loc),
   1005         Msg(Msg) {}
   1006 
   1007   static bool classof(const DiagnosticInfo *DI) {
   1008     return DI->getKind() == DK_Unsupported;
   1009   }
   1010 
   1011   const Twine &getMessage() const { return Msg; }
   1012 
   1013   void print(DiagnosticPrinter &DP) const override;
   1014 };
   1015 
   1016 } // end namespace llvm
   1017 
   1018 #endif // LLVM_IR_DIAGNOSTICINFO_H
   1019