From: Francis Visoiu Mistrih Date: Mon, 17 Jun 2019 16:06:00 +0000 (+0000) Subject: [Remarks] Extend -fsave-optimization-record to specify the format X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=1cb383ef62173c35ee4c3ee7f5dde9739e8cc4de;p=llvm [Remarks] Extend -fsave-optimization-record to specify the format Use -fsave-optimization-record= to specify a different format than the default, which is YAML. For now, only YAML is supported. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@363573 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/IR/RemarkStreamer.h b/include/llvm/IR/RemarkStreamer.h index 4ba8491a9b4..9b6d82ee30c 100644 --- a/include/llvm/IR/RemarkStreamer.h +++ b/include/llvm/IR/RemarkStreamer.h @@ -85,10 +85,20 @@ struct RemarkSetupPatternError : RemarkSetupErrorInfo { using RemarkSetupErrorInfo::RemarkSetupErrorInfo; }; +struct RemarkSetupFormatError : RemarkSetupErrorInfo { + static char ID; + using RemarkSetupErrorInfo::RemarkSetupErrorInfo; +}; + +enum class RemarksSerializerFormat { Unknown, YAML }; + +Expected parseSerializerFormat(StringRef Format); + /// Setup optimization remarks. Expected> setupOptimizationRemarks(LLVMContext &Context, StringRef RemarksFilename, - StringRef RemarksPasses, bool RemarksWithHotness, + StringRef RemarksPasses, StringRef RemarksFormat, + bool RemarksWithHotness, unsigned RemarksHotnessThreshold = 0); } // end namespace llvm diff --git a/include/llvm/LTO/Config.h b/include/llvm/LTO/Config.h index 25c423715f1..fb107e3fbe0 100644 --- a/include/llvm/LTO/Config.h +++ b/include/llvm/LTO/Config.h @@ -108,6 +108,9 @@ struct Config { /// 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; diff --git a/include/llvm/LTO/LTO.h b/include/llvm/LTO/LTO.h index cbddede66c0..ca0a8b64523 100644 --- a/include/llvm/LTO/LTO.h +++ b/include/llvm/LTO/LTO.h @@ -20,6 +20,7 @@ #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" @@ -85,8 +86,8 @@ std::string getThinLTOOutputFile(const std::string &Path, /// Setup optimization remarks. Expected> 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> diff --git a/lib/IR/RemarkStreamer.cpp b/lib/IR/RemarkStreamer.cpp index e0f9a9d70c3..2c3bc8406e5 100644 --- a/lib/IR/RemarkStreamer.cpp +++ b/lib/IR/RemarkStreamer.cpp @@ -109,10 +109,37 @@ void RemarkStreamer::emit(const DiagnosticInfoOptimizationBase &Diag) { char RemarkSetupFileError::ID = 0; char RemarkSetupPatternError::ID = 0; +char RemarkSetupFormatError::ID = 0; + +static std::unique_ptr +formatToSerializer(RemarksSerializerFormat RemarksFormat, raw_ostream &OS) { + switch (RemarksFormat) { + default: + llvm_unreachable("Unknown remark serializer format."); + return nullptr; + case RemarksSerializerFormat::YAML: + return llvm::make_unique(OS); + }; +} + +Expected +llvm::parseSerializerFormat(StringRef StrFormat) { + auto Format = StringSwitch(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> llvm::setupOptimizationRemarks(LLVMContext &Context, StringRef RemarksFilename, - StringRef RemarksPasses, bool RemarksWithHotness, + StringRef RemarksPasses, StringRef RemarksFormat, + bool RemarksWithHotness, unsigned RemarksHotnessThreshold) { if (RemarksWithHotness) Context.setDiagnosticsHotnessRequested(true); @@ -131,9 +158,13 @@ llvm::setupOptimizationRemarks(LLVMContext &Context, StringRef RemarksFilename, if (EC) return make_error(errorCodeToError(EC)); + Expected Format = + parseSerializerFormat(RemarksFormat); + if (Error E = Format.takeError()) + return make_error(std::move(E)); + Context.setRemarkStreamer(llvm::make_unique( - RemarksFilename, - llvm::make_unique(RemarksFile->os()))); + RemarksFilename, formatToSerializer(*Format, RemarksFile->os()))); if (!RemarksPasses.empty()) if (Error E = Context.getRemarkStreamer()->setFilter(RemarksPasses)) diff --git a/lib/LTO/LTO.cpp b/lib/LTO/LTO.cpp index fe1bdfcaa96..4ed13701aa9 100644 --- a/lib/LTO/LTO.cpp +++ b/lib/LTO/LTO.cpp @@ -1339,14 +1339,14 @@ Error LTO::runThinLTO(AddStreamFn AddStream, NativeObjectCache Cache, Expected> 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); diff --git a/lib/LTO/LTOBackend.cpp b/lib/LTO/LTOBackend.cpp index b0a7c434b67..7456e717516 100644 --- a/lib/LTO/LTOBackend.cpp +++ b/lib/LTO/LTOBackend.cpp @@ -431,9 +431,9 @@ Error lto::backend(Config &C, AddStreamFn AddStream, std::unique_ptr 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); @@ -488,7 +488,7 @@ Error lto::thinBackend(Config &Conf, unsigned Task, AddStreamFn AddStream, // 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); diff --git a/lib/LTO/LTOCodeGenerator.cpp b/lib/LTO/LTOCodeGenerator.cpp index ebc4cc5794a..6bb3bfaefc9 100644 --- a/lib/LTO/LTOCodeGenerator.cpp +++ b/lib/LTO/LTOCodeGenerator.cpp @@ -97,6 +97,11 @@ cl::opt "names match the given regular expression"), cl::value_desc("regex")); +cl::opt RemarksFormat( + "lto-pass-remarks-format", + cl::desc("The format used for serializing remarks (default: YAML)"), + cl::value_desc("format"), cl::init("yaml")); + cl::opt LTOStatsFile( "lto-stats-file", cl::desc("Save statistics to the specified file"), @@ -517,8 +522,9 @@ bool LTOCodeGenerator::optimize(bool DisableVerify, bool DisableInline, 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"); diff --git a/lib/LTO/ThinLTOCodeGenerator.cpp b/lib/LTO/ThinLTOCodeGenerator.cpp index 5d9aa8e571b..b5dbab0ca8f 100644 --- a/lib/LTO/ThinLTOCodeGenerator.cpp +++ b/lib/LTO/ThinLTOCodeGenerator.cpp @@ -73,6 +73,7 @@ extern cl::opt LTODiscardValueNames; extern cl::opt RemarksFilename; extern cl::opt RemarksPasses; extern cl::opt RemarksWithHotness; +extern cl::opt RemarksFormat; } namespace { @@ -1020,7 +1021,7 @@ void ThinLTOCodeGenerator::run() { 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"; diff --git a/test/ThinLTO/X86/diagnostic-handler-remarks.ll b/test/ThinLTO/X86/diagnostic-handler-remarks.ll index 4c13fe804d6..f0ff9542ee1 100644 --- a/test/ThinLTO/X86/diagnostic-handler-remarks.ll +++ b/test/ThinLTO/X86/diagnostic-handler-remarks.ll @@ -6,6 +6,7 @@ ; 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 diff --git a/test/tools/gold/X86/opt-remarks.ll b/test/tools/gold/X86/opt-remarks.ll index 4f8ae2c843c..c95447f0b55 100644 --- a/test/tools/gold/X86/opt-remarks.ll +++ b/test/tools/gold/X86/opt-remarks.ll @@ -3,10 +3,12 @@ ; 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 diff --git a/tools/gold/gold-plugin.cpp b/tools/gold/gold-plugin.cpp index 314d8637623..1cd287cb668 100644 --- a/tools/gold/gold-plugin.cpp +++ b/tools/gold/gold-plugin.cpp @@ -209,6 +209,7 @@ namespace options { 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; @@ -290,6 +291,8 @@ namespace options { 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 { @@ -913,6 +916,7 @@ static std::unique_ptr createLTO(IndexWriteCallback OnIndexWrite, 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; diff --git a/tools/llc/llc.cpp b/tools/llc/llc.cpp index 48a810cf6eb..76da843f065 100644 --- a/tools/llc/llc.cpp +++ b/tools/llc/llc.cpp @@ -155,6 +155,11 @@ static cl::opt "names match the given regular expression"), cl::value_desc("regex")); +static cl::opt RemarksFormat( + "pass-remarks-format", + cl::desc("The format used for serializing remarks (default: YAML)"), + cl::value_desc("format"), cl::init("yaml")); + namespace { static ManagedStatic> RunPassNames; @@ -329,7 +334,8 @@ int main(int argc, char **argv) { Expected> 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; diff --git a/tools/llvm-lto2/llvm-lto2.cpp b/tools/llvm-lto2/llvm-lto2.cpp index 7f8b5beb716..0bd9289dc93 100644 --- a/tools/llvm-lto2/llvm-lto2.cpp +++ b/tools/llvm-lto2/llvm-lto2.cpp @@ -107,6 +107,11 @@ static cl::opt "names match the given regular expression"), cl::value_desc("regex")); +static cl::opt RemarksFormat( + "pass-remarks-format", + cl::desc("The format used for serializing remarks (default: YAML)"), + cl::value_desc("format"), cl::init("yaml")); + static cl::opt SamplePGOFile("lto-sample-profile-file", cl::desc("Specify a SamplePGO profile file")); @@ -229,6 +234,7 @@ static int run(int argc, char **argv) { Conf.RemarksFilename = RemarksFilename; Conf.RemarksPasses = RemarksPasses; Conf.RemarksWithHotness = RemarksWithHotness; + Conf.RemarksFormat = RemarksFormat; Conf.SampleProfile = SamplePGOFile; Conf.CSIRProfile = CSPGOFile; diff --git a/tools/opt/opt.cpp b/tools/opt/opt.cpp index dde1d776fef..ccf8b073b82 100644 --- a/tools/opt/opt.cpp +++ b/tools/opt/opt.cpp @@ -273,6 +273,11 @@ static cl::opt "names match the given regular expression"), cl::value_desc("regex")); +static cl::opt RemarksFormat( + "pass-remarks-format", + cl::desc("The format used for serializing remarks (default: YAML)"), + cl::value_desc("format"), cl::init("yaml")); + cl::opt PGOKindFlag("pgo-kind", cl::init(NoPGO), cl::Hidden, cl::desc("The kind of profile guided optimization"), @@ -552,7 +557,8 @@ int main(int argc, char **argv) { Expected> RemarksFileOrErr = setupOptimizationRemarks(Context, RemarksFilename, RemarksPasses, - RemarksWithHotness, RemarksHotnessThreshold); + RemarksFormat, RemarksWithHotness, + RemarksHotnessThreshold); if (Error E = RemarksFileOrErr.takeError()) { errs() << toString(std::move(E)) << '\n'; return 1;