Reland "[Remarks] Add -foptimization-record-passes to filter remark emission"

Currently we have -Rpass for filtering the remarks that are displayed as
diagnostics, but when using -fsave-optimization-record, there is no way
to filter the remarks while generating them.

This adds support for filtering remarks by passes using a regex.
Ex: `clang -fsave-optimization-record -foptimization-record-passes=inline`

will only emit the remarks coming from the pass `inline`.

This adds:

* `-fsave-optimization-record` to the driver
* `-opt-record-passes` to cc1
* `-lto-pass-remarks-filter` to the LTOCodeGenerator
* `--opt-remarks-passes` to lld
* `-pass-remarks-filter` to llc, opt, llvm-lto, llvm-lto2
* `-opt-remarks-passes` to gold-plugin

Differential Revision: https://reviews.llvm.org/D59268

Original llvm-svn: 355964

llvm-svn: 355984
This commit is contained in:
Francis Visoiu Mistrih 2019-03-12 21:22:27 +00:00
parent b760558517
commit dd42236c6c
32 changed files with 162 additions and 10 deletions

View File

@ -238,6 +238,10 @@ public:
/// records.
std::string OptRecordFile;
/// The regex that filters the passes that should be saved to the optimization
/// records.
std::string OptRecordPasses;
/// Regular expression to select optimizations for which we should enable
/// optimization remarks. Transformation passes whose name matches this
/// expression (and support this feature), will emit a diagnostic

View File

@ -603,6 +603,8 @@ def arcmt_migrate : Flag<["-"], "arcmt-migrate">,
def opt_record_file : Separate<["-"], "opt-record-file">,
HelpText<"File name to use for YAML optimization record output">;
def opt_record_passes : Separate<["-"], "opt-record-passes">,
HelpText<"Only record remark information for passes whose names match the given regular expression">;
def print_stats : Flag<["-"], "print-stats">,
HelpText<"Print performance metrics and statistics">;

View File

@ -1715,6 +1715,10 @@ def fno_save_optimization_record : Flag<["-"], "fno-save-optimization-record">,
def foptimization_record_file_EQ : Joined<["-"], "foptimization-record-file=">,
Group<f_Group>,
HelpText<"Specify the file name of any generated YAML optimization record">;
def foptimization_record_passes_EQ : Joined<["-"], "foptimization-record-passes=">,
Group<f_Group>,
HelpText<"Only include passes which match a specified regular expression in the generated optimization record (by default, include all passes)">;
def ftest_coverage : Flag<["-"], "ftest-coverage">, Group<f_Group>;
def fvectorize : Flag<["-"], "fvectorize">, Group<f_Group>,

View File

@ -1340,6 +1340,7 @@ static void runThinLTOBackend(ModuleSummaryIndex *CombinedIndex, Module *M,
Conf.DebugPassManager = CGOpts.DebugPassManager;
Conf.RemarksWithHotness = CGOpts.DiagnosticsWithHotness;
Conf.RemarksFilename = CGOpts.OptRecordFile;
Conf.RemarksPasses = CGOpts.OptRecordPasses;
Conf.DwoPath = CGOpts.SplitDwarfFile;
switch (Action) {
case Backend_EmitNothing:

View File

@ -19,6 +19,7 @@
#include "clang/Basic/TargetInfo.h"
#include "clang/CodeGen/BackendUtil.h"
#include "clang/CodeGen/ModuleBuilder.h"
#include "clang/Driver/DriverDiagnostic.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendDiagnostic.h"
#include "clang/Lex/Preprocessor.h"
@ -280,6 +281,12 @@ namespace clang {
Ctx.setRemarkStreamer(llvm::make_unique<RemarkStreamer>(
CodeGenOpts.OptRecordFile, OptRecordFile->os()));
if (!CodeGenOpts.OptRecordPasses.empty())
if (Error E = Ctx.getRemarkStreamer()->setFilter(
CodeGenOpts.OptRecordPasses))
Diags.Report(diag::err_drv_optimization_remark_pattern)
<< toString(std::move(E)) << CodeGenOpts.OptRecordPasses;
if (CodeGenOpts.getProfileUse() != CodeGenOptions::ProfileNone)
Ctx.setDiagnosticsHotnessRequested(true);
}

View File

@ -5032,8 +5032,11 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
options::OPT_fno_apple_pragma_pack, false))
CmdArgs.push_back("-fapple-pragma-pack");
// Remarks can be enabled with any of the `-f.*optimization-record.*` flags.
if (Args.hasFlag(options::OPT_fsave_optimization_record,
options::OPT_foptimization_record_file_EQ,
options::OPT_fno_save_optimization_record, false) ||
Args.hasFlag(options::OPT_foptimization_record_passes_EQ,
options::OPT_fno_save_optimization_record, false)) {
CmdArgs.push_back("-opt-record-file");
@ -5068,6 +5071,11 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
llvm::sys::path::replace_extension(F, "opt.yaml");
CmdArgs.push_back(Args.MakeArgString(F));
}
if (const Arg *A =
Args.getLastArg(options::OPT_foptimization_record_passes_EQ)) {
CmdArgs.push_back("-opt-record-passes");
CmdArgs.push_back(A->getValue());
}
}
bool RewriteImports = Args.hasFlag(options::OPT_frewrite_imports,

View File

@ -483,6 +483,14 @@ void darwin::Linker::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back(Args.MakeArgString(Opt));
}
}
if (const Arg *A =
Args.getLastArg(options::OPT_foptimization_record_passes_EQ)) {
CmdArgs.push_back("-mllvm");
std::string Passes =
std::string("-lto-pass-remarks-filter=") + A->getValue();
CmdArgs.push_back(Args.MakeArgString(Passes));
}
}
// Propagate the -moutline flag to the linker in LTO.

View File

@ -1218,6 +1218,11 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
if (!Opts.OptRecordFile.empty())
NeedLocTracking = true;
if (Arg *A = Args.getLastArg(OPT_opt_record_passes)) {
Opts.OptRecordPasses = A->getValue();
NeedLocTracking = true;
}
if (Arg *A = Args.getLastArg(OPT_Rpass_EQ)) {
Opts.OptimizationRemarkPattern =
GenerateOptimizationRemarkRegex(Diags, Args, A);

View File

@ -3,6 +3,8 @@
// RUN: %clang_cc1 -triple arm64-apple-ios -S -o /dev/null %s -O2 -dwarf-column-info 2>&1 | FileCheck -allow-empty -check-prefix=NO_REMARK %s
// RUN: %clang_cc1 -triple arm64-apple-ios -S -o /dev/null %s -O2 -dwarf-column-info -opt-record-file %t.yaml
// RUN: cat %t.yaml | FileCheck -check-prefix=YAML %s
// RUN: %clang_cc1 -triple arm64-apple-ios -S -o /dev/null %s -O2 -dwarf-column-info -opt-record-file %t.yaml -opt-record-passes asm-printer
// RUN: cat %t.yaml | FileCheck -check-prefix=PASSES %s
void bar(float);
@ -15,15 +17,15 @@ void foo(float *p, int i) {
}
}
// REMARK: opt-record-MIR.c:10:11: remark: {{.}} spills {{.}} reloads generated in loop
// REMARK: opt-record-MIR.c:{{[1-9][0-9]*}}:{{[1-9][0-9]*}}: remark: {{.}} spills {{.}} reloads generated in loop
// NO_REMARK-NOT: remark:
// YAML: --- !Missed
// YAML: Pass: regalloc
// YAML: Name: LoopSpillReload
// YAML: DebugLoc: { File: {{[^,]+}},
// YAML: Line: 10,
// YAML: Column: 11 }
// YAML: Line: {{[1-9][0-9]*}}
// YAML: Column: {{[1-9][0-9]*}} }
// YAML: Function: foo
// YAML: Args:
// YAML: - NumSpills: '{{.}}'
@ -32,3 +34,6 @@ void foo(float *p, int i) {
// YAML: - String: ' reloads '
// YAML: - String: generated
// YAML: ...
// PASSES: Pass: asm-printer
// PASSES-NOT: regalloc

View File

@ -3,6 +3,8 @@
// RUN: llvm-profdata merge %S/Inputs/opt-record.proftext -o %t.profdata
// RUN: %clang_cc1 -O3 -triple x86_64-unknown-linux-gnu -target-cpu x86-64 -fprofile-instrument-use-path=%t.profdata %s -o %t -dwarf-column-info -opt-record-file %t.yaml -emit-obj
// RUN: cat %t.yaml | FileCheck -check-prefix=CHECK -check-prefix=CHECK-PGO %s
// RUN: %clang_cc1 -O3 -triple x86_64-unknown-linux-gnu -target-cpu x86-64 %s -o %t -dwarf-column-info -opt-record-file %t.yaml -opt-record-passes inline -emit-obj
// RUN: cat %t.yaml | FileCheck -check-prefix=CHECK-PASSES %s
// REQUIRES: x86-registered-target
void bar();
@ -23,6 +25,7 @@ void Test(int *res, int *c, int *d, int *p, int n) {
// CHECK: DebugLoc:
// CHECK: Function: foo
// CHECK-PGO: Hotness:
// CHECK-PASSES: Pass: inline
// CHECK: --- !Passed
// CHECK: Pass: loop-vectorize
@ -30,4 +33,4 @@ void Test(int *res, int *c, int *d, int *p, int n) {
// CHECK: DebugLoc:
// CHECK: Function: Test
// CHECK-PGO: Hotness:
// CHECK-PASSES-NOT: loop-vectorize

View File

@ -327,6 +327,10 @@
// RUN: FileCheck -check-prefix=PASS_REMARKS_WITH_HOTNESS_THRESHOLD %s < %t.log
// PASS_REMARKS_WITH_HOTNESS_THRESHOLD: "-mllvm" "-lto-pass-remarks-output" "-mllvm" "foo/bar.out.opt.yaml" "-mllvm" "-lto-pass-remarks-with-hotness" "-mllvm" "-lto-pass-remarks-hotness-threshold=100"
// RUN: %clang -target x86_64-apple-darwin12 %t.o -fsave-optimization-record -foptimization-record-passes=inline -### -o foo/bar.out 2> %t.log
// RUN: FileCheck -check-prefix=PASS_REMARKS_WITH_PASSES %s < %t.log
// PASS_REMARKS_WITH_PASSES: "-mllvm" "-lto-pass-remarks-output" "-mllvm" "foo/bar.out.opt.yaml" "-mllvm" "-lto-pass-remarks-filter=inline"
// RUN: %clang -target x86_64-apple-ios6.0 -miphoneos-version-min=6.0 -fprofile-instr-generate -### %t.o 2> %t.log
// RUN: FileCheck -check-prefix=LINK_PROFILE_FIRST %s < %t.log
// RUN: %clang -target x86_64-apple-darwin12 -fprofile-instr-generate -### %t.o 2> %t.log

View File

@ -12,6 +12,10 @@
// RUN: %clang -### -S -o FOO -foptimization-record-file=BAR.txt %s 2>&1 | FileCheck %s -check-prefix=CHECK-EQ
// RUN: %clang -### -S -o FOO -foptimization-record-file=BAR.txt -fno-save-optimization-record %s 2>&1 | FileCheck %s --check-prefix=CHECK-FOPT-DISABLE
// RUN: %clang -### -S -o FOO -fsave-optimization-record -foptimization-record-passes=inline %s 2>&1 | FileCheck %s -check-prefix=CHECK-EQ-PASSES
// RUN: %clang -### -S -o FOO -foptimization-record-passes=inline %s 2>&1 | FileCheck %s -check-prefix=CHECK-EQ-PASSES
// RUN: %clang -### -S -o FOO -foptimization-record-passes=inline -fno-save-optimization-record %s 2>&1 | FileCheck %s --check-prefix=CHECK-FOPT-DISABLE-PASSES
//
// CHECK: "-cc1"
// CHECK: "-opt-record-file" "FOO.opt.yaml"
@ -23,3 +27,8 @@
// CHECK-EQ: "-opt-record-file" "BAR.txt"
// CHECK-FOPT-DISABLE-NOT: "-fno-save-optimization-record"
// CHECK-EQ-PASSES: "-cc1"
// CHECK-EQ-PASSES: "-opt-record-passes" "inline"
// CHECK-FOPT-DISABLE-PASSES-NOT: "-fno-save-optimization-record"

View File

@ -99,6 +99,7 @@ struct Configuration {
llvm::StringRef MapFile;
llvm::StringRef OutputFile;
llvm::StringRef OptRemarksFilename;
llvm::StringRef OptRemarksPasses;
llvm::StringRef ProgName;
llvm::StringRef SoName;
llvm::StringRef Sysroot;

View File

@ -818,6 +818,7 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) {
Config->OFormatBinary = isOutputFormatBinary(Args);
Config->Omagic = Args.hasFlag(OPT_omagic, OPT_no_omagic, false);
Config->OptRemarksFilename = Args.getLastArgValue(OPT_opt_remarks_filename);
Config->OptRemarksPasses = Args.getLastArgValue(OPT_opt_remarks_passes);
Config->OptRemarksWithHotness = Args.hasArg(OPT_opt_remarks_with_hotness);
Config->Optimize = args::getInteger(Args, OPT_O, 1);
Config->OrphanHandling = getOrphanHandling(Args);

View File

@ -97,6 +97,7 @@ static lto::Config createConfig() {
// Set up optimization remarks if we've been asked to.
C.RemarksFilename = Config->OptRemarksFilename;
C.RemarksPasses = Config->OptRemarksPasses;
C.RemarksWithHotness = Config->OptRemarksWithHotness;
C.SampleProfile = Config->LTOSampleProfile;

View File

@ -454,6 +454,8 @@ def disable_verify: F<"disable-verify">;
defm mllvm: Eq<"mllvm", "Additional arguments to forward to LLVM's option processing">;
def opt_remarks_filename: Separate<["--"], "opt-remarks-filename">,
HelpText<"YAML output file for optimization remarks">;
def opt_remarks_passes: Separate<["--"], "opt-remarks-passes">,
HelpText<"Regex for the passes that need to be serialized to the output file">;
def opt_remarks_with_hotness: Flag<["--"], "opt-remarks-with-hotness">,
HelpText<"Include hotness information in the optimization remarks file">;
defm plugin_opt: Eq<"plugin-opt", "specifies LTO options for compatibility with GNU linkers">;

View File

@ -329,6 +329,9 @@ Set the text and data sections to be readable and writable.
.It Fl -opt-remarks-filename Ar file
Write optimization remarks in YAML format to
.Ar file .
.It Fl -opt-remarks-passes Ar pass-regex
Filter optimization remarks by only allowing the passes matching
.Ar pass-regex .
.It Fl -opt-remarks-with-hotness
Include hotness information in the optimization remarks file.
.It Fl -orphan-handling Ns = Ns Ar mode

View File

@ -8,6 +8,9 @@
; RUN: %t.o -o %t -shared
; RUN: cat %t.yaml | FileCheck %s -check-prefix=YAML
; RUN: cat %t.hot.yaml | FileCheck %s -check-prefix=YAML-HOT
; RUN: ld.lld --opt-remarks-filename %t1.yaml --opt-remarks-passes inline %t.o \
; RUN: -o /dev/null -shared
; RUN: cat %t1.yaml | FileCheck %s -check-prefix=YAML-PASSES
; Check that @tinkywinky is inlined after optimizations.
; CHECK-LABEL: define i32 @main
@ -48,6 +51,8 @@
; YAML-HOT-NEXT: - String: ')'
; YAML-HOT-NEXT: ...
; YAML-PASSES: Pass: inline
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-scei-ps4"

View File

@ -14,8 +14,10 @@
#define LLVM_IR_REMARKSTREAMER_H
#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/YAMLTraits.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Regex.h"
#include <string>
#include <vector>
@ -26,6 +28,8 @@ class RemarkStreamer {
const std::string Filename;
/// The open raw_ostream that the remark diagnostics are emitted to.
raw_ostream &OS;
/// The regex used to filter remarks based on the passes that emit them.
Optional<Regex> PassFilter;
/// The YAML streamer.
yaml::Output YAMLOutput;
@ -36,6 +40,9 @@ public:
StringRef getFilename() const { return Filename; }
/// Return stream that the remark diagnostics are emitted to.
raw_ostream &getStream() { return OS; }
/// Set a pass filter based on a regex \p Filter.
/// Returns an error if the regex is invalid.
Error setFilter(StringRef Filter);
/// Emit a diagnostic through the streamer.
void emit(const DiagnosticInfoOptimizationBase &Diag);
};

View File

@ -96,6 +96,9 @@ struct Config {
/// Optimization remarks file path.
std::string RemarksFilename = "";
/// Optimization remarks pass filter.
std::string RemarksPasses = "";
/// Whether to emit optimization remarks with hotness informations.
bool RemarksWithHotness = false;

View File

@ -84,6 +84,7 @@ std::string getThinLTOOutputFile(const std::string &Path,
/// Setup optimization remarks.
Expected<std::unique_ptr<ToolOutputFile>>
setupOptimizationRemarks(LLVMContext &Context, StringRef LTORemarksFilename,
StringRef LTORemarksPasses,
bool LTOPassRemarksWithHotness, int Count = -1);
class LTO;

View File

@ -21,7 +21,21 @@ RemarkStreamer::RemarkStreamer(StringRef Filename, raw_ostream &OS)
assert(!Filename.empty() && "This needs to be a real filename.");
}
Error RemarkStreamer::setFilter(StringRef Filter) {
Regex R = Regex(Filter);
std::string RegexError;
if (!R.isValid(RegexError))
return createStringError(std::make_error_code(std::errc::invalid_argument),
RegexError.data());
PassFilter = std::move(R);
return Error::success();
}
void RemarkStreamer::emit(const DiagnosticInfoOptimizationBase &Diag) {
if (Optional<Regex> &Filter = PassFilter)
if (!Filter->match(Diag.getPassName()))
return;
DiagnosticInfoOptimizationBase *DiagPtr =
const_cast<DiagnosticInfoOptimizationBase *>(&Diag);
YAMLOutput << DiagPtr;

View File

@ -1312,6 +1312,7 @@ Error LTO::runThinLTO(AddStreamFn AddStream, NativeObjectCache Cache) {
Expected<std::unique_ptr<ToolOutputFile>>
lto::setupOptimizationRemarks(LLVMContext &Context,
StringRef LTORemarksFilename,
StringRef LTORemarksPasses,
bool LTOPassRemarksWithHotness, int Count) {
if (LTOPassRemarksWithHotness)
Context.setDiagnosticsHotnessRequested(true);
@ -1329,6 +1330,11 @@ lto::setupOptimizationRemarks(LLVMContext &Context,
return errorCodeToError(EC);
Context.setRemarkStreamer(
llvm::make_unique<RemarkStreamer>(Filename, DiagnosticFile->os()));
if (!LTORemarksPasses.empty())
if (Error E = Context.getRemarkStreamer()->setFilter(LTORemarksPasses))
return std::move(E);
DiagnosticFile->keep();
return std::move(DiagnosticFile);
}

View File

@ -429,8 +429,9 @@ Error lto::backend(Config &C, AddStreamFn AddStream,
std::unique_ptr<TargetMachine> TM = createTargetMachine(C, *TOrErr, *Mod);
// Setup optimization remarks.
auto DiagFileOrErr = lto::setupOptimizationRemarks(
Mod->getContext(), C.RemarksFilename, C.RemarksWithHotness);
auto DiagFileOrErr =
lto::setupOptimizationRemarks(Mod->getContext(), C.RemarksFilename,
C.RemarksPasses, C.RemarksWithHotness);
if (!DiagFileOrErr)
return DiagFileOrErr.takeError();
auto DiagnosticOutputFile = std::move(*DiagFileOrErr);
@ -484,7 +485,8 @@ Error lto::thinBackend(Config &Conf, unsigned Task, AddStreamFn AddStream,
// Setup optimization remarks.
auto DiagFileOrErr = lto::setupOptimizationRemarks(
Mod.getContext(), Conf.RemarksFilename, Conf.RemarksWithHotness, Task);
Mod.getContext(), Conf.RemarksFilename, Conf.RemarksPasses,
Conf.RemarksWithHotness, Task);
if (!DiagFileOrErr)
return DiagFileOrErr.takeError();
auto DiagnosticOutputFile = std::move(*DiagFileOrErr);

View File

@ -85,6 +85,12 @@ cl::opt<std::string>
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",
cl::desc("With PGO, include profile count in optimization remarks"),
@ -505,7 +511,7 @@ bool LTOCodeGenerator::optimize(bool DisableVerify, bool DisableInline,
return false;
auto DiagFileOrErr = lto::setupOptimizationRemarks(
Context, LTORemarksFilename, LTOPassRemarksWithHotness);
Context, LTORemarksFilename, LTORemarksPasses, LTOPassRemarksWithHotness);
if (!DiagFileOrErr) {
errs() << "Error: " << toString(DiagFileOrErr.takeError()) << "\n";
report_fatal_error("Can't get an output file for the remarks");

View File

@ -70,6 +70,7 @@ namespace llvm {
// Flags -discard-value-names, defined in LTOCodeGenerator.cpp
extern cl::opt<bool> LTODiscardValueNames;
extern cl::opt<std::string> LTORemarksFilename;
extern cl::opt<std::string> LTORemarksPasses;
extern cl::opt<bool> LTOPassRemarksWithHotness;
}
@ -972,7 +973,8 @@ void ThinLTOCodeGenerator::run() {
Context.setDiscardValueNames(LTODiscardValueNames);
Context.enableDebugTypeODRUniquing();
auto DiagFileOrErr = lto::setupOptimizationRemarks(
Context, LTORemarksFilename, LTOPassRemarksWithHotness, count);
Context, LTORemarksFilename, LTORemarksPasses,
LTOPassRemarksWithHotness, count);
if (!DiagFileOrErr) {
errs() << "Error: " << toString(DiagFileOrErr.takeError()) << "\n";
report_fatal_error("ThinLTO: Can't get an output file for the "

View File

@ -4,6 +4,7 @@
; RUN: llvm-as < %s >%t.bc
; RUN: rm -f %t.yaml
; RUN: llvm-lto2 run -pass-remarks-output=%t.yaml \
; RUN: -pass-remarks-filter=inline \
; RUN: -r %t.bc,tinkywinky,p \
; RUN: -r %t.bc,patatino,px \
; RUN: -r %t.bc,main,px -o %t.o %t.bc
@ -13,6 +14,7 @@
; RUN: opt -module-summary %s -o %t.bc
; RUN: rm -f %t.thin.1.yaml
; RUN: llvm-lto2 run -pass-remarks-output=%t \
; RUN: -pass-remarks-filter=inline \
; RUN: -r %t.bc,tinkywinky,p \
; RUN: -r %t.bc,patatino,px \
; RUN: -r %t.bc,main,px -o %t.o %t.bc

View File

@ -5,6 +5,7 @@
; RUN: rm -f %t.yaml.thin.0.yaml %t.yaml.thin.1.yaml
; RUN: llvm-lto -thinlto-action=run \
; RUN: -lto-pass-remarks-output=%t.yaml \
; RUN: -lto-pass-remarks-filter=inline \
; RUN: -exported-symbol _func2 \
; RUN: -exported-symbol _main %t1.bc %t2.bc 2>&1 | \
; RUN: FileCheck %s -allow-empty

View File

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

View File

@ -148,6 +148,12 @@ static cl::opt<std::string>
cl::desc("YAML output filename for pass remarks"),
cl::value_desc("filename"));
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"));
namespace {
static ManagedStatic<std::vector<std::string>> RunPassNames;
@ -336,6 +342,12 @@ int main(int argc, char **argv) {
}
Context.setRemarkStreamer(
llvm::make_unique<RemarkStreamer>(RemarksFilename, YamlFile->os()));
if (!RemarksPasses.empty())
if (Error E = Context.getRemarkStreamer()->setFilter(RemarksPasses)) {
WithColor::error(errs(), argv[0]) << E << '\n';
return 1;
}
}
if (InputLanguage != "" && InputLanguage != "ir" &&

View File

@ -100,6 +100,12 @@ static cl::opt<bool> OptRemarksWithHotness(
cl::desc("Whether to include hotness informations in the remarks.\n"
"Has effect only if -pass-remarks-output is specified."));
static cl::opt<std::string>
OptRemarksPasses("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>
SamplePGOFile("lto-sample-profile-file",
cl::desc("Specify a SamplePGO profile file"));
@ -220,6 +226,7 @@ static int run(int argc, char **argv) {
// Optimization remarks.
Conf.RemarksFilename = OptRemarksOutput;
Conf.RemarksPasses = OptRemarksPasses;
Conf.RemarksWithHotness = OptRemarksWithHotness;
Conf.SampleProfile = SamplePGOFile;

View File

@ -275,6 +275,12 @@ static cl::opt<std::string>
cl::desc("YAML output filename for pass remarks"),
cl::value_desc("filename"));
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"));
cl::opt<PGOKind>
PGOKindFlag("pgo-kind", cl::init(NoPGO), cl::Hidden,
cl::desc("The kind of profile guided optimization"),
@ -566,6 +572,12 @@ int main(int argc, char **argv) {
}
Context.setRemarkStreamer(llvm::make_unique<RemarkStreamer>(
RemarksFilename, OptRemarkFile->os()));
if (!RemarksPasses.empty())
if (Error E = Context.getRemarkStreamer()->setFilter(RemarksPasses)) {
errs() << E << '\n';
return 1;
}
}
// Load the input module...