12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031 |
- #pragma once
- #ifdef __GNUC__
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wunused-parameter"
- #endif
- //===- llvm/IR/DiagnosticInfo.h - Diagnostic Declaration --------*- C++ -*-===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- //
- // This file declares the different classes involved in low level diagnostics.
- //
- // Diagnostics reporting is still done as part of the LLVMContext.
- //===----------------------------------------------------------------------===//
- #ifndef LLVM_IR_DIAGNOSTICINFO_H
- #define LLVM_IR_DIAGNOSTICINFO_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/Support/CBindingWrapping.h"
- #include "llvm/Support/TypeSize.h"
- #include "llvm/Support/YAMLTraits.h"
- #include <algorithm>
- #include <cstdint>
- #include <functional>
- #include <iterator>
- #include <string>
- namespace llvm {
- // Forward declarations.
- class DiagnosticPrinter;
- class Function;
- class Instruction;
- class InstructionCost;
- class LLVMContext;
- class Module;
- class SMDiagnostic;
- /// Defines the different supported severity of a diagnostic.
- enum DiagnosticSeverity : char {
- DS_Error,
- DS_Warning,
- DS_Remark,
- // A note attaches additional information to one of the previous diagnostic
- // types.
- DS_Note
- };
- /// 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_InlineAsm,
- DK_ResourceLimit,
- DK_StackSize,
- DK_Linker,
- DK_Lowering,
- DK_DebugMetadataVersion,
- DK_DebugMetadataInvalid,
- DK_ISelFallback,
- DK_SampleProfile,
- DK_OptimizationRemark,
- DK_OptimizationRemarkMissed,
- DK_OptimizationRemarkAnalysis,
- 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 // Must be last value to work with
- // getNextAvailablePluginDiagnosticKind
- };
- /// 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
- /// and assign it to each of its classes.
- /// The returned ID will be greater than or equal to DK_FirstPluginKind.
- /// Thus, the plugin identifiers will not conflict with the
- /// DiagnosticKind values.
- int getNextAvailablePluginDiagnosticKind();
- /// 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
- /// frontend).
- class DiagnosticInfo {
- private:
- /// Kind defines the kind of report this is about.
- const /* DiagnosticKind */ int Kind;
- /// Severity gives the severity of the diagnostic.
- const DiagnosticSeverity Severity;
- virtual void anchor();
- public:
- DiagnosticInfo(/* DiagnosticKind */ int Kind, DiagnosticSeverity Severity)
- : Kind(Kind), Severity(Severity) {}
- virtual ~DiagnosticInfo() = default;
- /* DiagnosticKind */ int getKind() const { return Kind; }
- DiagnosticSeverity getSeverity() const { return Severity; }
- /// Print using the given \p DP a user-friendly message.
- /// This is the default message that will be printed to the user.
- /// It is used when the frontend does not directly take advantage
- /// of the information contained in fields of the subclasses.
- /// The printed message must not end with '.' nor start with a severity
- /// keyword.
- virtual void print(DiagnosticPrinter &DP) const = 0;
- };
- using DiagnosticHandlerFunction = std::function<void(const DiagnosticInfo &)>;
- /// 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 = 0;
- /// Message to be reported.
- const Twine &MsgStr;
- /// Optional origin of the problem.
- const Instruction *Instr = nullptr;
- public:
- /// \p MsgStr is the message to be reported to the frontend.
- /// This class does not copy \p MsgStr, therefore the reference must be valid
- /// for the whole life time of the Diagnostic.
- DiagnosticInfoInlineAsm(const Twine &MsgStr,
- DiagnosticSeverity Severity = DS_Error)
- : DiagnosticInfo(DK_InlineAsm, Severity), MsgStr(MsgStr) {}
- /// \p LocCookie if non-zero gives the line number for this report.
- /// \p MsgStr gives the message.
- /// This class does not copy \p MsgStr, therefore the reference must be valid
- /// for the whole life time of the Diagnostic.
- DiagnosticInfoInlineAsm(unsigned LocCookie, const Twine &MsgStr,
- DiagnosticSeverity Severity = DS_Error)
- : DiagnosticInfo(DK_InlineAsm, Severity), LocCookie(LocCookie),
- MsgStr(MsgStr) {}
- /// \p Instr gives the original instruction that triggered the diagnostic.
- /// \p MsgStr gives the message.
- /// This class does not copy \p MsgStr, therefore the reference must be valid
- /// for the whole life time of the Diagnostic.
- /// Same for \p I.
- DiagnosticInfoInlineAsm(const Instruction &I, const Twine &MsgStr,
- DiagnosticSeverity Severity = DS_Error);
- unsigned getLocCookie() const { return LocCookie; }
- const Twine &getMsgStr() const { return MsgStr; }
- const Instruction *getInstruction() const { return Instr; }
- /// \see DiagnosticInfo::print.
- void print(DiagnosticPrinter &DP) const override;
- static bool classof(const DiagnosticInfo *DI) {
- return DI->getKind() == DK_InlineAsm;
- }
- };
- /// Diagnostic information for stack size etc. reporting.
- /// This is basically a function and a size.
- class DiagnosticInfoResourceLimit : public DiagnosticInfo {
- private:
- /// The function that is concerned by this resource limit diagnostic.
- const Function &Fn;
- /// 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.
- 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; }
- 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 {
- void anchor() override;
- 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;
- }
- };
- /// Diagnostic information for debug metadata version reporting.
- /// This is basically a module and a version.
- class DiagnosticInfoDebugMetadataVersion : public DiagnosticInfo {
- private:
- /// The module that is concerned by this debug metadata version diagnostic.
- const Module &M;
- /// The actual metadata version.
- unsigned MetadataVersion;
- 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)
- : DiagnosticInfo(DK_DebugMetadataVersion, Severity), M(M),
- MetadataVersion(MetadataVersion) {}
- const Module &getModule() const { return M; }
- unsigned getMetadataVersion() const { return MetadataVersion; }
- /// \see DiagnosticInfo::print.
- void print(DiagnosticPrinter &DP) const override;
- static bool classof(const DiagnosticInfo *DI) {
- return DI->getKind() == DK_DebugMetadataVersion;
- }
- };
- /// 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:
- DiagnosticInfoSampleProfile(StringRef FileName, unsigned LineNum,
- const Twine &Msg,
- DiagnosticSeverity Severity = DS_Error)
- : DiagnosticInfo(DK_SampleProfile, Severity), FileName(FileName),
- LineNum(LineNum), Msg(Msg) {}
- DiagnosticInfoSampleProfile(StringRef FileName, const Twine &Msg,
- DiagnosticSeverity Severity = DS_Error)
- : DiagnosticInfo(DK_SampleProfile, Severity), FileName(FileName),
- Msg(Msg) {}
- DiagnosticInfoSampleProfile(const Twine &Msg,
- DiagnosticSeverity Severity = DS_Error)
- : DiagnosticInfo(DK_SampleProfile, Severity), Msg(Msg) {}
- /// \see DiagnosticInfo::print.
- void print(DiagnosticPrinter &DP) const override;
- static bool classof(const DiagnosticInfo *DI) {
- return DI->getKind() == DK_SampleProfile;
- }
- StringRef getFileName() const { return FileName; }
- unsigned getLineNum() const { return LineNum; }
- const Twine &getMsg() const { return Msg; }
- private:
- /// Name of the input file associated with this diagnostic.
- StringRef FileName;
- /// Line number where the diagnostic occurred. If 0, no line number will
- /// be emitted in the message.
- unsigned LineNum = 0;
- /// Message to report.
- const Twine &Msg;
- };
- /// Diagnostic information for the PGO profiler.
- class DiagnosticInfoPGOProfile : public DiagnosticInfo {
- public:
- DiagnosticInfoPGOProfile(const char *FileName, const Twine &Msg,
- DiagnosticSeverity Severity = DS_Error)
- : DiagnosticInfo(DK_PGOProfile, Severity), FileName(FileName), Msg(Msg) {}
- /// \see DiagnosticInfo::print.
- void print(DiagnosticPrinter &DP) const override;
- static bool classof(const DiagnosticInfo *DI) {
- return DI->getKind() == DK_PGOProfile;
- }
- const char *getFileName() const { return FileName; }
- const Twine &getMsg() const { return Msg; }
- private:
- /// Name of the input file associated with this diagnostic.
- const char *FileName;
- /// Message to report.
- const Twine &Msg;
- };
- class DiagnosticLocation {
- DIFile *File = nullptr;
- unsigned Line = 0;
- unsigned Column = 0;
- public:
- DiagnosticLocation() = default;
- DiagnosticLocation(const DebugLoc &DL);
- DiagnosticLocation(const DISubprogram *SP);
- bool isValid() const { return File; }
- /// Return the full path to the file.
- std::string getAbsolutePath() const;
- /// Return the file name relative to the compilation directory.
- StringRef getRelativePath() const;
- unsigned getLine() const { return Line; }
- unsigned getColumn() const { return Column; }
- };
- /// Common features for diagnostics with an associated location.
- class DiagnosticInfoWithLocationBase : public DiagnosticInfo {
- void anchor() override;
- public:
- /// \p Fn is the function where the diagnostic is being emitted. \p Loc is
- /// the location information to use in the diagnostic.
- DiagnosticInfoWithLocationBase(enum DiagnosticKind Kind,
- enum DiagnosticSeverity Severity,
- const Function &Fn,
- const DiagnosticLocation &Loc)
- : DiagnosticInfo(Kind, Severity), Fn(Fn), Loc(Loc) {}
- /// Return true if location information is available for this diagnostic.
- 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,
- /// it returns "<unknown>:0:0".
- const std::string getLocationStr() const;
- /// Return location information for this diagnostic in three parts:
- /// the relative source file path, line number and column.
- void getLocation(StringRef &RelativePath, unsigned &Line,
- unsigned &Column) const;
- /// Return the absolute path tot the file.
- std::string getAbsolutePath() const;
-
- const Function &getFunction() const { return Fn; }
- DiagnosticLocation getLocation() const { return Loc; }
- private:
- /// Function where this diagnostic is triggered.
- const Function &Fn;
- /// Debug location where this diagnostic is triggered.
- DiagnosticLocation Loc;
- };
- /// Common features for diagnostics dealing with optimization remarks
- /// that are used by both IR and MIR passes.
- class DiagnosticInfoOptimizationBase : public DiagnosticInfoWithLocationBase {
- public:
- /// 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, ElementCount EC);
- Argument(StringRef Key, bool B) : Key(Key), Val(B ? "true" : "false") {}
- Argument(StringRef Key, DebugLoc dl);
- Argument(StringRef Key, InstructionCost C);
- };
- /// \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.
- DiagnosticInfoOptimizationBase(enum DiagnosticKind Kind,
- enum DiagnosticSeverity Severity,
- 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;
- /// Return true if this optimization remark is enabled by one of
- /// of the LLVM command line flags (-pass-remarks, -pass-remarks-missed,
- /// or -pass-remarks-analysis). Note that this only handles the LLVM
- /// flags. We cannot access Clang flags from here (they are handled
- /// in BackendConsumer::OptimizationRemarkHandler).
- virtual bool isEnabled() const = 0;
- StringRef getPassName() const { return PassName; }
- StringRef getRemarkName() const { return RemarkName; }
- std::string getMsg() const;
- Optional<uint64_t> getHotness() const { return Hotness; }
- void setHotness(Optional<uint64_t> H) { Hotness = H; }
- bool isVerbose() const { return IsVerbose; }
- ArrayRef<Argument> getArgs() const { return Args; }
- 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;
- /// Textual identifier for the remark (single-word, camel-case). Can be used
- /// by external tools reading the 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<uint64_t> Hotness;
- /// Arguments collected via the streaming interface.
- SmallVector<Argument, 4> 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;
- };
- /// 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 <class RemarkT>
- RemarkT &
- operator<<(RemarkT &R,
- std::enable_if_t<
- std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
- StringRef>
- S) {
- R.insert(S);
- return R;
- }
- /// Also allow r-value for the remark to allow insertion into a
- /// temporarily-constructed remark.
- template <class RemarkT>
- RemarkT &
- operator<<(RemarkT &&R,
- std::enable_if_t<
- std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
- StringRef>
- S) {
- R.insert(S);
- return R;
- }
- template <class RemarkT>
- RemarkT &
- operator<<(RemarkT &R,
- std::enable_if_t<
- std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
- DiagnosticInfoOptimizationBase::Argument>
- A) {
- R.insert(A);
- return R;
- }
- template <class RemarkT>
- RemarkT &
- operator<<(RemarkT &&R,
- std::enable_if_t<
- std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
- DiagnosticInfoOptimizationBase::Argument>
- A) {
- R.insert(A);
- return R;
- }
- template <class RemarkT>
- RemarkT &
- operator<<(RemarkT &R,
- std::enable_if_t<
- std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
- DiagnosticInfoOptimizationBase::setIsVerbose>
- V) {
- R.insert(V);
- return R;
- }
- template <class RemarkT>
- RemarkT &
- operator<<(RemarkT &&R,
- std::enable_if_t<
- std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
- DiagnosticInfoOptimizationBase::setIsVerbose>
- V) {
- R.insert(V);
- return R;
- }
- template <class RemarkT>
- RemarkT &
- operator<<(RemarkT &R,
- std::enable_if_t<
- std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
- DiagnosticInfoOptimizationBase::setExtraArgs>
- EA) {
- R.insert(EA);
- return R;
- }
- /// Common features for diagnostics dealing with optimization remarks
- /// that are used by IR passes.
- class DiagnosticInfoIROptimization : public DiagnosticInfoOptimizationBase {
- void anchor() override;
- 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 = nullptr;
- };
- /// Diagnostic information for applied optimization remarks.
- 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 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.
- 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_OptimizationRemarkMissed;
- }
- /// \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-missed=, then the
- /// diagnostic will be emitted. \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.
- 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_OptimizationRemarkAnalysis;
- }
- /// \see DiagnosticInfoOptimizationBase::isEnabled.
- bool isEnabled() const override;
- 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 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.
- 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 OptimizationRemarkAnalysisFPCommute : public OptimizationRemarkAnalysis {
- void anchor() override;
- 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 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.
- 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 OptimizationRemarkAnalysisAliasing : public OptimizationRemarkAnalysis {
- void anchor() override;
- 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 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.
- 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.
- class DiagnosticInfoMIRParser : public DiagnosticInfo {
- const SMDiagnostic &Diagnostic;
- public:
- DiagnosticInfoMIRParser(DiagnosticSeverity Severity,
- const SMDiagnostic &Diagnostic)
- : DiagnosticInfo(DK_MIRParser, Severity), Diagnostic(Diagnostic) {}
- const SMDiagnostic &getDiagnostic() const { return Diagnostic; }
- void print(DiagnosticPrinter &DP) const override;
- static bool classof(const DiagnosticInfo *DI) {
- return DI->getKind() == DK_MIRParser;
- }
- };
- /// 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)
- /// Diagnostic information for optimization failures.
- class DiagnosticInfoOptimizationFailure : public DiagnosticInfoIROptimization {
- public:
- /// \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 DiagnosticLocation &Loc,
- const Twine &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;
- }
- /// \see DiagnosticInfoOptimizationBase::isEnabled.
- bool isEnabled() const override;
- };
- /// Diagnostic information for unsupported feature in backend.
- class DiagnosticInfoUnsupported : public DiagnosticInfoWithLocationBase {
- private:
- Twine Msg;
- public:
- /// \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,
- const DiagnosticLocation &Loc = DiagnosticLocation(),
- DiagnosticSeverity Severity = DS_Error)
- : DiagnosticInfoWithLocationBase(DK_Unsupported, Severity, Fn, Loc),
- Msg(Msg) {}
- static bool classof(const DiagnosticInfo *DI) {
- return DI->getKind() == DK_Unsupported;
- }
- const Twine &getMessage() const { return Msg; }
- void print(DiagnosticPrinter &DP) const override;
- };
- } // end namespace llvm
- #endif // LLVM_IR_DIAGNOSTICINFO_H
- #ifdef __GNUC__
- #pragma GCC diagnostic pop
- #endif
|