using RemarkSetupErrorInfo<RemarkSetupPatternError>::RemarkSetupErrorInfo;
};
+struct RemarkSetupFormatError : RemarkSetupErrorInfo<RemarkSetupFormatError> {
+ static char ID;
+ using RemarkSetupErrorInfo<RemarkSetupFormatError>::RemarkSetupErrorInfo;
+};
+
+enum class RemarksSerializerFormat { Unknown, YAML };
+
+Expected<RemarksSerializerFormat> parseSerializerFormat(StringRef Format);
+
/// Setup optimization remarks.
Expected<std::unique_ptr<ToolOutputFile>>
setupOptimizationRemarks(LLVMContext &Context, StringRef RemarksFilename,
- StringRef RemarksPasses, bool RemarksWithHotness,
+ StringRef RemarksPasses, StringRef RemarksFormat,
+ bool RemarksWithHotness,
unsigned RemarksHotnessThreshold = 0);
} // end namespace llvm
/// Whether to emit optimization remarks with hotness informations.
bool RemarksWithHotness = false;
+ /// The format used for serializing remarks (default: YAML).
+ std::string RemarksFormat = "";
+
/// Whether to emit the pass manager debuggging informations.
bool DebugPassManager = false;
#include "llvm/ADT/StringSet.h"
#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/IR/ModuleSummaryIndex.h"
+#include "llvm/IR/RemarkStreamer.h"
#include "llvm/LTO/Config.h"
#include "llvm/Linker/IRMover.h"
#include "llvm/Object/IRSymtab.h"
/// Setup optimization remarks.
Expected<std::unique_ptr<ToolOutputFile>>
setupOptimizationRemarks(LLVMContext &Context, StringRef RemarksFilename,
- StringRef RemarksPasses, bool RemarksWithHotness,
- int Count = -1);
+ StringRef RemarksPasses, StringRef RemarksFormat,
+ bool RemarksWithHotness, int Count = -1);
/// Setups the output file for saving statistics.
Expected<std::unique_ptr<ToolOutputFile>>
char RemarkSetupFileError::ID = 0;
char RemarkSetupPatternError::ID = 0;
+char RemarkSetupFormatError::ID = 0;
+
+static std::unique_ptr<remarks::Serializer>
+formatToSerializer(RemarksSerializerFormat RemarksFormat, raw_ostream &OS) {
+ switch (RemarksFormat) {
+ default:
+ llvm_unreachable("Unknown remark serializer format.");
+ return nullptr;
+ case RemarksSerializerFormat::YAML:
+ return llvm::make_unique<remarks::YAMLSerializer>(OS);
+ };
+}
+
+Expected<RemarksSerializerFormat>
+llvm::parseSerializerFormat(StringRef StrFormat) {
+ auto Format = StringSwitch<RemarksSerializerFormat>(StrFormat)
+ .Cases("", "yaml", RemarksSerializerFormat::YAML)
+ .Default(RemarksSerializerFormat::Unknown);
+
+ if (Format == RemarksSerializerFormat::Unknown)
+ return createStringError(std::make_error_code(std::errc::invalid_argument),
+ "Unknown remark serializer format: '%s'",
+ StrFormat.data());
+
+ return Format;
+}
Expected<std::unique_ptr<ToolOutputFile>>
llvm::setupOptimizationRemarks(LLVMContext &Context, StringRef RemarksFilename,
- StringRef RemarksPasses, bool RemarksWithHotness,
+ StringRef RemarksPasses, StringRef RemarksFormat,
+ bool RemarksWithHotness,
unsigned RemarksHotnessThreshold) {
if (RemarksWithHotness)
Context.setDiagnosticsHotnessRequested(true);
if (EC)
return make_error<RemarkSetupFileError>(errorCodeToError(EC));
+ Expected<RemarksSerializerFormat> Format =
+ parseSerializerFormat(RemarksFormat);
+ if (Error E = Format.takeError())
+ return make_error<RemarkSetupFormatError>(std::move(E));
+
Context.setRemarkStreamer(llvm::make_unique<RemarkStreamer>(
- RemarksFilename,
- llvm::make_unique<remarks::YAMLSerializer>(RemarksFile->os())));
+ RemarksFilename, formatToSerializer(*Format, RemarksFile->os())));
if (!RemarksPasses.empty())
if (Error E = Context.getRemarkStreamer()->setFilter(RemarksPasses))
Expected<std::unique_ptr<ToolOutputFile>>
lto::setupOptimizationRemarks(LLVMContext &Context, StringRef RemarksFilename,
- StringRef RemarksPasses, bool RemarksWithHotness,
- int Count) {
+ StringRef RemarksPasses, StringRef RemarksFormat,
+ bool RemarksWithHotness, int Count) {
std::string Filename = RemarksFilename;
if (!Filename.empty() && Count != -1)
Filename += ".thin." + llvm::utostr(Count) + ".yaml";
auto ResultOrErr = llvm::setupOptimizationRemarks(
- Context, Filename, RemarksPasses, RemarksWithHotness);
+ Context, Filename, RemarksPasses, RemarksFormat, RemarksWithHotness);
if (Error E = ResultOrErr.takeError())
return std::move(E);
std::unique_ptr<TargetMachine> TM = createTargetMachine(C, *TOrErr, *Mod);
// Setup optimization remarks.
- auto DiagFileOrErr =
- lto::setupOptimizationRemarks(Mod->getContext(), C.RemarksFilename,
- C.RemarksPasses, C.RemarksWithHotness);
+ auto DiagFileOrErr = lto::setupOptimizationRemarks(
+ Mod->getContext(), C.RemarksFilename, C.RemarksPasses, C.RemarksFormat,
+ C.RemarksWithHotness);
if (!DiagFileOrErr)
return DiagFileOrErr.takeError();
auto DiagnosticOutputFile = std::move(*DiagFileOrErr);
// Setup optimization remarks.
auto DiagFileOrErr = lto::setupOptimizationRemarks(
Mod.getContext(), Conf.RemarksFilename, Conf.RemarksPasses,
- Conf.RemarksWithHotness, Task);
+ Conf.RemarksFormat, Conf.RemarksWithHotness, Task);
if (!DiagFileOrErr)
return DiagFileOrErr.takeError();
auto DiagnosticOutputFile = std::move(*DiagFileOrErr);
"names match the given regular expression"),
cl::value_desc("regex"));
+cl::opt<std::string> RemarksFormat(
+ "lto-pass-remarks-format",
+ cl::desc("The format used for serializing remarks (default: YAML)"),
+ cl::value_desc("format"), cl::init("yaml"));
+
cl::opt<std::string> LTOStatsFile(
"lto-stats-file",
cl::desc("Save statistics to the specified file"),
if (!this->determineTarget())
return false;
- auto DiagFileOrErr = lto::setupOptimizationRemarks(
- Context, RemarksFilename, RemarksPasses, RemarksWithHotness);
+ auto DiagFileOrErr =
+ lto::setupOptimizationRemarks(Context, RemarksFilename, RemarksPasses,
+ RemarksFormat, RemarksWithHotness);
if (!DiagFileOrErr) {
errs() << "Error: " << toString(DiagFileOrErr.takeError()) << "\n";
report_fatal_error("Can't get an output file for the remarks");
extern cl::opt<std::string> RemarksFilename;
extern cl::opt<std::string> RemarksPasses;
extern cl::opt<bool> RemarksWithHotness;
+extern cl::opt<std::string> RemarksFormat;
}
namespace {
Context.setDiscardValueNames(LTODiscardValueNames);
Context.enableDebugTypeODRUniquing();
auto DiagFileOrErr = lto::setupOptimizationRemarks(
- Context, RemarksFilename, RemarksPasses,
+ Context, RemarksFilename, RemarksPasses, RemarksFormat,
RemarksWithHotness, count);
if (!DiagFileOrErr) {
errs() << "Error: " << toString(DiagFileOrErr.takeError()) << "\n";
; RUN: llvm-lto -thinlto-action=run \
; RUN: -lto-pass-remarks-output=%t.yaml \
; RUN: -lto-pass-remarks-filter=inline \
+; RUN: -lto-pass-remarks-format=yaml \
; RUN: -exported-symbol _func2 \
; RUN: -exported-symbol _main %t1.bc %t2.bc 2>&1 | \
; RUN: FileCheck %s -allow-empty
; RUN: %gold -m elf_x86_64 -plugin %llvmshlibdir/LLVMgold%shlibext -shared \
; RUN: -plugin-opt=save-temps \
; RUN: -plugin-opt=opt-remarks-passes=inline \
+; RUN: -plugin-opt=opt-remarks-format=yaml \
; RUN: -plugin-opt=opt-remarks-filename=%t.yaml %t.o -o %t2.o 2>&1
; RUN: llvm-dis %t2.o.0.4.opt.bc -o - | FileCheck %s
; RUN: %gold -m elf_x86_64 -plugin %llvmshlibdir/LLVMgold%shlibext -shared \
; RUN: -plugin-opt=opt-remarks-passes=inline \
+; RUN: -plugin-opt=opt-remarks-format=yaml \
; RUN: -plugin-opt=opt-remarks-with-hotness \
; RUN: -plugin-opt=opt-remarks-filename=%t.hot.yaml %t.o -o %t2.o 2>&1
; RUN: cat %t.yaml | FileCheck %s -check-prefix=YAML
static std::string RemarksFilename;
static std::string RemarksPasses;
static bool RemarksWithHotness = false;
+ static std::string RemarksFormat;
// Context sensitive PGO options.
static std::string cs_profile_path;
RemarksPasses = opt.substr(strlen("opt-remarks-passes="));
} else if (opt == "opt-remarks-with-hotness") {
RemarksWithHotness = true;
+ } else if (opt.startswith("opt-remarks-format=")) {
+ RemarksFormat = opt.substr(strlen("opt-remarks-format="));
} else if (opt.startswith("stats-file=")) {
stats_file = opt.substr(strlen("stats-file="));
} else {
Conf.RemarksFilename = options::RemarksFilename;
Conf.RemarksPasses = options::RemarksPasses;
Conf.RemarksWithHotness = options::RemarksWithHotness;
+ Conf.RemarksFormat = options::RemarksFormat;
// Use new pass manager if set in driver
Conf.UseNewPM = options::new_pass_manager;
"names match the given regular expression"),
cl::value_desc("regex"));
+static cl::opt<std::string> RemarksFormat(
+ "pass-remarks-format",
+ cl::desc("The format used for serializing remarks (default: YAML)"),
+ cl::value_desc("format"), cl::init("yaml"));
+
namespace {
static ManagedStatic<std::vector<std::string>> RunPassNames;
Expected<std::unique_ptr<ToolOutputFile>> RemarksFileOrErr =
setupOptimizationRemarks(Context, RemarksFilename, RemarksPasses,
- RemarksWithHotness, RemarksHotnessThreshold);
+ RemarksFormat, RemarksWithHotness,
+ RemarksHotnessThreshold);
if (Error E = RemarksFileOrErr.takeError()) {
WithColor::error(errs(), argv[0]) << toString(std::move(E)) << '\n';
return 1;
"names match the given regular expression"),
cl::value_desc("regex"));
+static cl::opt<std::string> RemarksFormat(
+ "pass-remarks-format",
+ cl::desc("The format used for serializing remarks (default: YAML)"),
+ cl::value_desc("format"), cl::init("yaml"));
+
static cl::opt<std::string>
SamplePGOFile("lto-sample-profile-file",
cl::desc("Specify a SamplePGO profile file"));
Conf.RemarksFilename = RemarksFilename;
Conf.RemarksPasses = RemarksPasses;
Conf.RemarksWithHotness = RemarksWithHotness;
+ Conf.RemarksFormat = RemarksFormat;
Conf.SampleProfile = SamplePGOFile;
Conf.CSIRProfile = CSPGOFile;
"names match the given regular expression"),
cl::value_desc("regex"));
+static cl::opt<std::string> RemarksFormat(
+ "pass-remarks-format",
+ cl::desc("The format used for serializing remarks (default: YAML)"),
+ cl::value_desc("format"), cl::init("yaml"));
+
cl::opt<PGOKind>
PGOKindFlag("pgo-kind", cl::init(NoPGO), cl::Hidden,
cl::desc("The kind of profile guided optimization"),
Expected<std::unique_ptr<ToolOutputFile>> RemarksFileOrErr =
setupOptimizationRemarks(Context, RemarksFilename, RemarksPasses,
- RemarksWithHotness, RemarksHotnessThreshold);
+ RemarksFormat, RemarksWithHotness,
+ RemarksHotnessThreshold);
if (Error E = RemarksFileOrErr.takeError()) {
errs() << toString(std::move(E)) << '\n';
return 1;