summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/Basic/CodeGenOptions.h4
-rw-r--r--clang/include/clang/Driver/CC1Options.td2
-rw-r--r--clang/include/clang/Driver/Options.td4
-rw-r--r--clang/lib/CodeGen/BackendUtil.cpp1
-rw-r--r--clang/lib/CodeGen/CodeGenAction.cpp7
-rw-r--r--clang/lib/Driver/ToolChains/Clang.cpp8
-rw-r--r--clang/lib/Driver/ToolChains/Darwin.cpp8
-rw-r--r--clang/lib/Frontend/CompilerInvocation.cpp5
-rw-r--r--clang/test/CodeGen/opt-record-MIR.c11
-rw-r--r--clang/test/CodeGen/opt-record.c5
-rw-r--r--clang/test/Driver/darwin-ld.c4
-rw-r--r--clang/test/Driver/opt-record.c9
-rw-r--r--lld/ELF/Config.h1
-rw-r--r--lld/ELF/Driver.cpp1
-rw-r--r--lld/ELF/LTO.cpp1
-rw-r--r--lld/ELF/Options.td2
-rw-r--r--lld/docs/ld.lld.13
-rw-r--r--lld/test/ELF/lto/opt-remarks.ll5
-rw-r--r--llvm/include/llvm/IR/RemarkStreamer.h7
-rw-r--r--llvm/include/llvm/LTO/Config.h3
-rw-r--r--llvm/include/llvm/LTO/LTO.h1
-rw-r--r--llvm/lib/IR/RemarkStreamer.cpp14
-rw-r--r--llvm/lib/LTO/LTO.cpp6
-rw-r--r--llvm/lib/LTO/LTOBackend.cpp8
-rw-r--r--llvm/lib/LTO/LTOCodeGenerator.cpp8
-rw-r--r--llvm/lib/LTO/ThinLTOCodeGenerator.cpp4
-rw-r--r--llvm/test/LTO/Resolution/X86/diagnostic-handler-remarks.ll2
-rw-r--r--llvm/test/ThinLTO/X86/diagnostic-handler-remarks.ll1
-rw-r--r--llvm/tools/gold/gold-plugin.cpp6
-rw-r--r--llvm/tools/llc/llc.cpp12
-rw-r--r--llvm/tools/llvm-lto2/llvm-lto2.cpp7
-rw-r--r--llvm/tools/opt/opt.cpp12
32 files changed, 162 insertions, 10 deletions
diff --git a/clang/include/clang/Basic/CodeGenOptions.h b/clang/include/clang/Basic/CodeGenOptions.h
index fc284f8c677..200706fda7c 100644
--- a/clang/include/clang/Basic/CodeGenOptions.h
+++ b/clang/include/clang/Basic/CodeGenOptions.h
@@ -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
diff --git a/clang/include/clang/Driver/CC1Options.td b/clang/include/clang/Driver/CC1Options.td
index f4f8fae39e3..2825a927797 100644
--- a/clang/include/clang/Driver/CC1Options.td
+++ b/clang/include/clang/Driver/CC1Options.td
@@ -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">;
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 81e4ce75b02..0f05effe278 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -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>,
diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index 30a3dc830f6..34705ad8ff8 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -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:
diff --git a/clang/lib/CodeGen/CodeGenAction.cpp b/clang/lib/CodeGen/CodeGenAction.cpp
index f59adcd3fb9..cab3a6bc32b 100644
--- a/clang/lib/CodeGen/CodeGenAction.cpp
+++ b/clang/lib/CodeGen/CodeGenAction.cpp
@@ -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);
}
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 3bc7412911b..bf9ab9dd107 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -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,
diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp
index ea93fadcdc2..f91ab1946f5 100644
--- a/clang/lib/Driver/ToolChains/Darwin.cpp
+++ b/clang/lib/Driver/ToolChains/Darwin.cpp
@@ -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.
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 1cd1cb1ff47..b5872b961cc 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -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);
diff --git a/clang/test/CodeGen/opt-record-MIR.c b/clang/test/CodeGen/opt-record-MIR.c
index 37239281e9e..f9b4e745805 100644
--- a/clang/test/CodeGen/opt-record-MIR.c
+++ b/clang/test/CodeGen/opt-record-MIR.c
@@ -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
diff --git a/clang/test/CodeGen/opt-record.c b/clang/test/CodeGen/opt-record.c
index 3bc3c41f784..3f134854fe5 100644
--- a/clang/test/CodeGen/opt-record.c
+++ b/clang/test/CodeGen/opt-record.c
@@ -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
diff --git a/clang/test/Driver/darwin-ld.c b/clang/test/Driver/darwin-ld.c
index 181d4e324cc..b120bbe8a34 100644
--- a/clang/test/Driver/darwin-ld.c
+++ b/clang/test/Driver/darwin-ld.c
@@ -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
diff --git a/clang/test/Driver/opt-record.c b/clang/test/Driver/opt-record.c
index 7b4ec48632e..44ad4a2a6b3 100644
--- a/clang/test/Driver/opt-record.c
+++ b/clang/test/Driver/opt-record.c
@@ -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"
diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h
index 9981098eb6c..a6b96b40548 100644
--- a/lld/ELF/Config.h
+++ b/lld/ELF/Config.h
@@ -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;
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 44f2293f199..c27e36f94a2 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -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);
diff --git a/lld/ELF/LTO.cpp b/lld/ELF/LTO.cpp
index b19996d5e9a..c97ff4d2476 100644
--- a/lld/ELF/LTO.cpp
+++ b/lld/ELF/LTO.cpp
@@ -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;
diff --git a/lld/ELF/Options.td b/lld/ELF/Options.td
index 013235287b3..968cf1900b6 100644
--- a/lld/ELF/Options.td
+++ b/lld/ELF/Options.td
@@ -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">;
diff --git a/lld/docs/ld.lld.1 b/lld/docs/ld.lld.1
index 2e499bac81e..d18914ca509 100644
--- a/lld/docs/ld.lld.1
+++ b/lld/docs/ld.lld.1
@@ -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
diff --git a/lld/test/ELF/lto/opt-remarks.ll b/lld/test/ELF/lto/opt-remarks.ll
index bef7e016a1c..e37bfd345ac 100644
--- a/lld/test/ELF/lto/opt-remarks.ll
+++ b/lld/test/ELF/lto/opt-remarks.ll
@@ -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"
diff --git a/llvm/include/llvm/IR/RemarkStreamer.h b/llvm/include/llvm/IR/RemarkStreamer.h
index 38baa2b3b4b..64de27e3726 100644
--- a/llvm/include/llvm/IR/RemarkStreamer.h
+++ b/llvm/include/llvm/IR/RemarkStreamer.h
@@ -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);
};
diff --git a/llvm/include/llvm/LTO/Config.h b/llvm/include/llvm/LTO/Config.h
index bf8cc98ac4d..1e2eeab11c0 100644
--- a/llvm/include/llvm/LTO/Config.h
+++ b/llvm/include/llvm/LTO/Config.h
@@ -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;
diff --git a/llvm/include/llvm/LTO/LTO.h b/llvm/include/llvm/LTO/LTO.h
index ab4d874b55e..be37dbd0c59 100644
--- a/llvm/include/llvm/LTO/LTO.h
+++ b/llvm/include/llvm/LTO/LTO.h
@@ -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;
diff --git a/llvm/lib/IR/RemarkStreamer.cpp b/llvm/lib/IR/RemarkStreamer.cpp
index 0b983408e46..022c17d6722 100644
--- a/llvm/lib/IR/RemarkStreamer.cpp
+++ b/llvm/lib/IR/RemarkStreamer.cpp
@@ -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;
diff --git a/llvm/lib/LTO/LTO.cpp b/llvm/lib/LTO/LTO.cpp
index f6e34c5d061..99318c19a89 100644
--- a/llvm/lib/LTO/LTO.cpp
+++ b/llvm/lib/LTO/LTO.cpp
@@ -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);
}
diff --git a/llvm/lib/LTO/LTOBackend.cpp b/llvm/lib/LTO/LTOBackend.cpp
index 0595771bd00..64c596931fa 100644
--- a/llvm/lib/LTO/LTOBackend.cpp
+++ b/llvm/lib/LTO/LTOBackend.cpp
@@ -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);
diff --git a/llvm/lib/LTO/LTOCodeGenerator.cpp b/llvm/lib/LTO/LTOCodeGenerator.cpp
index 1b1de2ba187..f02907f7a86 100644
--- a/llvm/lib/LTO/LTOCodeGenerator.cpp
+++ b/llvm/lib/LTO/LTOCodeGenerator.cpp
@@ -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");
diff --git a/llvm/lib/LTO/ThinLTOCodeGenerator.cpp b/llvm/lib/LTO/ThinLTOCodeGenerator.cpp
index 557afd6c360..d4ee66a53e0 100644
--- a/llvm/lib/LTO/ThinLTOCodeGenerator.cpp
+++ b/llvm/lib/LTO/ThinLTOCodeGenerator.cpp
@@ -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 "
diff --git a/llvm/test/LTO/Resolution/X86/diagnostic-handler-remarks.ll b/llvm/test/LTO/Resolution/X86/diagnostic-handler-remarks.ll
index 03db4a722b5..beb0f4fa49b 100644
--- a/llvm/test/LTO/Resolution/X86/diagnostic-handler-remarks.ll
+++ b/llvm/test/LTO/Resolution/X86/diagnostic-handler-remarks.ll
@@ -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
diff --git a/llvm/test/ThinLTO/X86/diagnostic-handler-remarks.ll b/llvm/test/ThinLTO/X86/diagnostic-handler-remarks.ll
index d4606ba999d..4c13fe804d6 100644
--- a/llvm/test/ThinLTO/X86/diagnostic-handler-remarks.ll
+++ b/llvm/test/ThinLTO/X86/diagnostic-handler-remarks.ll
@@ -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
diff --git a/llvm/tools/gold/gold-plugin.cpp b/llvm/tools/gold/gold-plugin.cpp
index fbf78b02551..dc61ff925ce 100644
--- a/llvm/tools/gold/gold-plugin.cpp
+++ b/llvm/tools/gold/gold-plugin.cpp
@@ -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
diff --git a/llvm/tools/llc/llc.cpp b/llvm/tools/llc/llc.cpp
index a566d15cd81..be103845e97 100644
--- a/llvm/tools/llc/llc.cpp
+++ b/llvm/tools/llc/llc.cpp
@@ -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" &&
diff --git a/llvm/tools/llvm-lto2/llvm-lto2.cpp b/llvm/tools/llvm-lto2/llvm-lto2.cpp
index 6cceb8e4cf8..df51921396a 100644
--- a/llvm/tools/llvm-lto2/llvm-lto2.cpp
+++ b/llvm/tools/llvm-lto2/llvm-lto2.cpp
@@ -101,6 +101,12 @@ static cl::opt<bool> OptRemarksWithHotness(
"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;
diff --git a/llvm/tools/opt/opt.cpp b/llvm/tools/opt/opt.cpp
index 06745b0cca0..b4c39e2fca8 100644
--- a/llvm/tools/opt/opt.cpp
+++ b/llvm/tools/opt/opt.cpp
@@ -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...
OpenPOWER on IntegriCloud