[OpenMP] Add extra flag handling to linker wrapper

This patch adds support for a few extra flags in the linker wrapper,
such as debugging flags, verbose output, and passing arguments to ptxas. We also
now forward pass remarks to the LLVM backend so they will show up in the LTO
passes.

Depends on D117049

Differential Revision: https://reviews.llvm.org/D117156
This commit is contained in:
Joseph Huber 2022-01-12 16:14:52 -05:00
parent f28c3153ee
commit cb7cfaec71
2 changed files with 83 additions and 11 deletions

View File

@ -8215,6 +8215,37 @@ void LinkerWrapper::ConstructJob(Compilation &C, const JobAction &JA,
Linker->ConstructJob(C, JA, Output, Inputs, Args, LinkingOutput);
const auto &LinkCommand = C.getJobs().getJobs().back();
CmdArgs.push_back("-host-triple");
CmdArgs.push_back(Args.MakeArgString(getToolChain().getTripleString()));
if (Args.hasArg(options::OPT_v))
CmdArgs.push_back("-v");
// Add debug information if present.
if (const Arg *A = Args.getLastArg(options::OPT_g_Group)) {
const Option &Opt = A->getOption();
if (Opt.matches(options::OPT_gN_Group)) {
if (Opt.matches(options::OPT_gline_directives_only) ||
Opt.matches(options::OPT_gline_tables_only))
CmdArgs.push_back("-gline-directives-only");
} else
CmdArgs.push_back("-g");
}
for (const auto &A : Args.getAllArgValues(options::OPT_Xcuda_ptxas))
CmdArgs.push_back(Args.MakeArgString("-ptxas-option=" + A));
// Forward remarks passes to the LLVM backend in the wrapper.
if (const Arg *A = Args.getLastArg(options::OPT_Rpass_EQ))
CmdArgs.push_back(
Args.MakeArgString(Twine("-pass-remarks=") + A->getValue()));
if (const Arg *A = Args.getLastArg(options::OPT_Rpass_missed_EQ))
CmdArgs.push_back(
Args.MakeArgString(Twine("-pass-remarks-missed=") + A->getValue()));
if (const Arg *A = Args.getLastArg(options::OPT_Rpass_analysis_EQ))
CmdArgs.push_back(
Args.MakeArgString(Twine("-pass-remarks-analysis=") + A->getValue()));
// Add the linker arguments to be forwarded by the wrapper.
CmdArgs.push_back("-linker-path");
CmdArgs.push_back(LinkCommand->getExecutable());
CmdArgs.push_back("--");
@ -8224,7 +8255,7 @@ void LinkerWrapper::ConstructJob(Compilation &C, const JobAction &JA,
const char *Exec =
Args.MakeArgString(getToolChain().GetProgramPath("clang-linker-wrapper"));
// Replace the executable and arguments associated with the link job to the
// Replace the executable and arguments of the link job with the
// wrapper.
LinkCommand->replaceExecutable(Exec);
LinkCommand->replaceArguments(CmdArgs);

View File

@ -48,6 +48,12 @@ using namespace llvm::object;
static cl::opt<bool> Help("h", cl::desc("Alias for -help"), cl::Hidden);
enum DebugKind {
NoDebugInfo,
DirectivesOnly,
FullDebugInfo,
};
// Mark all our options with this category, everything else (except for -help)
// will be hidden.
static cl::OptionCategory
@ -58,29 +64,53 @@ static cl::opt<bool> StripSections(
cl::desc("Strip offloading sections from the host object file."),
cl::init(true), cl::cat(ClangLinkerWrapperCategory));
static cl::opt<std::string> LinkerUserPath("linker-path",
static cl::opt<std::string> LinkerUserPath("linker-path", cl::Required,
cl::desc("Path of linker binary"),
cl::cat(ClangLinkerWrapperCategory));
static cl::opt<std::string>
TargetFeatures("target-feature", cl::desc("Target features for triple"),
TargetFeatures("target-feature", cl::ZeroOrMore,
cl::desc("Target features for triple"),
cl::cat(ClangLinkerWrapperCategory));
static cl::opt<std::string> OptLevel("opt-level",
static cl::opt<std::string> OptLevel("opt-level", cl::ZeroOrMore,
cl::desc("Optimization level for LTO"),
cl::init("O2"),
cl::cat(ClangLinkerWrapperCategory));
static cl::opt<std::string>
BitcodeLibrary("target-library",
BitcodeLibrary("target-library", cl::ZeroOrMore,
cl::desc("Path for the target bitcode library"),
cl::cat(ClangLinkerWrapperCategory));
static cl::opt<bool> EmbedBC(
"target-embed-bc", cl::ZeroOrMore,
cl::desc("Embed linked bitcode instead of an executable device image."),
cl::desc("Embed linked bitcode instead of an executable device image"),
cl::init(false), cl::cat(ClangLinkerWrapperCategory));
static cl::opt<std::string>
HostTriple("host-triple", cl::ZeroOrMore,
cl::desc("Triple to use for the host compilation"),
cl::init(sys::getDefaultTargetTriple()),
cl::cat(ClangLinkerWrapperCategory));
static cl::opt<std::string>
PtxasOption("ptxas-option", cl::ZeroOrMore,
cl::desc("Argument to pass to the ptxas invocation"),
cl::cat(ClangLinkerWrapperCategory));
static cl::opt<bool> Verbose("v", cl::ZeroOrMore,
cl::desc("Verbose output from tools"),
cl::init(false),
cl::cat(ClangLinkerWrapperCategory));
static cl::opt<DebugKind> DebugInfo(
cl::desc("Choose debugging level:"), cl::init(NoDebugInfo),
cl::values(clEnumValN(NoDebugInfo, "g0", "No debug information"),
clEnumValN(DirectivesOnly, "gline-directives-only",
"Direction information"),
clEnumValN(FullDebugInfo, "g", "Full debugging support")));
// Do not parse linker options.
static cl::list<std::string>
HostLinkerArgs(cl::Positional,
@ -480,6 +510,14 @@ Expected<std::string> assemble(StringRef InputFile, Triple TheTriple,
std::string Opt = "-" + OptLevel;
CmdArgs.push_back(*PtxasPath);
CmdArgs.push_back(TheTriple.isArch64Bit() ? "-m64" : "-m32");
if (Verbose)
CmdArgs.push_back("-v");
if (DebugInfo == DirectivesOnly && OptLevel[1] == '0')
CmdArgs.push_back("-lineinfo");
else if (DebugInfo == FullDebugInfo && OptLevel[1] == '0')
CmdArgs.push_back("-g");
if (!PtxasOption.empty())
CmdArgs.push_back(PtxasOption);
CmdArgs.push_back("-o");
CmdArgs.push_back(TempFile);
CmdArgs.push_back(Opt);
@ -511,10 +549,13 @@ Expected<std::string> link(ArrayRef<std::string> InputFiles,
return createFileError(TempFile, EC);
TempFiles.push_back(static_cast<std::string>(TempFile));
// TODO: Pass in arguments like `-g` and `-v` from the driver.
SmallVector<StringRef, 16> CmdArgs;
CmdArgs.push_back(*NvlinkPath);
CmdArgs.push_back(TheTriple.isArch64Bit() ? "-m64" : "-m32");
if (Verbose)
CmdArgs.push_back("-v");
if (DebugInfo != NoDebugInfo)
CmdArgs.push_back("-g");
CmdArgs.push_back("-o");
CmdArgs.push_back(TempFile);
CmdArgs.push_back("-arch");
@ -563,16 +604,16 @@ void diagnosticHandler(const DiagnosticInfo &DI) {
switch (DI.getSeverity()) {
case DS_Error:
WithColor::error(errs(), LinkerExecutable) << ErrStorage;
WithColor::error(errs(), LinkerExecutable) << ErrStorage << "\n";
break;
case DS_Warning:
WithColor::warning(errs(), LinkerExecutable) << ErrStorage;
WithColor::warning(errs(), LinkerExecutable) << ErrStorage << "\n";
break;
case DS_Note:
WithColor::note(errs(), LinkerExecutable) << ErrStorage;
WithColor::note(errs(), LinkerExecutable) << ErrStorage << "\n";
break;
case DS_Remark:
WithColor::remark(errs(), LinkerExecutable) << ErrStorage;
WithColor::remark(errs(), LinkerExecutable) << ErrStorage << "\n";
break;
}
}