[Remarks] Refactor optimization remarks setup

* Add a common function to setup opt-remarks
* Rename common options to the same names
* Add error types to distinguish between file errors and regex errors

llvm-svn: 363328
This commit is contained in:
Francis Visoiu Mistrih 2019-06-13 21:46:57 +00:00
parent a5b12be60f
commit 6e6e3af55b
12 changed files with 182 additions and 162 deletions

View File

@ -262,35 +262,32 @@ namespace clang {
Ctx.getDiagnosticHandler(); Ctx.getDiagnosticHandler();
Ctx.setDiagnosticHandler(llvm::make_unique<ClangDiagnosticHandler>( Ctx.setDiagnosticHandler(llvm::make_unique<ClangDiagnosticHandler>(
CodeGenOpts, this)); CodeGenOpts, this));
Ctx.setDiagnosticsHotnessRequested(CodeGenOpts.DiagnosticsWithHotness);
if (CodeGenOpts.DiagnosticsHotnessThreshold != 0)
Ctx.setDiagnosticsHotnessThreshold(
CodeGenOpts.DiagnosticsHotnessThreshold);
std::unique_ptr<llvm::ToolOutputFile> OptRecordFile; Expected<std::unique_ptr<llvm::ToolOutputFile>> OptRecordFileOrErr =
if (!CodeGenOpts.OptRecordFile.empty()) { setupOptimizationRemarks(Ctx, CodeGenOpts.OptRecordFile,
std::error_code EC; CodeGenOpts.OptRecordPasses,
OptRecordFile = llvm::make_unique<llvm::ToolOutputFile>( CodeGenOpts.DiagnosticsWithHotness,
CodeGenOpts.OptRecordFile, EC, sys::fs::F_None); CodeGenOpts.DiagnosticsHotnessThreshold);
if (EC) {
Diags.Report(diag::err_cannot_open_file) <<
CodeGenOpts.OptRecordFile << EC.message();
return;
}
Ctx.setRemarkStreamer(llvm::make_unique<RemarkStreamer>( if (Error E = OptRecordFileOrErr.takeError()) {
CodeGenOpts.OptRecordFile, handleAllErrors(
llvm::make_unique<remarks::YAMLSerializer>(OptRecordFile->os()))); std::move(E),
[&](const RemarkSetupFileError &E) {
if (!CodeGenOpts.OptRecordPasses.empty()) Diags.Report(diag::err_cannot_open_file)
if (Error E = Ctx.getRemarkStreamer()->setFilter( << CodeGenOpts.OptRecordFile << E.message();
CodeGenOpts.OptRecordPasses)) },
Diags.Report(diag::err_drv_optimization_remark_pattern) [&](const RemarkSetupPatternError &E) {
<< toString(std::move(E)) << CodeGenOpts.OptRecordPasses; Diags.Report(diag::err_drv_optimization_remark_pattern)
<< E.message() << CodeGenOpts.OptRecordPasses;
if (CodeGenOpts.getProfileUse() != CodeGenOptions::ProfileNone) });
Ctx.setDiagnosticsHotnessRequested(true); return;
} }
std::unique_ptr<llvm::ToolOutputFile> OptRecordFile =
std::move(*OptRecordFileOrErr);
if (OptRecordFile &&
CodeGenOpts.getProfileUse() != CodeGenOptions::ProfileNone)
Ctx.setDiagnosticsHotnessRequested(true);
// Link each LinkModule into our module. // Link each LinkModule into our module.
if (LinkInModules()) if (LinkInModules())

View File

@ -17,6 +17,7 @@
#include "llvm/Remarks/RemarkSerializer.h" #include "llvm/Remarks/RemarkSerializer.h"
#include "llvm/Support/Error.h" #include "llvm/Support/Error.h"
#include "llvm/Support/Regex.h" #include "llvm/Support/Regex.h"
#include "llvm/Support/ToolOutputFile.h"
#include "llvm/Support/raw_ostream.h" #include "llvm/Support/raw_ostream.h"
#include <string> #include <string>
#include <vector> #include <vector>
@ -57,6 +58,33 @@ public:
/// Emit a diagnostic through the streamer. /// Emit a diagnostic through the streamer.
void emit(const DiagnosticInfoOptimizationBase &Diag); void emit(const DiagnosticInfoOptimizationBase &Diag);
}; };
template <typename ThisError>
struct RemarkSetupErrorInfo : public ErrorInfo<ThisError> {
Error E;
RemarkSetupErrorInfo(Error E) : E(std::move(E)) {}
void log(raw_ostream &OS) const override { OS << E; }
std::error_code convertToErrorCode() const override {
return errorToErrorCode(E);
}
};
struct RemarkSetupFileError : RemarkSetupErrorInfo<RemarkSetupFileError> {
static char ID;
using RemarkSetupErrorInfo<RemarkSetupFileError>::RemarkSetupErrorInfo;
};
struct RemarkSetupPatternError : RemarkSetupErrorInfo<RemarkSetupPatternError> {
static char ID;
using RemarkSetupErrorInfo<RemarkSetupPatternError>::RemarkSetupErrorInfo;
};
/// Setup optimization remarks.
Expected<std::unique_ptr<ToolOutputFile>>
setupOptimizationRemarks(LLVMContext &Context, StringRef RemarksFilename,
StringRef RemarksPasses, bool RemarksWithHotness,
unsigned RemarksHotnessThreshold = 0);
} // end namespace llvm } // end namespace llvm
#endif // LLVM_IR_REMARKSTREAMER_H #endif // LLVM_IR_REMARKSTREAMER_H

View File

@ -84,9 +84,9 @@ std::string getThinLTOOutputFile(const std::string &Path,
/// Setup optimization remarks. /// Setup optimization remarks.
Expected<std::unique_ptr<ToolOutputFile>> Expected<std::unique_ptr<ToolOutputFile>>
setupOptimizationRemarks(LLVMContext &Context, StringRef LTORemarksFilename, setupOptimizationRemarks(LLVMContext &Context, StringRef RemarksFilename,
StringRef LTORemarksPasses, StringRef RemarksPasses, bool RemarksWithHotness,
bool LTOPassRemarksWithHotness, int Count = -1); int Count = -1);
/// Setups the output file for saving statistics. /// Setups the output file for saving statistics.
Expected<std::unique_ptr<ToolOutputFile>> Expected<std::unique_ptr<ToolOutputFile>>

View File

@ -106,3 +106,38 @@ void RemarkStreamer::emit(const DiagnosticInfoOptimizationBase &Diag) {
// Then, emit the remark through the serializer. // Then, emit the remark through the serializer.
Serializer->emit(R); Serializer->emit(R);
} }
char RemarkSetupFileError::ID = 0;
char RemarkSetupPatternError::ID = 0;
Expected<std::unique_ptr<ToolOutputFile>>
llvm::setupOptimizationRemarks(LLVMContext &Context, StringRef RemarksFilename,
StringRef RemarksPasses, bool RemarksWithHotness,
unsigned RemarksHotnessThreshold) {
if (RemarksWithHotness)
Context.setDiagnosticsHotnessRequested(true);
if (RemarksHotnessThreshold)
Context.setDiagnosticsHotnessThreshold(RemarksHotnessThreshold);
if (RemarksFilename.empty())
return nullptr;
std::error_code EC;
auto RemarksFile =
llvm::make_unique<ToolOutputFile>(RemarksFilename, EC, sys::fs::F_None);
// We don't use llvm::FileError here because some diagnostics want the file
// name separately.
if (EC)
return errorCodeToError(EC);
Context.setRemarkStreamer(llvm::make_unique<RemarkStreamer>(
RemarksFilename,
llvm::make_unique<remarks::YAMLSerializer>(RemarksFile->os())));
if (!RemarksPasses.empty())
if (Error E = Context.getRemarkStreamer()->setFilter(RemarksPasses))
return std::move(E);
return std::move(RemarksFile);
}

View File

@ -1338,34 +1338,22 @@ Error LTO::runThinLTO(AddStreamFn AddStream, NativeObjectCache Cache,
} }
Expected<std::unique_ptr<ToolOutputFile>> Expected<std::unique_ptr<ToolOutputFile>>
lto::setupOptimizationRemarks(LLVMContext &Context, lto::setupOptimizationRemarks(LLVMContext &Context, StringRef RemarksFilename,
StringRef LTORemarksFilename, StringRef RemarksPasses, bool RemarksWithHotness,
StringRef LTORemarksPasses, int Count) {
bool LTOPassRemarksWithHotness, int Count) { std::string Filename = RemarksFilename;
if (LTOPassRemarksWithHotness) if (!Filename.empty() && Count != -1)
Context.setDiagnosticsHotnessRequested(true);
if (LTORemarksFilename.empty())
return nullptr;
std::string Filename = LTORemarksFilename;
if (Count != -1)
Filename += ".thin." + llvm::utostr(Count) + ".yaml"; Filename += ".thin." + llvm::utostr(Count) + ".yaml";
std::error_code EC; auto ResultOrErr = llvm::setupOptimizationRemarks(
auto DiagnosticFile = Context, Filename, RemarksPasses, RemarksWithHotness);
llvm::make_unique<ToolOutputFile>(Filename, EC, sys::fs::F_None); if (Error E = ResultOrErr.takeError())
if (EC) return std::move(E);
return errorCodeToError(EC);
Context.setRemarkStreamer(llvm::make_unique<RemarkStreamer>(
Filename,
llvm::make_unique<remarks::YAMLSerializer>(DiagnosticFile->os())));
if (!LTORemarksPasses.empty()) if (*ResultOrErr)
if (Error E = Context.getRemarkStreamer()->setFilter(LTORemarksPasses)) (*ResultOrErr)->keep();
return std::move(E);
DiagnosticFile->keep(); return ResultOrErr;
return std::move(DiagnosticFile);
} }
Expected<std::unique_ptr<ToolOutputFile>> Expected<std::unique_ptr<ToolOutputFile>>

View File

@ -22,6 +22,7 @@
#include "llvm/Bitcode/BitcodeWriter.h" #include "llvm/Bitcode/BitcodeWriter.h"
#include "llvm/IR/LegacyPassManager.h" #include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/PassManager.h" #include "llvm/IR/PassManager.h"
#include "llvm/IR/RemarkStreamer.h"
#include "llvm/IR/Verifier.h" #include "llvm/IR/Verifier.h"
#include "llvm/LTO/LTO.h" #include "llvm/LTO/LTO.h"
#include "llvm/MC/SubtargetFeature.h" #include "llvm/MC/SubtargetFeature.h"
@ -32,9 +33,9 @@
#include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h" #include "llvm/Support/Path.h"
#include "llvm/Support/Program.h" #include "llvm/Support/Program.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/TargetRegistry.h" #include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/ThreadPool.h" #include "llvm/Support/ThreadPool.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetMachine.h"
#include "llvm/Transforms/IPO.h" #include "llvm/Transforms/IPO.h"
#include "llvm/Transforms/IPO/PassManagerBuilder.h" #include "llvm/Transforms/IPO/PassManagerBuilder.h"

View File

@ -33,6 +33,7 @@
#include "llvm/IR/Mangler.h" #include "llvm/IR/Mangler.h"
#include "llvm/IR/Module.h" #include "llvm/IR/Module.h"
#include "llvm/IR/PassTimingInfo.h" #include "llvm/IR/PassTimingInfo.h"
#include "llvm/IR/RemarkStreamer.h"
#include "llvm/IR/Verifier.h" #include "llvm/IR/Verifier.h"
#include "llvm/InitializePasses.h" #include "llvm/InitializePasses.h"
#include "llvm/LTO/LTO.h" #include "llvm/LTO/LTO.h"
@ -80,22 +81,22 @@ cl::opt<bool> LTODiscardValueNames(
#endif #endif
cl::Hidden); cl::Hidden);
cl::opt<std::string> cl::opt<bool> RemarksWithHotness(
LTORemarksFilename("lto-pass-remarks-output",
cl::desc("Output filename for pass remarks"),
cl::value_desc("filename"));
cl::opt<std::string>
LTORemarksPasses("lto-pass-remarks-filter",
cl::desc("Only record optimization remarks from passes "
"whose names match the given regular expression"),
cl::value_desc("regex"));
cl::opt<bool> LTOPassRemarksWithHotness(
"lto-pass-remarks-with-hotness", "lto-pass-remarks-with-hotness",
cl::desc("With PGO, include profile count in optimization remarks"), cl::desc("With PGO, include profile count in optimization remarks"),
cl::Hidden); cl::Hidden);
cl::opt<std::string>
RemarksFilename("lto-pass-remarks-output",
cl::desc("Output filename for pass remarks"),
cl::value_desc("filename"));
cl::opt<std::string>
RemarksPasses("lto-pass-remarks-filter",
cl::desc("Only record optimization remarks from passes whose "
"names match the given regular expression"),
cl::value_desc("regex"));
cl::opt<std::string> LTOStatsFile( cl::opt<std::string> LTOStatsFile(
"lto-stats-file", "lto-stats-file",
cl::desc("Save statistics to the specified file"), cl::desc("Save statistics to the specified file"),
@ -517,7 +518,7 @@ bool LTOCodeGenerator::optimize(bool DisableVerify, bool DisableInline,
return false; return false;
auto DiagFileOrErr = lto::setupOptimizationRemarks( auto DiagFileOrErr = lto::setupOptimizationRemarks(
Context, LTORemarksFilename, LTORemarksPasses, LTOPassRemarksWithHotness); Context, RemarksFilename, RemarksPasses, RemarksWithHotness);
if (!DiagFileOrErr) { if (!DiagFileOrErr) {
errs() << "Error: " << toString(DiagFileOrErr.takeError()) << "\n"; errs() << "Error: " << toString(DiagFileOrErr.takeError()) << "\n";
report_fatal_error("Can't get an output file for the remarks"); report_fatal_error("Can't get an output file for the remarks");

View File

@ -29,6 +29,7 @@
#include "llvm/IR/LegacyPassManager.h" #include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/Mangler.h" #include "llvm/IR/Mangler.h"
#include "llvm/IR/PassTimingInfo.h" #include "llvm/IR/PassTimingInfo.h"
#include "llvm/IR/RemarkStreamer.h"
#include "llvm/IR/Verifier.h" #include "llvm/IR/Verifier.h"
#include "llvm/IRReader/IRReader.h" #include "llvm/IRReader/IRReader.h"
#include "llvm/LTO/LTO.h" #include "llvm/LTO/LTO.h"
@ -69,9 +70,9 @@ using namespace llvm;
namespace llvm { namespace llvm {
// Flags -discard-value-names, defined in LTOCodeGenerator.cpp // Flags -discard-value-names, defined in LTOCodeGenerator.cpp
extern cl::opt<bool> LTODiscardValueNames; extern cl::opt<bool> LTODiscardValueNames;
extern cl::opt<std::string> LTORemarksFilename; extern cl::opt<std::string> RemarksFilename;
extern cl::opt<std::string> LTORemarksPasses; extern cl::opt<std::string> RemarksPasses;
extern cl::opt<bool> LTOPassRemarksWithHotness; extern cl::opt<bool> RemarksWithHotness;
} }
namespace { namespace {
@ -1019,8 +1020,8 @@ void ThinLTOCodeGenerator::run() {
Context.setDiscardValueNames(LTODiscardValueNames); Context.setDiscardValueNames(LTODiscardValueNames);
Context.enableDebugTypeODRUniquing(); Context.enableDebugTypeODRUniquing();
auto DiagFileOrErr = lto::setupOptimizationRemarks( auto DiagFileOrErr = lto::setupOptimizationRemarks(
Context, LTORemarksFilename, LTORemarksPasses, Context, RemarksFilename, RemarksPasses,
LTOPassRemarksWithHotness, count); RemarksWithHotness, count);
if (!DiagFileOrErr) { if (!DiagFileOrErr) {
errs() << "Error: " << toString(DiagFileOrErr.takeError()) << "\n"; errs() << "Error: " << toString(DiagFileOrErr.takeError()) << "\n";
report_fatal_error("ThinLTO: Can't get an output file for the " report_fatal_error("ThinLTO: Can't get an output file for the "

View File

@ -206,9 +206,9 @@ namespace options {
static std::string stats_file; static std::string stats_file;
// Optimization remarks filename, accepted passes and hotness options // Optimization remarks filename, accepted passes and hotness options
static std::string OptRemarksFilename; static std::string RemarksFilename;
static std::string OptRemarksFilter; static std::string RemarksPasses;
static bool OptRemarksWithHotness = false; static bool RemarksWithHotness = false;
// Context sensitive PGO options. // Context sensitive PGO options.
static std::string cs_profile_path; static std::string cs_profile_path;
@ -285,11 +285,11 @@ namespace options {
} else if (opt.startswith("dwo_dir=")) { } else if (opt.startswith("dwo_dir=")) {
dwo_dir = opt.substr(strlen("dwo_dir=")); dwo_dir = opt.substr(strlen("dwo_dir="));
} else if (opt.startswith("opt-remarks-filename=")) { } else if (opt.startswith("opt-remarks-filename=")) {
OptRemarksFilename = opt.substr(strlen("opt-remarks-filename=")); RemarksFilename = opt.substr(strlen("opt-remarks-filename="));
} else if (opt.startswith("opt-remarks-passes=")) { } else if (opt.startswith("opt-remarks-passes=")) {
OptRemarksFilter = opt.substr(strlen("opt-remarks-passes=")); RemarksPasses = opt.substr(strlen("opt-remarks-passes="));
} else if (opt == "opt-remarks-with-hotness") { } else if (opt == "opt-remarks-with-hotness") {
OptRemarksWithHotness = true; RemarksWithHotness = true;
} else if (opt.startswith("stats-file=")) { } else if (opt.startswith("stats-file=")) {
stats_file = opt.substr(strlen("stats-file=")); stats_file = opt.substr(strlen("stats-file="));
} else { } else {
@ -910,9 +910,9 @@ static std::unique_ptr<LTO> createLTO(IndexWriteCallback OnIndexWrite,
Conf.DwoDir = options::dwo_dir; Conf.DwoDir = options::dwo_dir;
// Set up optimization remarks handling. // Set up optimization remarks handling.
Conf.RemarksFilename = options::OptRemarksFilename; Conf.RemarksFilename = options::RemarksFilename;
Conf.RemarksPasses = options::OptRemarksFilter; Conf.RemarksPasses = options::RemarksPasses;
Conf.RemarksWithHotness = options::OptRemarksWithHotness; Conf.RemarksWithHotness = options::RemarksWithHotness;
// Use new pass manager if set in driver // Use new pass manager if set in driver
Conf.UseNewPM = options::new_pass_manager; Conf.UseNewPM = options::new_pass_manager;

View File

@ -133,19 +133,20 @@ static cl::opt<bool> DiscardValueNames(
static cl::list<std::string> IncludeDirs("I", cl::desc("include search path")); static cl::list<std::string> IncludeDirs("I", cl::desc("include search path"));
static cl::opt<bool> PassRemarksWithHotness( static cl::opt<bool> RemarksWithHotness(
"pass-remarks-with-hotness", "pass-remarks-with-hotness",
cl::desc("With PGO, include profile count in optimization remarks"), cl::desc("With PGO, include profile count in optimization remarks"),
cl::Hidden); cl::Hidden);
static cl::opt<unsigned> PassRemarksHotnessThreshold( static cl::opt<unsigned>
"pass-remarks-hotness-threshold", RemarksHotnessThreshold("pass-remarks-hotness-threshold",
cl::desc("Minimum profile count required for an optimization remark to be output"), cl::desc("Minimum profile count required for "
cl::Hidden); "an optimization remark to be output"),
cl::Hidden);
static cl::opt<std::string> static cl::opt<std::string>
RemarksFilename("pass-remarks-output", RemarksFilename("pass-remarks-output",
cl::desc("YAML output filename for pass remarks"), cl::desc("Output filename for pass remarks"),
cl::value_desc("filename")); cl::value_desc("filename"));
static cl::opt<std::string> static cl::opt<std::string>
@ -326,31 +327,14 @@ int main(int argc, char **argv) {
llvm::make_unique<LLCDiagnosticHandler>(&HasError)); llvm::make_unique<LLCDiagnosticHandler>(&HasError));
Context.setInlineAsmDiagnosticHandler(InlineAsmDiagHandler, &HasError); Context.setInlineAsmDiagnosticHandler(InlineAsmDiagHandler, &HasError);
if (PassRemarksWithHotness) Expected<std::unique_ptr<ToolOutputFile>> RemarksFileOrErr =
Context.setDiagnosticsHotnessRequested(true); setupOptimizationRemarks(Context, RemarksFilename, RemarksPasses,
RemarksWithHotness, RemarksHotnessThreshold);
if (PassRemarksHotnessThreshold) if (Error E = RemarksFileOrErr.takeError()) {
Context.setDiagnosticsHotnessThreshold(PassRemarksHotnessThreshold); WithColor::error(errs(), argv[0]) << toString(std::move(E)) << '\n';
return 1;
std::unique_ptr<ToolOutputFile> YamlFile;
if (RemarksFilename != "") {
std::error_code EC;
YamlFile =
llvm::make_unique<ToolOutputFile>(RemarksFilename, EC, sys::fs::F_None);
if (EC) {
WithColor::error(errs(), argv[0]) << EC.message() << '\n';
return 1;
}
Context.setRemarkStreamer(llvm::make_unique<RemarkStreamer>(
RemarksFilename,
llvm::make_unique<remarks::YAMLSerializer>(YamlFile->os())));
if (!RemarksPasses.empty())
if (Error E = Context.getRemarkStreamer()->setFilter(RemarksPasses)) {
WithColor::error(errs(), argv[0]) << E << '\n';
return 1;
}
} }
std::unique_ptr<ToolOutputFile> RemarksFile = std::move(*RemarksFileOrErr);
if (InputLanguage != "" && InputLanguage != "ir" && if (InputLanguage != "" && InputLanguage != "ir" &&
InputLanguage != "mir") { InputLanguage != "mir") {
@ -365,8 +349,8 @@ int main(int argc, char **argv) {
if (int RetVal = compileModule(argv, Context)) if (int RetVal = compileModule(argv, Context))
return RetVal; return RetVal;
if (YamlFile) if (RemarksFile)
YamlFile->keep(); RemarksFile->keep();
return 0; return 0;
} }

View File

@ -91,20 +91,21 @@ static cl::opt<std::string> DefaultTriple(
cl::desc( cl::desc(
"Replace unspecified target triples in input files with this triple")); "Replace unspecified target triples in input files with this triple"));
static cl::opt<std::string> static cl::opt<bool> RemarksWithHotness(
OptRemarksOutput("pass-remarks-output",
cl::desc("YAML output file for optimization remarks"));
static cl::opt<bool> OptRemarksWithHotness(
"pass-remarks-with-hotness", "pass-remarks-with-hotness",
cl::desc("Whether to include hotness informations in the remarks.\n" cl::desc("With PGO, include profile count in optimization remarks"),
"Has effect only if -pass-remarks-output is specified.")); cl::Hidden);
static cl::opt<std::string> static cl::opt<std::string>
OptRemarksPasses("pass-remarks-filter", RemarksFilename("pass-remarks-output",
cl::desc("Only record optimization remarks from passes " cl::desc("Output filename for pass remarks"),
"whose names match the given regular expression"), cl::value_desc("filename"));
cl::value_desc("regex"));
static cl::opt<std::string>
RemarksPasses("pass-remarks-filter",
cl::desc("Only record optimization remarks from passes whose "
"names match the given regular expression"),
cl::value_desc("regex"));
static cl::opt<std::string> static cl::opt<std::string>
SamplePGOFile("lto-sample-profile-file", SamplePGOFile("lto-sample-profile-file",
@ -225,9 +226,9 @@ static int run(int argc, char **argv) {
"Config::addSaveTemps failed"); "Config::addSaveTemps failed");
// Optimization remarks. // Optimization remarks.
Conf.RemarksFilename = OptRemarksOutput; Conf.RemarksFilename = RemarksFilename;
Conf.RemarksPasses = OptRemarksPasses; Conf.RemarksPasses = RemarksPasses;
Conf.RemarksWithHotness = OptRemarksWithHotness; Conf.RemarksWithHotness = RemarksWithHotness;
Conf.SampleProfile = SamplePGOFile; Conf.SampleProfile = SamplePGOFile;
Conf.CSIRProfile = CSPGOFile; Conf.CSIRProfile = CSPGOFile;

View File

@ -251,19 +251,20 @@ static cl::opt<bool> Coroutines(
cl::desc("Enable coroutine passes."), cl::desc("Enable coroutine passes."),
cl::init(false), cl::Hidden); cl::init(false), cl::Hidden);
static cl::opt<bool> PassRemarksWithHotness( static cl::opt<bool> RemarksWithHotness(
"pass-remarks-with-hotness", "pass-remarks-with-hotness",
cl::desc("With PGO, include profile count in optimization remarks"), cl::desc("With PGO, include profile count in optimization remarks"),
cl::Hidden); cl::Hidden);
static cl::opt<unsigned> PassRemarksHotnessThreshold( static cl::opt<unsigned>
"pass-remarks-hotness-threshold", RemarksHotnessThreshold("pass-remarks-hotness-threshold",
cl::desc("Minimum profile count required for an optimization remark to be output"), cl::desc("Minimum profile count required for "
cl::Hidden); "an optimization remark to be output"),
cl::Hidden);
static cl::opt<std::string> static cl::opt<std::string>
RemarksFilename("pass-remarks-output", RemarksFilename("pass-remarks-output",
cl::desc("YAML output filename for pass remarks"), cl::desc("Output filename for pass remarks"),
cl::value_desc("filename")); cl::value_desc("filename"));
static cl::opt<std::string> static cl::opt<std::string>
@ -549,31 +550,14 @@ int main(int argc, char **argv) {
if (!DisableDITypeMap) if (!DisableDITypeMap)
Context.enableDebugTypeODRUniquing(); Context.enableDebugTypeODRUniquing();
if (PassRemarksWithHotness) Expected<std::unique_ptr<ToolOutputFile>> RemarksFileOrErr =
Context.setDiagnosticsHotnessRequested(true); setupOptimizationRemarks(Context, RemarksFilename, RemarksPasses,
RemarksWithHotness, RemarksHotnessThreshold);
if (PassRemarksHotnessThreshold) if (Error E = RemarksFileOrErr.takeError()) {
Context.setDiagnosticsHotnessThreshold(PassRemarksHotnessThreshold); errs() << toString(std::move(E)) << '\n';
return 1;
std::unique_ptr<ToolOutputFile> OptRemarkFile;
if (RemarksFilename != "") {
std::error_code EC;
OptRemarkFile =
llvm::make_unique<ToolOutputFile>(RemarksFilename, EC, sys::fs::F_None);
if (EC) {
errs() << EC.message() << '\n';
return 1;
}
Context.setRemarkStreamer(llvm::make_unique<RemarkStreamer>(
RemarksFilename,
llvm::make_unique<remarks::YAMLSerializer>(OptRemarkFile->os())));
if (!RemarksPasses.empty())
if (Error E = Context.getRemarkStreamer()->setFilter(RemarksPasses)) {
errs() << E << '\n';
return 1;
}
} }
std::unique_ptr<ToolOutputFile> RemarksFile = std::move(*RemarksFileOrErr);
// Load the input module... // Load the input module...
std::unique_ptr<Module> M = std::unique_ptr<Module> M =
@ -687,7 +671,7 @@ int main(int argc, char **argv) {
// string. Hand off the rest of the functionality to the new code for that // string. Hand off the rest of the functionality to the new code for that
// layer. // layer.
return runPassPipeline(argv[0], *M, TM.get(), Out.get(), ThinLinkOut.get(), return runPassPipeline(argv[0], *M, TM.get(), Out.get(), ThinLinkOut.get(),
OptRemarkFile.get(), PassPipeline, OK, VK, RemarksFile.get(), PassPipeline, OK, VK,
PreserveAssemblyUseListOrder, PreserveAssemblyUseListOrder,
PreserveBitcodeUseListOrder, EmitSummaryIndex, PreserveBitcodeUseListOrder, EmitSummaryIndex,
EmitModuleHash, EnableDebugify) EmitModuleHash, EnableDebugify)
@ -923,8 +907,8 @@ int main(int argc, char **argv) {
"the compile-twice option\n"; "the compile-twice option\n";
Out->os() << BOS->str(); Out->os() << BOS->str();
Out->keep(); Out->keep();
if (OptRemarkFile) if (RemarksFile)
OptRemarkFile->keep(); RemarksFile->keep();
return 1; return 1;
} }
Out->os() << BOS->str(); Out->os() << BOS->str();
@ -937,8 +921,8 @@ int main(int argc, char **argv) {
if (!NoOutput || PrintBreakpoints) if (!NoOutput || PrintBreakpoints)
Out->keep(); Out->keep();
if (OptRemarkFile) if (RemarksFile)
OptRemarkFile->keep(); RemarksFile->keep();
if (ThinLinkOut) if (ThinLinkOut)
ThinLinkOut->keep(); ThinLinkOut->keep();