#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/IR/DebugLoc.h"
#include "llvm/Support/CBindingWrapping.h"
#include "llvm/Support/YAMLTraits.h"
-#include "llvm-c/Types.h"
-#include <functional>
#include <algorithm>
#include <cstdint>
+#include <functional>
#include <iterator>
#include <string>
class Module;
class SMDiagnostic;
-/// \brief Defines the different supported severity of a diagnostic.
+/// Defines the different supported severity of a diagnostic.
enum DiagnosticSeverity : char {
DS_Error,
DS_Warning,
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_InlineAsm,
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
/// 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
public:
/// \p The function that is concerned by this stack size diagnostic.
/// \p The computed stack size.
- DiagnosticInfoResourceLimit(const Function &Fn,
- const char *ResourceName,
+ 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) {}
+ : DiagnosticInfo(Kind, Severity), Fn(Fn), ResourceName(ResourceName),
+ ResourceSize(ResourceSize), ResourceLimit(ResourceLimit) {}
const Function &getFunction() const { return Fn; }
const char *getResourceName() const { return ResourceName; }
void print(DiagnosticPrinter &DP) const override;
static bool classof(const DiagnosticInfo *DI) {
- return DI->getKind() == DK_ResourceLimit ||
- DI->getKind() == DK_StackSize;
+ return DI->getKind() == DK_ResourceLimit || DI->getKind() == DK_StackSize;
}
};
class DiagnosticInfoStackSize : public DiagnosticInfoResourceLimit {
public:
- DiagnosticInfoStackSize(const Function &Fn,
- uint64_t StackSize,
+ DiagnosticInfoStackSize(const Function &Fn, uint64_t StackSize,
DiagnosticSeverity Severity = DS_Warning,
uint64_t StackLimit = 0)
- : DiagnosticInfoResourceLimit(Fn, "stack size", StackSize,
- Severity, DK_StackSize, StackLimit) {}
+ : DiagnosticInfoResourceLimit(Fn, "stack size", StackSize, Severity,
+ DK_StackSize, StackLimit) {}
uint64_t getStackSize() const { return getResourceSize(); }
uint64_t getStackLimit() const { return getResourceLimit(); }
/// \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) {}
DiagnosticLocation Loc;
};
-/// \brief Common features for diagnostics dealing with optimization remarks
+/// Common features for diagnostics dealing with optimization remarks
/// that are used by both IR and MIR passes.
class DiagnosticInfoOptimizationBase : public DiagnosticInfoWithLocationBase {
public:
- /// \brief Used to set IsVerbose via the stream interface.
+ /// Used to set IsVerbose via the stream interface.
struct setIsVerbose {};
- /// \brief When an instance of this is inserted into the stream, the arguments
+ /// 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 {};
- /// \brief Used in the streaming interface as the general argument type. It
+ /// Used in the streaming interface as the general argument type. It
/// internally converts everything into a key-value pair.
struct Argument {
- StringRef Key;
+ 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
: DiagnosticInfoWithLocationBase(Kind, Severity, Fn, Loc),
PassName(PassName), RemarkName(RemarkName) {}
- DiagnosticInfoOptimizationBase &operator<<(StringRef S);
- DiagnosticInfoOptimizationBase &operator<<(Argument A);
- DiagnosticInfoOptimizationBase &operator<<(setIsVerbose V);
- DiagnosticInfoOptimizationBase &operator<<(setExtraArgs EA);
+ 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;
/// The remark is expected to be noisy.
bool IsVerbose = false;
- /// \brief If positive, the index of the first argument that only appear in
+ /// 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<DiagnosticInfoOptimizationBase *>;
};
-/// \brief Common features for diagnostics dealing with optimization remarks
+/// 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,
+ typename std::enable_if<
+ std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::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 <class RemarkT>
+RemarkT &
+operator<<(RemarkT &&R,
+ typename std::enable_if<
+ std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
+ StringRef>::type S) {
+ R.insert(S);
+ return R;
+}
+
+template <class RemarkT>
+RemarkT &
+operator<<(RemarkT &R,
+ typename std::enable_if<
+ std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
+ DiagnosticInfoOptimizationBase::Argument>::type A) {
+ R.insert(A);
+ return R;
+}
+
+template <class RemarkT>
+RemarkT &
+operator<<(RemarkT &&R,
+ typename std::enable_if<
+ std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
+ DiagnosticInfoOptimizationBase::Argument>::type A) {
+ R.insert(A);
+ return R;
+}
+
+template <class RemarkT>
+RemarkT &
+operator<<(RemarkT &R,
+ typename std::enable_if<
+ std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
+ DiagnosticInfoOptimizationBase::setIsVerbose>::type V) {
+ R.insert(V);
+ return R;
+}
+
+template <class RemarkT>
+RemarkT &
+operator<<(RemarkT &&R,
+ typename std::enable_if<
+ std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
+ DiagnosticInfoOptimizationBase::setIsVerbose>::type V) {
+ R.insert(V);
+ return R;
+}
+
+template <class RemarkT>
+RemarkT &
+operator<<(RemarkT &R,
+ typename std::enable_if<
+ std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::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:
Loc),
CodeRegion(CodeRegion) {}
- /// \brief This is ctor variant allows a pass to build an optimization remark
+ /// 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
return DI->getKind() == DK_OptimizationRemark;
}
- static bool isEnabled(StringRef PassName);
-
/// \see DiagnosticInfoOptimizationBase::isEnabled.
- bool isEnabled() const override { return isEnabled(getPassName()); }
+ bool isEnabled() const override;
private:
/// This is deprecated now and only used by the function API below.
const DiagnosticLocation &Loc, const Twine &Msg)
: DiagnosticInfoIROptimization(DK_OptimizationRemark, DS_Remark, PassName,
Fn, Loc, Msg) {}
-
- friend void emitOptimizationRemark(LLVMContext &Ctx, const char *PassName,
- const Function &Fn,
- const DiagnosticLocation &Loc,
- const Twine &Msg);
};
/// Diagnostic information for missed-optimization remarks.
const DiagnosticLocation &Loc,
const Value *CodeRegion);
- /// \brief Same as above but \p Inst is used to derive code region and debug
+ /// Same as above but \p Inst is used to derive code region and debug
/// location.
OptimizationRemarkMissed(const char *PassName, StringRef RemarkName,
const Instruction *Inst);
return DI->getKind() == DK_OptimizationRemarkMissed;
}
- static bool isEnabled(StringRef PassName);
-
/// \see DiagnosticInfoOptimizationBase::isEnabled.
- bool isEnabled() const override { return isEnabled(getPassName()); }
+ bool isEnabled() const override;
private:
/// This is deprecated now and only used by the function API below.
const DiagnosticLocation &Loc, const Twine &Msg)
: DiagnosticInfoIROptimization(DK_OptimizationRemarkMissed, DS_Remark,
PassName, Fn, Loc, Msg) {}
-
- friend void emitOptimizationRemarkMissed(LLVMContext &Ctx,
- const char *PassName,
- const Function &Fn,
- const DiagnosticLocation &Loc,
- const Twine &Msg);
};
/// Diagnostic information for optimization analysis remarks.
const DiagnosticLocation &Loc,
const Value *CodeRegion);
- /// \brief This is ctor variant allows a pass to build an optimization remark
+ /// 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
const OptimizationRemarkAnalysis &Orig)
: DiagnosticInfoIROptimization(PassName, Prepend, Orig) {}
- /// \brief Same as above but \p Inst is used to derive code region and debug
+ /// Same as above but \p Inst is used to derive code region and debug
/// location.
OptimizationRemarkAnalysis(const char *PassName, StringRef RemarkName,
const Instruction *Inst);
return DI->getKind() == DK_OptimizationRemarkAnalysis;
}
- static bool isEnabled(StringRef PassName);
-
/// \see DiagnosticInfoOptimizationBase::isEnabled.
- bool isEnabled() const override {
- return shouldAlwaysPrint() || isEnabled(getPassName());
- }
+ bool isEnabled() const override;
static const char *AlwaysPrint;
const DiagnosticLocation &Loc, const Twine &Msg)
: DiagnosticInfoIROptimization(DK_OptimizationRemarkAnalysis, DS_Remark,
PassName, Fn, Loc, Msg) {}
-
- friend void emitOptimizationRemarkAnalysis(LLVMContext &Ctx,
- const char *PassName,
- const Function &Fn,
- const DiagnosticLocation &Loc,
- const Twine &Msg);
};
/// Diagnostic information for optimization analysis remarks related to
const Twine &Msg)
: OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisFPCommute,
PassName, Fn, Loc, Msg) {}
-
- friend void emitOptimizationRemarkAnalysisFPCommute(
- LLVMContext &Ctx, const char *PassName, const Function &Fn,
- const DiagnosticLocation &Loc, const Twine &Msg);
};
/// Diagnostic information for optimization analysis remarks related to
const Twine &Msg)
: OptimizationRemarkAnalysis(DK_OptimizationRemarkAnalysisAliasing,
PassName, Fn, Loc, Msg) {}
-
- friend void emitOptimizationRemarkAnalysisAliasing(
- LLVMContext &Ctx, const char *PassName, const Function &Fn,
- const DiagnosticLocation &Loc, const Twine &Msg);
};
/// Diagnostic information for machine IR parser.
// Create wrappers for C Binding types (see CBindingWrapping.h).
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DiagnosticInfo, LLVMDiagnosticInfoRef)
-/// \brief Legacy interface to emit an optimization-applied message. Use
-/// (Machine)OptimizationRemarkEmitter instead.
-///
-/// \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 Loc
-/// 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 DiagnosticLocation &Loc,
- const Twine &Msg);
-
-/// \brief Legacy interface to emit an optimization-missed message. Use
-/// (Machine)OptimizationRemarkEmitter instead.
-///
-/// \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 Loc
-/// 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 DiagnosticLocation &Loc,
- const Twine &Msg);
-
-/// \brief Legacy interface to emit an optimization analysis remark message.
-/// Use (Machine)OptimizationRemarkEmitter instead.
-///
-/// \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 Loc 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 DiagnosticLocation &Loc,
- const Twine &Msg);
-
-/// \brief Legacy interface to emit an optimization analysis remark related to
-/// messages about floating-point non-commutativity. Use
-/// (Machine)OptimizationRemarkEmitter instead.
-///
-/// \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 Loc 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 DiagnosticLocation &Loc,
- const Twine &Msg);
-
-/// \brief Legacy interface to emit an optimization analysis remark related to
-/// messages about pointer aliasing. Use (Machine)OptimizationRemarkEmitter
-/// instead.
-///
-/// \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 Loc 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 DiagnosticLocation &Loc,
- const Twine &Msg);
-
/// Diagnostic information for optimization failures.
class DiagnosticInfoOptimizationFailure : public DiagnosticInfoIROptimization {
public:
void print(DiagnosticPrinter &DP) const override;
};
+namespace yaml {
+template <> struct MappingTraits<DiagnosticInfoOptimizationBase *> {
+ static void mapping(IO &io, DiagnosticInfoOptimizationBase *&OptDiag);
+};
+} // namespace yaml
+
} // end namespace llvm
#endif // LLVM_IR_DIAGNOSTICINFO_H