clang: lib/Driver/ToolChains/HIPSPV.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
17#include "llvm/Support/FileSystem.h"
18#include "llvm/Support/Path.h"
19
23using namespace clang;
25
26
27
29 StringRef Extension) {
30 if (C.getDriver().isSaveTempsEnabled()) {
31 return C.getArgs().MakeArgString(Prefix + "." + Extension);
32 }
33 auto TmpFile = C.getDriver().GetTemporaryPath(Prefix, Extension);
34 return C.addTempFile(C.getArgs().MakeArgString(TmpFile));
35}
36
37
39 const llvm::opt::ArgList &Args) {
40 StringRef Path = Args.getLastArgValue(options::OPT_hipspv_pass_plugin_EQ);
41 if (.empty()) {
42 if (llvm::sys::fs::exists(Path))
43 return Path.str();
44 D.Diag(diag::err_drv_no_such_file) << Path;
45 }
46
47 StringRef hipPath = Args.getLastArgValue(options::OPT_hip_path_EQ);
48 if (!hipPath.empty()) {
50 llvm::sys::path::append(PluginPath, "lib", "libLLVMHipSpvPasses.so");
51 if (llvm::sys::fs::exists(PluginPath))
52 return PluginPath.str().str();
53 PluginPath.assign(hipPath);
54 llvm::sys::path::append(PluginPath, "lib", "llvm",
55 "libLLVMHipSpvPasses.so");
56 if (llvm::sys::fs::exists(PluginPath))
57 return PluginPath.str().str();
58 }
59
60 return std::string();
61}
62
63void HIPSPV::Linker::constructLinkAndEmitSpirvCommand(
65 const InputInfo &Output, const llvm::opt::ArgList &Args) const {
66
67 assert(!Inputs.empty() && "Must have at least one input.");
68 std::string Name = std::string(llvm::sys::path::stem(Output.getFilename()));
69 const char *TempFile = getTempFile(C, Name + "-link", "bc");
70
71
72 ArgStringList LinkArgs{};
73 for (auto Input : Inputs)
74 LinkArgs.push_back(Input.getFilename());
75 LinkArgs.append({"-o", TempFile});
76 const char *LlvmLink =
77 Args.MakeArgString(getToolChain().GetProgramPath("llvm-link"));
79 LlvmLink, LinkArgs, Inputs, Output));
80
81
82
83
84
85 auto PassPluginPath = findPassPlugin(C.getDriver(), Args);
86 if (!PassPluginPath.empty()) {
87 const char *PassPathCStr = C.getArgs().MakeArgString(PassPluginPath);
88 const char *OptOutput = getTempFile(C, Name + "-lower", "bc");
89 ArgStringList OptArgs{TempFile, "-load-pass-plugin",
90 PassPathCStr, "-passes=hip-post-link-passes",
91 "-o", OptOutput};
92 const char *Opt = Args.MakeArgString(getToolChain().GetProgramPath("opt"));
93 C.addCommand(std::make_unique(
95 TempFile = OptOutput;
96 }
97
98
99
100 llvm::opt::ArgStringList TrArgs{"--spirv-max-version=1.1",
101 "--spirv-ext=+all"};
104}
105
109 const ArgList &Args,
110 const char *LinkingOutput) const {
111 if (Inputs.size() > 0 && Inputs[0].getType() == types::TY_Image &&
112 JA.getType() == types::TY_Object)
114 Args, JA, *this);
115
116 if (JA.getType() == types::TY_HIP_FATBIN)
118 Args, *this);
119
120 constructLinkAndEmitSpirvCommand(C, JA, Inputs, Output, Args);
121}
122
124 const ToolChain &HostTC, const ArgList &Args)
125 : ToolChain(D, Triple, Args), HostTC(HostTC) {
126
127
129}
130
132 const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args,
135
137 "Only HIP offloading kinds are supported for GPUs.");
138
139 CC1Args.append(
140 {"-fcuda-is-device", "-fcuda-allow-variadic-functions",
141
142
143
144 "-mllvm", "-vectorize-loops=false", "-mllvm", "-vectorize-slp=false"});
145
146
147
148 if (!DriverArgs.hasArg(options::OPT_fvisibility_EQ,
149 options::OPT_fvisibility_ms_compat))
150 CC1Args.append(
151 {"-fvisibility=hidden", "-fapply-global-visibility-to-externs"});
152
155 CC1Args.append({"-mlink-builtin-bitcode",
156 DriverArgs.MakeArgString(BCFile.Path)});
157 });
158}
159
163}
164
167}
168
172}
173
175 ArgStringList &CC1Args) const {
177}
178
180 const ArgList &Args, ArgStringList &CC1Args) const {
182}
183
185 ArgStringList &CC1Args) const {
187}
188
190 ArgStringList &CC1Args) const {
191 if (DriverArgs.hasArg(options::OPT_nogpuinc))
192 return;
193
194 StringRef hipPath = DriverArgs.getLastArgValue(options::OPT_hip_path_EQ);
195 if (hipPath.empty()) {
196 getDriver().Diag(diag::err_drv_hipspv_no_hip_path);
197 return;
198 }
200 llvm::sys::path::append(P, "include");
201 CC1Args.append({"-isystem", DriverArgs.MakeArgString(P)});
202}
203
207 if (DriverArgs.hasArg(options::OPT_nogpulib))
208 return {};
209
210 ArgStringList LibraryPaths;
211
212 auto HipDeviceLibPathArgs = DriverArgs.getAllArgValues(
213
214 clang::driver::options::OPT_rocm_device_lib_path_EQ);
215 for (auto Path : HipDeviceLibPathArgs)
216 LibraryPaths.push_back(DriverArgs.MakeArgString(Path));
217
218 StringRef HipPath = DriverArgs.getLastArgValue(options::OPT_hip_path_EQ);
219 if (!HipPath.empty()) {
221 llvm::sys::path::append(Path, "lib", "hip-device-lib");
222 LibraryPaths.push_back(DriverArgs.MakeArgString(Path));
223 }
224
225 addDirectoryList(DriverArgs, LibraryPaths, "", "HIP_DEVICE_LIB_PATH");
226
227
228 auto BCLibArgs = DriverArgs.getAllArgValues(options::OPT_hip_device_lib_EQ);
229 if (!BCLibArgs.empty()) {
230 llvm::for_each(BCLibArgs, [&](StringRef BCName) {
232 for (std::string LibraryPath : LibraryPaths) {
234 llvm::sys::path::append(Path, BCName);
236 if (llvm::sys::fs::exists(FullName)) {
237 BCLibs.emplace_back(FullName.str());
238 return;
239 }
240 }
241 getDriver().Diag(diag::err_drv_no_such_file) << BCName;
242 });
243 } else {
244
245 auto TT = getTriple().normalize();
246 std::string BCName = "hipspv-" + TT + ".bc";
247 for (auto *LibPath : LibraryPaths) {
249 llvm::sys::path::append(Path, BCName);
250 if (llvm::sys::fs::exists(Path)) {
251 BCLibs.emplace_back(Path.str().str());
252 return BCLibs;
253 }
254 }
255 getDriver().Diag(diag::err_drv_no_hipspv_device_lib)
256 << 1 << ("'" + TT + "' target");
257 return {};
258 }
259
260 return BCLibs;
261}
262
264
265
266
267
268
269
270
271
272
274}
275
277 const ArgList &Args) const {
279}
280
282 llvm::codegenoptions::DebugInfoKind &DebugInfoKind,
283 const llvm::opt::ArgList &Args) const {
284
285
286
287 DebugInfoKind = llvm::codegenoptions::NoDebugInfo;
288}
static std::string findPassPlugin(const Driver &D, const llvm::opt::ArgList &Args)
static const char * getTempFile(Compilation &C, StringRef Prefix, StringRef Extension)
types::ID getType() const
Compilation - A set of tasks to perform for a single driver invocation.
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
DiagnosticBuilder Diag(unsigned DiagID) const
InputInfo - Wrapper for information about an input source.
const char * getFilename() const
The JSON file list parser is used to communicate input to InstallAPI.
static constexpr ResponseFileSupport None()
Returns a ResponseFileSupport indicating that response files are not supported.