@@ -1415,6 +1415,132 @@ static bool isNoCommonDefault(const llvm::Triple &Triple) {
14151415 }
14161416}
14171417
1418+ static bool shouldEmitRemarks (const ArgList &Args) {
1419+ // -fsave-optimization-record enables it.
1420+ if (Args.hasFlag (options::OPT_fsave_optimization_record,
1421+ options::OPT_fno_save_optimization_record, false ))
1422+ return true ;
1423+
1424+ // -fsave-optimization-record=<format> enables it as well.
1425+ if (Args.hasFlag (options::OPT_fsave_optimization_record_EQ,
1426+ options::OPT_fno_save_optimization_record, false ))
1427+ return true ;
1428+
1429+ // -foptimization-record-file alone enables it too.
1430+ if (Args.hasFlag (options::OPT_foptimization_record_file_EQ,
1431+ options::OPT_fno_save_optimization_record, false ))
1432+ return true ;
1433+
1434+ // -foptimization-record-passes alone enables it too.
1435+ if (Args.hasFlag (options::OPT_foptimization_record_passes_EQ,
1436+ options::OPT_fno_save_optimization_record, false ))
1437+ return true ;
1438+ return false ;
1439+ }
1440+
1441+ static bool hasMultipleInvocations (const llvm::Triple &Triple,
1442+ const ArgList &Args) {
1443+ // Supported only on Darwin where we invoke the compiler multiple times
1444+ // followed by an invocation to lipo.
1445+ if (!Triple.isOSDarwin ())
1446+ return false ;
1447+ // If more than one "-arch <arch>" is specified, we're targeting multiple
1448+ // architectures resulting in a fat binary.
1449+ return Args.getAllArgValues (options::OPT_arch).size () > 1 ;
1450+ }
1451+
1452+ static bool checkRemarksOptions (const Driver &D, const ArgList &Args,
1453+ const llvm::Triple &Triple) {
1454+ // When enabling remarks, we need to error if:
1455+ // * The remark file is specified but we're targeting multiple architectures,
1456+ // which means more than one remark file is being generated.
1457+ bool hasMultipleInvocations = ::hasMultipleInvocations (Triple, Args);
1458+ bool hasExplicitOutputFile =
1459+ Args.getLastArg (options::OPT_foptimization_record_file_EQ);
1460+ if (hasMultipleInvocations && hasExplicitOutputFile) {
1461+ D.Diag (diag::err_drv_invalid_output_with_multiple_archs)
1462+ << " -foptimization-record-file" ;
1463+ return false ;
1464+ }
1465+ return true ;
1466+ }
1467+
1468+ static void renderRemarksOptions (const ArgList &Args, ArgStringList &CmdArgs,
1469+ const llvm::Triple &Triple,
1470+ const InputInfo &Input, const JobAction &JA) {
1471+ CmdArgs.push_back (" -opt-record-file" );
1472+
1473+ const Arg *A = Args.getLastArg (options::OPT_foptimization_record_file_EQ);
1474+ if (A) {
1475+ CmdArgs.push_back (A->getValue ());
1476+ } else {
1477+ bool hasMultipleArchs =
1478+ Triple.isOSDarwin () && // Only supported on Darwin platforms.
1479+ Args.getAllArgValues (options::OPT_arch).size () > 1 ;
1480+ SmallString<128 > F;
1481+
1482+ if (Args.hasArg (options::OPT_c) || Args.hasArg (options::OPT_S)) {
1483+ if (Arg *FinalOutput = Args.getLastArg (options::OPT_o))
1484+ F = FinalOutput->getValue ();
1485+ }
1486+
1487+ if (F.empty ()) {
1488+ // Use the input filename.
1489+ F = llvm::sys::path::stem (Input.getBaseInput ());
1490+
1491+ // If we're compiling for an offload architecture (i.e. a CUDA device),
1492+ // we need to make the file name for the device compilation different
1493+ // from the host compilation.
1494+ if (!JA.isDeviceOffloading (Action::OFK_None) &&
1495+ !JA.isDeviceOffloading (Action::OFK_Host)) {
1496+ llvm::sys::path::replace_extension (F, " " );
1497+ F += Action::GetOffloadingFileNamePrefix (JA.getOffloadingDeviceKind (),
1498+ Triple.normalize ());
1499+ F += " -" ;
1500+ F += JA.getOffloadingArch ();
1501+ }
1502+ }
1503+
1504+ // If we're having more than one "-arch", we should name the files
1505+ // differently so that every cc1 invocation writes to a different file.
1506+ // We're doing that by appending "-<arch>" with "<arch>" being the arch
1507+ // name from the triple.
1508+ if (hasMultipleArchs) {
1509+ // First, remember the extension.
1510+ SmallString<64 > OldExtension = llvm::sys::path::extension (F);
1511+ // then, remove it.
1512+ llvm::sys::path::replace_extension (F, " " );
1513+ // attach -<arch> to it.
1514+ F += " -" ;
1515+ F += Triple.getArchName ();
1516+ // put back the extension.
1517+ llvm::sys::path::replace_extension (F, OldExtension);
1518+ }
1519+
1520+ std::string Extension = " opt." ;
1521+ if (const Arg *A =
1522+ Args.getLastArg (options::OPT_fsave_optimization_record_EQ))
1523+ Extension += A->getValue ();
1524+ else
1525+ Extension += " yaml" ;
1526+
1527+ llvm::sys::path::replace_extension (F, Extension);
1528+ CmdArgs.push_back (Args.MakeArgString (F));
1529+ }
1530+
1531+ if (const Arg *A =
1532+ Args.getLastArg (options::OPT_foptimization_record_passes_EQ)) {
1533+ CmdArgs.push_back (" -opt-record-passes" );
1534+ CmdArgs.push_back (A->getValue ());
1535+ }
1536+
1537+ if (const Arg *A =
1538+ Args.getLastArg (options::OPT_fsave_optimization_record_EQ)) {
1539+ CmdArgs.push_back (" -opt-record-format" );
1540+ CmdArgs.push_back (A->getValue ());
1541+ }
1542+ }
1543+
14181544namespace {
14191545void RenderARMABI (const llvm::Triple &Triple, const ArgList &Args,
14201546 ArgStringList &CmdArgs) {
@@ -5412,85 +5538,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
54125538 CmdArgs.push_back (" -fapple-pragma-pack" );
54135539
54145540 // Remarks can be enabled with any of the `-f.*optimization-record.*` flags.
5415- if (Args.hasFlag (options::OPT_fsave_optimization_record,
5416- options::OPT_foptimization_record_file_EQ,
5417- options::OPT_fno_save_optimization_record, false ) ||
5418- Args.hasFlag (options::OPT_fsave_optimization_record_EQ,
5419- options::OPT_fno_save_optimization_record, false ) ||
5420- Args.hasFlag (options::OPT_foptimization_record_passes_EQ,
5421- options::OPT_fno_save_optimization_record, false )) {
5422- CmdArgs.push_back (" -opt-record-file" );
5423-
5424- const Arg *A = Args.getLastArg (options::OPT_foptimization_record_file_EQ);
5425- if (A) {
5426- CmdArgs.push_back (A->getValue ());
5427- } else {
5428- bool hasMultipleArchs =
5429- Triple.isOSDarwin () && // Only supported on Darwin platforms.
5430- Args.getAllArgValues (options::OPT_arch).size () > 1 ;
5431- SmallString<128 > F;
5432-
5433- if (Args.hasArg (options::OPT_c) || Args.hasArg (options::OPT_S)) {
5434- if (Arg *FinalOutput = Args.getLastArg (options::OPT_o))
5435- F = FinalOutput->getValue ();
5436- }
5437-
5438- if (F.empty ()) {
5439- // Use the input filename.
5440- F = llvm::sys::path::stem (Input.getBaseInput ());
5441-
5442- // If we're compiling for an offload architecture (i.e. a CUDA device),
5443- // we need to make the file name for the device compilation different
5444- // from the host compilation.
5445- if (!JA.isDeviceOffloading (Action::OFK_None) &&
5446- !JA.isDeviceOffloading (Action::OFK_Host)) {
5447- llvm::sys::path::replace_extension (F, " " );
5448- F += Action::GetOffloadingFileNamePrefix (JA.getOffloadingDeviceKind (),
5449- Triple.normalize ());
5450- F += " -" ;
5451- F += JA.getOffloadingArch ();
5452- }
5453- }
5454-
5455- // If we're having more than one "-arch", we should name the files
5456- // differently so that every cc1 invocation writes to a different file.
5457- // We're doing that by appending "-<arch>" with "<arch>" being the arch
5458- // name from the triple.
5459- if (hasMultipleArchs) {
5460- // First, remember the extension.
5461- SmallString<64 > OldExtension = llvm::sys::path::extension (F);
5462- // then, remove it.
5463- llvm::sys::path::replace_extension (F, " " );
5464- // attach -<arch> to it.
5465- F += " -" ;
5466- F += Triple.getArchName ();
5467- // put back the extension.
5468- llvm::sys::path::replace_extension (F, OldExtension);
5469- }
5470-
5471- std::string Extension = " opt." ;
5472- if (const Arg *A =
5473- Args.getLastArg (options::OPT_fsave_optimization_record_EQ))
5474- Extension += A->getValue ();
5475- else
5476- Extension += " yaml" ;
5477-
5478- llvm::sys::path::replace_extension (F, Extension);
5479- CmdArgs.push_back (Args.MakeArgString (F));
5480- }
5481-
5482- if (const Arg *A =
5483- Args.getLastArg (options::OPT_foptimization_record_passes_EQ)) {
5484- CmdArgs.push_back (" -opt-record-passes" );
5485- CmdArgs.push_back (A->getValue ());
5486- }
5487-
5488- if (const Arg *A =
5489- Args.getLastArg (options::OPT_fsave_optimization_record_EQ)) {
5490- CmdArgs.push_back (" -opt-record-format" );
5491- CmdArgs.push_back (A->getValue ());
5492- }
5493- }
5541+ if (shouldEmitRemarks (Args) && checkRemarksOptions (D, Args, Triple))
5542+ renderRemarksOptions (Args, CmdArgs, Triple, Input, JA);
54945543
54955544 bool RewriteImports = Args.hasFlag (options::OPT_frewrite_imports,
54965545 options::OPT_fno_rewrite_imports, false );
0 commit comments