xref: /freebsd/contrib/llvm-project/clang/lib/Driver/ToolChains/AMDGPUOpenMP.cpp (revision 700637cbb5e582861067a11aaca4d053546871d2)
1 //===- AMDGPUOpenMP.cpp - AMDGPUOpenMP ToolChain Implementation -*- C++ -*-===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "AMDGPUOpenMP.h"
10 #include "AMDGPU.h"
11 #include "clang/Driver/Compilation.h"
12 #include "clang/Driver/Driver.h"
13 #include "clang/Driver/Options.h"
14 #include "clang/Driver/Tool.h"
15 #include "llvm/ADT/STLExtras.h"
16 
17 using namespace clang::driver;
18 using namespace clang::driver::toolchains;
19 using namespace clang::driver::tools;
20 using namespace clang;
21 using namespace llvm::opt;
22 
AMDGPUOpenMPToolChain(const Driver & D,const llvm::Triple & Triple,const ToolChain & HostTC,const ArgList & Args)23 AMDGPUOpenMPToolChain::AMDGPUOpenMPToolChain(const Driver &D,
24                                              const llvm::Triple &Triple,
25                                              const ToolChain &HostTC,
26                                              const ArgList &Args)
27     : ROCMToolChain(D, Triple, Args), HostTC(HostTC) {
28   // Lookup binaries into the driver directory, this is used to
29   // discover the 'amdgpu-arch' executable.
30   getProgramPaths().push_back(getDriver().Dir);
31   // Diagnose unsupported sanitizer options only once.
32   diagnoseUnsupportedSanitizers(Args);
33 }
34 
addClangTargetOptions(const llvm::opt::ArgList & DriverArgs,llvm::opt::ArgStringList & CC1Args,Action::OffloadKind DeviceOffloadingKind) const35 void AMDGPUOpenMPToolChain::addClangTargetOptions(
36     const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args,
37     Action::OffloadKind DeviceOffloadingKind) const {
38   HostTC.addClangTargetOptions(DriverArgs, CC1Args, DeviceOffloadingKind);
39 
40   assert(DeviceOffloadingKind == Action::OFK_OpenMP &&
41          "Only OpenMP offloading kinds are supported.");
42 
43   if (!DriverArgs.hasFlag(options::OPT_offloadlib, options::OPT_no_offloadlib,
44                           true))
45     return;
46 
47   for (auto BCFile : getDeviceLibs(DriverArgs)) {
48     CC1Args.push_back(BCFile.ShouldInternalize ? "-mlink-builtin-bitcode"
49                                                : "-mlink-bitcode-file");
50     CC1Args.push_back(DriverArgs.MakeArgString(BCFile.Path));
51   }
52 
53   // Link the bitcode library late if we're using device LTO.
54   if (getDriver().isUsingOffloadLTO())
55     return;
56 }
57 
TranslateArgs(const llvm::opt::DerivedArgList & Args,StringRef BoundArch,Action::OffloadKind DeviceOffloadKind) const58 llvm::opt::DerivedArgList *AMDGPUOpenMPToolChain::TranslateArgs(
59     const llvm::opt::DerivedArgList &Args, StringRef BoundArch,
60     Action::OffloadKind DeviceOffloadKind) const {
61   DerivedArgList *DAL =
62       HostTC.TranslateArgs(Args, BoundArch, DeviceOffloadKind);
63 
64   if (!DAL)
65     DAL = new DerivedArgList(Args.getBaseArgs());
66 
67   const OptTable &Opts = getDriver().getOpts();
68 
69   // Skip sanitize options passed from the HostTC. Claim them early.
70   // The decision to sanitize device code is computed only by
71   // 'shouldSkipSanitizeOption'.
72   if (DAL->hasArg(options::OPT_fsanitize_EQ))
73     DAL->claimAllArgs(options::OPT_fsanitize_EQ);
74 
75   for (Arg *A : Args)
76     if (!shouldSkipSanitizeOption(*this, Args, BoundArch, A) &&
77         !llvm::is_contained(*DAL, A))
78       DAL->append(A);
79 
80   if (!BoundArch.empty()) {
81     DAL->eraseArg(options::OPT_march_EQ);
82     DAL->AddJoinedArg(nullptr, Opts.getOption(options::OPT_march_EQ),
83                       BoundArch);
84   }
85 
86   return DAL;
87 }
88 
addClangWarningOptions(ArgStringList & CC1Args) const89 void AMDGPUOpenMPToolChain::addClangWarningOptions(
90     ArgStringList &CC1Args) const {
91   AMDGPUToolChain::addClangWarningOptions(CC1Args);
92   HostTC.addClangWarningOptions(CC1Args);
93 }
94 
95 ToolChain::CXXStdlibType
GetCXXStdlibType(const ArgList & Args) const96 AMDGPUOpenMPToolChain::GetCXXStdlibType(const ArgList &Args) const {
97   return HostTC.GetCXXStdlibType(Args);
98 }
99 
AddClangCXXStdlibIncludeArgs(const llvm::opt::ArgList & Args,llvm::opt::ArgStringList & CC1Args) const100 void AMDGPUOpenMPToolChain::AddClangCXXStdlibIncludeArgs(
101     const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CC1Args) const {
102   HostTC.AddClangCXXStdlibIncludeArgs(Args, CC1Args);
103 }
104 
AddClangSystemIncludeArgs(const ArgList & DriverArgs,ArgStringList & CC1Args) const105 void AMDGPUOpenMPToolChain::AddClangSystemIncludeArgs(
106     const ArgList &DriverArgs, ArgStringList &CC1Args) const {
107   HostTC.AddClangSystemIncludeArgs(DriverArgs, CC1Args);
108 }
109 
AddIAMCUIncludeArgs(const ArgList & Args,ArgStringList & CC1Args) const110 void AMDGPUOpenMPToolChain::AddIAMCUIncludeArgs(const ArgList &Args,
111                                                 ArgStringList &CC1Args) const {
112   HostTC.AddIAMCUIncludeArgs(Args, CC1Args);
113 }
114 
getSupportedSanitizers() const115 SanitizerMask AMDGPUOpenMPToolChain::getSupportedSanitizers() const {
116   // The AMDGPUOpenMPToolChain only supports sanitizers in the sense that it
117   // allows sanitizer arguments on the command line if they are supported by the
118   // host toolchain. The AMDGPUOpenMPToolChain will actually ignore any command
119   // line arguments for any of these "supported" sanitizers. That means that no
120   // sanitization of device code is actually supported at this time.
121   //
122   // This behavior is necessary because the host and device toolchains
123   // invocations often share the command line, so the device toolchain must
124   // tolerate flags meant only for the host toolchain.
125   return HostTC.getSupportedSanitizers();
126 }
127 
128 VersionTuple
computeMSVCVersion(const Driver * D,const ArgList & Args) const129 AMDGPUOpenMPToolChain::computeMSVCVersion(const Driver *D,
130                                           const ArgList &Args) const {
131   return HostTC.computeMSVCVersion(D, Args);
132 }
133 
134 llvm::SmallVector<ToolChain::BitCodeLibraryInfo, 12>
getDeviceLibs(const llvm::opt::ArgList & Args) const135 AMDGPUOpenMPToolChain::getDeviceLibs(const llvm::opt::ArgList &Args) const {
136   if (!Args.hasFlag(options::OPT_offloadlib, options::OPT_no_offloadlib, true))
137     return {};
138 
139   StringRef GpuArch = getProcessorFromTargetID(
140       getTriple(), Args.getLastArgValue(options::OPT_march_EQ));
141 
142   SmallVector<BitCodeLibraryInfo, 12> BCLibs;
143   for (auto BCLib : getCommonDeviceLibNames(Args, GpuArch.str(),
144                                             /*IsOpenMP=*/true))
145     BCLibs.emplace_back(BCLib);
146 
147   return BCLibs;
148 }
149