using namespace clang;
using namespace llvm::opt;
+static void renderRpassOptions(const ArgList &Args, ArgStringList &CmdArgs) {
+ if (const Arg *A = Args.getLastArg(options::OPT_Rpass_EQ))
+ CmdArgs.push_back(Args.MakeArgString(Twine("--plugin-opt=-pass-remarks=") +
+ A->getValue()));
+
+ if (const Arg *A = Args.getLastArg(options::OPT_Rpass_missed_EQ))
+ CmdArgs.push_back(Args.MakeArgString(
+ Twine("--plugin-opt=-pass-remarks-missed=") + A->getValue()));
+
+ if (const Arg *A = Args.getLastArg(options::OPT_Rpass_analysis_EQ))
+ CmdArgs.push_back(Args.MakeArgString(
+ Twine("--plugin-opt=-pass-remarks-analysis=") + A->getValue()));
+}
+
+static void renderRemarksOptions(const ArgList &Args, ArgStringList &CmdArgs,
+ const llvm::Triple &Triple,
+ const InputInfo &Input,
+ const InputInfo &Output) {
+ StringRef Format = "yaml";
+ if (const Arg *A = Args.getLastArg(options::OPT_fsave_optimization_record_EQ))
+ Format = A->getValue();
+
+ SmallString<128> F;
+ const Arg *A = Args.getLastArg(options::OPT_foptimization_record_file_EQ);
+ if (A)
+ F = A->getValue();
+ else if (Output.isFilename())
+ F = Output.getFilename();
+
+ assert(!F.empty() && "Cannot determine remarks output name.");
+ // Append "opt.ld.<format>" to the end of the file name.
+ CmdArgs.push_back(
+ Args.MakeArgString(Twine("--plugin-opt=opt-remarks-filename=") + F +
+ Twine(".opt.ld.") + Format));
+
+ if (const Arg *A =
+ Args.getLastArg(options::OPT_foptimization_record_passes_EQ))
+ CmdArgs.push_back(Args.MakeArgString(
+ Twine("--plugin-opt=opt-remarks-passes=") + A->getValue()));
+
+ CmdArgs.push_back(Args.MakeArgString(
+ Twine("--plugin-opt=opt-remarks-format=") + Format.data()));
+}
+
+static void renderRemarksHotnessOptions(const ArgList &Args,
+ ArgStringList &CmdArgs) {
+ if (Args.hasFlag(options::OPT_fdiagnostics_show_hotness,
+ options::OPT_fno_diagnostics_show_hotness, false))
+ CmdArgs.push_back("--plugin-opt=opt-remarks-with-hotness");
+
+ if (const Arg *A =
+ Args.getLastArg(options::OPT_fdiagnostics_hotness_threshold_EQ))
+ CmdArgs.push_back(Args.MakeArgString(
+ Twine("--plugin-opt=opt-remarks-hotness-threshold=") + A->getValue()));
+}
+
void tools::addPathIfExists(const Driver &D, const Twine &Path,
ToolChain::path_list &Paths) {
if (D.getVFS().exists(Path))
Args.MakeArgString(Twine("-plugin-opt=stats-file=") + StatsFile));
addX86AlignBranchArgs(D, Args, CmdArgs, /*IsLTO=*/true);
+
+ // Handle remark diagnostics on screen options: '-Rpass-*'.
+ renderRpassOptions(Args, CmdArgs);
+
+ // Handle serialized remarks options: '-fsave-optimization-record'
+ // and '-foptimization-record-*'.
+ if (willEmitRemarks(Args))
+ renderRemarksOptions(Args, CmdArgs, ToolChain.getEffectiveTriple(), Input,
+ Output);
+
+ // Handle remarks hotness/threshold related options.
+ renderRemarksHotnessOptions(Args, CmdArgs);
}
void tools::addArchSpecificRPath(const ToolChain &TC, const ArgList &Args,
// CHECK-EQ-FORMAT: "-opt-record-format" "some-format"
// CHECK-FOPT-DISABLE-FORMAT-NOT: "-fno-save-optimization-record"
+
+// Test remarks options pass-through
+// No pass-through: lto is disabled
+// RUN: %clang -target x86_64 -### -o FOO -fdiagnostics-hotness-threshold=100 -fsave-optimization-record %s 2>&1 | FileCheck %s -check-prefix=CHECK-NOPASS
+
+// Pass-through:
+// RUN: %clang -target x86_64-linux -### -fuse-ld=lld -flto -fdiagnostics-hotness-threshold=100 -fsave-optimization-record -foptimization-record-passes=inline %s 2>&1 | FileCheck %s -check-prefix=CHECK-PASS-A
+// RUN: %clang -target x86_64-linux -### -o FOO -fuse-ld=gold -flto -fdiagnostics-hotness-threshold=100 -fsave-optimization-record -foptimization-record-passes=inline %s 2>&1 | FileCheck %s -check-prefix=CHECK-PASS
+// RUN: %clang -target x86_64-linux -### -o FOO -fuse-ld=lld -flto=thin -fdiagnostics-hotness-threshold=100 -fsave-optimization-record=some-format -foptimization-record-file=FOO.txt %s 2>&1 | FileCheck %s -check-prefix=CHECK-PASS-CUSTOM
+// RUN: %clang -target x86_64-linux -### -o FOO -fuse-ld=lld -flto=thin -fdiagnostics-hotness-threshold=100 -Rpass=inline -Rpass-missed=inline -Rpass-analysis=inline %s 2>&1 | FileCheck %s -check-prefix=CHECK-PASS-RPASS
+
+// CHECK-NOPASS-NOT: "--plugin-opt=opt-remarks-filename="
+// CHECK-NOPASS-NOT: "--plugin-opt=opt-remarks-passes=inline"
+// CHECK-NOPASS-NOT: "--plugin-opt=opt-remarks-format=yaml"
+// CHECK-NOPASS-NOT: "--plugin-opt=opt-remarks-hotness-threshold=100"
+
+// CHECK-PASS-A: "--plugin-opt=opt-remarks-filename=a.out.opt.ld.yaml"
+// CHECK-PASS-A-SAME: "--plugin-opt=opt-remarks-passes=inline"
+// CHECK-PASS-A-SAME: "--plugin-opt=opt-remarks-format=yaml"
+// CHECK-PASS-A-SAME: "--plugin-opt=opt-remarks-hotness-threshold=100"
+
+// CHECK-PASS: "--plugin-opt=opt-remarks-filename=FOO.opt.ld.yaml"
+// CHECK-PASS-SAME: "--plugin-opt=opt-remarks-passes=inline"
+// CHECK-PASS-SAME: "--plugin-opt=opt-remarks-format=yaml"
+// CHECK-PASS-SAME: "--plugin-opt=opt-remarks-hotness-threshold=100"
+
+// CHECK-PASS-CUSTOM: "--plugin-opt=opt-remarks-filename=FOO.txt.opt.ld.some-format"
+// CHECK-PASS-CUSTOM-SAME: "--plugin-opt=opt-remarks-format=some-format"
+// CHECK-PASS-CUSTOM-SAME: "--plugin-opt=opt-remarks-hotness-threshold=100"
+
+// CHECK-PASS-RPASS: "--plugin-opt=-pass-remarks=inline"
+// CHECK-PASS-RPASS-SAME: "--plugin-opt=-pass-remarks-missed=inline"
+// CHECK-PASS-RPASS-SAME: "--plugin-opt=-pass-remarks-analysis=inline"
+// CHECK-PASS-RPASS-SAME: "--plugin-opt=opt-remarks-hotness-threshold=100"