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/ADT/None.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 "llvm-c/Types.h"
     27 #include <functional>
     28 #include <algorithm>
     29 #include <cstdint>
     30 #include <iterator>
     31 #include <string>
     32 
     33 namespace llvm {
     34 
     35 // Forward declarations.
     36 class DiagnosticPrinter;
     37 class Function;
     38 class Instruction;
     39 class LLVMContext;
     40 class Module;
     41 class SMDiagnostic;
     42 
     43 /// \brief Defines the different supported severity of a diagnostic.
     44 enum DiagnosticSeverity : char {
     45   DS_Error,
     46   DS_Warning,
     47   DS_Remark,
     48   // A note attaches additional information to one of the previous diagnostic
     49   // types.
     50   DS_Note
     51 };
     52 
     53 /// \brief Defines the different supported kind of a diagnostic.
     54 /// This enum should be extended with a new ID for each added concrete subclass.
     55 enum DiagnosticKind {
     56   DK_InlineAsm,
     57   DK_ResourceLimit,
     58   DK_StackSize,
     59   DK_Linker,
     60   DK_DebugMetadataVersion,
     61   DK_DebugMetadataInvalid,
     62   DK_ISelFallback,
     63   DK_SampleProfile,
     64   DK_OptimizationRemark,
     65   DK_OptimizationRemarkMissed,
     66   DK_OptimizationRemarkAnalysis,
     67   DK_OptimizationRemarkAnalysisFPCommute,
     68   DK_OptimizationRemarkAnalysisAliasing,
     69   DK_OptimizationFailure,
     70   DK_FirstRemark = DK_OptimizationRemark,
     71   DK_LastRemark = DK_OptimizationFailure,
     72   DK_MachineOptimizationRemark,
     73   DK_MachineOptimizationRemarkMissed,
     74   DK_MachineOptimizationRemarkAnalysis,
     75   DK_FirstMachineRemark = DK_MachineOptimizationRemark,
     76   DK_LastMachineRemark = DK_MachineOptimizationRemarkAnalysis,
     77   DK_MIRParser,
     78   DK_PGOProfile,
     79   DK_Unsupported,
     80   DK_FirstPluginKind
     81 };
     82 
     83 /// \brief Get the next available kind ID for a plugin diagnostic.
     84 /// Each time this function is called, it returns a different number.
     85 /// Therefore, a plugin that wants to "identify" its own classes
     86 /// with a dynamic identifier, just have to use this method to get a new ID
     87 /// and assign it to each of its classes.
     88 /// The returned ID will be greater than or equal to DK_FirstPluginKind.
     89 /// Thus, the plugin identifiers will not conflict with the
     90 /// DiagnosticKind values.
     91 int getNextAvailablePluginDiagnosticKind();
     92 
     93 /// \brief This is the base abstract class for diagnostic reporting in
     94 /// the backend.
     95 /// The print method must be overloaded by the subclasses to print a
     96 /// user-friendly message in the client of the backend (let us call it a
     97 /// frontend).
     98 class DiagnosticInfo {
     99 private:
    100   /// Kind defines the kind of report this is about.
    101   const /* DiagnosticKind */ int Kind;
    102   /// Severity gives the severity of the diagnostic.
    103   const DiagnosticSeverity Severity;
    104 
    105 public:
    106   DiagnosticInfo(/* DiagnosticKind */ int Kind, DiagnosticSeverity Severity)
    107       : Kind(Kind), Severity(Severity) {}
    108 
    109   virtual ~DiagnosticInfo() = default;
    110 
    111   /* DiagnosticKind */ int getKind() const { return Kind; }
    112   DiagnosticSeverity getSeverity() const { return Severity; }
    113 
    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;
    121 };
    122 
    123 typedef std::function<void(const DiagnosticInfo &)> DiagnosticHandlerFunction;
    124 
    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;
    131   /// Message to be reported.
    132   const Twine &MsgStr;
    133   /// Optional origin of the problem.
    134   const Instruction *Instr;
    135 
    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), LocCookie(0), MsgStr(MsgStr),
    143         Instr(nullptr) {}
    144 
    145   /// \p LocCookie if non-zero gives the line number for this report.
    146   /// \p MsgStr gives the message.
    147   /// This class does not copy \p MsgStr, therefore the reference must be valid
    148   /// for the whole life time of the Diagnostic.
    149   DiagnosticInfoInlineAsm(unsigned LocCookie, const Twine &MsgStr,
    150                           DiagnosticSeverity Severity = DS_Error)
    151       : DiagnosticInfo(DK_InlineAsm, Severity), LocCookie(LocCookie),
    152         MsgStr(MsgStr), Instr(nullptr) {}
    153 
    154   /// \p Instr gives the original instruction that triggered the diagnostic.
    155   /// \p MsgStr gives the message.
    156   /// This class does not copy \p MsgStr, therefore the reference must be valid
    157   /// for the whole life time of the Diagnostic.
    158   /// Same for \p I.
    159   DiagnosticInfoInlineAsm(const Instruction &I, const Twine &MsgStr,
    160                           DiagnosticSeverity Severity = DS_Error);
    161 
    162   unsigned getLocCookie() const { return LocCookie; }
    163   const Twine &getMsgStr() const { return MsgStr; }
    164   const Instruction *getInstruction() const { return Instr; }
    165 
    166   /// \see DiagnosticInfo::print.
    167   void print(DiagnosticPrinter &DP) const override;
    168 
    169   static bool classof(const DiagnosticInfo *DI) {
    170     return DI->getKind() == DK_InlineAsm;
    171   }
    172 };
    173 
    174 /// Diagnostic information for stack size etc. reporting.
    175 /// This is basically a function and a size.
    176 class DiagnosticInfoResourceLimit : public DiagnosticInfo {
    177 private:
    178   /// The function that is concerned by this resource limit diagnostic.
    179   const Function &Fn;
    180 
    181   /// Description of the resource type (e.g. stack size)
    182   const char *ResourceName;
    183 
    184   /// The computed size usage
    185   uint64_t ResourceSize;
    186 
    187   // Threshould passed
    188   uint64_t ResourceLimit;
    189 
    190 public:
    191   /// \p The function that is concerned by this stack size diagnostic.
    192   /// \p The computed stack size.
    193   DiagnosticInfoResourceLimit(const Function &Fn,
    194                               const char *ResourceName,
    195                               uint64_t ResourceSize,
    196                               DiagnosticSeverity Severity = DS_Warning,
    197                               DiagnosticKind Kind = DK_ResourceLimit,
    198                               uint64_t ResourceLimit = 0)
    199       : DiagnosticInfo(Kind, Severity),
    200         Fn(Fn),
    201         ResourceName(ResourceName),
    202         ResourceSize(ResourceSize),
    203         ResourceLimit(ResourceLimit) {}
    204 
    205   const Function &getFunction() const { return Fn; }
    206   const char *getResourceName() const { return ResourceName; }
    207   uint64_t getResourceSize() const { return ResourceSize; }
    208   uint64_t getResourceLimit() const { return ResourceLimit; }
    209 
    210   /// \see DiagnosticInfo::print.
    211   void print(DiagnosticPrinter &DP) const override;
    212 
    213   static bool classof(const DiagnosticInfo *DI) {
    214     return DI->getKind() == DK_ResourceLimit ||
    215            DI->getKind() == DK_StackSize;
    216   }
    217 };
    218 
    219 class DiagnosticInfoStackSize : public DiagnosticInfoResourceLimit {
    220 public:
    221   DiagnosticInfoStackSize(const Function &Fn,
    222                           uint64_t StackSize,
    223                           DiagnosticSeverity Severity = DS_Warning,
    224                           uint64_t StackLimit = 0)
    225     : DiagnosticInfoResourceLimit(Fn, "stack size", StackSize,
    226                                   Severity, DK_StackSize, StackLimit) {}
    227 
    228   uint64_t getStackSize() const { return getResourceSize(); }
    229   uint64_t getStackLimit() const { return getResourceLimit(); }
    230 
    231   static bool classof(const DiagnosticInfo *DI) {
    232     return DI->getKind() == DK_StackSize;
    233   }
    234 };
    235 
    236 /// Diagnostic information for debug metadata version reporting.
    237 /// This is basically a module and a version.
    238 class DiagnosticInfoDebugMetadataVersion : public DiagnosticInfo {
    239 private:
    240   /// The module that is concerned by this debug metadata version diagnostic.
    241   const Module &M;
    242   /// The actual metadata version.
    243   unsigned MetadataVersion;
    244 
    245 public:
    246   /// \p The module that is concerned by this debug metadata version diagnostic.
    247   /// \p The actual metadata version.
    248   DiagnosticInfoDebugMetadataVersion(const Module &M, unsigned MetadataVersion,
    249                           DiagnosticSeverity Severity = DS_Warning)
    250       : DiagnosticInfo(DK_DebugMetadataVersion, Severity), M(M),
    251         MetadataVersion(MetadataVersion) {}
    252 
    253   const Module &getModule() const { return M; }
    254   unsigned getMetadataVersion() const { return MetadataVersion; }
    255 
    256   /// \see DiagnosticInfo::print.
    257   void print(DiagnosticPrinter &DP) const override;
    258 
    259   static bool classof(const DiagnosticInfo *DI) {
    260     return DI->getKind() == DK_DebugMetadataVersion;
    261   }
    262 };
    263 
    264 /// Diagnostic information for stripping invalid debug metadata.
    265 class DiagnosticInfoIgnoringInvalidDebugMetadata : public DiagnosticInfo {
    266 private:
    267   /// The module that is concerned by this debug metadata version diagnostic.
    268   const Module &M;
    269 
    270 public:
    271   /// \p The module that is concerned by this debug metadata version diagnostic.
    272   DiagnosticInfoIgnoringInvalidDebugMetadata(
    273       const Module &M, DiagnosticSeverity Severity = DS_Warning)
    274       : DiagnosticInfo(DK_DebugMetadataVersion, Severity), M(M) {}
    275 
    276   const Module &getModule() const { return M; }
    277 
    278   /// \see DiagnosticInfo::print.
    279   void print(DiagnosticPrinter &DP) const override;
    280 
    281   static bool classof(const DiagnosticInfo *DI) {
    282     return DI->getKind() == DK_DebugMetadataInvalid;
    283   }
    284 };
    285 
    286 /// Diagnostic information for the sample profiler.
    287 class DiagnosticInfoSampleProfile : public DiagnosticInfo {
    288 public:
    289   DiagnosticInfoSampleProfile(StringRef FileName, unsigned LineNum,
    290                               const Twine &Msg,
    291                               DiagnosticSeverity Severity = DS_Error)
    292       : DiagnosticInfo(DK_SampleProfile, Severity), FileName(FileName),
    293         LineNum(LineNum), Msg(Msg) {}
    294   DiagnosticInfoSampleProfile(StringRef FileName, const Twine &Msg,
    295                               DiagnosticSeverity Severity = DS_Error)
    296       : DiagnosticInfo(DK_SampleProfile, Severity), FileName(FileName),
    297         LineNum(0), Msg(Msg) {}
    298   DiagnosticInfoSampleProfile(const Twine &Msg,
    299                               DiagnosticSeverity Severity = DS_Error)
    300       : DiagnosticInfo(DK_SampleProfile, Severity), LineNum(0), Msg(Msg) {}
    301 
    302   /// \see DiagnosticInfo::print.
    303   void print(DiagnosticPrinter &DP) const override;
    304 
    305   static bool classof(const DiagnosticInfo *DI) {
    306     return DI->getKind() == DK_SampleProfile;
    307   }
    308 
    309   StringRef getFileName() const { return FileName; }
    310   unsigned getLineNum() const { return LineNum; }
    311   const Twine &getMsg() const { return Msg; }
    312 
    313 private:
    314   /// Name of the input file associated with this diagnostic.
    315   StringRef FileName;
    316 
    317   /// Line number where the diagnostic occurred. If 0, no line number will
    318   /// be emitted in the message.
    319   unsigned LineNum;
    320 
    321   /// Message to report.
    322   const Twine &Msg;
    323 };
    324 
    325 /// Diagnostic information for the PGO profiler.
    326 class DiagnosticInfoPGOProfile : public DiagnosticInfo {
    327 public:
    328   DiagnosticInfoPGOProfile(const char *FileName, const Twine &Msg,
    329                            DiagnosticSeverity Severity = DS_Error)
    330       : DiagnosticInfo(DK_PGOProfile, Severity), FileName(FileName), Msg(Msg) {}
    331 
    332   /// \see DiagnosticInfo::print.
    333   void print(DiagnosticPrinter &DP) const override;
    334 
    335   static bool classof(const DiagnosticInfo *DI) {
    336     return DI->getKind() == DK_PGOProfile;
    337   }
    338 
    339   const char *getFileName() const { return FileName; }
    340   const Twine &getMsg() const { return Msg; }
    341 
    342 private:
    343   /// Name of the input file associated with this diagnostic.
    344   const char *FileName;
    345 
    346   /// Message to report.
    347   const Twine &Msg;
    348 };
    349 
    350 class DiagnosticLocation {
    351   StringRef Filename;
    352   unsigned Line = 0;
    353   unsigned Column = 0;
    354 public:
    355   DiagnosticLocation() {}
    356   DiagnosticLocation(const DebugLoc &DL);
    357   DiagnosticLocation(const DISubprogram *SP);
    358 
    359   bool isValid() const { return !Filename.empty(); }
    360   StringRef getFilename() const { return Filename; }
    361   unsigned getLine() const { return Line; }
    362   unsigned getColumn() const { return Column; }
    363 };
    364 
    365 /// Common features for diagnostics with an associated location.
    366 class DiagnosticInfoWithLocationBase : public DiagnosticInfo {
    367 public:
    368   /// \p Fn is the function where the diagnostic is being emitted. \p Loc is
    369   /// the location information to use in the diagnostic.
    370   DiagnosticInfoWithLocationBase(enum DiagnosticKind Kind,
    371                                  enum DiagnosticSeverity Severity,
    372                                  const Function &Fn,
    373                                  const DiagnosticLocation &Loc)
    374       : DiagnosticInfo(Kind, Severity), Fn(Fn), Loc(Loc) {}
    375 
    376   /// Return true if location information is available for this diagnostic.
    377   bool isLocationAvailable() const { return Loc.isValid(); }
    378 
    379   /// Return a string with the location information for this diagnostic
    380   /// in the format "file:line:col". If location information is not available,
    381   /// it returns "<unknown>:0:0".
    382   const std::string getLocationStr() const;
    383 
    384   /// Return location information for this diagnostic in three parts:
    385   /// the source file name, line number and column.
    386   void getLocation(StringRef *Filename, unsigned *Line, unsigned *Column) const;
    387 
    388   const Function &getFunction() const { return Fn; }
    389   DiagnosticLocation getLocation() const { return Loc; }
    390 
    391 private:
    392   /// Function where this diagnostic is triggered.
    393   const Function &Fn;
    394 
    395   /// Debug location where this diagnostic is triggered.
    396   DiagnosticLocation Loc;
    397 };
    398 
    399 /// \brief Common features for diagnostics dealing with optimization remarks
    400 /// that are used by both IR and MIR passes.
    401 class DiagnosticInfoOptimizationBase : public DiagnosticInfoWithLocationBase {
    402 public:
    403   /// \brief Used to set IsVerbose via the stream interface.
    404   struct setIsVerbose {};
    405 
    406   /// \brief When an instance of this is inserted into the stream, the arguments
    407   /// following will not appear in the remark printed in the compiler output
    408   /// (-Rpass) but only in the optimization record file
    409   /// (-fsave-optimization-record).
    410   struct setExtraArgs {};
    411 
    412   /// \brief Used in the streaming interface as the general argument type.  It
    413   /// internally converts everything into a key-value pair.
    414   struct Argument {
    415     StringRef Key;
    416     std::string Val;
    417     // If set, the debug location corresponding to the value.
    418     DiagnosticLocation Loc;
    419 
    420     explicit Argument(StringRef Str = "") : Key("String"), Val(Str) {}
    421     Argument(StringRef Key, const Value *V);
    422     Argument(StringRef Key, const Type *T);
    423     Argument(StringRef Key, int N);
    424     Argument(StringRef Key, unsigned N);
    425     Argument(StringRef Key, bool B) : Key(Key), Val(B ? "true" : "false") {}
    426   };
    427 
    428   /// \p PassName is the name of the pass emitting this diagnostic. \p
    429   /// RemarkName is a textual identifier for the remark (single-word,
    430   /// camel-case). \p Fn is the function where the diagnostic is being emitted.
    431   /// \p Loc is the location information to use in the diagnostic. If line table
    432   /// information is available, the diagnostic will include the source code
    433   /// location.
    434   DiagnosticInfoOptimizationBase(enum DiagnosticKind Kind,
    435                                  enum DiagnosticSeverity Severity,
    436                                  const char *PassName, StringRef RemarkName,
    437                                  const Function &Fn,
    438                                  const DiagnosticLocation &Loc)
    439       : DiagnosticInfoWithLocationBase(Kind, Severity, Fn, Loc),
    440         PassName(PassName), RemarkName(RemarkName) {}
    441 
    442   DiagnosticInfoOptimizationBase &operator<<(StringRef S);
    443   DiagnosticInfoOptimizationBase &operator<<(Argument A);
    444   DiagnosticInfoOptimizationBase &operator<<(setIsVerbose V);
    445   DiagnosticInfoOptimizationBase &operator<<(setExtraArgs EA);
    446 
    447   /// \see DiagnosticInfo::print.
    448   void print(DiagnosticPrinter &DP) const override;
    449 
    450   /// Return true if this optimization remark is enabled by one of
    451   /// of the LLVM command line flags (-pass-remarks, -pass-remarks-missed,
    452   /// or -pass-remarks-analysis). Note that this only handles the LLVM
    453   /// flags. We cannot access Clang flags from here (they are handled
    454   /// in BackendConsumer::OptimizationRemarkHandler).
    455   virtual bool isEnabled() const = 0;
    456 
    457   StringRef getPassName() const { return PassName; }
    458   std::string getMsg() const;
    459   Optional<uint64_t> getHotness() const { return Hotness; }
    460   void setHotness(Optional<uint64_t> H) { Hotness = H; }
    461 
    462   bool isVerbose() const { return IsVerbose; }
    463 
    464   static bool classof(const DiagnosticInfo *DI) {
    465     return (DI->getKind() >= DK_FirstRemark &&
    466             DI->getKind() <= DK_LastRemark) ||
    467            (DI->getKind() >= DK_FirstMachineRemark &&
    468             DI->getKind() <= DK_LastMachineRemark);
    469   }
    470 
    471   bool isPassed() const {
    472     return (getKind() == DK_OptimizationRemark ||
    473             getKind() == DK_MachineOptimizationRemark);
    474   }
    475 
    476   bool isMissed() const {
    477     return (getKind() == DK_OptimizationRemarkMissed ||
    478             getKind() == DK_MachineOptimizationRemarkMissed);
    479   }
    480 
    481   bool isAnalysis() const {
    482     return (getKind() == DK_OptimizationRemarkAnalysis ||
    483             getKind() == DK_MachineOptimizationRemarkAnalysis);
    484   }
    485 
    486 protected:
    487   /// Name of the pass that triggers this report. If this matches the
    488   /// regular expression given in -Rpass=regexp, then the remark will
    489   /// be emitted.
    490   const char *PassName;
    491 
    492   /// Textual identifier for the remark (single-word, camel-case). Can be used
    493   /// by external tools reading the YAML output file for optimization remarks to
    494   /// identify the remark.
    495   StringRef RemarkName;
    496 
    497   /// If profile information is available, this is the number of times the
    498   /// corresponding code was executed in a profile instrumentation run.
    499   Optional<uint64_t> Hotness;
    500 
    501   /// Arguments collected via the streaming interface.
    502   SmallVector<Argument, 4> Args;
    503 
    504   /// The remark is expected to be noisy.
    505   bool IsVerbose = false;
    506 
    507   /// \brief If positive, the index of the first argument that only appear in
    508   /// the optimization records and not in the remark printed in the compiler
    509   /// output.
    510   int FirstExtraArgIndex = -1;
    511 
    512   friend struct yaml::MappingTraits<DiagnosticInfoOptimizationBase *>;
    513 };
    514 
    515 /// \brief Common features for diagnostics dealing with optimization remarks
    516 /// that are used by IR passes.
    517 class DiagnosticInfoIROptimization : public DiagnosticInfoOptimizationBase {
    518 public:
    519   /// \p PassName is the name of the pass emitting this diagnostic. \p
    520   /// RemarkName is a textual identifier for the remark (single-word,
    521   /// camel-case). \p Fn is the function where the diagnostic is being emitted.
    522   /// \p Loc is the location information to use in the diagnostic. If line table
    523   /// information is available, the diagnostic will include the source code
    524   /// location. \p CodeRegion is IR value (currently basic block) that the
    525   /// optimization operates on. This is currently used to provide run-time
    526   /// hotness information with PGO.
    527   DiagnosticInfoIROptimization(enum DiagnosticKind Kind,
    528                                enum DiagnosticSeverity Severity,
    529                                const char *PassName, StringRef RemarkName,
    530                                const Function &Fn,
    531                                const DiagnosticLocation &Loc,
    532                                const Value *CodeRegion = nullptr)
    533       : DiagnosticInfoOptimizationBase(Kind, Severity, PassName, RemarkName, Fn,
    534                                        Loc),
    535         CodeRegion(CodeRegion) {}
    536 
    537   /// \brief This is ctor variant allows a pass to build an optimization remark
    538   /// from an existing remark.
    539   ///
    540   /// This is useful when a transformation pass (e.g LV) wants to emit a remark
    541   /// (\p Orig) generated by one of its analyses (e.g. LAA) as its own analysis
    542   /// remark.  The string \p Prepend will be emitted before the original
    543   /// message.
    544   DiagnosticInfoIROptimization(const char *PassName, StringRef Prepend,
    545                                const DiagnosticInfoIROptimization &Orig)
    546       : DiagnosticInfoOptimizationBase(
    547             (DiagnosticKind)Orig.getKind(), Orig.getSeverity(), PassName,
    548             Orig.RemarkName, Orig.getFunction(), Orig.getLocation()),
    549         CodeRegion(Orig.getCodeRegion()) {
    550     *this << Prepend;
    551     std::copy(Orig.Args.begin(), Orig.Args.end(), std::back_inserter(Args));
    552   }
    553 
    554   /// Legacy interface.
    555   /// \p PassName is the name of the pass emitting this diagnostic.
    556   /// \p Fn is the function where the diagnostic is being emitted. \p Loc is
    557   /// the location information to use in the diagnostic. If line table
    558   /// information is available, the diagnostic will include the source code
    559   /// location. \p Msg is the message to show. Note that this class does not
    560   /// copy this message, so this reference must be valid for the whole life time
    561   /// of the diagnostic.
    562   DiagnosticInfoIROptimization(enum DiagnosticKind Kind,
    563                                enum DiagnosticSeverity Severity,
    564                                const char *PassName, const Function &Fn,
    565                                const DiagnosticLocation &Loc, const Twine &Msg)
    566       : DiagnosticInfoOptimizationBase(Kind, Severity, PassName, "", Fn, Loc) {
    567     *this << Msg.str();
    568   }
    569 
    570   const Value *getCodeRegion() const { return CodeRegion; }
    571 
    572   static bool classof(const DiagnosticInfo *DI) {
    573     return DI->getKind() >= DK_FirstRemark && DI->getKind() <= DK_LastRemark;
    574   }
    575 
    576 private:
    577   /// The IR value (currently basic block) that the optimization operates on.
    578   /// This is currently used to provide run-time hotness information with PGO.
    579   const Value *CodeRegion;
    580 };
    581 
    582 /// Diagnostic information for applied optimization remarks.
    583 class OptimizationRemark : public DiagnosticInfoIROptimization {
    584 public:
    585   /// \p PassName is the name of the pass emitting this diagnostic. If this name
    586   /// matches the regular expression given in -Rpass=, then the diagnostic will
    587   /// be emitted. \p RemarkName is a textual identifier for the remark (single-
    588   /// word, camel-case). \p Loc is the debug location and \p CodeRegion is the
    589   /// region that the optimization operates on (currently only block is
    590   /// supported).
    591   OptimizationRemark(const char *PassName, StringRef RemarkName,
    592                      const DiagnosticLocation &Loc, const Value *CodeRegion);
    593 
    594   /// Same as above, but the debug location and code region are derived from \p
    595   /// Instr.
    596   OptimizationRemark(const char *PassName, StringRef RemarkName,
    597                      const Instruction *Inst);
    598 
    599   /// Same as above, but the debug location and code region are derived from \p
    600   /// Func.
    601   OptimizationRemark(const char *PassName, StringRef RemarkName,
    602                      const Function *Func);
    603 
    604   static bool classof(const DiagnosticInfo *DI) {
    605     return DI->getKind() == DK_OptimizationRemark;
    606   }
    607 
    608   static bool isEnabled(StringRef PassName);
    609 
    610   /// \see DiagnosticInfoOptimizationBase::isEnabled.
    611   bool isEnabled() const override { return isEnabled(getPassName()); }
    612 
    613 private:
    614   /// This is deprecated now and only used by the function API below.
    615   /// \p PassName is the name of the pass emitting this diagnostic. If
    616   /// this name matches the regular expression given in -Rpass=, then the
    617   /// diagnostic will be emitted. \p Fn is the function where the diagnostic
    618   /// is being emitted. \p Loc is the location information to use in the
    619   /// diagnostic. If line table information is available, the diagnostic
    620   /// will include the source code location. \p Msg is the message to show.
    621   /// Note that this class does not copy this message, so this reference
    622   /// must be valid for the whole life time of the diagnostic.
    623   OptimizationRemark(const char *PassName, const Function &Fn,
    624                      const DiagnosticLocation &Loc, const Twine &Msg)
    625       : DiagnosticInfoIROptimization(DK_OptimizationRemark, DS_Remark, PassName,
    626                                      Fn, Loc, Msg) {}
    627 
    628   friend void emitOptimizationRemark(LLVMContext &Ctx, const char *PassName,
    629                                      const Function &Fn,
    630                                      const DiagnosticLocation &Loc,
    631                                      const Twine &Msg);
    632 };
    633 
    634 /// Diagnostic information for missed-optimization remarks.
    635 class OptimizationRemarkMissed : public DiagnosticInfoIROptimization {
    636 public:
    637   /// \p PassName is the name of the pass emitting this diagnostic. If this name
    638   /// matches the regular expression given in -Rpass-missed=, then the
    639   /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
    640   /// remark (single-word, camel-case). \p Loc is the debug location and \p
    641   /// CodeRegion is the region that the optimization operates on (currently only
    642   /// block is supported).
    643   OptimizationRemarkMissed(const char *PassName, StringRef RemarkName,
    644                            const DiagnosticLocation &Loc,
    645                            const Value *CodeRegion);
    646 
    647   /// \brief Same as above but \p Inst is used to derive code region and debug
    648   /// location.
    649   OptimizationRemarkMissed(const char *PassName, StringRef RemarkName,
    650                            const Instruction *Inst);
    651 
    652   static bool classof(const DiagnosticInfo *DI) {
    653     return DI->getKind() == DK_OptimizationRemarkMissed;
    654   }
    655 
    656   static bool isEnabled(StringRef PassName);
    657 
    658   /// \see DiagnosticInfoOptimizationBase::isEnabled.
    659   bool isEnabled() const override { return isEnabled(getPassName()); }
    660 
    661 private:
    662   /// This is deprecated now and only used by the function API below.
    663   /// \p PassName is the name of the pass emitting this diagnostic. If
    664   /// this name matches the regular expression given in -Rpass-missed=, then the
    665   /// diagnostic will be emitted. \p Fn is the function where the diagnostic
    666   /// is being emitted. \p Loc is the location information to use in the
    667   /// diagnostic. If line table information is available, the diagnostic
    668   /// will include the source code location. \p Msg is the message to show.
    669   /// Note that this class does not copy this message, so this reference
    670   /// must be valid for the whole life time of the diagnostic.
    671   OptimizationRemarkMissed(const char *PassName, const Function &Fn,
    672                            const DiagnosticLocation &Loc, const Twine &Msg)
    673       : DiagnosticInfoIROptimization(DK_OptimizationRemarkMissed, DS_Remark,
    674                                      PassName, Fn, Loc, Msg) {}
    675 
    676   friend void emitOptimizationRemarkMissed(LLVMContext &Ctx,
    677                                            const char *PassName,
    678                                            const Function &Fn,
    679                                            const DiagnosticLocation &Loc,
    680                                            const Twine &Msg);
    681 };
    682 
    683 /// Diagnostic information for optimization analysis remarks.
    684 class OptimizationRemarkAnalysis : public DiagnosticInfoIROptimization {
    685 public:
    686   /// \p PassName is the name of the pass emitting this diagnostic. If this name
    687   /// matches the regular expression given in -Rpass-analysis=, then the
    688   /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
    689   /// remark (single-word, camel-case). \p Loc is the debug location and \p
    690   /// CodeRegion is the region that the optimization operates on (currently only
    691   /// block is supported).
    692   OptimizationRemarkAnalysis(const char *PassName, StringRef RemarkName,
    693                              const DiagnosticLocation &Loc,
    694                              const Value *CodeRegion);
    695 
    696   /// \brief This is ctor variant allows a pass to build an optimization remark
    697   /// from an existing remark.
    698   ///
    699   /// This is useful when a transformation pass (e.g LV) wants to emit a remark
    700   /// (\p Orig) generated by one of its analyses (e.g. LAA) as its own analysis
    701   /// remark.  The string \p Prepend will be emitted before the original
    702   /// message.
    703   OptimizationRemarkAnalysis(const char *PassName, StringRef Prepend,
    704                              const OptimizationRemarkAnalysis &Orig)
    705       : DiagnosticInfoIROptimization(PassName, Prepend, Orig) {}
    706 
    707   /// \brief Same as above but \p Inst is used to derive code region and debug
    708   /// location.
    709   OptimizationRemarkAnalysis(const char *PassName, StringRef RemarkName,
    710                              const Instruction *Inst);
    711 
    712   static bool classof(const DiagnosticInfo *DI) {
    713     return DI->getKind() == DK_OptimizationRemarkAnalysis;
    714   }
    715 
    716   static bool isEnabled(StringRef PassName);
    717 
    718   /// \see DiagnosticInfoOptimizationBase::isEnabled.
    719   bool isEnabled() const override {
    720     return shouldAlwaysPrint() || isEnabled(getPassName());
    721   }
    722 
    723   static const char *AlwaysPrint;
    724 
    725   bool shouldAlwaysPrint() const { return getPassName() == AlwaysPrint; }
    726 
    727 protected:
    728   OptimizationRemarkAnalysis(enum DiagnosticKind Kind, const char *PassName,
    729                              const Function &Fn, const DiagnosticLocation &Loc,
    730                              const Twine &Msg)
    731       : DiagnosticInfoIROptimization(Kind, DS_Remark, PassName, Fn, Loc, Msg) {}
    732 
    733   OptimizationRemarkAnalysis(enum DiagnosticKind Kind, const char *PassName,
    734                              StringRef RemarkName,
    735                              const DiagnosticLocation &Loc,
    736                              const Value *CodeRegion);
    737 
    738 private:
    739   /// This is deprecated now and only used by the function API below.
    740   /// \p PassName is the name of the pass emitting this diagnostic. If
    741   /// this name matches the regular expression given in -Rpass-analysis=, then
    742   /// the diagnostic will be emitted. \p Fn is the function where the diagnostic
    743   /// is being emitted. \p Loc is the location information to use in the
    744   /// diagnostic. If line table information is available, the diagnostic will
    745   /// include the source code location. \p Msg is the message to show. Note that
    746   /// this class does not copy this message, so this reference must be valid for
    747   /// the whole life time of the diagnostic.
    748   OptimizationRemarkAnalysis(const char *PassName, const Function &Fn,
    749                              const DiagnosticLocation &Loc, const Twine &Msg)
    750       : DiagnosticInfoIROptimization(DK_OptimizationRemarkAnalysis, DS_Remark,
    751                                      PassName, Fn, Loc, Msg) {}
    752 
    753   friend void emitOptimizationRemarkAnalysis(LLVMContext &Ctx,
    754                                              const char *PassName,
    755                                              const Function &Fn,
    756                                              const DiagnosticLocation &Loc,
    757                                              const Twine &Msg);
    758 };
    759 
    760 /// Diagnostic information for optimization analysis remarks related to
    761 /// floating-point non-commutativity.
    762 class OptimizationRemarkAnalysisFPCommute : public OptimizationRemarkAnalysis {
    763 public:
    764   /// \p PassName is the name of the pass emitting this diagnostic. If this name
    765   /// matches the regular expression given in -Rpass-analysis=, then the
    766   /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
    767   /// remark (single-word, camel-case). \p Loc is the debug location and \p
    768   /// CodeRegion is the region that the optimization operates on (currently only
    769   /// block is supported). The front-end will append its own message related to
    770   /// options that address floating-point non-commutativity.
    771   OptimizationRemarkAnalysisFPCommute(const char *PassName,
    772                                       StringRef RemarkName,
    773                                       const DiagnosticLocation &Loc,
    774                                       const Value *CodeRegion)
    775       : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisFPCommute,
    776                                    PassName, RemarkName, Loc, CodeRegion) {}
    777 
    778   static bool classof(const DiagnosticInfo *DI) {
    779     return DI->getKind() == DK_OptimizationRemarkAnalysisFPCommute;
    780   }
    781 
    782 private:
    783   /// This is deprecated now and only used by the function API below.
    784   /// \p PassName is the name of the pass emitting this diagnostic. If
    785   /// this name matches the regular expression given in -Rpass-analysis=, then
    786   /// the diagnostic will be emitted. \p Fn is the function where the diagnostic
    787   /// is being emitted. \p Loc is the location information to use in the
    788   /// diagnostic. If line table information is available, the diagnostic will
    789   /// include the source code location. \p Msg is the message to show. The
    790   /// front-end will append its own message related to options that address
    791   /// floating-point non-commutativity. Note that this class does not copy this
    792   /// message, so this reference must be valid for the whole life time of the
    793   /// diagnostic.
    794   OptimizationRemarkAnalysisFPCommute(const char *PassName, const Function &Fn,
    795                                       const DiagnosticLocation &Loc,
    796                                       const Twine &Msg)
    797       : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisFPCommute,
    798                                    PassName, Fn, Loc, Msg) {}
    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 } // end namespace llvm
   1016 
   1017 #endif // LLVM_IR_DIAGNOSTICINFO_H
   1018