From f0801cb9e3caeb41a078bc091b9ed624695c83e4 Mon Sep 17 00:00:00 2001 From: Tarun Prabhu Date: Mon, 12 Aug 2024 14:32:08 -0600 Subject: [PATCH 1/6] [clang][flang][mlir] Support -frecord-command-line option Add support for the -frecord-command-line option that will produce the llvm.commandline metadata which will eventually be saved in the object file. This behavior is also supported in clang. Some refactoring of the code in flang to handle these command line options was carried out. The corresponding -grecord-command-line option which saves the command line in the debug information has not yet been enabled for flang. --- clang/include/clang/Driver/Options.td | 14 ++-- clang/lib/Driver/CMakeLists.txt | 1 + clang/lib/Driver/ToolChains/Clang.cpp | 48 ++---------- clang/lib/Driver/ToolChains/CommonUtils.cpp | 76 +++++++++++++++++++ clang/lib/Driver/ToolChains/CommonUtils.h | 44 +++++++++++ clang/lib/Driver/ToolChains/Flang.cpp | 15 ++++ flang/include/flang/Frontend/CodeGenOptions.h | 3 + flang/include/flang/Lower/Bridge.h | 12 ++- .../Optimizer/Dialect/Support/FIRContext.h | 6 ++ flang/lib/Frontend/CompilerInvocation.cpp | 6 ++ flang/lib/Frontend/FrontendActions.cpp | 2 +- flang/lib/Lower/Bridge.cpp | 8 +- .../Optimizer/Dialect/Support/FIRContext.cpp | 16 ++++ flang/test/Driver/frecord-command-line.f90 | 16 ++++ flang/test/Lower/record-command-line.f90 | 9 +++ flang/tools/bbc/CMakeLists.txt | 1 + flang/tools/bbc/bbc.cpp | 10 ++- .../mlir/Dialect/LLVMIR/LLVMDialect.td | 1 + .../include/mlir/Target/LLVMIR/ModuleImport.h | 4 + .../mlir/Target/LLVMIR/ModuleTranslation.h | 3 + mlir/lib/Target/LLVMIR/ModuleImport.cpp | 19 +++++ mlir/lib/Target/LLVMIR/ModuleTranslation.cpp | 17 +++++ mlir/test/Target/LLVMIR/Import/commandline.ll | 6 ++ mlir/test/Target/LLVMIR/commandline.mlir | 6 ++ 24 files changed, 284 insertions(+), 59 deletions(-) create mode 100644 clang/lib/Driver/ToolChains/CommonUtils.cpp create mode 100644 clang/lib/Driver/ToolChains/CommonUtils.h create mode 100644 flang/test/Driver/frecord-command-line.f90 create mode 100644 flang/test/Lower/record-command-line.f90 create mode 100644 mlir/test/Target/LLVMIR/Import/commandline.ll create mode 100644 mlir/test/Target/LLVMIR/commandline.mlir diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index aa3ae92fb6ae78a..11dd17aa7af9a00 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -1994,16 +1994,18 @@ def fparse_all_comments : Flag<["-"], "fparse-all-comments">, Group, MarshallingInfoFlag>; def frecord_command_line : Flag<["-"], "frecord-command-line">, - DocBrief<[{Generate a section named ".GCC.command.line" containing the clang + DocBrief<[{Generate a section named ".GCC.command.line" containing the driver command-line. After linking, the section may contain multiple command lines, which will be individually terminated by null bytes. Separate arguments within a command line are combined with spaces; spaces and backslashes within an argument are escaped with backslashes. This format differs from the format of the equivalent section produced by GCC with the -frecord-gcc-switches flag. This option is currently only supported on ELF targets.}]>, - Group; + Group, + Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>; def fno_record_command_line : Flag<["-"], "fno-record-command-line">, - Group; + Group, + Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>; def : Flag<["-"], "frecord-gcc-switches">, Alias; def : Flag<["-"], "fno-record-gcc-switches">, Alias; def fcommon : Flag<["-"], "fcommon">, Group, @@ -7141,6 +7143,9 @@ def mrelocation_model : Separate<["-"], "mrelocation-model">, NormalizedValues<["Static", "PIC_", "ROPI", "RWPI", "ROPI_RWPI", "DynamicNoPIC"]>, MarshallingInfoEnum, "PIC_">; def debug_info_kind_EQ : Joined<["-"], "debug-info-kind=">; +def record_command_line : Separate<["-"], "record-command-line">, + HelpText<"The string to embed in the .LLVM.command.line section.">, + MarshallingInfoString>; } // let Visibility = [CC1Option, CC1AsOption, FC1Option] @@ -7161,9 +7166,6 @@ def debugger_tuning_EQ : Joined<["-"], "debugger-tuning=">, def dwarf_debug_flags : Separate<["-"], "dwarf-debug-flags">, HelpText<"The string to embed in the Dwarf debug flags record.">, MarshallingInfoString>; -def record_command_line : Separate<["-"], "record-command-line">, - HelpText<"The string to embed in the .LLVM.command.line section.">, - MarshallingInfoString>; def compress_debug_sections_EQ : Joined<["-", "--"], "compress-debug-sections=">, HelpText<"DWARF debug sections compression type">, Values<"none,zlib,zstd">, NormalizedValuesScope<"llvm::DebugCompressionType">, NormalizedValues<["None", "Zlib", "Zstd"]>, diff --git a/clang/lib/Driver/CMakeLists.txt b/clang/lib/Driver/CMakeLists.txt index 32a4378ab499faf..0b92077384e9bcc 100644 --- a/clang/lib/Driver/CMakeLists.txt +++ b/clang/lib/Driver/CMakeLists.txt @@ -48,6 +48,7 @@ add_clang_library(clangDriver ToolChains/BareMetal.cpp ToolChains/Clang.cpp ToolChains/CommonArgs.cpp + ToolChains/CommonUtils.cpp ToolChains/CrossWindows.cpp ToolChains/CSKYToolChain.cpp ToolChains/Cuda.cpp diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index c00df5f5bc729c5..2cf9af81a13eb41 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -21,6 +21,7 @@ #include "Arch/VE.h" #include "Arch/X86.h" #include "CommonArgs.h" +#include "CommonUtils.h" #include "Hexagon.h" #include "MSP430.h" #include "PS4CPU.h" @@ -94,24 +95,6 @@ static void CheckCodeGenerationOptions(const Driver &D, const ArgList &Args) { << "-static"; } -// Add backslashes to escape spaces and other backslashes. -// This is used for the space-separated argument list specified with -// the -dwarf-debug-flags option. -static void EscapeSpacesAndBackslashes(const char *Arg, - SmallVectorImpl &Res) { - for (; *Arg; ++Arg) { - switch (*Arg) { - default: - break; - case ' ': - case '\\': - Res.push_back('\\'); - break; - } - Res.push_back(*Arg); - } -} - /// Apply \a Work on the current tool chain \a RegularToolChain and any other /// offloading tool chain that is associated with the current action \a JA. static void @@ -7702,31 +7685,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // Also record command line arguments into the debug info if // -grecord-gcc-switches options is set on. // By default, -gno-record-gcc-switches is set on and no recording. - auto GRecordSwitches = - Args.hasFlag(options::OPT_grecord_command_line, - options::OPT_gno_record_command_line, false); - auto FRecordSwitches = - Args.hasFlag(options::OPT_frecord_command_line, - options::OPT_fno_record_command_line, false); - if (FRecordSwitches && !Triple.isOSBinFormatELF() && - !Triple.isOSBinFormatXCOFF() && !Triple.isOSBinFormatMachO()) - D.Diag(diag::err_drv_unsupported_opt_for_target) - << Args.getLastArg(options::OPT_frecord_command_line)->getAsString(Args) - << TripleStr; - if (TC.UseDwarfDebugFlags() || GRecordSwitches || FRecordSwitches) { - ArgStringList OriginalArgs; - for (const auto &Arg : Args) - Arg->render(Args, OriginalArgs); - - SmallString<256> Flags; - EscapeSpacesAndBackslashes(Exec, Flags); - for (const char *OriginalArg : OriginalArgs) { - SmallString<128> EscapedArg; - EscapeSpacesAndBackslashes(OriginalArg, EscapedArg); - Flags += " "; - Flags += EscapedArg; - } - auto FlagsArgString = Args.MakeArgString(Flags); + auto GRecordSwitches = false; + auto FRecordSwitches = false; + if (ShouldRecordCommandLine(TC, Args, FRecordSwitches, GRecordSwitches)) { + auto FlagsArgString = RenderEscapedCommandLine(TC, Args); if (TC.UseDwarfDebugFlags() || GRecordSwitches) { CmdArgs.push_back("-dwarf-debug-flags"); CmdArgs.push_back(FlagsArgString); diff --git a/clang/lib/Driver/ToolChains/CommonUtils.cpp b/clang/lib/Driver/ToolChains/CommonUtils.cpp new file mode 100644 index 000000000000000..20d76990517a43c --- /dev/null +++ b/clang/lib/Driver/ToolChains/CommonUtils.cpp @@ -0,0 +1,76 @@ +//===--- CommonUtils.h - Common utilities for the toolchains ----*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "CommonUtils.h" +#include "clang/Driver/Driver.h" +#include "llvm/ADT/SmallString.h" + +using namespace clang::driver; + +namespace clang { + +void EscapeSpacesAndBackslashes(const char *Arg, + llvm::SmallVectorImpl &Res) { + for (; *Arg; ++Arg) { + switch (*Arg) { + default: + break; + case ' ': + case '\\': + Res.push_back('\\'); + break; + } + Res.push_back(*Arg); + } +} + +const char *RenderEscapedCommandLine(const ToolChain &TC, + const llvm::opt::ArgList &Args) { + const Driver &D = TC.getDriver(); + const char *Exec = D.getClangProgramPath(); + + llvm::opt::ArgStringList OriginalArgs; + for (const auto &Arg : Args) + Arg->render(Args, OriginalArgs); + + llvm::SmallString<256> Flags; + EscapeSpacesAndBackslashes(Exec, Flags); + for (const char *OriginalArg : OriginalArgs) { + llvm::SmallString<128> EscapedArg; + EscapeSpacesAndBackslashes(OriginalArg, EscapedArg); + Flags += " "; + Flags += EscapedArg; + } + + return Args.MakeArgString(Flags); +} + +bool ShouldRecordCommandLine(const ToolChain &TC, + const llvm::opt::ArgList &Args, + bool &FRecordCommandLine, + bool &GRecordCommandLine) { + const Driver &D = TC.getDriver(); + const llvm::Triple &Triple = TC.getEffectiveTriple(); + const std::string &TripleStr = Triple.getTriple(); + + FRecordCommandLine = + Args.hasFlag(options::OPT_frecord_command_line, + options::OPT_fno_record_command_line, false); + GRecordCommandLine = + Args.hasFlag(options::OPT_grecord_command_line, + options::OPT_gno_record_command_line, false); + if (FRecordCommandLine && !Triple.isOSBinFormatELF() && + !Triple.isOSBinFormatXCOFF() && !Triple.isOSBinFormatMachO()) + D.Diag(diag::err_drv_unsupported_opt_for_target) + << Args.getLastArg(options::OPT_frecord_command_line)->getAsString(Args) + << TripleStr; + + return FRecordCommandLine || TC.UseDwarfDebugFlags() || GRecordCommandLine; +} + +} // namespace clang diff --git a/clang/lib/Driver/ToolChains/CommonUtils.h b/clang/lib/Driver/ToolChains/CommonUtils.h new file mode 100644 index 000000000000000..1ae1c54cf58db4b --- /dev/null +++ b/clang/lib/Driver/ToolChains/CommonUtils.h @@ -0,0 +1,44 @@ +//===--- CommonUtils.h - Common utilities for the toolchains ----*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_COMMONUTILS_H +#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_COMMONUTILS_H + +#include "clang/Driver/ToolChain.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/Option/ArgList.h" + +namespace clang { + +// Add backslashes to escape spaces and other backslashes. +// This is used for the space-separated argument list specified with +// the -dwarf-debug-flags option. +void EscapeSpacesAndBackslashes(const char *Arg, + llvm::SmallVectorImpl &Res); + +/// Join the args in the given ArgList, escape spaces and backslashes and +/// return the joined string. This is used when saving the command line as a +/// result of using either the -frecord-command-line or -grecord-command-line +/// options. The lifetime of the returned c-string will match that of the Args +/// argument. +const char *RenderEscapedCommandLine(const clang::driver::ToolChain &TC, + const llvm::opt::ArgList &Args); + +/// Check if the command line should be recorded in the object file. This is +/// done if either -frecord-command-line or -grecord-command-line options have +/// been passed. This also does some error checking since -frecord-command-line +/// is currently only supported on ELF platforms. The last two boolean +/// arguments are out parameters and will be set depending on the command +/// line options that were passed. +bool ShouldRecordCommandLine(const clang::driver::ToolChain &TC, + const llvm::opt::ArgList &Args, + bool &FRecordCommandLine, + bool &GRecordCommandLine); +} // namespace clang + +#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_COMMONUTILS_H diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp index 6ce79d27e98c481..2ef14e306cf324b 100644 --- a/clang/lib/Driver/ToolChains/Flang.cpp +++ b/clang/lib/Driver/ToolChains/Flang.cpp @@ -9,6 +9,7 @@ #include "Flang.h" #include "Arch/RISCV.h" #include "CommonArgs.h" +#include "CommonUtils.h" #include "clang/Basic/CodeGenOptions.h" #include "clang/Driver/Options.h" @@ -885,6 +886,20 @@ void Flang::ConstructJob(Compilation &C, const JobAction &JA, addDashXForInput(Args, Input, CmdArgs); + bool FRecordCmdLine = false; + bool GRecordCmdLine = false; + if (ShouldRecordCommandLine(TC, Args, FRecordCmdLine, GRecordCmdLine)) { + const char *CmdLine = RenderEscapedCommandLine(TC, Args); + if (FRecordCmdLine) { + CmdArgs.push_back("-record-command-line"); + CmdArgs.push_back(CmdLine); + } + if (TC.UseDwarfDebugFlags() || GRecordCmdLine) { + CmdArgs.push_back("-dwarf-debug-flags"); + CmdArgs.push_back(CmdLine); + } + } + CmdArgs.push_back(Input.getFilename()); // TODO: Replace flang-new with flang once the new driver replaces the diff --git a/flang/include/flang/Frontend/CodeGenOptions.h b/flang/include/flang/Frontend/CodeGenOptions.h index ac7fcbcba4f7476..f19943335737b91 100644 --- a/flang/include/flang/Frontend/CodeGenOptions.h +++ b/flang/include/flang/Frontend/CodeGenOptions.h @@ -63,6 +63,9 @@ class CodeGenOptions : public CodeGenOptionsBase { /// The directory where temp files are stored if specified by -save-temps std::optional SaveTempsDir; + /// The string containing the commandline for the llvm.commandline metadata. + std::optional RecordCommandLine; + /// The name of the file to which the backend should save YAML optimization /// records. std::string OptRecordFile; diff --git a/flang/include/flang/Lower/Bridge.h b/flang/include/flang/Lower/Bridge.h index 4379ed512cdf0a4..8ea5ed52e282180 100644 --- a/flang/include/flang/Lower/Bridge.h +++ b/flang/include/flang/Lower/Bridge.h @@ -14,6 +14,8 @@ #define FORTRAN_LOWER_BRIDGE_H #include "flang/Common/Fortran.h" +#include "flang/Frontend/CodeGenOptions.h" +#include "flang/Frontend/TargetOptions.h" #include "flang/Lower/AbstractConverter.h" #include "flang/Lower/EnvironmentDefault.h" #include "flang/Lower/LoweringOptions.h" @@ -65,11 +67,13 @@ class LoweringBridge { const Fortran::lower::LoweringOptions &loweringOptions, const std::vector &envDefaults, const Fortran::common::LanguageFeatureControl &languageFeatures, - const llvm::TargetMachine &targetMachine, llvm::StringRef tuneCPU) { + const llvm::TargetMachine &targetMachine, + const Fortran::frontend::TargetOptions &targetOptions, + const Fortran::frontend::CodeGenOptions &codeGenOptions) { return LoweringBridge(ctx, semanticsContext, defaultKinds, intrinsics, targetCharacteristics, allCooked, triple, kindMap, loweringOptions, envDefaults, languageFeatures, - targetMachine, tuneCPU); + targetMachine, targetOptions, codeGenOptions); } //===--------------------------------------------------------------------===// @@ -148,7 +152,9 @@ class LoweringBridge { const Fortran::lower::LoweringOptions &loweringOptions, const std::vector &envDefaults, const Fortran::common::LanguageFeatureControl &languageFeatures, - const llvm::TargetMachine &targetMachine, const llvm::StringRef tuneCPU); + const llvm::TargetMachine &targetMachine, + const Fortran::frontend::TargetOptions &targetOptions, + const Fortran::frontend::CodeGenOptions &codeGenOptions); LoweringBridge() = delete; LoweringBridge(const LoweringBridge &) = delete; diff --git a/flang/include/flang/Optimizer/Dialect/Support/FIRContext.h b/flang/include/flang/Optimizer/Dialect/Support/FIRContext.h index e45011c8e02a33b..2df14f83c11e175 100644 --- a/flang/include/flang/Optimizer/Dialect/Support/FIRContext.h +++ b/flang/include/flang/Optimizer/Dialect/Support/FIRContext.h @@ -77,6 +77,12 @@ void setIdent(mlir::ModuleOp mod, llvm::StringRef ident); /// Get the compiler identifier from the Module. llvm::StringRef getIdent(mlir::ModuleOp mod); +/// Set the command line used in this invocation. +void setCommandline(mlir::ModuleOp mod, llvm::StringRef cmdLine); + +/// Get the command line used in this invocation. +llvm::StringRef getCommandline(mlir::ModuleOp mod); + /// Helper for determining the target from the host, etc. Tools may use this /// function to provide a consistent interpretation of the `--target=` /// command-line option. diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp index 90c327546198b5a..8441c7d8d2e9bc5 100644 --- a/flang/lib/Frontend/CompilerInvocation.cpp +++ b/flang/lib/Frontend/CompilerInvocation.cpp @@ -348,6 +348,12 @@ static void parseCodeGenArgs(Fortran::frontend::CodeGenOptions &opts, if (auto *a = args.getLastArg(clang::driver::options::OPT_save_temps_EQ)) opts.SaveTempsDir = a->getValue(); + // -record-command-line option. + if (const llvm::opt::Arg *a = + args.getLastArg(clang::driver::options::OPT_record_command_line)) { + opts.RecordCommandLine = a->getValue(); + } + // -mlink-builtin-bitcode for (auto *a : args.filtered(clang::driver::options::OPT_mlink_builtin_bitcode)) diff --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp index 267c3ceb44f33e9..62a041c8202fcb5 100644 --- a/flang/lib/Frontend/FrontendActions.cpp +++ b/flang/lib/Frontend/FrontendActions.cpp @@ -302,7 +302,7 @@ bool CodeGenAction::beginSourceFileAction() { kindMap, ci.getInvocation().getLoweringOpts(), ci.getInvocation().getFrontendOpts().envDefaults, ci.getInvocation().getFrontendOpts().features, targetMachine, - ci.getInvocation().getTargetOpts().cpuToTuneFor); + ci.getInvocation().getTargetOpts(), ci.getInvocation().getCodeGenOpts()); // Fetch module from lb, so we can set mlirModule = std::make_unique(lb.getModule()); diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp index ebcb76139696615..68dca2194282809 100644 --- a/flang/lib/Lower/Bridge.cpp +++ b/flang/lib/Lower/Bridge.cpp @@ -6064,7 +6064,9 @@ Fortran::lower::LoweringBridge::LoweringBridge( const Fortran::lower::LoweringOptions &loweringOptions, const std::vector &envDefaults, const Fortran::common::LanguageFeatureControl &languageFeatures, - const llvm::TargetMachine &targetMachine, const llvm::StringRef tuneCPU) + const llvm::TargetMachine &targetMachine, + const Fortran::frontend::TargetOptions &targetOpts, + const Fortran::frontend::CodeGenOptions &cgOpts) : semanticsContext{semanticsContext}, defaultKinds{defaultKinds}, intrinsics{intrinsics}, targetCharacteristics{targetCharacteristics}, cooked{&cooked}, context{context}, kindMap{kindMap}, @@ -6121,11 +6123,13 @@ Fortran::lower::LoweringBridge::LoweringBridge( fir::setTargetTriple(*module.get(), triple); fir::setKindMapping(*module.get(), kindMap); fir::setTargetCPU(*module.get(), targetMachine.getTargetCPU()); - fir::setTuneCPU(*module.get(), tuneCPU); + fir::setTuneCPU(*module.get(), targetOpts.cpuToTuneFor); fir::setTargetFeatures(*module.get(), targetMachine.getTargetFeatureString()); fir::support::setMLIRDataLayout(*module.get(), targetMachine.createDataLayout()); fir::setIdent(*module.get(), Fortran::common::getFlangFullVersion()); + if (cgOpts.RecordCommandLine) + fir::setCommandline(*module.get(), *cgOpts.RecordCommandLine); } void Fortran::lower::genCleanUpInRegionIfAny( diff --git a/flang/lib/Optimizer/Dialect/Support/FIRContext.cpp b/flang/lib/Optimizer/Dialect/Support/FIRContext.cpp index 5bd8e2d43363616..01c0be66d1ecc35 100644 --- a/flang/lib/Optimizer/Dialect/Support/FIRContext.cpp +++ b/flang/lib/Optimizer/Dialect/Support/FIRContext.cpp @@ -130,6 +130,22 @@ llvm::StringRef fir::getIdent(mlir::ModuleOp mod) { return {}; } +void fir::setCommandline(mlir::ModuleOp mod, llvm::StringRef cmdLine) { + if (cmdLine.empty()) + return; + + mlir::MLIRContext *ctx = mod.getContext(); + mod->setAttr(mlir::LLVM::LLVMDialect::getCommandlineAttrName(), + mlir::StringAttr::get(ctx, cmdLine)); +} + +llvm::StringRef fir::getCommandline(mlir::ModuleOp mod) { + if (auto attr = mod->getAttrOfType( + mlir::LLVM::LLVMDialect::getCommandlineAttrName())) + return attr; + return {}; +} + std::string fir::determineTargetTriple(llvm::StringRef triple) { // Treat "" or "default" as stand-ins for the default machine. if (triple.empty() || triple == "default") diff --git a/flang/test/Driver/frecord-command-line.f90 b/flang/test/Driver/frecord-command-line.f90 new file mode 100644 index 000000000000000..bc4ce79e4a51c37 --- /dev/null +++ b/flang/test/Driver/frecord-command-line.f90 @@ -0,0 +1,16 @@ +! This only checks that the command line is correctly passed on to the +! -record-command-line option FC1 option and that the latter does not complain +! about anything. The correct lowering to a module attribute and beyond will +! be checked in other tests. +! +! RUN: %flang -### -target x86_64-unknown-linux -frecord-command-line %s 2>&1 | FileCheck --check-prefix=CHECK-RECORD %s +! RUN: %flang -### -target x86_64-unknown-macosx -frecord-command-line %s 2>&1 | FileCheck --check-prefix=CHECK-RECORD %s +! RUN: not %flang -### -target x86_64-unknown-windows -frecord-command-line %s 2>&1 | FileCheck --check-prefix=CHECK-RECORD-ERROR %s + +! RUN: %flang -### -target x86_64-unknown-linux -fno-record-command-line %s 2>&1 | FileCheck --check-prefix=CHECK-NO-RECORD %s +! RUN: %flang -### -target x86_64-unknown-macosx -fno-record-command-line %s 2>&1 | FileCheck --check-prefix=CHECK-NO-RECORD %s +! RUN: %flang -### -target x86_64-unknown-windows -fno-record-command-line %s 2>&1 | FileCheck --check-prefix=CHECK-NO-RECORD %s + +! CHECK-RECORD: "-record-command-line" +! CHECK-NO-RECORD-NOT: "-record-command-line" +! CHECK-RECORD-ERROR: error: unsupported option '-frecord-command-line' for target diff --git a/flang/test/Lower/record-command-line.f90 b/flang/test/Lower/record-command-line.f90 new file mode 100644 index 000000000000000..a7a25bb9e8725c5 --- /dev/null +++ b/flang/test/Lower/record-command-line.f90 @@ -0,0 +1,9 @@ +! The actual command line is recorded by the frontend and passed on to FC1 as +! the argument to -record-command-line, so in this test, we just match against +! some string with spaces that mimics what a hypothetical command line. + +! RUN: %flang_fc1 -record-command-line "exec -o infile" %s -emit-fir -o - | FileCheck %s + +! CHECK: module attributes { +! CHECK-SAME: llvm.commandline = "exec -o infile" + diff --git a/flang/tools/bbc/CMakeLists.txt b/flang/tools/bbc/CMakeLists.txt index 69316d4dc61de34..7db3b5d40c7c946 100644 --- a/flang/tools/bbc/CMakeLists.txt +++ b/flang/tools/bbc/CMakeLists.txt @@ -35,4 +35,5 @@ FortranParser FortranEvaluate FortranSemantics FortranLower +flangFrontend ) diff --git a/flang/tools/bbc/bbc.cpp b/flang/tools/bbc/bbc.cpp index dcff4503f16571a..b4a177b16d4bac8 100644 --- a/flang/tools/bbc/bbc.cpp +++ b/flang/tools/bbc/bbc.cpp @@ -18,6 +18,7 @@ #include "flang/Common/OpenMP-features.h" #include "flang/Common/Version.h" #include "flang/Common/default-kinds.h" +#include "flang/Frontend/CodeGenOptions.h" #include "flang/Frontend/TargetOptions.h" #include "flang/Lower/Bridge.h" #include "flang/Lower/PFTBuilder.h" @@ -373,12 +374,13 @@ static llvm::LogicalResult convertFortranSourceToMLIR( loweringOptions.setLowerToHighLevelFIR(useHLFIR || emitHLFIR); loweringOptions.setNSWOnLoopVarInc(setNSW); std::vector envDefaults = {}; - constexpr const char *tuneCPU = ""; + Fortran::frontend::TargetOptions targetOpts; + Fortran::frontend::CodeGenOptions cgOpts; auto burnside = Fortran::lower::LoweringBridge::create( ctx, semanticsContext, defKinds, semanticsContext.intrinsics(), semanticsContext.targetCharacteristics(), parsing.allCooked(), targetTriple, kindMap, loweringOptions, envDefaults, - semanticsContext.languageFeatures(), targetMachine, tuneCPU); + semanticsContext.languageFeatures(), targetMachine, targetOpts, cgOpts); mlir::ModuleOp mlirModule = burnside.getModule(); if (enableOpenMP) { if (enableOpenMPGPU && !enableOpenMPDevice) { @@ -557,8 +559,8 @@ int main(int argc, char **argv) { std::string compilerVersion = Fortran::common::getFlangToolFullVersion("bbc"); std::string compilerOptions = ""; Fortran::tools::setUpTargetCharacteristics( - semanticsContext.targetCharacteristics(), *targetMachine, {}, - compilerVersion, compilerOptions); + semanticsContext.targetCharacteristics(), *targetMachine, compilerVersion, + compilerOptions); return mlir::failed( convertFortranSourceToMLIR(inputFilename, options, programPrefix, diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMDialect.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMDialect.td index edcc34461f2f264..27a2b418aadb2a4 100644 --- a/mlir/include/mlir/Dialect/LLVMIR/LLVMDialect.td +++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMDialect.td @@ -33,6 +33,7 @@ def LLVM_Dialect : Dialect { static StringRef getAliasScopesAttrName() { return "alias_scopes"; } static StringRef getAccessGroupsAttrName() { return "access_groups"; } static StringRef getIdentAttrName() { return "llvm.ident"; } + static StringRef getCommandlineAttrName() { return "llvm.commandline"; } /// Names of llvm parameter attributes. static StringRef getAlignAttrName() { return "llvm.align"; } diff --git a/mlir/include/mlir/Target/LLVMIR/ModuleImport.h b/mlir/include/mlir/Target/LLVMIR/ModuleImport.h index 11f62c283d6a96e..d32aed69cd90e80 100644 --- a/mlir/include/mlir/Target/LLVMIR/ModuleImport.h +++ b/mlir/include/mlir/Target/LLVMIR/ModuleImport.h @@ -199,6 +199,10 @@ class ModuleImport { /// Converts !llvm.ident metadata to the llvm.ident LLVM ModuleOp attribute. LogicalResult convertIdentMetadata(); + /// Converts !llvm.commandline metadata to the llvm.commandline LLVM ModuleOp + /// attribute. + LogicalResult convertCommandlineMetadata(); + /// Converts all LLVM metadata nodes that translate to attributes such as /// alias analysis or access group metadata, and builds a map from the /// metadata nodes to the converted attributes. diff --git a/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h b/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h index 3c85338bc642f69..ffeeeae57ae9521 100644 --- a/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h +++ b/mlir/include/mlir/Target/LLVMIR/ModuleTranslation.h @@ -332,6 +332,9 @@ class ModuleTranslation { /// Process the ident LLVM Metadata, if it exists. LogicalResult createIdentMetadata(); + /// Process the llvm.commandline LLVM Metadata, if it exists. + LogicalResult createCommandlineMetadata(); + /// Translates dialect attributes attached to the given operation. LogicalResult convertDialectAttributes(Operation *op, diff --git a/mlir/lib/Target/LLVMIR/ModuleImport.cpp b/mlir/lib/Target/LLVMIR/ModuleImport.cpp index 21f2050cbceb9c0..57dc0bf27d8c27b 100644 --- a/mlir/lib/Target/LLVMIR/ModuleImport.cpp +++ b/mlir/lib/Target/LLVMIR/ModuleImport.cpp @@ -535,6 +535,23 @@ LogicalResult ModuleImport::convertIdentMetadata() { return success(); } +LogicalResult ModuleImport::convertCommandlineMetadata() { + for (const llvm::NamedMDNode &nmd : llvmModule->named_metadata()) { + // llvm.commandline should have a single operand. That operand is itself an + // MDNode with a single string operand. + if (nmd.getName() != LLVMDialect::getCommandlineAttrName()) + continue; + + if (nmd.getNumOperands() == 1) + if (auto *md = dyn_cast(nmd.getOperand(0))) + if (md->getNumOperands() == 1) + if (auto *mdStr = dyn_cast(md->getOperand(0))) + mlirModule->setAttr(LLVMDialect::getCommandlineAttrName(), + builder.getStringAttr(mdStr->getString())); + } + return success(); +} + LogicalResult ModuleImport::convertMetadata() { OpBuilder::InsertionGuard guard(builder); builder.setInsertionPointToEnd(mlirModule.getBody()); @@ -565,6 +582,8 @@ LogicalResult ModuleImport::convertMetadata() { return failure(); if (failed(convertIdentMetadata())) return failure(); + if (failed(convertCommandlineMetadata())) + return failure(); return success(); } diff --git a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp index fcb329eb7a92c10..3c6fbe64dc3184a 100644 --- a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp +++ b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp @@ -1830,6 +1830,21 @@ LogicalResult ModuleTranslation::createIdentMetadata() { return success(); } +LogicalResult ModuleTranslation::createCommandlineMetadata() { + if (auto attr = mlirModule->getAttrOfType( + LLVMDialect::getCommandlineAttrName())) { + StringRef cmdLine = attr; + llvm::LLVMContext &ctx = llvmModule->getContext(); + llvm::NamedMDNode *nmd = llvmModule->getOrInsertNamedMetadata( + LLVMDialect::getCommandlineAttrName()); + llvm::MDNode *md = + llvm::MDNode::get(ctx, llvm::MDString::get(ctx, cmdLine)); + nmd->addOperand(md); + } + + return success(); +} + void ModuleTranslation::setLoopMetadata(Operation *op, llvm::Instruction *inst) { LoopAnnotationAttr attr = @@ -1983,6 +1998,8 @@ mlir::translateModuleToLLVMIR(Operation *module, llvm::LLVMContext &llvmContext, return nullptr; if (failed(translator.createIdentMetadata())) return nullptr; + if (failed(translator.createCommandlineMetadata())) + return nullptr; // Convert other top-level operations if possible. for (Operation &o : getModuleBody(module).getOperations()) { diff --git a/mlir/test/Target/LLVMIR/Import/commandline.ll b/mlir/test/Target/LLVMIR/Import/commandline.ll new file mode 100644 index 000000000000000..f31aec8cc5aac1b --- /dev/null +++ b/mlir/test/Target/LLVMIR/Import/commandline.ll @@ -0,0 +1,6 @@ +; RUN: mlir-translate -import-llvm -split-input-file %s | FileCheck %s + +; CHECK: module attributes { +; CHECK-SAME: llvm.commandline = "exec -o infile" +!llvm.commandline = !{!0} +!0 = !{!"exec -o infile"} diff --git a/mlir/test/Target/LLVMIR/commandline.mlir b/mlir/test/Target/LLVMIR/commandline.mlir new file mode 100644 index 000000000000000..817a5ac2164e9f2 --- /dev/null +++ b/mlir/test/Target/LLVMIR/commandline.mlir @@ -0,0 +1,6 @@ +// RUN: mlir-translate -mlir-to-llvmir %s | FileCheck %s + +// CHECK: !llvm.commandline = !{![[S:[0-9]+]]} +// CHECK: ![[S]] = !{!"exec -o infile"} +module attributes {llvm.commandline = "exec -o infile"} { +} From 93ab47ba0ccff585c59632ffefdc79123068e95e Mon Sep 17 00:00:00 2001 From: Tarun Prabhu Date: Mon, 9 Sep 2024 12:49:39 -0600 Subject: [PATCH 2/6] Rebase with main and fix bad merge from previous rebase. --- flang/tools/bbc/bbc.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/flang/tools/bbc/bbc.cpp b/flang/tools/bbc/bbc.cpp index b4a177b16d4bac8..935fae2fc96a708 100644 --- a/flang/tools/bbc/bbc.cpp +++ b/flang/tools/bbc/bbc.cpp @@ -559,8 +559,8 @@ int main(int argc, char **argv) { std::string compilerVersion = Fortran::common::getFlangToolFullVersion("bbc"); std::string compilerOptions = ""; Fortran::tools::setUpTargetCharacteristics( - semanticsContext.targetCharacteristics(), *targetMachine, compilerVersion, - compilerOptions); + semanticsContext.targetCharacteristics(), *targetMachine, {}, + compilerVersion, compilerOptions); return mlir::failed( convertFortranSourceToMLIR(inputFilename, options, programPrefix, From 0ec620b2da40d92dcd4723072d3c035e4955ffeb Mon Sep 17 00:00:00 2001 From: Tarun Prabhu Date: Mon, 16 Sep 2024 13:27:39 -0600 Subject: [PATCH 3/6] Address reviewer comments. Don't create a CommonUtils file, but move the code to CommonArgs instead. That code has been put in the clang::driver namespace. --- clang/lib/Driver/CMakeLists.txt | 1 - clang/lib/Driver/ToolChains/Clang.cpp | 1 - clang/lib/Driver/ToolChains/CommonArgs.cpp | 59 ++++++++++++++++ clang/lib/Driver/ToolChains/CommonArgs.h | 26 +++++++ clang/lib/Driver/ToolChains/CommonUtils.cpp | 76 --------------------- clang/lib/Driver/ToolChains/CommonUtils.h | 44 ------------ clang/lib/Driver/ToolChains/Flang.cpp | 1 - 7 files changed, 85 insertions(+), 123 deletions(-) delete mode 100644 clang/lib/Driver/ToolChains/CommonUtils.cpp delete mode 100644 clang/lib/Driver/ToolChains/CommonUtils.h diff --git a/clang/lib/Driver/CMakeLists.txt b/clang/lib/Driver/CMakeLists.txt index 0b92077384e9bcc..32a4378ab499faf 100644 --- a/clang/lib/Driver/CMakeLists.txt +++ b/clang/lib/Driver/CMakeLists.txt @@ -48,7 +48,6 @@ add_clang_library(clangDriver ToolChains/BareMetal.cpp ToolChains/Clang.cpp ToolChains/CommonArgs.cpp - ToolChains/CommonUtils.cpp ToolChains/CrossWindows.cpp ToolChains/CSKYToolChain.cpp ToolChains/Cuda.cpp diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 2cf9af81a13eb41..c0cddda02722c16 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -21,7 +21,6 @@ #include "Arch/VE.h" #include "Arch/X86.h" #include "CommonArgs.h" -#include "CommonUtils.h" #include "Hexagon.h" #include "MSP430.h" #include "PS4CPU.h" diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp index 043d9e487644395..ec2fbb6a0e4d52d 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -2960,3 +2960,62 @@ void tools::addMCModel(const Driver &D, const llvm::opt::ArgList &Args, } } } + +void driver::EscapeSpacesAndBackslashes(const char *Arg, + llvm::SmallVectorImpl &Res) { + for (; *Arg; ++Arg) { + switch (*Arg) { + default: + break; + case ' ': + case '\\': + Res.push_back('\\'); + break; + } + Res.push_back(*Arg); + } +} + +const char *driver::RenderEscapedCommandLine(const ToolChain &TC, + const llvm::opt::ArgList &Args) { + const Driver &D = TC.getDriver(); + const char *Exec = D.getClangProgramPath(); + + llvm::opt::ArgStringList OriginalArgs; + for (const auto &Arg : Args) + Arg->render(Args, OriginalArgs); + + llvm::SmallString<256> Flags; + EscapeSpacesAndBackslashes(Exec, Flags); + for (const char *OriginalArg : OriginalArgs) { + llvm::SmallString<128> EscapedArg; + EscapeSpacesAndBackslashes(OriginalArg, EscapedArg); + Flags += " "; + Flags += EscapedArg; + } + + return Args.MakeArgString(Flags); +} + +bool driver::ShouldRecordCommandLine(const ToolChain &TC, + const llvm::opt::ArgList &Args, + bool &FRecordCommandLine, + bool &GRecordCommandLine) { + const Driver &D = TC.getDriver(); + const llvm::Triple &Triple = TC.getEffectiveTriple(); + const std::string &TripleStr = Triple.getTriple(); + + FRecordCommandLine = + Args.hasFlag(options::OPT_frecord_command_line, + options::OPT_fno_record_command_line, false); + GRecordCommandLine = + Args.hasFlag(options::OPT_grecord_command_line, + options::OPT_gno_record_command_line, false); + if (FRecordCommandLine && !Triple.isOSBinFormatELF() && + !Triple.isOSBinFormatXCOFF() && !Triple.isOSBinFormatMachO()) + D.Diag(diag::err_drv_unsupported_opt_for_target) + << Args.getLastArg(options::OPT_frecord_command_line)->getAsString(Args) + << TripleStr; + + return FRecordCommandLine || TC.UseDwarfDebugFlags() || GRecordCommandLine; +} diff --git a/clang/lib/Driver/ToolChains/CommonArgs.h b/clang/lib/Driver/ToolChains/CommonArgs.h index 8695d3fe5b55b83..3afa9338a6a377e 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.h +++ b/clang/lib/Driver/ToolChains/CommonArgs.h @@ -234,6 +234,32 @@ void addMCModel(const Driver &D, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs); } // end namespace tools + +/// Add backslashes to escape spaces and other backslashes. +/// This is used for the space-separated argument list specified with +/// the -dwarf-debug-flags option. +void EscapeSpacesAndBackslashes(const char *Arg, + llvm::SmallVectorImpl &Res); + +/// Join the args in the given ArgList, escape spaces and backslashes and +/// return the joined string. This is used when saving the command line as a +/// result of using either the -frecord-command-line or -grecord-command-line +/// options. The lifetime of the returned c-string will match that of the Args +/// argument. +const char *RenderEscapedCommandLine(const ToolChain &TC, + const llvm::opt::ArgList &Args); + +/// Check if the command line should be recorded in the object file. This is +/// done if either -frecord-command-line or -grecord-command-line options have +/// been passed. This also does some error checking since -frecord-command-line +/// is currently only supported on ELF platforms. The last two boolean +/// arguments are out parameters and will be set depending on the command +/// line options that were passed. +bool ShouldRecordCommandLine(const ToolChain &TC, + const llvm::opt::ArgList &Args, + bool &FRecordCommandLine, + bool &GRecordCommandLine); + } // end namespace driver } // end namespace clang diff --git a/clang/lib/Driver/ToolChains/CommonUtils.cpp b/clang/lib/Driver/ToolChains/CommonUtils.cpp deleted file mode 100644 index 20d76990517a43c..000000000000000 --- a/clang/lib/Driver/ToolChains/CommonUtils.cpp +++ /dev/null @@ -1,76 +0,0 @@ -//===--- CommonUtils.h - Common utilities for the toolchains ----*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "CommonUtils.h" -#include "clang/Driver/Driver.h" -#include "llvm/ADT/SmallString.h" - -using namespace clang::driver; - -namespace clang { - -void EscapeSpacesAndBackslashes(const char *Arg, - llvm::SmallVectorImpl &Res) { - for (; *Arg; ++Arg) { - switch (*Arg) { - default: - break; - case ' ': - case '\\': - Res.push_back('\\'); - break; - } - Res.push_back(*Arg); - } -} - -const char *RenderEscapedCommandLine(const ToolChain &TC, - const llvm::opt::ArgList &Args) { - const Driver &D = TC.getDriver(); - const char *Exec = D.getClangProgramPath(); - - llvm::opt::ArgStringList OriginalArgs; - for (const auto &Arg : Args) - Arg->render(Args, OriginalArgs); - - llvm::SmallString<256> Flags; - EscapeSpacesAndBackslashes(Exec, Flags); - for (const char *OriginalArg : OriginalArgs) { - llvm::SmallString<128> EscapedArg; - EscapeSpacesAndBackslashes(OriginalArg, EscapedArg); - Flags += " "; - Flags += EscapedArg; - } - - return Args.MakeArgString(Flags); -} - -bool ShouldRecordCommandLine(const ToolChain &TC, - const llvm::opt::ArgList &Args, - bool &FRecordCommandLine, - bool &GRecordCommandLine) { - const Driver &D = TC.getDriver(); - const llvm::Triple &Triple = TC.getEffectiveTriple(); - const std::string &TripleStr = Triple.getTriple(); - - FRecordCommandLine = - Args.hasFlag(options::OPT_frecord_command_line, - options::OPT_fno_record_command_line, false); - GRecordCommandLine = - Args.hasFlag(options::OPT_grecord_command_line, - options::OPT_gno_record_command_line, false); - if (FRecordCommandLine && !Triple.isOSBinFormatELF() && - !Triple.isOSBinFormatXCOFF() && !Triple.isOSBinFormatMachO()) - D.Diag(diag::err_drv_unsupported_opt_for_target) - << Args.getLastArg(options::OPT_frecord_command_line)->getAsString(Args) - << TripleStr; - - return FRecordCommandLine || TC.UseDwarfDebugFlags() || GRecordCommandLine; -} - -} // namespace clang diff --git a/clang/lib/Driver/ToolChains/CommonUtils.h b/clang/lib/Driver/ToolChains/CommonUtils.h deleted file mode 100644 index 1ae1c54cf58db4b..000000000000000 --- a/clang/lib/Driver/ToolChains/CommonUtils.h +++ /dev/null @@ -1,44 +0,0 @@ -//===--- CommonUtils.h - Common utilities for the toolchains ----*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_COMMONUTILS_H -#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_COMMONUTILS_H - -#include "clang/Driver/ToolChain.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/Option/ArgList.h" - -namespace clang { - -// Add backslashes to escape spaces and other backslashes. -// This is used for the space-separated argument list specified with -// the -dwarf-debug-flags option. -void EscapeSpacesAndBackslashes(const char *Arg, - llvm::SmallVectorImpl &Res); - -/// Join the args in the given ArgList, escape spaces and backslashes and -/// return the joined string. This is used when saving the command line as a -/// result of using either the -frecord-command-line or -grecord-command-line -/// options. The lifetime of the returned c-string will match that of the Args -/// argument. -const char *RenderEscapedCommandLine(const clang::driver::ToolChain &TC, - const llvm::opt::ArgList &Args); - -/// Check if the command line should be recorded in the object file. This is -/// done if either -frecord-command-line or -grecord-command-line options have -/// been passed. This also does some error checking since -frecord-command-line -/// is currently only supported on ELF platforms. The last two boolean -/// arguments are out parameters and will be set depending on the command -/// line options that were passed. -bool ShouldRecordCommandLine(const clang::driver::ToolChain &TC, - const llvm::opt::ArgList &Args, - bool &FRecordCommandLine, - bool &GRecordCommandLine); -} // namespace clang - -#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_COMMONUTILS_H diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp index 2ef14e306cf324b..d78049944885274 100644 --- a/clang/lib/Driver/ToolChains/Flang.cpp +++ b/clang/lib/Driver/ToolChains/Flang.cpp @@ -9,7 +9,6 @@ #include "Flang.h" #include "Arch/RISCV.h" #include "CommonArgs.h" -#include "CommonUtils.h" #include "clang/Basic/CodeGenOptions.h" #include "clang/Driver/Options.h" From 24f7ed46083efedfd294b7024e86c8f8e16f8acb Mon Sep 17 00:00:00 2001 From: Tarun Prabhu Date: Mon, 16 Sep 2024 18:30:23 -0600 Subject: [PATCH 4/6] Change group of command-line options to f_group since that does not suggest that the options are "clang only" --- clang/include/clang/Driver/Options.td | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 11dd17aa7af9a00..021230ceed4cb4b 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -2001,10 +2001,10 @@ within a command line are combined with spaces; spaces and backslashes within an argument are escaped with backslashes. This format differs from the format of the equivalent section produced by GCC with the -frecord-gcc-switches flag. This option is currently only supported on ELF targets.}]>, - Group, + Group, Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>; def fno_record_command_line : Flag<["-"], "fno-record-command-line">, - Group, + Group, Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>; def : Flag<["-"], "frecord-gcc-switches">, Alias; def : Flag<["-"], "fno-record-gcc-switches">, Alias; From 08344cd3cf0c13217939055c8bdeefc77595fb63 Mon Sep 17 00:00:00 2001 From: Tarun Prabhu Date: Tue, 17 Sep 2024 04:10:29 -0600 Subject: [PATCH 5/6] Move functions to clang::driver::tools namespace --- clang/lib/Driver/ToolChains/CommonArgs.cpp | 16 ++++++++-------- clang/lib/Driver/ToolChains/CommonArgs.h | 3 +-- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp index ec2fbb6a0e4d52d..3a7ffabb8ed272d 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -2961,8 +2961,8 @@ void tools::addMCModel(const Driver &D, const llvm::opt::ArgList &Args, } } -void driver::EscapeSpacesAndBackslashes(const char *Arg, - llvm::SmallVectorImpl &Res) { +void tools::EscapeSpacesAndBackslashes(const char *Arg, + llvm::SmallVectorImpl &Res) { for (; *Arg; ++Arg) { switch (*Arg) { default: @@ -2976,8 +2976,8 @@ void driver::EscapeSpacesAndBackslashes(const char *Arg, } } -const char *driver::RenderEscapedCommandLine(const ToolChain &TC, - const llvm::opt::ArgList &Args) { +const char *tools::RenderEscapedCommandLine(const ToolChain &TC, + const llvm::opt::ArgList &Args) { const Driver &D = TC.getDriver(); const char *Exec = D.getClangProgramPath(); @@ -2997,10 +2997,10 @@ const char *driver::RenderEscapedCommandLine(const ToolChain &TC, return Args.MakeArgString(Flags); } -bool driver::ShouldRecordCommandLine(const ToolChain &TC, - const llvm::opt::ArgList &Args, - bool &FRecordCommandLine, - bool &GRecordCommandLine) { +bool tools::ShouldRecordCommandLine(const ToolChain &TC, + const llvm::opt::ArgList &Args, + bool &FRecordCommandLine, + bool &GRecordCommandLine) { const Driver &D = TC.getDriver(); const llvm::Triple &Triple = TC.getEffectiveTriple(); const std::string &TripleStr = Triple.getTriple(); diff --git a/clang/lib/Driver/ToolChains/CommonArgs.h b/clang/lib/Driver/ToolChains/CommonArgs.h index 3afa9338a6a377e..9caee4763ed02f3 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.h +++ b/clang/lib/Driver/ToolChains/CommonArgs.h @@ -233,8 +233,6 @@ void addMCModel(const Driver &D, const llvm::opt::ArgList &Args, const llvm::Reloc::Model &RelocationModel, llvm::opt::ArgStringList &CmdArgs); -} // end namespace tools - /// Add backslashes to escape spaces and other backslashes. /// This is used for the space-separated argument list specified with /// the -dwarf-debug-flags option. @@ -260,6 +258,7 @@ bool ShouldRecordCommandLine(const ToolChain &TC, bool &FRecordCommandLine, bool &GRecordCommandLine); +} // end namespace tools } // end namespace driver } // end namespace clang From 4e2ceeca0dd84c3e8c50fb7b9a8c94f270d78883 Mon Sep 17 00:00:00 2001 From: Tarun Prabhu Date: Thu, 19 Sep 2024 12:02:19 -0600 Subject: [PATCH 6/6] Rename the functions to use camel case. --- clang/lib/Driver/ToolChains/Clang.cpp | 8 ++++---- clang/lib/Driver/ToolChains/CommonArgs.cpp | 10 +++++----- clang/lib/Driver/ToolChains/CommonArgs.h | 6 +++--- clang/lib/Driver/ToolChains/Flang.cpp | 4 ++-- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index c0cddda02722c16..7e83ec0e70cbcf2 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -7686,8 +7686,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // By default, -gno-record-gcc-switches is set on and no recording. auto GRecordSwitches = false; auto FRecordSwitches = false; - if (ShouldRecordCommandLine(TC, Args, FRecordSwitches, GRecordSwitches)) { - auto FlagsArgString = RenderEscapedCommandLine(TC, Args); + if (shouldRecordCommandLine(TC, Args, FRecordSwitches, GRecordSwitches)) { + auto FlagsArgString = renderEscapedCommandLine(TC, Args); if (TC.UseDwarfDebugFlags() || GRecordSwitches) { CmdArgs.push_back("-dwarf-debug-flags"); CmdArgs.push_back(FlagsArgString); @@ -8687,10 +8687,10 @@ void ClangAs::ConstructJob(Compilation &C, const JobAction &JA, SmallString<256> Flags; const char *Exec = getToolChain().getDriver().getClangProgramPath(); - EscapeSpacesAndBackslashes(Exec, Flags); + escapeSpacesAndBackslashes(Exec, Flags); for (const char *OriginalArg : OriginalArgs) { SmallString<128> EscapedArg; - EscapeSpacesAndBackslashes(OriginalArg, EscapedArg); + escapeSpacesAndBackslashes(OriginalArg, EscapedArg); Flags += " "; Flags += EscapedArg; } diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp index 3a7ffabb8ed272d..102e5231d31608d 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -2961,7 +2961,7 @@ void tools::addMCModel(const Driver &D, const llvm::opt::ArgList &Args, } } -void tools::EscapeSpacesAndBackslashes(const char *Arg, +void tools::escapeSpacesAndBackslashes(const char *Arg, llvm::SmallVectorImpl &Res) { for (; *Arg; ++Arg) { switch (*Arg) { @@ -2976,7 +2976,7 @@ void tools::EscapeSpacesAndBackslashes(const char *Arg, } } -const char *tools::RenderEscapedCommandLine(const ToolChain &TC, +const char *tools::renderEscapedCommandLine(const ToolChain &TC, const llvm::opt::ArgList &Args) { const Driver &D = TC.getDriver(); const char *Exec = D.getClangProgramPath(); @@ -2986,10 +2986,10 @@ const char *tools::RenderEscapedCommandLine(const ToolChain &TC, Arg->render(Args, OriginalArgs); llvm::SmallString<256> Flags; - EscapeSpacesAndBackslashes(Exec, Flags); + escapeSpacesAndBackslashes(Exec, Flags); for (const char *OriginalArg : OriginalArgs) { llvm::SmallString<128> EscapedArg; - EscapeSpacesAndBackslashes(OriginalArg, EscapedArg); + escapeSpacesAndBackslashes(OriginalArg, EscapedArg); Flags += " "; Flags += EscapedArg; } @@ -2997,7 +2997,7 @@ const char *tools::RenderEscapedCommandLine(const ToolChain &TC, return Args.MakeArgString(Flags); } -bool tools::ShouldRecordCommandLine(const ToolChain &TC, +bool tools::shouldRecordCommandLine(const ToolChain &TC, const llvm::opt::ArgList &Args, bool &FRecordCommandLine, bool &GRecordCommandLine) { diff --git a/clang/lib/Driver/ToolChains/CommonArgs.h b/clang/lib/Driver/ToolChains/CommonArgs.h index 9caee4763ed02f3..e9b42bb872ed548 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.h +++ b/clang/lib/Driver/ToolChains/CommonArgs.h @@ -236,7 +236,7 @@ void addMCModel(const Driver &D, const llvm::opt::ArgList &Args, /// Add backslashes to escape spaces and other backslashes. /// This is used for the space-separated argument list specified with /// the -dwarf-debug-flags option. -void EscapeSpacesAndBackslashes(const char *Arg, +void escapeSpacesAndBackslashes(const char *Arg, llvm::SmallVectorImpl &Res); /// Join the args in the given ArgList, escape spaces and backslashes and @@ -244,7 +244,7 @@ void EscapeSpacesAndBackslashes(const char *Arg, /// result of using either the -frecord-command-line or -grecord-command-line /// options. The lifetime of the returned c-string will match that of the Args /// argument. -const char *RenderEscapedCommandLine(const ToolChain &TC, +const char *renderEscapedCommandLine(const ToolChain &TC, const llvm::opt::ArgList &Args); /// Check if the command line should be recorded in the object file. This is @@ -253,7 +253,7 @@ const char *RenderEscapedCommandLine(const ToolChain &TC, /// is currently only supported on ELF platforms. The last two boolean /// arguments are out parameters and will be set depending on the command /// line options that were passed. -bool ShouldRecordCommandLine(const ToolChain &TC, +bool shouldRecordCommandLine(const ToolChain &TC, const llvm::opt::ArgList &Args, bool &FRecordCommandLine, bool &GRecordCommandLine); diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp index d78049944885274..65c29b3dd7f6585 100644 --- a/clang/lib/Driver/ToolChains/Flang.cpp +++ b/clang/lib/Driver/ToolChains/Flang.cpp @@ -887,8 +887,8 @@ void Flang::ConstructJob(Compilation &C, const JobAction &JA, bool FRecordCmdLine = false; bool GRecordCmdLine = false; - if (ShouldRecordCommandLine(TC, Args, FRecordCmdLine, GRecordCmdLine)) { - const char *CmdLine = RenderEscapedCommandLine(TC, Args); + if (shouldRecordCommandLine(TC, Args, FRecordCmdLine, GRecordCmdLine)) { + const char *CmdLine = renderEscapedCommandLine(TC, Args); if (FRecordCmdLine) { CmdArgs.push_back("-record-command-line"); CmdArgs.push_back(CmdLine);