1 //===- AMDGPUOpenMP.cpp - AMDGPUOpenMP ToolChain Implementation -*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "AMDGPUOpenMP.h"
11 #include "CommonArgs.h"
12 #include "ToolChains/ROCm.h"
13 #include "clang/Basic/DiagnosticDriver.h"
14 #include "clang/Driver/Compilation.h"
15 #include "clang/Driver/Driver.h"
16 #include "clang/Driver/DriverDiagnostic.h"
17 #include "clang/Driver/InputInfo.h"
18 #include "clang/Driver/Options.h"
19 #include "clang/Driver/Tool.h"
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"
26 using namespace clang::driver
;
27 using namespace clang::driver::toolchains
;
28 using namespace clang::driver::tools
;
29 using namespace clang
;
30 using namespace llvm::opt
;
32 AMDGPUOpenMPToolChain::AMDGPUOpenMPToolChain(const Driver
&D
,
33 const llvm::Triple
&Triple
,
34 const ToolChain
&HostTC
,
36 : ROCMToolChain(D
, Triple
, Args
), HostTC(HostTC
) {
37 // Lookup binaries into the driver directory, this is used to
38 // discover the 'amdgpu-arch' executable.
39 getProgramPaths().push_back(getDriver().Dir
);
42 void AMDGPUOpenMPToolChain::addClangTargetOptions(
43 const llvm::opt::ArgList
&DriverArgs
, llvm::opt::ArgStringList
&CC1Args
,
44 Action::OffloadKind DeviceOffloadingKind
) const {
45 HostTC
.addClangTargetOptions(DriverArgs
, CC1Args
, DeviceOffloadingKind
);
47 assert(DeviceOffloadingKind
== Action::OFK_OpenMP
&&
48 "Only OpenMP offloading kinds are supported.");
50 if (DriverArgs
.hasArg(options::OPT_nogpulib
))
53 for (auto BCFile
: getDeviceLibs(DriverArgs
)) {
54 CC1Args
.push_back(BCFile
.ShouldInternalize
? "-mlink-builtin-bitcode"
55 : "-mlink-bitcode-file");
56 CC1Args
.push_back(DriverArgs
.MakeArgString(BCFile
.Path
));
59 // Link the bitcode library late if we're using device LTO.
60 if (getDriver().isUsingOffloadLTO())
64 llvm::opt::DerivedArgList
*AMDGPUOpenMPToolChain::TranslateArgs(
65 const llvm::opt::DerivedArgList
&Args
, StringRef BoundArch
,
66 Action::OffloadKind DeviceOffloadKind
) const {
68 HostTC
.TranslateArgs(Args
, BoundArch
, DeviceOffloadKind
);
70 DAL
= new DerivedArgList(Args
.getBaseArgs());
72 const OptTable
&Opts
= getDriver().getOpts();
74 if (DeviceOffloadKind
== Action::OFK_OpenMP
) {
76 if (!llvm::is_contained(*DAL
, A
))
79 if (!DAL
->hasArg(options::OPT_march_EQ
)) {
80 StringRef Arch
= BoundArch
;
82 auto ArchsOrErr
= getSystemGPUArchs(Args
);
85 llvm::formatv("{0}", llvm::fmt_consume(ArchsOrErr
.takeError()));
86 getDriver().Diag(diag::err_drv_undetermined_gpu_arch
)
87 << llvm::Triple::getArchTypeName(getArch()) << ErrMsg
<< "-march";
88 Arch
= OffloadArchToString(OffloadArch::HIPDefault
);
90 Arch
= Args
.MakeArgString(ArchsOrErr
->front());
93 DAL
->AddJoinedArg(nullptr, Opts
.getOption(options::OPT_march_EQ
), Arch
);
103 if (!BoundArch
.empty()) {
104 DAL
->eraseArg(options::OPT_march_EQ
);
105 DAL
->AddJoinedArg(nullptr, Opts
.getOption(options::OPT_march_EQ
),
112 void AMDGPUOpenMPToolChain::addClangWarningOptions(
113 ArgStringList
&CC1Args
) const {
114 AMDGPUToolChain::addClangWarningOptions(CC1Args
);
115 HostTC
.addClangWarningOptions(CC1Args
);
118 ToolChain::CXXStdlibType
119 AMDGPUOpenMPToolChain::GetCXXStdlibType(const ArgList
&Args
) const {
120 return HostTC
.GetCXXStdlibType(Args
);
123 void AMDGPUOpenMPToolChain::AddClangCXXStdlibIncludeArgs(
124 const llvm::opt::ArgList
&Args
, llvm::opt::ArgStringList
&CC1Args
) const {
125 HostTC
.AddClangCXXStdlibIncludeArgs(Args
, CC1Args
);
128 void AMDGPUOpenMPToolChain::AddClangSystemIncludeArgs(
129 const ArgList
&DriverArgs
, ArgStringList
&CC1Args
) const {
130 HostTC
.AddClangSystemIncludeArgs(DriverArgs
, CC1Args
);
133 void AMDGPUOpenMPToolChain::AddIAMCUIncludeArgs(const ArgList
&Args
,
134 ArgStringList
&CC1Args
) const {
135 HostTC
.AddIAMCUIncludeArgs(Args
, CC1Args
);
138 SanitizerMask
AMDGPUOpenMPToolChain::getSupportedSanitizers() const {
139 // The AMDGPUOpenMPToolChain only supports sanitizers in the sense that it
140 // allows sanitizer arguments on the command line if they are supported by the
141 // host toolchain. The AMDGPUOpenMPToolChain will actually ignore any command
142 // line arguments for any of these "supported" sanitizers. That means that no
143 // sanitization of device code is actually supported at this time.
145 // This behavior is necessary because the host and device toolchains
146 // invocations often share the command line, so the device toolchain must
147 // tolerate flags meant only for the host toolchain.
148 return HostTC
.getSupportedSanitizers();
152 AMDGPUOpenMPToolChain::computeMSVCVersion(const Driver
*D
,
153 const ArgList
&Args
) const {
154 return HostTC
.computeMSVCVersion(D
, Args
);
157 llvm::SmallVector
<ToolChain::BitCodeLibraryInfo
, 12>
158 AMDGPUOpenMPToolChain::getDeviceLibs(const llvm::opt::ArgList
&Args
) const {
159 if (Args
.hasArg(options::OPT_nogpulib
))
162 if (!RocmInstallation
->hasDeviceLibrary()) {
163 getDriver().Diag(diag::err_drv_no_rocm_device_lib
) << 0;
167 StringRef GpuArch
= getProcessorFromTargetID(
168 getTriple(), Args
.getLastArgValue(options::OPT_march_EQ
));
170 SmallVector
<BitCodeLibraryInfo
, 12> BCLibs
;
171 for (auto BCLib
: getCommonDeviceLibNames(Args
, GpuArch
.str(),
173 BCLibs
.emplace_back(BCLib
);