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