LCOV - code coverage report
Current view: top level - include/llvm/IR - DiagnosticInfo.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 89 89 100.0 %
Date: 2017-09-14 15:23:50 Functions: 12 43 27.9 %
Legend: Lines: hit not hit

          Line data    Source code
       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     1391270 :       : 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         265 : 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         154 :       : 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         108 :       : DiagnosticInfo(DK_InlineAsm, Severity), LocCookie(LocCookie),
     150         216 :         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          29 : 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, const char *ResourceName,
     192             :                               uint64_t ResourceSize,
     193             :                               DiagnosticSeverity Severity = DS_Warning,
     194             :                               DiagnosticKind Kind = DK_ResourceLimit,
     195             :                               uint64_t ResourceLimit = 0)
     196          29 :       : DiagnosticInfo(Kind, Severity), Fn(Fn), ResourceName(ResourceName),
     197          58 :         ResourceSize(ResourceSize), ResourceLimit(ResourceLimit) {}
     198             : 
     199             :   const Function &getFunction() const { return Fn; }
     200             :   const char *getResourceName() const { return ResourceName; }
     201             :   uint64_t getResourceSize() const { return ResourceSize; }
     202             :   uint64_t getResourceLimit() const { return ResourceLimit; }
     203             : 
     204             :   /// \see DiagnosticInfo::print.
     205             :   void print(DiagnosticPrinter &DP) const override;
     206             : 
     207             :   static bool classof(const DiagnosticInfo *DI) {
     208             :     return DI->getKind() == DK_ResourceLimit || DI->getKind() == DK_StackSize;
     209             :   }
     210             : };
     211             : 
     212          40 : class DiagnosticInfoStackSize : public DiagnosticInfoResourceLimit {
     213             : public:
     214             :   DiagnosticInfoStackSize(const Function &Fn, uint64_t StackSize,
     215             :                           DiagnosticSeverity Severity = DS_Warning,
     216             :                           uint64_t StackLimit = 0)
     217             :       : DiagnosticInfoResourceLimit(Fn, "stack size", StackSize, Severity,
     218          40 :                                     DK_StackSize, StackLimit) {}
     219             : 
     220          17 :   uint64_t getStackSize() const { return getResourceSize(); }
     221             :   uint64_t getStackLimit() const { return getResourceLimit(); }
     222             : 
     223             :   static bool classof(const DiagnosticInfo *DI) {
     224             :     return DI->getKind() == DK_StackSize;
     225             :   }
     226             : };
     227             : 
     228             : /// Diagnostic information for debug metadata version reporting.
     229             : /// This is basically a module and a version.
     230          54 : class DiagnosticInfoDebugMetadataVersion : public DiagnosticInfo {
     231             : private:
     232             :   /// The module that is concerned by this debug metadata version diagnostic.
     233             :   const Module &M;
     234             :   /// The actual metadata version.
     235             :   unsigned MetadataVersion;
     236             : 
     237             : public:
     238             :   /// \p The module that is concerned by this debug metadata version diagnostic.
     239             :   /// \p The actual metadata version.
     240             :   DiagnosticInfoDebugMetadataVersion(const Module &M, unsigned MetadataVersion,
     241             :                                      DiagnosticSeverity Severity = DS_Warning)
     242          54 :       : DiagnosticInfo(DK_DebugMetadataVersion, Severity), M(M),
     243         108 :         MetadataVersion(MetadataVersion) {}
     244             : 
     245             :   const Module &getModule() const { return M; }
     246             :   unsigned getMetadataVersion() const { return MetadataVersion; }
     247             : 
     248             :   /// \see DiagnosticInfo::print.
     249             :   void print(DiagnosticPrinter &DP) const override;
     250             : 
     251             :   static bool classof(const DiagnosticInfo *DI) {
     252             :     return DI->getKind() == DK_DebugMetadataVersion;
     253             :   }
     254             : };
     255             : 
     256             : /// Diagnostic information for stripping invalid debug metadata.
     257          10 : class DiagnosticInfoIgnoringInvalidDebugMetadata : public DiagnosticInfo {
     258             : private:
     259             :   /// The module that is concerned by this debug metadata version diagnostic.
     260             :   const Module &M;
     261             : 
     262             : public:
     263             :   /// \p The module that is concerned by this debug metadata version diagnostic.
     264             :   DiagnosticInfoIgnoringInvalidDebugMetadata(
     265             :       const Module &M, DiagnosticSeverity Severity = DS_Warning)
     266          20 :       : DiagnosticInfo(DK_DebugMetadataVersion, Severity), M(M) {}
     267             : 
     268             :   const Module &getModule() const { return M; }
     269             : 
     270             :   /// \see DiagnosticInfo::print.
     271             :   void print(DiagnosticPrinter &DP) const override;
     272             : 
     273             :   static bool classof(const DiagnosticInfo *DI) {
     274             :     return DI->getKind() == DK_DebugMetadataInvalid;
     275             :   }
     276             : };
     277             : 
     278             : /// Diagnostic information for the sample profiler.
     279          14 : class DiagnosticInfoSampleProfile : public DiagnosticInfo {
     280             : public:
     281             :   DiagnosticInfoSampleProfile(StringRef FileName, unsigned LineNum,
     282             :                               const Twine &Msg,
     283             :                               DiagnosticSeverity Severity = DS_Error)
     284          16 :       : DiagnosticInfo(DK_SampleProfile, Severity), FileName(FileName),
     285          32 :         LineNum(LineNum), Msg(Msg) {}
     286             :   DiagnosticInfoSampleProfile(StringRef FileName, const Twine &Msg,
     287             :                               DiagnosticSeverity Severity = DS_Error)
     288           4 :       : DiagnosticInfo(DK_SampleProfile, Severity), FileName(FileName),
     289           8 :         Msg(Msg) {}
     290             :   DiagnosticInfoSampleProfile(const Twine &Msg,
     291             :                               DiagnosticSeverity Severity = DS_Error)
     292          18 :       : DiagnosticInfo(DK_SampleProfile, Severity), Msg(Msg) {}
     293             : 
     294             :   /// \see DiagnosticInfo::print.
     295             :   void print(DiagnosticPrinter &DP) const override;
     296             : 
     297             :   static bool classof(const DiagnosticInfo *DI) {
     298             :     return DI->getKind() == DK_SampleProfile;
     299             :   }
     300             : 
     301             :   StringRef getFileName() const { return FileName; }
     302             :   unsigned getLineNum() const { return LineNum; }
     303             :   const Twine &getMsg() const { return Msg; }
     304             : 
     305             : private:
     306             :   /// Name of the input file associated with this diagnostic.
     307             :   StringRef FileName;
     308             : 
     309             :   /// Line number where the diagnostic occurred. If 0, no line number will
     310             :   /// be emitted in the message.
     311             :   unsigned LineNum = 0;
     312             : 
     313             :   /// Message to report.
     314             :   const Twine &Msg;
     315             : };
     316             : 
     317             : /// Diagnostic information for the PGO profiler.
     318           4 : class DiagnosticInfoPGOProfile : public DiagnosticInfo {
     319             : public:
     320             :   DiagnosticInfoPGOProfile(const char *FileName, const Twine &Msg,
     321             :                            DiagnosticSeverity Severity = DS_Error)
     322          16 :       : DiagnosticInfo(DK_PGOProfile, Severity), FileName(FileName), Msg(Msg) {}
     323             : 
     324             :   /// \see DiagnosticInfo::print.
     325             :   void print(DiagnosticPrinter &DP) const override;
     326             : 
     327             :   static bool classof(const DiagnosticInfo *DI) {
     328             :     return DI->getKind() == DK_PGOProfile;
     329             :   }
     330             : 
     331             :   const char *getFileName() const { return FileName; }
     332             :   const Twine &getMsg() const { return Msg; }
     333             : 
     334             : private:
     335             :   /// Name of the input file associated with this diagnostic.
     336             :   const char *FileName;
     337             : 
     338             :   /// Message to report.
     339             :   const Twine &Msg;
     340             : };
     341             : 
     342             : class DiagnosticLocation {
     343             :   StringRef Filename;
     344             :   unsigned Line = 0;
     345             :   unsigned Column = 0;
     346             : 
     347             : public:
     348     6629960 :   DiagnosticLocation() = default;
     349             :   DiagnosticLocation(const DebugLoc &DL);
     350             :   DiagnosticLocation(const DISubprogram *SP);
     351             : 
     352       12821 :   bool isValid() const { return !Filename.empty(); }
     353             :   StringRef getFilename() const { return Filename; }
     354             :   unsigned getLine() const { return Line; }
     355             :   unsigned getColumn() const { return Column; }
     356             : };
     357             : 
     358             : /// Common features for diagnostics with an associated location.
     359     1390643 : class DiagnosticInfoWithLocationBase : public DiagnosticInfo {
     360             : public:
     361             :   /// \p Fn is the function where the diagnostic is being emitted. \p Loc is
     362             :   /// the location information to use in the diagnostic.
     363             :   DiagnosticInfoWithLocationBase(enum DiagnosticKind Kind,
     364             :                                  enum DiagnosticSeverity Severity,
     365             :                                  const Function &Fn,
     366             :                                  const DiagnosticLocation &Loc)
     367     2781296 :       : DiagnosticInfo(Kind, Severity), Fn(Fn), Loc(Loc) {}
     368             : 
     369             :   /// Return true if location information is available for this diagnostic.
     370        2408 :   bool isLocationAvailable() const { return Loc.isValid(); }
     371             : 
     372             :   /// Return a string with the location information for this diagnostic
     373             :   /// in the format "file:line:col". If location information is not available,
     374             :   /// it returns "<unknown>:0:0".
     375             :   const std::string getLocationStr() const;
     376             : 
     377             :   /// Return location information for this diagnostic in three parts:
     378             :   /// the source file name, line number and column.
     379             :   void getLocation(StringRef *Filename, unsigned *Line, unsigned *Column) const;
     380             : 
     381             :   const Function &getFunction() const { return Fn; }
     382        9003 :   DiagnosticLocation getLocation() const { return Loc; }
     383             : 
     384             : private:
     385             :   /// Function where this diagnostic is triggered.
     386             :   const Function &Fn;
     387             : 
     388             :   /// Debug location where this diagnostic is triggered.
     389             :   DiagnosticLocation Loc;
     390             : };
     391             : 
     392             : /// \brief Common features for diagnostics dealing with optimization remarks
     393             : /// that are used by both IR and MIR passes.
     394     5562080 : class DiagnosticInfoOptimizationBase : public DiagnosticInfoWithLocationBase {
     395             : public:
     396             :   /// \brief Used to set IsVerbose via the stream interface.
     397             :   struct setIsVerbose {};
     398             : 
     399             :   /// \brief When an instance of this is inserted into the stream, the arguments
     400             :   /// following will not appear in the remark printed in the compiler output
     401             :   /// (-Rpass) but only in the optimization record file
     402             :   /// (-fsave-optimization-record).
     403             :   struct setExtraArgs {};
     404             : 
     405             :   /// \brief Used in the streaming interface as the general argument type.  It
     406             :   /// internally converts everything into a key-value pair.
     407    22399270 :   struct Argument {
     408             :     std::string Key;
     409             :     std::string Val;
     410             :     // If set, the debug location corresponding to the value.
     411             :     DiagnosticLocation Loc;
     412             : 
     413     8973028 :     explicit Argument(StringRef Str = "") : Key("String"), Val(Str) {}
     414             :     Argument(StringRef Key, const Value *V);
     415             :     Argument(StringRef Key, const Type *T);
     416             :     Argument(StringRef Key, StringRef S);
     417             :     Argument(StringRef Key, int N);
     418             :     Argument(StringRef Key, long N);
     419             :     Argument(StringRef Key, long long N);
     420             :     Argument(StringRef Key, unsigned N);
     421             :     Argument(StringRef Key, unsigned long N);
     422             :     Argument(StringRef Key, unsigned long long N);
     423          65 :     Argument(StringRef Key, bool B) : Key(Key), Val(B ? "true" : "false") {}
     424             :     Argument(StringRef Key, DebugLoc dl);
     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     1390524 :       : DiagnosticInfoWithLocationBase(Kind, Severity, Fn, Loc),
     439     5562096 :         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     1347772 :   StringRef getPassName() const { return PassName; }
     457             :   std::string getMsg() const;
     458     2063208 :   Optional<uint64_t> getHotness() const { return Hotness; }
     459     2062948 :   void setHotness(Optional<uint64_t> H) { Hotness = H; }
     460             : 
     461             :   bool isVerbose() const { return IsVerbose; }
     462             : 
     463             :   static bool classof(const DiagnosticInfo *DI) {
     464      603785 :     return (DI->getKind() >= DK_FirstRemark &&
     465      574923 :             DI->getKind() <= DK_LastRemark) ||
     466      545151 :            (DI->getKind() >= DK_FirstMachineRemark &&
     467      272348 :             DI->getKind() <= DK_LastMachineRemark);
     468             :   }
     469             : 
     470             :   bool isPassed() const {
     471      989631 :     return (getKind() == DK_OptimizationRemark ||
     472      354886 :             getKind() == DK_MachineOptimizationRemark);
     473             :   }
     474             : 
     475             :   bool isMissed() const {
     476      369578 :     return (getKind() == DK_OptimizationRemarkMissed ||
     477       14692 :             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     2211024 : 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     1105283 :       : DiagnosticInfoOptimizationBase(Kind, Severity, PassName, RemarkName, Fn,
     533             :                                        Loc),
     534     2210566 :         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         225 :   DiagnosticInfoIROptimization(const char *PassName, StringRef Prepend,
     544             :                                const DiagnosticInfoIROptimization &Orig)
     545         225 :       : DiagnosticInfoOptimizationBase(
     546         225 :             (DiagnosticKind)Orig.getKind(), Orig.getSeverity(), PassName,
     547         450 :             Orig.RemarkName, Orig.getFunction(), Orig.getLocation()),
     548         900 :         CodeRegion(Orig.getCodeRegion()) {
     549         225 :     *this << Prepend;
     550        1125 :     std::copy(Orig.Args.begin(), Orig.Args.end(), std::back_inserter(Args));
     551         225 :   }
     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           8 :   DiagnosticInfoIROptimization(enum DiagnosticKind Kind,
     562             :                                enum DiagnosticSeverity Severity,
     563             :                                const char *PassName, const Function &Fn,
     564             :                                const DiagnosticLocation &Loc, const Twine &Msg)
     565          16 :       : DiagnosticInfoOptimizationBase(Kind, Severity, PassName, "", Fn, Loc) {
     566          24 :     *this << Msg.str();
     567           8 :   }
     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     1287620 : 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      727854 :   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             : 
     628             : /// Diagnostic information for missed-optimization remarks.
     629      896276 : class OptimizationRemarkMissed : public DiagnosticInfoIROptimization {
     630             : public:
     631             :   /// \p PassName is the name of the pass emitting this diagnostic. If this name
     632             :   /// matches the regular expression given in -Rpass-missed=, then the
     633             :   /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
     634             :   /// remark (single-word, camel-case). \p Loc is the debug location and \p
     635             :   /// CodeRegion is the region that the optimization operates on (currently only
     636             :   /// block is supported).
     637             :   OptimizationRemarkMissed(const char *PassName, StringRef RemarkName,
     638             :                            const DiagnosticLocation &Loc,
     639             :                            const Value *CodeRegion);
     640             : 
     641             :   /// \brief Same as above but \p Inst is used to derive code region and debug
     642             :   /// location.
     643             :   OptimizationRemarkMissed(const char *PassName, StringRef RemarkName,
     644             :                            const Instruction *Inst);
     645             : 
     646             :   static bool classof(const DiagnosticInfo *DI) {
     647             :     return DI->getKind() == DK_OptimizationRemarkMissed;
     648             :   }
     649             : 
     650             :   static bool isEnabled(StringRef PassName);
     651             : 
     652             :   /// \see DiagnosticInfoOptimizationBase::isEnabled.
     653       34002 :   bool isEnabled() const override { return isEnabled(getPassName()); }
     654             : 
     655             : private:
     656             :   /// This is deprecated now and only used by the function API below.
     657             :   /// \p PassName is the name of the pass emitting this diagnostic. If
     658             :   /// this name matches the regular expression given in -Rpass-missed=, then the
     659             :   /// diagnostic will be emitted. \p Fn is the function where the diagnostic
     660             :   /// is being emitted. \p Loc is the location information to use in the
     661             :   /// diagnostic. If line table information is available, the diagnostic
     662             :   /// will include the source code location. \p Msg is the message to show.
     663             :   /// Note that this class does not copy this message, so this reference
     664             :   /// must be valid for the whole life time of the diagnostic.
     665             :   OptimizationRemarkMissed(const char *PassName, const Function &Fn,
     666             :                            const DiagnosticLocation &Loc, const Twine &Msg)
     667             :       : DiagnosticInfoIROptimization(DK_OptimizationRemarkMissed, DS_Remark,
     668             :                                      PassName, Fn, Loc, Msg) {}
     669             : };
     670             : 
     671             : /// Diagnostic information for optimization analysis remarks.
     672       27086 : class OptimizationRemarkAnalysis : public DiagnosticInfoIROptimization {
     673             : public:
     674             :   /// \p PassName is the name of the pass emitting this diagnostic. If this name
     675             :   /// matches the regular expression given in -Rpass-analysis=, then the
     676             :   /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
     677             :   /// remark (single-word, camel-case). \p Loc is the debug location and \p
     678             :   /// CodeRegion is the region that the optimization operates on (currently only
     679             :   /// block is supported).
     680             :   OptimizationRemarkAnalysis(const char *PassName, StringRef RemarkName,
     681             :                              const DiagnosticLocation &Loc,
     682             :                              const Value *CodeRegion);
     683             : 
     684             :   /// \brief This is ctor variant allows a pass to build an optimization remark
     685             :   /// from an existing remark.
     686             :   ///
     687             :   /// This is useful when a transformation pass (e.g LV) wants to emit a remark
     688             :   /// (\p Orig) generated by one of its analyses (e.g. LAA) as its own analysis
     689             :   /// remark.  The string \p Prepend will be emitted before the original
     690             :   /// message.
     691             :   OptimizationRemarkAnalysis(const char *PassName, StringRef Prepend,
     692             :                              const OptimizationRemarkAnalysis &Orig)
     693         225 :       : DiagnosticInfoIROptimization(PassName, Prepend, Orig) {}
     694             : 
     695             :   /// \brief Same as above but \p Inst is used to derive code region and debug
     696             :   /// location.
     697             :   OptimizationRemarkAnalysis(const char *PassName, StringRef RemarkName,
     698             :                              const Instruction *Inst);
     699             : 
     700             :   static bool classof(const DiagnosticInfo *DI) {
     701       13857 :     return DI->getKind() == DK_OptimizationRemarkAnalysis;
     702             :   }
     703             : 
     704             :   static bool isEnabled(StringRef PassName);
     705             : 
     706             :   /// \see DiagnosticInfoOptimizationBase::isEnabled.
     707        9554 :   bool isEnabled() const override {
     708       18997 :     return shouldAlwaysPrint() || isEnabled(getPassName());
     709             :   }
     710             : 
     711             :   static const char *AlwaysPrint;
     712             : 
     713       34059 :   bool shouldAlwaysPrint() const { return getPassName() == AlwaysPrint; }
     714             : 
     715             : protected:
     716             :   OptimizationRemarkAnalysis(enum DiagnosticKind Kind, const char *PassName,
     717             :                              const Function &Fn, const DiagnosticLocation &Loc,
     718             :                              const Twine &Msg)
     719             :       : DiagnosticInfoIROptimization(Kind, DS_Remark, PassName, Fn, Loc, Msg) {}
     720             : 
     721             :   OptimizationRemarkAnalysis(enum DiagnosticKind Kind, const char *PassName,
     722             :                              StringRef RemarkName,
     723             :                              const DiagnosticLocation &Loc,
     724             :                              const Value *CodeRegion);
     725             : 
     726             : private:
     727             :   /// This is deprecated now and only used by the function API below.
     728             :   /// \p PassName is the name of the pass emitting this diagnostic. If
     729             :   /// this name matches the regular expression given in -Rpass-analysis=, then
     730             :   /// the diagnostic will be emitted. \p Fn is the function where the diagnostic
     731             :   /// is being emitted. \p Loc is the location information to use in the
     732             :   /// diagnostic. If line table information is available, the diagnostic will
     733             :   /// include the source code location. \p Msg is the message to show. Note that
     734             :   /// this class does not copy this message, so this reference must be valid for
     735             :   /// the whole life time of the diagnostic.
     736             :   OptimizationRemarkAnalysis(const char *PassName, const Function &Fn,
     737             :                              const DiagnosticLocation &Loc, const Twine &Msg)
     738             :       : DiagnosticInfoIROptimization(DK_OptimizationRemarkAnalysis, DS_Remark,
     739             :                                      PassName, Fn, Loc, Msg) {}
     740             : };
     741             : 
     742             : /// Diagnostic information for optimization analysis remarks related to
     743             : /// floating-point non-commutativity.
     744          16 : class OptimizationRemarkAnalysisFPCommute : public OptimizationRemarkAnalysis {
     745             : public:
     746             :   /// \p PassName is the name of the pass emitting this diagnostic. If this name
     747             :   /// matches the regular expression given in -Rpass-analysis=, then the
     748             :   /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
     749             :   /// remark (single-word, camel-case). \p Loc is the debug location and \p
     750             :   /// CodeRegion is the region that the optimization operates on (currently only
     751             :   /// block is supported). The front-end will append its own message related to
     752             :   /// options that address floating-point non-commutativity.
     753             :   OptimizationRemarkAnalysisFPCommute(const char *PassName,
     754             :                                       StringRef RemarkName,
     755             :                                       const DiagnosticLocation &Loc,
     756             :                                       const Value *CodeRegion)
     757           8 :       : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisFPCommute,
     758           8 :                                    PassName, RemarkName, Loc, CodeRegion) {}
     759             : 
     760             :   static bool classof(const DiagnosticInfo *DI) {
     761             :     return DI->getKind() == DK_OptimizationRemarkAnalysisFPCommute;
     762             :   }
     763             : 
     764             : private:
     765             :   /// This is deprecated now and only used by the function API below.
     766             :   /// \p PassName is the name of the pass emitting this diagnostic. If
     767             :   /// this name matches the regular expression given in -Rpass-analysis=, then
     768             :   /// the diagnostic will be emitted. \p Fn is the function where the diagnostic
     769             :   /// is being emitted. \p Loc is the location information to use in the
     770             :   /// diagnostic. If line table information is available, the diagnostic will
     771             :   /// include the source code location. \p Msg is the message to show. The
     772             :   /// front-end will append its own message related to options that address
     773             :   /// floating-point non-commutativity. Note that this class does not copy this
     774             :   /// message, so this reference must be valid for the whole life time of the
     775             :   /// diagnostic.
     776             :   OptimizationRemarkAnalysisFPCommute(const char *PassName, const Function &Fn,
     777             :                                       const DiagnosticLocation &Loc,
     778             :                                       const Twine &Msg)
     779             :       : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisFPCommute,
     780             :                                    PassName, Fn, Loc, Msg) {}
     781             : };
     782             : 
     783             : /// Diagnostic information for optimization analysis remarks related to
     784             : /// pointer aliasing.
     785          16 : class OptimizationRemarkAnalysisAliasing : public OptimizationRemarkAnalysis {
     786             : public:
     787             :   /// \p PassName is the name of the pass emitting this diagnostic. If this name
     788             :   /// matches the regular expression given in -Rpass-analysis=, then the
     789             :   /// diagnostic will be emitted. \p RemarkName is a textual identifier for the
     790             :   /// remark (single-word, camel-case). \p Loc is the debug location and \p
     791             :   /// CodeRegion is the region that the optimization operates on (currently only
     792             :   /// block is supported). The front-end will append its own message related to
     793             :   /// options that address pointer aliasing legality.
     794             :   OptimizationRemarkAnalysisAliasing(const char *PassName, StringRef RemarkName,
     795             :                                      const DiagnosticLocation &Loc,
     796             :                                      const Value *CodeRegion)
     797           8 :       : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisAliasing,
     798           8 :                                    PassName, RemarkName, Loc, CodeRegion) {}
     799             : 
     800             :   static bool classof(const DiagnosticInfo *DI) {
     801             :     return DI->getKind() == DK_OptimizationRemarkAnalysisAliasing;
     802             :   }
     803             : 
     804             : private:
     805             :   /// This is deprecated now and only used by the function API below.
     806             :   /// \p PassName is the name of the pass emitting this diagnostic. If
     807             :   /// this name matches the regular expression given in -Rpass-analysis=, then
     808             :   /// the diagnostic will be emitted. \p Fn is the function where the diagnostic
     809             :   /// is being emitted. \p Loc is the location information to use in the
     810             :   /// diagnostic. If line table information is available, the diagnostic will
     811             :   /// include the source code location. \p Msg is the message to show. The
     812             :   /// front-end will append its own message related to options that address
     813             :   /// pointer aliasing legality. Note that this class does not copy this
     814             :   /// message, so this reference must be valid for the whole life time of the
     815             :   /// diagnostic.
     816             :   OptimizationRemarkAnalysisAliasing(const char *PassName, const Function &Fn,
     817             :                                      const DiagnosticLocation &Loc,
     818             :                                      const Twine &Msg)
     819             :       : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisAliasing,
     820             :                                    PassName, Fn, Loc, Msg) {}
     821             : };
     822             : 
     823             : /// Diagnostic information for machine IR parser.
     824         112 : class DiagnosticInfoMIRParser : public DiagnosticInfo {
     825             :   const SMDiagnostic &Diagnostic;
     826             : 
     827             : public:
     828             :   DiagnosticInfoMIRParser(DiagnosticSeverity Severity,
     829             :                           const SMDiagnostic &Diagnostic)
     830         224 :       : DiagnosticInfo(DK_MIRParser, Severity), Diagnostic(Diagnostic) {}
     831             : 
     832             :   const SMDiagnostic &getDiagnostic() const { return Diagnostic; }
     833             : 
     834             :   void print(DiagnosticPrinter &DP) const override;
     835             : 
     836             :   static bool classof(const DiagnosticInfo *DI) {
     837             :     return DI->getKind() == DK_MIRParser;
     838             :   }
     839             : };
     840             : 
     841             : /// Diagnostic information for ISel fallback path.
     842          83 : class DiagnosticInfoISelFallback : public DiagnosticInfo {
     843             :   /// The function that is concerned by this diagnostic.
     844             :   const Function &Fn;
     845             : 
     846             : public:
     847             :   DiagnosticInfoISelFallback(const Function &Fn,
     848             :                              DiagnosticSeverity Severity = DS_Warning)
     849         166 :       : DiagnosticInfo(DK_ISelFallback, Severity), Fn(Fn) {}
     850             : 
     851             :   const Function &getFunction() const { return Fn; }
     852             : 
     853             :   void print(DiagnosticPrinter &DP) const override;
     854             : 
     855             :   static bool classof(const DiagnosticInfo *DI) {
     856             :     return DI->getKind() == DK_ISelFallback;
     857             :   }
     858             : };
     859             : 
     860             : // Create wrappers for C Binding types (see CBindingWrapping.h).
     861             : DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DiagnosticInfo, LLVMDiagnosticInfoRef)
     862             : 
     863             : /// Diagnostic information for optimization failures.
     864          42 : class DiagnosticInfoOptimizationFailure : public DiagnosticInfoIROptimization {
     865             : public:
     866             :   /// \p Fn is the function where the diagnostic is being emitted. \p Loc is
     867             :   /// the location information to use in the diagnostic. If line table
     868             :   /// information is available, the diagnostic will include the source code
     869             :   /// location. \p Msg is the message to show. Note that this class does not
     870             :   /// copy this message, so this reference must be valid for the whole life time
     871             :   /// of the diagnostic.
     872             :   DiagnosticInfoOptimizationFailure(const Function &Fn,
     873             :                                     const DiagnosticLocation &Loc,
     874             :                                     const Twine &Msg)
     875           8 :       : DiagnosticInfoIROptimization(DK_OptimizationFailure, DS_Warning,
     876           8 :                                      nullptr, Fn, Loc, Msg) {}
     877             : 
     878             :   /// \p PassName is the name of the pass emitting this diagnostic.  \p
     879             :   /// RemarkName is a textual identifier for the remark (single-word,
     880             :   /// camel-case).  \p Loc is the debug location and \p CodeRegion is the
     881             :   /// region that the optimization operates on (currently basic block is
     882             :   /// supported).
     883             :   DiagnosticInfoOptimizationFailure(const char *PassName, StringRef RemarkName,
     884             :                                     const DiagnosticLocation &Loc,
     885             :                                     const Value *CodeRegion);
     886             : 
     887             :   static bool classof(const DiagnosticInfo *DI) {
     888             :     return DI->getKind() == DK_OptimizationFailure;
     889             :   }
     890             : 
     891             :   /// \see DiagnosticInfoOptimizationBase::isEnabled.
     892             :   bool isEnabled() const override;
     893             : };
     894             : 
     895             : /// Diagnostic information for unsupported feature in backend.
     896         246 : class DiagnosticInfoUnsupported : public DiagnosticInfoWithLocationBase {
     897             : private:
     898             :   Twine Msg;
     899             : 
     900             : public:
     901             :   /// \p Fn is the function where the diagnostic is being emitted. \p Loc is
     902             :   /// the location information to use in the diagnostic. If line table
     903             :   /// information is available, the diagnostic will include the source code
     904             :   /// location. \p Msg is the message to show. Note that this class does not
     905             :   /// copy this message, so this reference must be valid for the whole life time
     906             :   /// of the diagnostic.
     907             :   DiagnosticInfoUnsupported(
     908             :       const Function &Fn, const Twine &Msg,
     909             :       const DiagnosticLocation &Loc = DiagnosticLocation(),
     910             :       DiagnosticSeverity Severity = DS_Error)
     911         124 :       : DiagnosticInfoWithLocationBase(DK_Unsupported, Severity, Fn, Loc),
     912         248 :         Msg(Msg) {}
     913             : 
     914             :   static bool classof(const DiagnosticInfo *DI) {
     915             :     return DI->getKind() == DK_Unsupported;
     916             :   }
     917             : 
     918           2 :   const Twine &getMessage() const { return Msg; }
     919             : 
     920             :   void print(DiagnosticPrinter &DP) const override;
     921             : };
     922             : 
     923             : } // end namespace llvm
     924             : 
     925             : #endif // LLVM_IR_DIAGNOSTICINFO_H

Generated by: LCOV version 1.13