return Args.hasArg(options::OPT_fobjc_link_runtime);
}
+static bool checkRemarksOptions(const Driver &D, const ArgList &Args,
+ const llvm::Triple &Triple) {
+ // When enabling remarks, we need to error if:
+ // * The remark file is specified but we're targeting multiple architectures,
+ // which means more than one remark file is being generated.
+ bool hasMultipleInvocations =
+ Args.getAllArgValues(options::OPT_arch).size() > 1;
+ bool hasExplicitOutputFile =
+ Args.getLastArg(options::OPT_foptimization_record_file_EQ);
+ if (hasMultipleInvocations && hasExplicitOutputFile) {
+ D.Diag(diag::err_drv_invalid_output_with_multiple_archs)
+ << "-foptimization-record-file";
+ return false;
+ }
+ return true;
+}
+
+static void renderRemarksOptions(const ArgList &Args, ArgStringList &CmdArgs,
+ const llvm::Triple &Triple,
+ const InputInfo &Output, const JobAction &JA) {
+ StringRef Format = "yaml";
+ if (const Arg *A = Args.getLastArg(options::OPT_fsave_optimization_record_EQ))
+ Format = A->getValue();
+
+ CmdArgs.push_back("-mllvm");
+ CmdArgs.push_back("-lto-pass-remarks-output");
+ CmdArgs.push_back("-mllvm");
+
+ const Arg *A = Args.getLastArg(options::OPT_foptimization_record_file_EQ);
+ if (A) {
+ CmdArgs.push_back(A->getValue());
+ } else {
+ assert(Output.isFilename() && "Unexpected ld output.");
+ SmallString<128> F;
+ F = Output.getFilename();
+ F += ".opt.";
+ F += Format;
+
+ CmdArgs.push_back(Args.MakeArgString(F));
+ }
+
+ 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));
+ }
+
+ if (!Format.empty()) {
+ CmdArgs.push_back("-mllvm");
+ Twine FormatArg = Twine("-lto-pass-remarks-format=") + Format;
+ CmdArgs.push_back(Args.MakeArgString(FormatArg));
+ }
+
+ if (getLastProfileUseArg(Args)) {
+ CmdArgs.push_back("-mllvm");
+ CmdArgs.push_back("-lto-pass-remarks-with-hotness");
+
+ if (const Arg *A =
+ Args.getLastArg(options::OPT_fdiagnostics_hotness_threshold_EQ)) {
+ CmdArgs.push_back("-mllvm");
+ std::string Opt =
+ std::string("-lto-pass-remarks-hotness-threshold=") + A->getValue();
+ CmdArgs.push_back(Args.MakeArgString(Opt));
+ }
+ }
+}
+
void darwin::Linker::ConstructJob(Compilation &C, const JobAction &JA,
const InputInfo &Output,
const InputInfoList &Inputs,
// we follow suite for ease of comparison.
AddLinkArgs(C, Args, CmdArgs, Inputs);
- // For LTO, pass the name of the optimization record file and other
- // opt-remarks flags.
- if (Args.hasFlag(options::OPT_fsave_optimization_record,
- options::OPT_fsave_optimization_record_EQ,
- options::OPT_fno_save_optimization_record, false)) {
- CmdArgs.push_back("-mllvm");
- CmdArgs.push_back("-lto-pass-remarks-output");
- CmdArgs.push_back("-mllvm");
-
- SmallString<128> F;
- F = Output.getFilename();
- F += ".opt.";
- if (const Arg *A =
- Args.getLastArg(options::OPT_fsave_optimization_record_EQ))
- F += A->getValue();
- else
- F += "yaml";
-
- CmdArgs.push_back(Args.MakeArgString(F));
-
- if (getLastProfileUseArg(Args)) {
- CmdArgs.push_back("-mllvm");
- CmdArgs.push_back("-lto-pass-remarks-with-hotness");
-
- if (const Arg *A =
- Args.getLastArg(options::OPT_fdiagnostics_hotness_threshold_EQ)) {
- CmdArgs.push_back("-mllvm");
- std::string Opt =
- std::string("-lto-pass-remarks-hotness-threshold=") + A->getValue();
- 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));
- }
-
- if (const Arg *A =
- Args.getLastArg(options::OPT_fsave_optimization_record_EQ)) {
- CmdArgs.push_back("-mllvm");
- std::string Format =
- std::string("-lto-pass-remarks-format=") + A->getValue();
- CmdArgs.push_back(Args.MakeArgString(Format));
- }
- }
+ if (checkRemarksOptions(getToolChain().getDriver(), Args,
+ getToolChain().getTriple()))
+ renderRemarksOptions(Args, CmdArgs, getToolChain().getTriple(), Output, JA);
// Propagate the -moutline flag to the linker in LTO.
if (Arg *A =
// LINK_VERSION_DIGITS: invalid version number in '-mlinker-version=133.3.0.1.a'
// LINK_VERSION_DIGITS: invalid version number in '-mlinker-version=133.3.0.1a'
-// Check that we're passing -lto-pass-remarks-output for LTO
-// RUN: %clang -target x86_64-apple-darwin12 %t.o -fsave-optimization-record -### -o foo/bar.out 2> %t.log
-// RUN: FileCheck -check-prefix=PASS_REMARKS_OUTPUT %s < %t.log
-// PASS_REMARKS_OUTPUT: "-mllvm" "-lto-pass-remarks-output" "-mllvm" "foo/bar.out.opt.yaml"
-// PASS_REMARKS_OUTPUT-NOT: -lto-pass-remarks-with-hotness
-
-// RUN: %clang -target x86_64-apple-darwin12 %t.o -fsave-optimization-record -### 2> %t.log
-// RUN: FileCheck -check-prefix=PASS_REMARKS_OUTPUT_NO_O %s < %t.log
-// PASS_REMARKS_OUTPUT_NO_O: "-mllvm" "-lto-pass-remarks-output" "-mllvm" "a.out.opt.yaml"
-
-// RUN: %clang -target x86_64-apple-darwin12 %t.o -fsave-optimization-record -fprofile-instr-use=blah -### -o foo/bar.out 2> %t.log
-// RUN: FileCheck -check-prefix=PASS_REMARKS_WITH_HOTNESS %s < %t.log
-// PASS_REMARKS_WITH_HOTNESS: "-mllvm" "-lto-pass-remarks-output" "-mllvm" "foo/bar.out.opt.yaml" "-mllvm" "-lto-pass-remarks-with-hotness"
-
-// RUN: %clang -target x86_64-apple-darwin12 %t.o -fsave-optimization-record -fprofile-instr-use=blah -fdiagnostics-hotness-threshold=100 -### -o foo/bar.out 2> %t.log
-// 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-darwin12 %t.o -fsave-optimization-record=some-format -### -o foo/bar.out 2> %t.log
-// RUN: FileCheck -check-prefix=PASS_REMARKS_WITH_FORMAT %s < %t.log
-// PASS_REMARKS_WITH_FORMAT: "-mllvm" "-lto-pass-remarks-output" "-mllvm" "foo/bar.out.opt.some-format" "-mllvm" "-lto-pass-remarks-format=some-format"
-
// 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
--- /dev/null
+// REQUIRES: system-darwin
+
+// RUN: touch %t.o
+//
+// Check that we're passing -lto-pass-remarks-output for LTO
+// RUN: %clang -target x86_64-apple-darwin12 %t.o -fsave-optimization-record -### -o foo/bar.out 2> %t.log
+// RUN: FileCheck -check-prefix=PASS_REMARKS_OUTPUT %s < %t.log
+// PASS_REMARKS_OUTPUT: "-mllvm" "-lto-pass-remarks-output" "-mllvm" "foo/bar.out.opt.yaml" "-mllvm" "-lto-pass-remarks-format=yaml"
+// PASS_REMARKS_OUTPUT-NOT: -lto-pass-remarks-with-hotness
+
+// RUN: %clang -target x86_64-apple-darwin12 %t.o -fsave-optimization-record -### 2> %t.log
+// RUN: FileCheck -check-prefix=PASS_REMARKS_OUTPUT_NO_O %s < %t.log
+// PASS_REMARKS_OUTPUT_NO_O: "-mllvm" "-lto-pass-remarks-output" "-mllvm" "a.out.opt.yaml"
+
+// RUN: %clang -target x86_64-apple-darwin12 %t.o -fsave-optimization-record -fprofile-instr-use=blah -### -o foo/bar.out 2> %t.log
+// RUN: FileCheck -check-prefix=PASS_REMARKS_WITH_HOTNESS %s < %t.log
+// PASS_REMARKS_WITH_HOTNESS: "-mllvm" "-lto-pass-remarks-output" "-mllvm" "foo/bar.out.opt.yaml" "-mllvm" "-lto-pass-remarks-format=yaml" "-mllvm" "-lto-pass-remarks-with-hotness"
+
+// RUN: %clang -target x86_64-apple-darwin12 %t.o -fsave-optimization-record -fprofile-instr-use=blah -fdiagnostics-hotness-threshold=100 -### -o foo/bar.out 2> %t.log
+// 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-format=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-darwin12 %t.o -fsave-optimization-record=some-format -### -o foo/bar.out 2> %t.log
+// RUN: FileCheck -check-prefix=PASS_REMARKS_WITH_FORMAT %s < %t.log
+// PASS_REMARKS_WITH_FORMAT: "-mllvm" "-lto-pass-remarks-output" "-mllvm" "foo/bar.out.opt.some-format" "-mllvm" "-lto-pass-remarks-format=some-format"
+
+// RUN: %clang -target x86_64-apple-darwin12 %t.o -foptimization-record-file=remarks-custom.opt.yaml -### -o foo/bar.out 2> %t.log
+// RUN: FileCheck -check-prefix=PASS_REMARKS_WITH_FILE %s < %t.log
+// PASS_REMARKS_WITH_FILE: "-mllvm" "-lto-pass-remarks-output" "-mllvm" "remarks-custom.opt.yaml"
+
+// RUN: %clang -target x86_64-apple-darwin12 -arch x86_64 -arch x86_64h %t.o -fsave-optimization-record -### -o foo/bar.out 2> %t.log
+// RUN: FileCheck -check-prefix=PASS_REMARKS_WITH_FAT %s < %t.log
+// PASS_REMARKS_WITH_FAT: "-arch" "x86_64"{{.*}}"-mllvm" "-lto-pass-remarks-output"
+// PASS_REMARKS_WITH_FAT-NEXT: "-arch" "x86_64h"{{.*}}"-mllvm" "-lto-pass-remarks-output"
+//
+// RUN: %clang -target x86_64-apple-darwin12 -arch x86_64 -arch x86_64h %t.o -foptimization-record-file=custom.opt.yaml -### -o foo/bar.out 2> %t.log
+// RUN: FileCheck -check-prefix=PASS_REMARKS_WITH_FILE_FAT %s < %t.log
+// PASS_REMARKS_WITH_FILE_FAT: error: cannot use '-foptimization-record-file' output with multiple -arch options