X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=include%2Fllvm%2FIR%2FDiagnosticInfo.h;h=b8fdae2fcadbeb88b05f34dd6171deed3e2ab39c;hb=788bdbbd5c99d805a2992689b1c5bad255da131c;hp=256e15eeb4200ef185a14cdfd2fbdbb3d39a12c5;hpb=ed25e06529f4ba99b76c82c496084099cb09612c;p=android-x86%2Fexternal-llvm.git diff --git a/include/llvm/IR/DiagnosticInfo.h b/include/llvm/IR/DiagnosticInfo.h index 256e15eeb42..b8fdae2fcad 100644 --- a/include/llvm/IR/DiagnosticInfo.h +++ b/include/llvm/IR/DiagnosticInfo.h @@ -1,4 +1,4 @@ -//===- llvm/Support/DiagnosticInfo.h - Diagnostic Declaration ---*- C++ -*-===// +//===- llvm/IR/DiagnosticInfo.h - Diagnostic Declaration --------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -15,12 +15,19 @@ #ifndef LLVM_IR_DIAGNOSTICINFO_H #define LLVM_IR_DIAGNOSTICINFO_H -#include "llvm/ADT/ArrayRef.h" +#include "llvm-c/Types.h" +#include "llvm/ADT/Optional.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" #include "llvm/ADT/Twine.h" #include "llvm/IR/DebugLoc.h" -#include "llvm/IR/Module.h" -#include "llvm/Support/Casting.h" +#include "llvm/Support/CBindingWrapping.h" +#include "llvm/Support/YAMLTraits.h" +#include +#include #include +#include +#include namespace llvm { @@ -28,13 +35,12 @@ namespace llvm { class DiagnosticPrinter; class Function; class Instruction; -class LLVMContextImpl; -class Value; -class DebugLoc; +class LLVMContext; +class Module; class SMDiagnostic; -/// \brief Defines the different supported severity of a diagnostic. -enum DiagnosticSeverity { +/// Defines the different supported severity of a diagnostic. +enum DiagnosticSeverity : char { DS_Error, DS_Warning, DS_Remark, @@ -43,14 +49,16 @@ enum DiagnosticSeverity { DS_Note }; -/// \brief Defines the different supported kind of a diagnostic. +/// Defines the different supported kind of a diagnostic. /// This enum should be extended with a new ID for each added concrete subclass. enum DiagnosticKind { - DK_Bitcode, DK_InlineAsm, + DK_ResourceLimit, DK_StackSize, DK_Linker, DK_DebugMetadataVersion, + DK_DebugMetadataInvalid, + DK_ISelFallback, DK_SampleProfile, DK_OptimizationRemark, DK_OptimizationRemarkMissed, @@ -58,13 +66,20 @@ enum DiagnosticKind { DK_OptimizationRemarkAnalysisFPCommute, DK_OptimizationRemarkAnalysisAliasing, DK_OptimizationFailure, + DK_FirstRemark = DK_OptimizationRemark, + DK_LastRemark = DK_OptimizationFailure, + DK_MachineOptimizationRemark, + DK_MachineOptimizationRemarkMissed, + DK_MachineOptimizationRemarkAnalysis, + DK_FirstMachineRemark = DK_MachineOptimizationRemark, + DK_LastMachineRemark = DK_MachineOptimizationRemarkAnalysis, DK_MIRParser, DK_PGOProfile, DK_Unsupported, DK_FirstPluginKind }; -/// \brief Get the next available kind ID for a plugin diagnostic. +/// Get the next available kind ID for a plugin diagnostic. /// Each time this function is called, it returns a different number. /// Therefore, a plugin that wants to "identify" its own classes /// with a dynamic identifier, just have to use this method to get a new ID @@ -74,7 +89,7 @@ enum DiagnosticKind { /// DiagnosticKind values. int getNextAvailablePluginDiagnosticKind(); -/// \brief This is the base abstract class for diagnostic reporting in +/// This is the base abstract class for diagnostic reporting in /// the backend. /// The print method must be overloaded by the subclasses to print a /// user-friendly message in the client of the backend (let us call it a @@ -90,7 +105,7 @@ public: DiagnosticInfo(/* DiagnosticKind */ int Kind, DiagnosticSeverity Severity) : Kind(Kind), Severity(Severity) {} - virtual ~DiagnosticInfo() {} + virtual ~DiagnosticInfo() = default; /* DiagnosticKind */ int getKind() const { return Kind; } DiagnosticSeverity getSeverity() const { return Severity; } @@ -102,22 +117,20 @@ public: /// The printed message must not end with '.' nor start with a severity /// keyword. virtual void print(DiagnosticPrinter &DP) const = 0; - - static const char *AlwaysPrint; }; -typedef std::function DiagnosticHandlerFunction; +using DiagnosticHandlerFunction = std::function; /// Diagnostic information for inline asm reporting. /// This is basically a message and an optional location. class DiagnosticInfoInlineAsm : public DiagnosticInfo { private: /// Optional line information. 0 if not set. - unsigned LocCookie; + unsigned LocCookie = 0; /// Message to be reported. const Twine &MsgStr; /// Optional origin of the problem. - const Instruction *Instr; + const Instruction *Instr = nullptr; public: /// \p MsgStr is the message to be reported to the frontend. @@ -125,8 +138,7 @@ public: /// for the whole life time of the Diagnostic. DiagnosticInfoInlineAsm(const Twine &MsgStr, DiagnosticSeverity Severity = DS_Error) - : DiagnosticInfo(DK_InlineAsm, Severity), LocCookie(0), MsgStr(MsgStr), - Instr(nullptr) {} + : DiagnosticInfo(DK_InlineAsm, Severity), MsgStr(MsgStr) {} /// \p LocCookie if non-zero gives the line number for this report. /// \p MsgStr gives the message. @@ -135,7 +147,7 @@ public: DiagnosticInfoInlineAsm(unsigned LocCookie, const Twine &MsgStr, DiagnosticSeverity Severity = DS_Error) : DiagnosticInfo(DK_InlineAsm, Severity), LocCookie(LocCookie), - MsgStr(MsgStr), Instr(nullptr) {} + MsgStr(MsgStr) {} /// \p Instr gives the original instruction that triggered the diagnostic. /// \p MsgStr gives the message. @@ -157,29 +169,58 @@ public: } }; -/// Diagnostic information for stack size reporting. +/// Diagnostic information for stack size etc. reporting. /// This is basically a function and a size. -class DiagnosticInfoStackSize : public DiagnosticInfo { +class DiagnosticInfoResourceLimit : public DiagnosticInfo { private: - /// The function that is concerned by this stack size diagnostic. + /// The function that is concerned by this resource limit diagnostic. const Function &Fn; - /// The computed stack size. - unsigned StackSize; + + /// Description of the resource type (e.g. stack size) + const char *ResourceName; + + /// The computed size usage + uint64_t ResourceSize; + + // Threshould passed + uint64_t ResourceLimit; public: /// \p The function that is concerned by this stack size diagnostic. /// \p The computed stack size. - DiagnosticInfoStackSize(const Function &Fn, unsigned StackSize, - DiagnosticSeverity Severity = DS_Warning) - : DiagnosticInfo(DK_StackSize, Severity), Fn(Fn), StackSize(StackSize) {} + DiagnosticInfoResourceLimit(const Function &Fn, const char *ResourceName, + uint64_t ResourceSize, + DiagnosticSeverity Severity = DS_Warning, + DiagnosticKind Kind = DK_ResourceLimit, + uint64_t ResourceLimit = 0) + : DiagnosticInfo(Kind, Severity), Fn(Fn), ResourceName(ResourceName), + ResourceSize(ResourceSize), ResourceLimit(ResourceLimit) {} const Function &getFunction() const { return Fn; } - unsigned getStackSize() const { return StackSize; } + const char *getResourceName() const { return ResourceName; } + uint64_t getResourceSize() const { return ResourceSize; } + uint64_t getResourceLimit() const { return ResourceLimit; } /// \see DiagnosticInfo::print. void print(DiagnosticPrinter &DP) const override; static bool classof(const DiagnosticInfo *DI) { + return DI->getKind() == DK_ResourceLimit || DI->getKind() == DK_StackSize; + } +}; + +class DiagnosticInfoStackSize : public DiagnosticInfoResourceLimit { +public: + DiagnosticInfoStackSize(const Function &Fn, uint64_t StackSize, + DiagnosticSeverity Severity = DS_Warning, + uint64_t StackLimit = 0) + : DiagnosticInfoResourceLimit(Fn, "stack size", StackSize, Severity, + DK_StackSize, StackLimit) {} + + uint64_t getStackSize() const { return getResourceSize(); } + uint64_t getStackLimit() const { return getResourceLimit(); } + + static bool classof(const DiagnosticInfo *DI) { return DI->getKind() == DK_StackSize; } }; @@ -197,7 +238,7 @@ public: /// \p The module that is concerned by this debug metadata version diagnostic. /// \p The actual metadata version. DiagnosticInfoDebugMetadataVersion(const Module &M, unsigned MetadataVersion, - DiagnosticSeverity Severity = DS_Warning) + DiagnosticSeverity Severity = DS_Warning) : DiagnosticInfo(DK_DebugMetadataVersion, Severity), M(M), MetadataVersion(MetadataVersion) {} @@ -212,6 +253,28 @@ public: } }; +/// Diagnostic information for stripping invalid debug metadata. +class DiagnosticInfoIgnoringInvalidDebugMetadata : public DiagnosticInfo { +private: + /// The module that is concerned by this debug metadata version diagnostic. + const Module &M; + +public: + /// \p The module that is concerned by this debug metadata version diagnostic. + DiagnosticInfoIgnoringInvalidDebugMetadata( + const Module &M, DiagnosticSeverity Severity = DS_Warning) + : DiagnosticInfo(DK_DebugMetadataVersion, Severity), M(M) {} + + const Module &getModule() const { return M; } + + /// \see DiagnosticInfo::print. + void print(DiagnosticPrinter &DP) const override; + + static bool classof(const DiagnosticInfo *DI) { + return DI->getKind() == DK_DebugMetadataInvalid; + } +}; + /// Diagnostic information for the sample profiler. class DiagnosticInfoSampleProfile : public DiagnosticInfo { public: @@ -223,10 +286,10 @@ public: DiagnosticInfoSampleProfile(StringRef FileName, const Twine &Msg, DiagnosticSeverity Severity = DS_Error) : DiagnosticInfo(DK_SampleProfile, Severity), FileName(FileName), - LineNum(0), Msg(Msg) {} + Msg(Msg) {} DiagnosticInfoSampleProfile(const Twine &Msg, DiagnosticSeverity Severity = DS_Error) - : DiagnosticInfo(DK_SampleProfile, Severity), LineNum(0), Msg(Msg) {} + : DiagnosticInfo(DK_SampleProfile, Severity), Msg(Msg) {} /// \see DiagnosticInfo::print. void print(DiagnosticPrinter &DP) const override; @@ -245,7 +308,7 @@ private: /// Line number where the diagnostic occurred. If 0, no line number will /// be emitted in the message. - unsigned LineNum; + unsigned LineNum = 0; /// Message to report. const Twine &Msg; @@ -276,19 +339,35 @@ private: const Twine &Msg; }; -/// Common features for diagnostics with an associated DebugLoc -class DiagnosticInfoWithDebugLocBase : public DiagnosticInfo { +class DiagnosticLocation { + StringRef Filename; + unsigned Line = 0; + unsigned Column = 0; + +public: + DiagnosticLocation() = default; + DiagnosticLocation(const DebugLoc &DL); + DiagnosticLocation(const DISubprogram *SP); + + bool isValid() const { return !Filename.empty(); } + StringRef getFilename() const { return Filename; } + unsigned getLine() const { return Line; } + unsigned getColumn() const { return Column; } +}; + +/// Common features for diagnostics with an associated location. +class DiagnosticInfoWithLocationBase : public DiagnosticInfo { public: - /// \p Fn is the function where the diagnostic is being emitted. \p DLoc is + /// \p Fn is the function where the diagnostic is being emitted. \p Loc is /// the location information to use in the diagnostic. - DiagnosticInfoWithDebugLocBase(enum DiagnosticKind Kind, + DiagnosticInfoWithLocationBase(enum DiagnosticKind Kind, enum DiagnosticSeverity Severity, const Function &Fn, - const DebugLoc &DLoc) - : DiagnosticInfo(Kind, Severity), Fn(Fn), DLoc(DLoc) {} + const DiagnosticLocation &Loc) + : DiagnosticInfo(Kind, Severity), Fn(Fn), Loc(Loc) {} /// Return true if location information is available for this diagnostic. - bool isLocationAvailable() const; + bool isLocationAvailable() const { return Loc.isValid(); } /// Return a string with the location information for this diagnostic /// in the format "file:line:col". If location information is not available, @@ -300,32 +379,71 @@ public: void getLocation(StringRef *Filename, unsigned *Line, unsigned *Column) const; const Function &getFunction() const { return Fn; } - const DebugLoc &getDebugLoc() const { return DLoc; } + DiagnosticLocation getLocation() const { return Loc; } private: /// Function where this diagnostic is triggered. const Function &Fn; /// Debug location where this diagnostic is triggered. - DebugLoc DLoc; + DiagnosticLocation Loc; }; -/// Common features for diagnostics dealing with optimization remarks. -class DiagnosticInfoOptimizationBase : public DiagnosticInfoWithDebugLocBase { +/// Common features for diagnostics dealing with optimization remarks +/// that are used by both IR and MIR passes. +class DiagnosticInfoOptimizationBase : public DiagnosticInfoWithLocationBase { public: - /// \p PassName is the name of the pass emitting this diagnostic. - /// \p Fn is the function where the diagnostic is being emitted. \p DLoc is - /// the location information to use in the diagnostic. If line table + /// Used to set IsVerbose via the stream interface. + struct setIsVerbose {}; + + /// When an instance of this is inserted into the stream, the arguments + /// following will not appear in the remark printed in the compiler output + /// (-Rpass) but only in the optimization record file + /// (-fsave-optimization-record). + struct setExtraArgs {}; + + /// Used in the streaming interface as the general argument type. It + /// internally converts everything into a key-value pair. + struct Argument { + std::string Key; + std::string Val; + // If set, the debug location corresponding to the value. + DiagnosticLocation Loc; + + explicit Argument(StringRef Str = "") : Key("String"), Val(Str) {} + Argument(StringRef Key, const Value *V); + Argument(StringRef Key, const Type *T); + Argument(StringRef Key, StringRef S); + Argument(StringRef Key, const char *S) : Argument(Key, StringRef(S)) {}; + Argument(StringRef Key, int N); + Argument(StringRef Key, float N); + Argument(StringRef Key, long N); + Argument(StringRef Key, long long N); + Argument(StringRef Key, unsigned N); + Argument(StringRef Key, unsigned long N); + Argument(StringRef Key, unsigned long long N); + Argument(StringRef Key, bool B) : Key(Key), Val(B ? "true" : "false") {} + Argument(StringRef Key, DebugLoc dl); + }; + + /// \p PassName is the name of the pass emitting this diagnostic. \p + /// RemarkName is a textual identifier for the remark (single-word, + /// camel-case). \p Fn is the function where the diagnostic is being emitted. + /// \p Loc is the location information to use in the diagnostic. If line table /// information is available, the diagnostic will include the source code - /// location. \p Msg is the message to show. Note that this class does not - /// copy this message, so this reference must be valid for the whole life time - /// of the diagnostic. + /// location. DiagnosticInfoOptimizationBase(enum DiagnosticKind Kind, enum DiagnosticSeverity Severity, - const char *PassName, const Function &Fn, - const DebugLoc &DLoc, const Twine &Msg) - : DiagnosticInfoWithDebugLocBase(Kind, Severity, Fn, DLoc), - PassName(PassName), Msg(Msg) {} + const char *PassName, StringRef RemarkName, + const Function &Fn, + const DiagnosticLocation &Loc) + : DiagnosticInfoWithLocationBase(Kind, Severity, Fn, Loc), + PassName(PassName), RemarkName(RemarkName) {} + + void insert(StringRef S); + void insert(Argument A); + void insert(setIsVerbose V); + void insert(setExtraArgs EA); /// \see DiagnosticInfo::print. void print(DiagnosticPrinter &DP) const override; @@ -337,157 +455,438 @@ public: /// in BackendConsumer::OptimizationRemarkHandler). virtual bool isEnabled() const = 0; - const char *getPassName() const { return PassName; } - const Twine &getMsg() const { return Msg; } + StringRef getPassName() const { return PassName; } + std::string getMsg() const; + Optional getHotness() const { return Hotness; } + void setHotness(Optional H) { Hotness = H; } -private: + bool isVerbose() const { return IsVerbose; } + + static bool classof(const DiagnosticInfo *DI) { + return (DI->getKind() >= DK_FirstRemark && + DI->getKind() <= DK_LastRemark) || + (DI->getKind() >= DK_FirstMachineRemark && + DI->getKind() <= DK_LastMachineRemark); + } + + bool isPassed() const { + return (getKind() == DK_OptimizationRemark || + getKind() == DK_MachineOptimizationRemark); + } + + bool isMissed() const { + return (getKind() == DK_OptimizationRemarkMissed || + getKind() == DK_MachineOptimizationRemarkMissed); + } + + bool isAnalysis() const { + return (getKind() == DK_OptimizationRemarkAnalysis || + getKind() == DK_MachineOptimizationRemarkAnalysis); + } + +protected: /// Name of the pass that triggers this report. If this matches the /// regular expression given in -Rpass=regexp, then the remark will /// be emitted. const char *PassName; - /// Message to report. - const Twine &Msg; + /// Textual identifier for the remark (single-word, camel-case). Can be used + /// by external tools reading the YAML output file for optimization remarks to + /// identify the remark. + StringRef RemarkName; + + /// If profile information is available, this is the number of times the + /// corresponding code was executed in a profile instrumentation run. + Optional Hotness; + + /// Arguments collected via the streaming interface. + SmallVector Args; + + /// The remark is expected to be noisy. + bool IsVerbose = false; + + /// If positive, the index of the first argument that only appear in + /// the optimization records and not in the remark printed in the compiler + /// output. + int FirstExtraArgIndex = -1; + + friend struct yaml::MappingTraits; +}; + +/// Allow the insertion operator to return the actual remark type rather than a +/// common base class. This allows returning the result of the insertion +/// directly by value, e.g. return OptimizationRemarkAnalysis(...) << "blah". +template +RemarkT & +operator<<(RemarkT &R, + typename std::enable_if< + std::is_base_of::value, + StringRef>::type S) { + R.insert(S); + return R; +} + +/// Also allow r-value for the remark to allow insertion into a +/// temporarily-constructed remark. +template +RemarkT & +operator<<(RemarkT &&R, + typename std::enable_if< + std::is_base_of::value, + StringRef>::type S) { + R.insert(S); + return R; +} + +template +RemarkT & +operator<<(RemarkT &R, + typename std::enable_if< + std::is_base_of::value, + DiagnosticInfoOptimizationBase::Argument>::type A) { + R.insert(A); + return R; +} + +template +RemarkT & +operator<<(RemarkT &&R, + typename std::enable_if< + std::is_base_of::value, + DiagnosticInfoOptimizationBase::Argument>::type A) { + R.insert(A); + return R; +} + +template +RemarkT & +operator<<(RemarkT &R, + typename std::enable_if< + std::is_base_of::value, + DiagnosticInfoOptimizationBase::setIsVerbose>::type V) { + R.insert(V); + return R; +} + +template +RemarkT & +operator<<(RemarkT &&R, + typename std::enable_if< + std::is_base_of::value, + DiagnosticInfoOptimizationBase::setIsVerbose>::type V) { + R.insert(V); + return R; +} + +template +RemarkT & +operator<<(RemarkT &R, + typename std::enable_if< + std::is_base_of::value, + DiagnosticInfoOptimizationBase::setExtraArgs>::type EA) { + R.insert(EA); + return R; +} + +/// Common features for diagnostics dealing with optimization remarks +/// that are used by IR passes. +class DiagnosticInfoIROptimization : public DiagnosticInfoOptimizationBase { +public: + /// \p PassName is the name of the pass emitting this diagnostic. \p + /// RemarkName is a textual identifier for the remark (single-word, + /// camel-case). \p Fn is the function where the diagnostic is being emitted. + /// \p Loc is the location information to use in the diagnostic. If line table + /// information is available, the diagnostic will include the source code + /// location. \p CodeRegion is IR value (currently basic block) that the + /// optimization operates on. This is currently used to provide run-time + /// hotness information with PGO. + DiagnosticInfoIROptimization(enum DiagnosticKind Kind, + enum DiagnosticSeverity Severity, + const char *PassName, StringRef RemarkName, + const Function &Fn, + const DiagnosticLocation &Loc, + const Value *CodeRegion = nullptr) + : DiagnosticInfoOptimizationBase(Kind, Severity, PassName, RemarkName, Fn, + Loc), + CodeRegion(CodeRegion) {} + + /// This is ctor variant allows a pass to build an optimization remark + /// from an existing remark. + /// + /// This is useful when a transformation pass (e.g LV) wants to emit a remark + /// (\p Orig) generated by one of its analyses (e.g. LAA) as its own analysis + /// remark. The string \p Prepend will be emitted before the original + /// message. + DiagnosticInfoIROptimization(const char *PassName, StringRef Prepend, + const DiagnosticInfoIROptimization &Orig) + : DiagnosticInfoOptimizationBase( + (DiagnosticKind)Orig.getKind(), Orig.getSeverity(), PassName, + Orig.RemarkName, Orig.getFunction(), Orig.getLocation()), + CodeRegion(Orig.getCodeRegion()) { + *this << Prepend; + std::copy(Orig.Args.begin(), Orig.Args.end(), std::back_inserter(Args)); + } + + /// Legacy interface. + /// \p PassName is the name of the pass emitting this diagnostic. + /// \p Fn is the function where the diagnostic is being emitted. \p Loc is + /// the location information to use in the diagnostic. If line table + /// information is available, the diagnostic will include the source code + /// location. \p Msg is the message to show. Note that this class does not + /// copy this message, so this reference must be valid for the whole life time + /// of the diagnostic. + DiagnosticInfoIROptimization(enum DiagnosticKind Kind, + enum DiagnosticSeverity Severity, + const char *PassName, const Function &Fn, + const DiagnosticLocation &Loc, const Twine &Msg) + : DiagnosticInfoOptimizationBase(Kind, Severity, PassName, "", Fn, Loc) { + *this << Msg.str(); + } + + const Value *getCodeRegion() const { return CodeRegion; } + + static bool classof(const DiagnosticInfo *DI) { + return DI->getKind() >= DK_FirstRemark && DI->getKind() <= DK_LastRemark; + } + +private: + /// The IR value (currently basic block) that the optimization operates on. + /// This is currently used to provide run-time hotness information with PGO. + const Value *CodeRegion; }; /// Diagnostic information for applied optimization remarks. -class DiagnosticInfoOptimizationRemark : public DiagnosticInfoOptimizationBase { +class OptimizationRemark : public DiagnosticInfoIROptimization { public: + /// \p PassName is the name of the pass emitting this diagnostic. If this name + /// matches the regular expression given in -Rpass=, then the diagnostic will + /// be emitted. \p RemarkName is a textual identifier for the remark (single- + /// word, camel-case). \p Loc is the debug location and \p CodeRegion is the + /// region that the optimization operates on (currently only block is + /// supported). + OptimizationRemark(const char *PassName, StringRef RemarkName, + const DiagnosticLocation &Loc, const Value *CodeRegion); + + /// Same as above, but the debug location and code region are derived from \p + /// Instr. + OptimizationRemark(const char *PassName, StringRef RemarkName, + const Instruction *Inst); + + /// Same as above, but the debug location and code region are derived from \p + /// Func. + OptimizationRemark(const char *PassName, StringRef RemarkName, + const Function *Func); + + static bool classof(const DiagnosticInfo *DI) { + return DI->getKind() == DK_OptimizationRemark; + } + + /// \see DiagnosticInfoOptimizationBase::isEnabled. + bool isEnabled() const override; + +private: + /// This is deprecated now and only used by the function API below. /// \p PassName is the name of the pass emitting this diagnostic. If /// this name matches the regular expression given in -Rpass=, then the /// diagnostic will be emitted. \p Fn is the function where the diagnostic - /// is being emitted. \p DLoc is the location information to use in the + /// is being emitted. \p Loc is the location information to use in the /// diagnostic. If line table information is available, the diagnostic /// will include the source code location. \p Msg is the message to show. /// Note that this class does not copy this message, so this reference /// must be valid for the whole life time of the diagnostic. - DiagnosticInfoOptimizationRemark(const char *PassName, const Function &Fn, - const DebugLoc &DLoc, const Twine &Msg) - : DiagnosticInfoOptimizationBase(DK_OptimizationRemark, DS_Remark, - PassName, Fn, DLoc, Msg) {} + OptimizationRemark(const char *PassName, const Function &Fn, + const DiagnosticLocation &Loc, const Twine &Msg) + : DiagnosticInfoIROptimization(DK_OptimizationRemark, DS_Remark, PassName, + Fn, Loc, Msg) {} +}; + +/// Diagnostic information for missed-optimization remarks. +class OptimizationRemarkMissed : public DiagnosticInfoIROptimization { +public: + /// \p PassName is the name of the pass emitting this diagnostic. If this name + /// matches the regular expression given in -Rpass-missed=, then the + /// diagnostic will be emitted. \p RemarkName is a textual identifier for the + /// remark (single-word, camel-case). \p Loc is the debug location and \p + /// CodeRegion is the region that the optimization operates on (currently only + /// block is supported). + OptimizationRemarkMissed(const char *PassName, StringRef RemarkName, + const DiagnosticLocation &Loc, + const Value *CodeRegion); + + /// Same as above but \p Inst is used to derive code region and debug + /// location. + OptimizationRemarkMissed(const char *PassName, StringRef RemarkName, + const Instruction *Inst); static bool classof(const DiagnosticInfo *DI) { - return DI->getKind() == DK_OptimizationRemark; + return DI->getKind() == DK_OptimizationRemarkMissed; } /// \see DiagnosticInfoOptimizationBase::isEnabled. bool isEnabled() const override; -}; -/// Diagnostic information for missed-optimization remarks. -class DiagnosticInfoOptimizationRemarkMissed - : public DiagnosticInfoOptimizationBase { -public: +private: + /// This is deprecated now and only used by the function API below. /// \p PassName is the name of the pass emitting this diagnostic. If /// this name matches the regular expression given in -Rpass-missed=, then the /// diagnostic will be emitted. \p Fn is the function where the diagnostic - /// is being emitted. \p DLoc is the location information to use in the + /// is being emitted. \p Loc is the location information to use in the /// diagnostic. If line table information is available, the diagnostic /// will include the source code location. \p Msg is the message to show. /// Note that this class does not copy this message, so this reference /// must be valid for the whole life time of the diagnostic. - DiagnosticInfoOptimizationRemarkMissed(const char *PassName, - const Function &Fn, - const DebugLoc &DLoc, const Twine &Msg) - : DiagnosticInfoOptimizationBase(DK_OptimizationRemarkMissed, DS_Remark, - PassName, Fn, DLoc, Msg) {} + OptimizationRemarkMissed(const char *PassName, const Function &Fn, + const DiagnosticLocation &Loc, const Twine &Msg) + : DiagnosticInfoIROptimization(DK_OptimizationRemarkMissed, DS_Remark, + PassName, Fn, Loc, Msg) {} +}; + +/// Diagnostic information for optimization analysis remarks. +class OptimizationRemarkAnalysis : public DiagnosticInfoIROptimization { +public: + /// \p PassName is the name of the pass emitting this diagnostic. If this name + /// matches the regular expression given in -Rpass-analysis=, then the + /// diagnostic will be emitted. \p RemarkName is a textual identifier for the + /// remark (single-word, camel-case). \p Loc is the debug location and \p + /// CodeRegion is the region that the optimization operates on (currently only + /// block is supported). + OptimizationRemarkAnalysis(const char *PassName, StringRef RemarkName, + const DiagnosticLocation &Loc, + const Value *CodeRegion); + + /// This is ctor variant allows a pass to build an optimization remark + /// from an existing remark. + /// + /// This is useful when a transformation pass (e.g LV) wants to emit a remark + /// (\p Orig) generated by one of its analyses (e.g. LAA) as its own analysis + /// remark. The string \p Prepend will be emitted before the original + /// message. + OptimizationRemarkAnalysis(const char *PassName, StringRef Prepend, + const OptimizationRemarkAnalysis &Orig) + : DiagnosticInfoIROptimization(PassName, Prepend, Orig) {} + + /// Same as above but \p Inst is used to derive code region and debug + /// location. + OptimizationRemarkAnalysis(const char *PassName, StringRef RemarkName, + const Instruction *Inst); static bool classof(const DiagnosticInfo *DI) { - return DI->getKind() == DK_OptimizationRemarkMissed; + return DI->getKind() == DK_OptimizationRemarkAnalysis; } /// \see DiagnosticInfoOptimizationBase::isEnabled. bool isEnabled() const override; -}; -/// Diagnostic information for optimization analysis remarks. -class DiagnosticInfoOptimizationRemarkAnalysis - : public DiagnosticInfoOptimizationBase { -public: + static const char *AlwaysPrint; + + bool shouldAlwaysPrint() const { return getPassName() == AlwaysPrint; } + +protected: + OptimizationRemarkAnalysis(enum DiagnosticKind Kind, const char *PassName, + const Function &Fn, const DiagnosticLocation &Loc, + const Twine &Msg) + : DiagnosticInfoIROptimization(Kind, DS_Remark, PassName, Fn, Loc, Msg) {} + + OptimizationRemarkAnalysis(enum DiagnosticKind Kind, const char *PassName, + StringRef RemarkName, + const DiagnosticLocation &Loc, + const Value *CodeRegion); + +private: + /// This is deprecated now and only used by the function API below. /// \p PassName is the name of the pass emitting this diagnostic. If /// this name matches the regular expression given in -Rpass-analysis=, then /// the diagnostic will be emitted. \p Fn is the function where the diagnostic - /// is being emitted. \p DLoc is the location information to use in the + /// is being emitted. \p Loc is the location information to use in the /// diagnostic. If line table information is available, the diagnostic will /// include the source code location. \p Msg is the message to show. Note that /// this class does not copy this message, so this reference must be valid for /// the whole life time of the diagnostic. - DiagnosticInfoOptimizationRemarkAnalysis(const char *PassName, - const Function &Fn, - const DebugLoc &DLoc, - const Twine &Msg) - : DiagnosticInfoOptimizationBase(DK_OptimizationRemarkAnalysis, DS_Remark, - PassName, Fn, DLoc, Msg) {} - - static bool classof(const DiagnosticInfo *DI) { - return DI->getKind() == DK_OptimizationRemarkAnalysis; - } - - /// \see DiagnosticInfoOptimizationBase::isEnabled. - bool isEnabled() const override; - -protected: - DiagnosticInfoOptimizationRemarkAnalysis(enum DiagnosticKind Kind, - const char *PassName, - const Function &Fn, - const DebugLoc &DLoc, - const Twine &Msg) - : DiagnosticInfoOptimizationBase(Kind, DS_Remark, PassName, Fn, DLoc, - Msg) {} + OptimizationRemarkAnalysis(const char *PassName, const Function &Fn, + const DiagnosticLocation &Loc, const Twine &Msg) + : DiagnosticInfoIROptimization(DK_OptimizationRemarkAnalysis, DS_Remark, + PassName, Fn, Loc, Msg) {} }; /// Diagnostic information for optimization analysis remarks related to /// floating-point non-commutativity. -class DiagnosticInfoOptimizationRemarkAnalysisFPCommute - : public DiagnosticInfoOptimizationRemarkAnalysis { +class OptimizationRemarkAnalysisFPCommute : public OptimizationRemarkAnalysis { public: + /// \p PassName is the name of the pass emitting this diagnostic. If this name + /// matches the regular expression given in -Rpass-analysis=, then the + /// diagnostic will be emitted. \p RemarkName is a textual identifier for the + /// remark (single-word, camel-case). \p Loc is the debug location and \p + /// CodeRegion is the region that the optimization operates on (currently only + /// block is supported). The front-end will append its own message related to + /// options that address floating-point non-commutativity. + OptimizationRemarkAnalysisFPCommute(const char *PassName, + StringRef RemarkName, + const DiagnosticLocation &Loc, + const Value *CodeRegion) + : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisFPCommute, + PassName, RemarkName, Loc, CodeRegion) {} + + static bool classof(const DiagnosticInfo *DI) { + return DI->getKind() == DK_OptimizationRemarkAnalysisFPCommute; + } + +private: + /// This is deprecated now and only used by the function API below. /// \p PassName is the name of the pass emitting this diagnostic. If /// this name matches the regular expression given in -Rpass-analysis=, then /// the diagnostic will be emitted. \p Fn is the function where the diagnostic - /// is being emitted. \p DLoc is the location information to use in the + /// is being emitted. \p Loc is the location information to use in the /// diagnostic. If line table information is available, the diagnostic will /// include the source code location. \p Msg is the message to show. The /// front-end will append its own message related to options that address /// floating-point non-commutativity. Note that this class does not copy this /// message, so this reference must be valid for the whole life time of the /// diagnostic. - DiagnosticInfoOptimizationRemarkAnalysisFPCommute(const char *PassName, - const Function &Fn, - const DebugLoc &DLoc, - const Twine &Msg) - : DiagnosticInfoOptimizationRemarkAnalysis( - DK_OptimizationRemarkAnalysisFPCommute, PassName, Fn, DLoc, Msg) {} - - static bool classof(const DiagnosticInfo *DI) { - return DI->getKind() == DK_OptimizationRemarkAnalysisFPCommute; - } + OptimizationRemarkAnalysisFPCommute(const char *PassName, const Function &Fn, + const DiagnosticLocation &Loc, + const Twine &Msg) + : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisFPCommute, + PassName, Fn, Loc, Msg) {} }; /// Diagnostic information for optimization analysis remarks related to /// pointer aliasing. -class DiagnosticInfoOptimizationRemarkAnalysisAliasing - : public DiagnosticInfoOptimizationRemarkAnalysis { +class OptimizationRemarkAnalysisAliasing : public OptimizationRemarkAnalysis { public: + /// \p PassName is the name of the pass emitting this diagnostic. If this name + /// matches the regular expression given in -Rpass-analysis=, then the + /// diagnostic will be emitted. \p RemarkName is a textual identifier for the + /// remark (single-word, camel-case). \p Loc is the debug location and \p + /// CodeRegion is the region that the optimization operates on (currently only + /// block is supported). The front-end will append its own message related to + /// options that address pointer aliasing legality. + OptimizationRemarkAnalysisAliasing(const char *PassName, StringRef RemarkName, + const DiagnosticLocation &Loc, + const Value *CodeRegion) + : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisAliasing, + PassName, RemarkName, Loc, CodeRegion) {} + + static bool classof(const DiagnosticInfo *DI) { + return DI->getKind() == DK_OptimizationRemarkAnalysisAliasing; + } + +private: + /// This is deprecated now and only used by the function API below. /// \p PassName is the name of the pass emitting this diagnostic. If /// this name matches the regular expression given in -Rpass-analysis=, then /// the diagnostic will be emitted. \p Fn is the function where the diagnostic - /// is being emitted. \p DLoc is the location information to use in the + /// is being emitted. \p Loc is the location information to use in the /// diagnostic. If line table information is available, the diagnostic will /// include the source code location. \p Msg is the message to show. The /// front-end will append its own message related to options that address /// pointer aliasing legality. Note that this class does not copy this /// message, so this reference must be valid for the whole life time of the /// diagnostic. - DiagnosticInfoOptimizationRemarkAnalysisAliasing(const char *PassName, - const Function &Fn, - const DebugLoc &DLoc, - const Twine &Msg) - : DiagnosticInfoOptimizationRemarkAnalysis( - DK_OptimizationRemarkAnalysisAliasing, PassName, Fn, DLoc, Msg) {} - - static bool classof(const DiagnosticInfo *DI) { - return DI->getKind() == DK_OptimizationRemarkAnalysisAliasing; - } + OptimizationRemarkAnalysisAliasing(const char *PassName, const Function &Fn, + const DiagnosticLocation &Loc, + const Twine &Msg) + : OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisAliasing, + PassName, Fn, Loc, Msg) {} }; /// Diagnostic information for machine IR parser. @@ -508,76 +907,51 @@ public: } }; +/// Diagnostic information for ISel fallback path. +class DiagnosticInfoISelFallback : public DiagnosticInfo { + /// The function that is concerned by this diagnostic. + const Function &Fn; + +public: + DiagnosticInfoISelFallback(const Function &Fn, + DiagnosticSeverity Severity = DS_Warning) + : DiagnosticInfo(DK_ISelFallback, Severity), Fn(Fn) {} + + const Function &getFunction() const { return Fn; } + + void print(DiagnosticPrinter &DP) const override; + + static bool classof(const DiagnosticInfo *DI) { + return DI->getKind() == DK_ISelFallback; + } +}; + // Create wrappers for C Binding types (see CBindingWrapping.h). DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DiagnosticInfo, LLVMDiagnosticInfoRef) -/// Emit an optimization-applied message. \p PassName is the name of the pass -/// emitting the message. If -Rpass= is given and \p PassName matches the -/// regular expression in -Rpass, then the remark will be emitted. \p Fn is -/// the function triggering the remark, \p DLoc is the debug location where -/// the diagnostic is generated. \p Msg is the message string to use. -void emitOptimizationRemark(LLVMContext &Ctx, const char *PassName, - const Function &Fn, const DebugLoc &DLoc, - const Twine &Msg); - -/// Emit an optimization-missed message. \p PassName is the name of the -/// pass emitting the message. If -Rpass-missed= is given and \p PassName -/// matches the regular expression in -Rpass, then the remark will be -/// emitted. \p Fn is the function triggering the remark, \p DLoc is the -/// debug location where the diagnostic is generated. \p Msg is the -/// message string to use. -void emitOptimizationRemarkMissed(LLVMContext &Ctx, const char *PassName, - const Function &Fn, const DebugLoc &DLoc, - const Twine &Msg); - -/// Emit an optimization analysis remark message. \p PassName is the name of -/// the pass emitting the message. If -Rpass-analysis= is given and \p -/// PassName matches the regular expression in -Rpass, then the remark will be -/// emitted. \p Fn is the function triggering the remark, \p DLoc is the debug -/// location where the diagnostic is generated. \p Msg is the message string -/// to use. -void emitOptimizationRemarkAnalysis(LLVMContext &Ctx, const char *PassName, - const Function &Fn, const DebugLoc &DLoc, - const Twine &Msg); - -/// Emit an optimization analysis remark related to messages about -/// floating-point non-commutativity. \p PassName is the name of the pass -/// emitting the message. If -Rpass-analysis= is given and \p PassName matches -/// the regular expression in -Rpass, then the remark will be emitted. \p Fn is -/// the function triggering the remark, \p DLoc is the debug location where the -/// diagnostic is generated. \p Msg is the message string to use. -void emitOptimizationRemarkAnalysisFPCommute(LLVMContext &Ctx, - const char *PassName, - const Function &Fn, - const DebugLoc &DLoc, - const Twine &Msg); - -/// Emit an optimization analysis remark related to messages about -/// pointer aliasing. \p PassName is the name of the pass emitting the message. -/// If -Rpass-analysis= is given and \p PassName matches the regular expression -/// in -Rpass, then the remark will be emitted. \p Fn is the function triggering -/// the remark, \p DLoc is the debug location where the diagnostic is generated. -/// \p Msg is the message string to use. -void emitOptimizationRemarkAnalysisAliasing(LLVMContext &Ctx, - const char *PassName, - const Function &Fn, - const DebugLoc &DLoc, - const Twine &Msg); - /// Diagnostic information for optimization failures. -class DiagnosticInfoOptimizationFailure - : public DiagnosticInfoOptimizationBase { +class DiagnosticInfoOptimizationFailure : public DiagnosticInfoIROptimization { public: - /// \p Fn is the function where the diagnostic is being emitted. \p DLoc is + /// \p Fn is the function where the diagnostic is being emitted. \p Loc is /// the location information to use in the diagnostic. If line table /// information is available, the diagnostic will include the source code /// location. \p Msg is the message to show. Note that this class does not /// copy this message, so this reference must be valid for the whole life time /// of the diagnostic. - DiagnosticInfoOptimizationFailure(const Function &Fn, const DebugLoc &DLoc, + DiagnosticInfoOptimizationFailure(const Function &Fn, + const DiagnosticLocation &Loc, const Twine &Msg) - : DiagnosticInfoOptimizationBase(DK_OptimizationFailure, DS_Warning, - nullptr, Fn, DLoc, Msg) {} + : DiagnosticInfoIROptimization(DK_OptimizationFailure, DS_Warning, + nullptr, Fn, Loc, Msg) {} + + /// \p PassName is the name of the pass emitting this diagnostic. \p + /// RemarkName is a textual identifier for the remark (single-word, + /// camel-case). \p Loc is the debug location and \p CodeRegion is the + /// region that the optimization operates on (currently basic block is + /// supported). + DiagnosticInfoOptimizationFailure(const char *PassName, StringRef RemarkName, + const DiagnosticLocation &Loc, + const Value *CodeRegion); static bool classof(const DiagnosticInfo *DI) { return DI->getKind() == DK_OptimizationFailure; @@ -588,21 +962,22 @@ public: }; /// Diagnostic information for unsupported feature in backend. -class DiagnosticInfoUnsupported - : public DiagnosticInfoWithDebugLocBase { +class DiagnosticInfoUnsupported : public DiagnosticInfoWithLocationBase { private: Twine Msg; public: - /// \p Fn is the function where the diagnostic is being emitted. \p DLoc is + /// \p Fn is the function where the diagnostic is being emitted. \p Loc is /// the location information to use in the diagnostic. If line table /// information is available, the diagnostic will include the source code /// location. \p Msg is the message to show. Note that this class does not /// copy this message, so this reference must be valid for the whole life time /// of the diagnostic. - DiagnosticInfoUnsupported(const Function &Fn, const Twine &Msg, - DebugLoc DLoc = DebugLoc()) - : DiagnosticInfoWithDebugLocBase(DK_Unsupported, DS_Error, Fn, DLoc), + DiagnosticInfoUnsupported( + const Function &Fn, const Twine &Msg, + const DiagnosticLocation &Loc = DiagnosticLocation(), + DiagnosticSeverity Severity = DS_Error) + : DiagnosticInfoWithLocationBase(DK_Unsupported, Severity, Fn, Loc), Msg(Msg) {} static bool classof(const DiagnosticInfo *DI) { @@ -611,21 +986,15 @@ public: const Twine &getMessage() const { return Msg; } - void print(DiagnosticPrinter &DP) const; + void print(DiagnosticPrinter &DP) const override; }; -/// Emit a warning when loop vectorization is specified but fails. \p Fn is the -/// function triggering the warning, \p DLoc is the debug location where the -/// diagnostic is generated. \p Msg is the message string to use. -void emitLoopVectorizeWarning(LLVMContext &Ctx, const Function &Fn, - const DebugLoc &DLoc, const Twine &Msg); - -/// Emit a warning when loop interleaving is specified but fails. \p Fn is the -/// function triggering the warning, \p DLoc is the debug location where the -/// diagnostic is generated. \p Msg is the message string to use. -void emitLoopInterleaveWarning(LLVMContext &Ctx, const Function &Fn, - const DebugLoc &DLoc, const Twine &Msg); +namespace yaml { +template <> struct MappingTraits { + static void mapping(IO &io, DiagnosticInfoOptimizationBase *&OptDiag); +}; +} // namespace yaml -} // End namespace llvm +} // end namespace llvm -#endif +#endif // LLVM_IR_DIAGNOSTICINFO_H