20 #include "llvm/ADT/STLExtras.h"
21 #include "llvm/Support/FileSystem.h"
22 #include "llvm/Support/FormatAdapters.h"
23 #include "llvm/Support/FormatVariadic.h"
24 #include "llvm/Support/Path.h"
29 using namespace clang;
36 const char *Extension) {
37 const char *OutputFileName;
38 if (
C.getDriver().isSaveTempsEnabled()) {
40 C.getArgs().MakeArgString(
Base.str() + Postfix +
"." + Extension);
43 C.getDriver().GetTemporaryPath(
Base.str() + Postfix, Extension);
44 OutputFileName =
C.addTempFile(
C.getArgs().MakeArgString(TmpName));
46 return OutputFileName;
49 static void addLLCOptArg(
const llvm::opt::ArgList &Args,
50 llvm::opt::ArgStringList &CmdArgs) {
51 if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
53 if (A->getOption().matches(options::OPT_O4) ||
54 A->getOption().matches(options::OPT_Ofast))
56 else if (A->getOption().matches(options::OPT_O0))
58 else if (A->getOption().matches(options::OPT_O)) {
63 OOpt = llvm::StringSwitch<const char *>(A->getValue())
72 CmdArgs.push_back(Args.MakeArgString(
"-O" + OOpt));
76 static bool checkSystemForAMDGPU(
const ArgList &Args,
const AMDGPUToolChain &TC,
80 llvm::formatv(
"{0}", llvm::fmt_consume(std::move(Err)));
81 TC.
getDriver().
Diag(diag::err_drv_undetermined_amdgpu_arch) << ErrMsg;
89 const char *AMDGCN::OpenMPLinker::constructLLVMLinkCommand(
92 StringRef SubArchName, StringRef OutputFilePrefix)
const {
93 ArgStringList CmdArgs;
95 for (
const auto &II : Inputs)
97 CmdArgs.push_back(II.getFilename());
100 if (Args.hasArg(options::OPT_l)) {
101 auto Lm = Args.getAllArgValues(options::OPT_l);
102 for (
auto &Lib : Lm) {
128 llvm::for_each(BCLibs, [&](StringRef BCFile) {
129 CmdArgs.push_back(Args.MakeArgString(BCFile));
138 CmdArgs.push_back(
"-o");
139 const char *OutputFileName =
140 getOutputFileName(C, OutputFilePrefix,
"-linked",
"bc");
141 CmdArgs.push_back(OutputFileName);
143 Args.MakeArgString(getToolChain().GetProgramPath(
"llvm-link"));
144 C.addCommand(std::make_unique<Command>(
146 InputInfo(&JA, Args.MakeArgString(OutputFileName))));
151 ArgStringList OptCmdArgs;
152 const char *OptOutputFileName =
153 getOutputFileName(C, OutputFilePrefix,
"-linked-opt",
"bc");
154 addLLCOptArg(Args, OptCmdArgs);
155 OptCmdArgs.push_back(OutputFileName);
156 OptCmdArgs.push_back(
"-o");
157 OptCmdArgs.push_back(OptOutputFileName);
158 const char *OptExec =
159 Args.MakeArgString(getToolChain().GetProgramPath(
"opt"));
160 C.addCommand(std::make_unique<Command>(
162 InputInfo(&JA, Args.MakeArgString(OutputFileName)),
163 InputInfo(&JA, Args.MakeArgString(OptOutputFileName))));
164 OutputFileName = OptOutputFileName;
167 return OutputFileName;
170 const char *AMDGCN::OpenMPLinker::constructLlcCommand(
172 const llvm::opt::ArgList &Args, llvm::StringRef SubArchName,
173 llvm::StringRef OutputFilePrefix,
const char *InputFileName,
174 bool OutputIsAsm)
const {
176 ArgStringList LlcArgs;
178 LlcArgs.push_back(InputFileName);
180 addLLCOptArg(Args, LlcArgs);
181 LlcArgs.push_back(
"-mtriple=amdgcn-amd-amdhsa");
182 LlcArgs.push_back(Args.MakeArgString(
"-mcpu=" + SubArchName));
184 Args.MakeArgString(Twine(
"-filetype=") + (OutputIsAsm ?
"asm" :
"obj")));
186 for (
const Arg *A : Args.filtered(options::OPT_mllvm)) {
187 LlcArgs.push_back(A->getValue(0));
191 LlcArgs.push_back(
"-o");
192 const char *LlcOutputFile =
193 getOutputFileName(C, OutputFilePrefix,
"", OutputIsAsm ?
"s" :
"o");
194 LlcArgs.push_back(LlcOutputFile);
195 const char *Llc = Args.MakeArgString(getToolChain().GetProgramPath(
"llc"));
196 C.addCommand(std::make_unique<Command>(
198 InputInfo(&JA, Args.MakeArgString(LlcOutputFile))));
199 return LlcOutputFile;
202 void AMDGCN::OpenMPLinker::constructLldCommand(
204 const InputInfo &Output,
const llvm::opt::ArgList &Args,
205 const char *InputFileName)
const {
208 ArgStringList LldArgs{
"-flavor",
"gnu",
"--no-undefined",
212 const char *Lld = Args.MakeArgString(getToolChain().GetProgramPath(
"lld"));
213 C.addCommand(std::make_unique<Command>(
224 const char *LinkingOutput)
const {
226 assert(getToolChain().getTriple().isAMDGCN() &&
"Unsupported target");
231 std::string GPUArch = Args.getLastArgValue(options::OPT_march_EQ).str();
232 if (GPUArch.empty()) {
233 if (!checkSystemForAMDGPU(Args, AMDGPUOpenMPTC, GPUArch))
239 for (
const auto &II : Inputs)
241 Prefix = llvm::sys::path::stem(II.getFilename()).str() +
"-" + GPUArch;
242 assert(Prefix.length() &&
"no linker inputs are files ");
245 const char *LLVMLinkCommand = constructLLVMLinkCommand(
246 AMDGPUOpenMPTC, C, JA, Inputs, Args, GPUArch, Prefix);
249 if (C.getDriver().isSaveTempsEnabled())
250 constructLlcCommand(C, JA, Inputs, Args, GPUArch, Prefix, LLVMLinkCommand,
252 const char *LlcCommand = constructLlcCommand(C, JA, Inputs, Args, GPUArch,
253 Prefix, LLVMLinkCommand);
254 constructLldCommand(C, JA, Inputs, Output, Args, LlcCommand);
258 const llvm::Triple &Triple,
268 const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args,
272 std::string GPUArch = DriverArgs.getLastArgValue(options::OPT_march_EQ).str();
273 if (GPUArch.empty()) {
274 if (!checkSystemForAMDGPU(DriverArgs, *
this, GPUArch))
279 "Only OpenMP offloading kinds are supported.");
281 CC1Args.push_back(
"-target-cpu");
282 CC1Args.push_back(DriverArgs.MakeArgStringRef(GPUArch));
283 CC1Args.push_back(
"-fcuda-is-device");
285 if (DriverArgs.hasArg(options::OPT_nogpulib))
296 const llvm::opt::DerivedArgList &Args, StringRef BoundArch,
298 DerivedArgList *DAL =
301 DAL =
new DerivedArgList(Args.getBaseArgs());
307 if (!llvm::is_contained(*DAL, A))
310 if (!DAL->hasArg(options::OPT_march_EQ)) {
312 if (BoundArch.empty())
313 checkSystemForAMDGPU(Args, *
this, Arch);
314 DAL->AddJoinedArg(
nullptr, Opts.getOption(options::OPT_march_EQ), Arch);
320 for (Arg *A : Args) {
324 if (!BoundArch.empty()) {
325 DAL->eraseArg(options::OPT_march_EQ);
326 DAL->AddJoinedArg(
nullptr, Opts.getOption(options::OPT_march_EQ),
339 ArgStringList &CC1Args)
const {
349 const ArgList &DriverArgs, ArgStringList &CC1Args)
const {
354 ArgStringList &CC1Args)
const {
373 const ArgList &Args)
const {