xref: /freebsd-src/contrib/llvm-project/clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1fe6060f1SDimitry Andric //===- AMDGPUOpenMP.cpp - AMDGPUOpenMP ToolChain Implementation -*- C++ -*-===//
2fe6060f1SDimitry Andric //
3fe6060f1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4fe6060f1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5fe6060f1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6fe6060f1SDimitry Andric //
7fe6060f1SDimitry Andric //===----------------------------------------------------------------------===//
8fe6060f1SDimitry Andric 
9fe6060f1SDimitry Andric #include "AMDGPUOpenMP.h"
10fe6060f1SDimitry Andric #include "AMDGPU.h"
11fe6060f1SDimitry Andric #include "CommonArgs.h"
1269ade1e0SDimitry Andric #include "ToolChains/ROCm.h"
13fe6060f1SDimitry Andric #include "clang/Basic/DiagnosticDriver.h"
14fe6060f1SDimitry Andric #include "clang/Driver/Compilation.h"
15fe6060f1SDimitry Andric #include "clang/Driver/Driver.h"
16fe6060f1SDimitry Andric #include "clang/Driver/DriverDiagnostic.h"
17fe6060f1SDimitry Andric #include "clang/Driver/InputInfo.h"
18fe6060f1SDimitry Andric #include "clang/Driver/Options.h"
1904eeddc0SDimitry Andric #include "clang/Driver/Tool.h"
2069ade1e0SDimitry Andric #include "llvm/ADT/STLExtras.h"
21fe6060f1SDimitry Andric #include "llvm/Support/FileSystem.h"
22fe6060f1SDimitry Andric #include "llvm/Support/FormatAdapters.h"
23fe6060f1SDimitry Andric #include "llvm/Support/FormatVariadic.h"
24fe6060f1SDimitry Andric #include "llvm/Support/Path.h"
25fe6060f1SDimitry Andric 
26fe6060f1SDimitry Andric using namespace clang::driver;
27fe6060f1SDimitry Andric using namespace clang::driver::toolchains;
28fe6060f1SDimitry Andric using namespace clang::driver::tools;
29fe6060f1SDimitry Andric using namespace clang;
30fe6060f1SDimitry Andric using namespace llvm::opt;
31fe6060f1SDimitry Andric 
32fe6060f1SDimitry Andric AMDGPUOpenMPToolChain::AMDGPUOpenMPToolChain(const Driver &D,
33fe6060f1SDimitry Andric                                              const llvm::Triple &Triple,
34fe6060f1SDimitry Andric                                              const ToolChain &HostTC,
35fe6060f1SDimitry Andric                                              const ArgList &Args)
36fe6060f1SDimitry Andric     : ROCMToolChain(D, Triple, Args), HostTC(HostTC) {
37fe6060f1SDimitry Andric   // Lookup binaries into the driver directory, this is used to
3806c3fb27SDimitry Andric   // discover the 'amdgpu-arch' executable.
39fe6060f1SDimitry Andric   getProgramPaths().push_back(getDriver().Dir);
40fe6060f1SDimitry Andric }
41fe6060f1SDimitry Andric 
42fe6060f1SDimitry Andric void AMDGPUOpenMPToolChain::addClangTargetOptions(
43fe6060f1SDimitry Andric     const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args,
44fe6060f1SDimitry Andric     Action::OffloadKind DeviceOffloadingKind) const {
45fe6060f1SDimitry Andric   HostTC.addClangTargetOptions(DriverArgs, CC1Args, DeviceOffloadingKind);
46fe6060f1SDimitry Andric 
47fe6060f1SDimitry Andric   assert(DeviceOffloadingKind == Action::OFK_OpenMP &&
48fe6060f1SDimitry Andric          "Only OpenMP offloading kinds are supported.");
49fe6060f1SDimitry Andric 
50fe6060f1SDimitry Andric   if (DriverArgs.hasArg(options::OPT_nogpulib))
51fe6060f1SDimitry Andric     return;
52fe6060f1SDimitry Andric 
53bdd1243dSDimitry Andric   for (auto BCFile : getDeviceLibs(DriverArgs)) {
54bdd1243dSDimitry Andric     CC1Args.push_back(BCFile.ShouldInternalize ? "-mlink-builtin-bitcode"
55bdd1243dSDimitry Andric                                                : "-mlink-bitcode-file");
56bdd1243dSDimitry Andric     CC1Args.push_back(DriverArgs.MakeArgString(BCFile.Path));
57bdd1243dSDimitry Andric   }
58bdd1243dSDimitry Andric 
591fd87a68SDimitry Andric   // Link the bitcode library late if we're using device LTO.
601fd87a68SDimitry Andric   if (getDriver().isUsingLTO(/* IsOffload */ true))
611fd87a68SDimitry Andric     return;
62fe6060f1SDimitry Andric }
63fe6060f1SDimitry Andric 
64fe6060f1SDimitry Andric llvm::opt::DerivedArgList *AMDGPUOpenMPToolChain::TranslateArgs(
65fe6060f1SDimitry Andric     const llvm::opt::DerivedArgList &Args, StringRef BoundArch,
66fe6060f1SDimitry Andric     Action::OffloadKind DeviceOffloadKind) const {
67fe6060f1SDimitry Andric   DerivedArgList *DAL =
68fe6060f1SDimitry Andric       HostTC.TranslateArgs(Args, BoundArch, DeviceOffloadKind);
69fe6060f1SDimitry Andric   if (!DAL)
70fe6060f1SDimitry Andric     DAL = new DerivedArgList(Args.getBaseArgs());
71fe6060f1SDimitry Andric 
72fe6060f1SDimitry Andric   const OptTable &Opts = getDriver().getOpts();
73fe6060f1SDimitry Andric 
7404eeddc0SDimitry Andric   if (DeviceOffloadKind == Action::OFK_OpenMP) {
7504eeddc0SDimitry Andric     for (Arg *A : Args)
7604eeddc0SDimitry Andric       if (!llvm::is_contained(*DAL, A))
7704eeddc0SDimitry Andric         DAL->append(A);
7804eeddc0SDimitry Andric 
7981ad6265SDimitry Andric     if (!DAL->hasArg(options::OPT_march_EQ)) {
80bdd1243dSDimitry Andric       StringRef Arch = BoundArch;
81bdd1243dSDimitry Andric       if (Arch.empty()) {
82bdd1243dSDimitry Andric         auto ArchsOrErr = getSystemGPUArchs(Args);
83bdd1243dSDimitry Andric         if (!ArchsOrErr) {
84bdd1243dSDimitry Andric           std::string ErrMsg =
85bdd1243dSDimitry Andric               llvm::formatv("{0}", llvm::fmt_consume(ArchsOrErr.takeError()));
86bdd1243dSDimitry Andric           getDriver().Diag(diag::err_drv_undetermined_gpu_arch)
87bdd1243dSDimitry Andric               << llvm::Triple::getArchTypeName(getArch()) << ErrMsg << "-march";
88*0fca6ea1SDimitry Andric           Arch = OffloadArchToString(OffloadArch::HIPDefault);
89bdd1243dSDimitry Andric         } else {
90bdd1243dSDimitry Andric           Arch = Args.MakeArgString(ArchsOrErr->front());
91bdd1243dSDimitry Andric         }
92bdd1243dSDimitry Andric       }
9304eeddc0SDimitry Andric       DAL->AddJoinedArg(nullptr, Opts.getOption(options::OPT_march_EQ), Arch);
9404eeddc0SDimitry Andric     }
9504eeddc0SDimitry Andric 
9604eeddc0SDimitry Andric     return DAL;
9704eeddc0SDimitry Andric   }
9804eeddc0SDimitry Andric 
99fe6060f1SDimitry Andric   for (Arg *A : Args) {
100fe6060f1SDimitry Andric     DAL->append(A);
101fe6060f1SDimitry Andric   }
102fe6060f1SDimitry Andric 
103fe6060f1SDimitry Andric   if (!BoundArch.empty()) {
104fe6060f1SDimitry Andric     DAL->eraseArg(options::OPT_march_EQ);
105fe6060f1SDimitry Andric     DAL->AddJoinedArg(nullptr, Opts.getOption(options::OPT_march_EQ),
106fe6060f1SDimitry Andric                       BoundArch);
107fe6060f1SDimitry Andric   }
108fe6060f1SDimitry Andric 
109fe6060f1SDimitry Andric   return DAL;
110fe6060f1SDimitry Andric }
111fe6060f1SDimitry Andric 
112fe6060f1SDimitry Andric void AMDGPUOpenMPToolChain::addClangWarningOptions(
113fe6060f1SDimitry Andric     ArgStringList &CC1Args) const {
114*0fca6ea1SDimitry Andric   AMDGPUToolChain::addClangWarningOptions(CC1Args);
115fe6060f1SDimitry Andric   HostTC.addClangWarningOptions(CC1Args);
116fe6060f1SDimitry Andric }
117fe6060f1SDimitry Andric 
118fe6060f1SDimitry Andric ToolChain::CXXStdlibType
119fe6060f1SDimitry Andric AMDGPUOpenMPToolChain::GetCXXStdlibType(const ArgList &Args) const {
120fe6060f1SDimitry Andric   return HostTC.GetCXXStdlibType(Args);
121fe6060f1SDimitry Andric }
122fe6060f1SDimitry Andric 
123fe6060f1SDimitry Andric void AMDGPUOpenMPToolChain::AddClangSystemIncludeArgs(
124fe6060f1SDimitry Andric     const ArgList &DriverArgs, ArgStringList &CC1Args) const {
125fe6060f1SDimitry Andric   HostTC.AddClangSystemIncludeArgs(DriverArgs, CC1Args);
126fe6060f1SDimitry Andric }
127fe6060f1SDimitry Andric 
128fe6060f1SDimitry Andric void AMDGPUOpenMPToolChain::AddIAMCUIncludeArgs(const ArgList &Args,
129fe6060f1SDimitry Andric                                                 ArgStringList &CC1Args) const {
130fe6060f1SDimitry Andric   HostTC.AddIAMCUIncludeArgs(Args, CC1Args);
131fe6060f1SDimitry Andric }
132fe6060f1SDimitry Andric 
133fe6060f1SDimitry Andric SanitizerMask AMDGPUOpenMPToolChain::getSupportedSanitizers() const {
134fe6060f1SDimitry Andric   // The AMDGPUOpenMPToolChain only supports sanitizers in the sense that it
135fe6060f1SDimitry Andric   // allows sanitizer arguments on the command line if they are supported by the
136fe6060f1SDimitry Andric   // host toolchain. The AMDGPUOpenMPToolChain will actually ignore any command
137fe6060f1SDimitry Andric   // line arguments for any of these "supported" sanitizers. That means that no
138fe6060f1SDimitry Andric   // sanitization of device code is actually supported at this time.
139fe6060f1SDimitry Andric   //
140fe6060f1SDimitry Andric   // This behavior is necessary because the host and device toolchains
141fe6060f1SDimitry Andric   // invocations often share the command line, so the device toolchain must
142fe6060f1SDimitry Andric   // tolerate flags meant only for the host toolchain.
143fe6060f1SDimitry Andric   return HostTC.getSupportedSanitizers();
144fe6060f1SDimitry Andric }
145fe6060f1SDimitry Andric 
146fe6060f1SDimitry Andric VersionTuple
147fe6060f1SDimitry Andric AMDGPUOpenMPToolChain::computeMSVCVersion(const Driver *D,
148fe6060f1SDimitry Andric                                           const ArgList &Args) const {
149fe6060f1SDimitry Andric   return HostTC.computeMSVCVersion(D, Args);
150fe6060f1SDimitry Andric }
151bdd1243dSDimitry Andric 
152bdd1243dSDimitry Andric llvm::SmallVector<ToolChain::BitCodeLibraryInfo, 12>
153bdd1243dSDimitry Andric AMDGPUOpenMPToolChain::getDeviceLibs(const llvm::opt::ArgList &Args) const {
154bdd1243dSDimitry Andric   if (Args.hasArg(options::OPT_nogpulib))
155bdd1243dSDimitry Andric     return {};
156bdd1243dSDimitry Andric 
15706c3fb27SDimitry Andric   if (!RocmInstallation->hasDeviceLibrary()) {
158bdd1243dSDimitry Andric     getDriver().Diag(diag::err_drv_no_rocm_device_lib) << 0;
159bdd1243dSDimitry Andric     return {};
160bdd1243dSDimitry Andric   }
161bdd1243dSDimitry Andric 
162bdd1243dSDimitry Andric   StringRef GpuArch = getProcessorFromTargetID(
163bdd1243dSDimitry Andric       getTriple(), Args.getLastArgValue(options::OPT_march_EQ));
164bdd1243dSDimitry Andric 
165bdd1243dSDimitry Andric   SmallVector<BitCodeLibraryInfo, 12> BCLibs;
166bdd1243dSDimitry Andric   for (auto BCLib : getCommonDeviceLibNames(Args, GpuArch.str(),
167bdd1243dSDimitry Andric                                             /*IsOpenMP=*/true))
168bdd1243dSDimitry Andric     BCLibs.emplace_back(BCLib);
169bdd1243dSDimitry Andric 
170bdd1243dSDimitry Andric   return BCLibs;
171bdd1243dSDimitry Andric }
172