@@ -430,6 +430,75 @@ static bool isObjCRuntimeLinked(const ArgList &Args) {
430430 return Args.hasArg (options::OPT_fobjc_link_runtime);
431431}
432432
433+ static bool checkRemarksOptions (const Driver &D, const ArgList &Args,
434+ const llvm::Triple &Triple) {
435+ // When enabling remarks, we need to error if:
436+ // * The remark file is specified but we're targeting multiple architectures,
437+ // which means more than one remark file is being generated.
438+ bool hasMultipleInvocations =
439+ Args.getAllArgValues (options::OPT_arch).size () > 1 ;
440+ bool hasExplicitOutputFile =
441+ Args.getLastArg (options::OPT_foptimization_record_file_EQ);
442+ if (hasMultipleInvocations && hasExplicitOutputFile) {
443+ D.Diag (diag::err_drv_invalid_output_with_multiple_archs)
444+ << " -foptimization-record-file" ;
445+ return false ;
446+ }
447+ return true ;
448+ }
449+
450+ static void renderRemarksOptions (const ArgList &Args, ArgStringList &CmdArgs,
451+ const llvm::Triple &Triple,
452+ const InputInfo &Output, const JobAction &JA) {
453+ StringRef Format = " yaml" ;
454+ if (const Arg *A = Args.getLastArg (options::OPT_fsave_optimization_record_EQ))
455+ Format = A->getValue ();
456+
457+ CmdArgs.push_back (" -mllvm" );
458+ CmdArgs.push_back (" -lto-pass-remarks-output" );
459+ CmdArgs.push_back (" -mllvm" );
460+
461+ const Arg *A = Args.getLastArg (options::OPT_foptimization_record_file_EQ);
462+ if (A) {
463+ CmdArgs.push_back (A->getValue ());
464+ } else {
465+ assert (Output.isFilename () && " Unexpected ld output." );
466+ SmallString<128 > F;
467+ F = Output.getFilename ();
468+ F += " .opt." ;
469+ F += Format;
470+
471+ CmdArgs.push_back (Args.MakeArgString (F));
472+ }
473+
474+ if (const Arg *A =
475+ Args.getLastArg (options::OPT_foptimization_record_passes_EQ)) {
476+ CmdArgs.push_back (" -mllvm" );
477+ std::string Passes =
478+ std::string (" -lto-pass-remarks-filter=" ) + A->getValue ();
479+ CmdArgs.push_back (Args.MakeArgString (Passes));
480+ }
481+
482+ if (!Format.empty ()) {
483+ CmdArgs.push_back (" -mllvm" );
484+ Twine FormatArg = Twine (" -lto-pass-remarks-format=" ) + Format;
485+ CmdArgs.push_back (Args.MakeArgString (FormatArg));
486+ }
487+
488+ if (getLastProfileUseArg (Args)) {
489+ CmdArgs.push_back (" -mllvm" );
490+ CmdArgs.push_back (" -lto-pass-remarks-with-hotness" );
491+
492+ if (const Arg *A =
493+ Args.getLastArg (options::OPT_fdiagnostics_hotness_threshold_EQ)) {
494+ CmdArgs.push_back (" -mllvm" );
495+ std::string Opt =
496+ std::string (" -lto-pass-remarks-hotness-threshold=" ) + A->getValue ();
497+ CmdArgs.push_back (Args.MakeArgString (Opt));
498+ }
499+ }
500+ }
501+
433502void darwin::Linker::ConstructJob (Compilation &C, const JobAction &JA,
434503 const InputInfo &Output,
435504 const InputInfoList &Inputs,
@@ -464,55 +533,9 @@ void darwin::Linker::ConstructJob(Compilation &C, const JobAction &JA,
464533 // we follow suite for ease of comparison.
465534 AddLinkArgs (C, Args, CmdArgs, Inputs);
466535
467- // For LTO, pass the name of the optimization record file and other
468- // opt-remarks flags.
469- if (Args.hasFlag (options::OPT_fsave_optimization_record,
470- options::OPT_fsave_optimization_record_EQ,
471- options::OPT_fno_save_optimization_record, false )) {
472- CmdArgs.push_back (" -mllvm" );
473- CmdArgs.push_back (" -lto-pass-remarks-output" );
474- CmdArgs.push_back (" -mllvm" );
475-
476- SmallString<128 > F;
477- F = Output.getFilename ();
478- F += " .opt." ;
479- if (const Arg *A =
480- Args.getLastArg (options::OPT_fsave_optimization_record_EQ))
481- F += A->getValue ();
482- else
483- F += " yaml" ;
484-
485- CmdArgs.push_back (Args.MakeArgString (F));
486-
487- if (getLastProfileUseArg (Args)) {
488- CmdArgs.push_back (" -mllvm" );
489- CmdArgs.push_back (" -lto-pass-remarks-with-hotness" );
490-
491- if (const Arg *A =
492- Args.getLastArg (options::OPT_fdiagnostics_hotness_threshold_EQ)) {
493- CmdArgs.push_back (" -mllvm" );
494- std::string Opt =
495- std::string (" -lto-pass-remarks-hotness-threshold=" ) + A->getValue ();
496- CmdArgs.push_back (Args.MakeArgString (Opt));
497- }
498- }
499-
500- if (const Arg *A =
501- Args.getLastArg (options::OPT_foptimization_record_passes_EQ)) {
502- CmdArgs.push_back (" -mllvm" );
503- std::string Passes =
504- std::string (" -lto-pass-remarks-filter=" ) + A->getValue ();
505- CmdArgs.push_back (Args.MakeArgString (Passes));
506- }
507-
508- if (const Arg *A =
509- Args.getLastArg (options::OPT_fsave_optimization_record_EQ)) {
510- CmdArgs.push_back (" -mllvm" );
511- std::string Format =
512- std::string (" -lto-pass-remarks-format=" ) + A->getValue ();
513- CmdArgs.push_back (Args.MakeArgString (Format));
514- }
515- }
536+ if (checkRemarksOptions (getToolChain ().getDriver (), Args,
537+ getToolChain ().getTriple ()))
538+ renderRemarksOptions (Args, CmdArgs, getToolChain ().getTriple (), Output, JA);
516539
517540 // Propagate the -moutline flag to the linker in LTO.
518541 if (Arg *A =
0 commit comments