17#include "llvm/Support/FileSystem.h"
18#include "llvm/Support/Path.h"
29 StringRef Extension) {
30 if (
C.getDriver().isSaveTempsEnabled()) {
31 return C.getArgs().MakeArgString(Prefix +
"." + Extension);
33 auto TmpFile =
C.getDriver().GetTemporaryPath(Prefix, Extension);
34 return C.addTempFile(
C.getArgs().MakeArgString(TmpFile));
39 const llvm::opt::ArgList &Args) {
40 StringRef
Path = Args.getLastArgValue(options::OPT_hipspv_pass_plugin_EQ);
42 if (llvm::sys::fs::exists(
Path))
44 D.Diag(diag::err_drv_no_such_file) <<
Path;
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();
63void HIPSPV::Linker::constructLinkAndEmitSpirvCommand(
65 const InputInfo &Output,
const llvm::opt::ArgList &Args)
const {
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");
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));
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",
92 const char *Opt = Args.MakeArgString(
getToolChain().GetProgramPath(
"opt"));
93 C.addCommand(std::make_unique<Command>(
100 llvm::opt::ArgStringList TrArgs{
"--spirv-max-version=1.1",
110 const char *LinkingOutput)
const {
111 if (Inputs.size() > 0 && Inputs[0].getType() == types::TY_Image &&
112 JA.
getType() == types::TY_Object)
116 if (JA.
getType() == types::TY_HIP_FATBIN)
120 constructLinkAndEmitSpirvCommand(
C, JA, Inputs, Output, Args);
124 const ToolChain &HostTC,
const ArgList &Args)
125 :
ToolChain(
D, Triple, Args), HostTC(HostTC) {
132 const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args,
137 "Only HIP offloading kinds are supported for GPUs.");
140 {
"-fcuda-is-device",
"-fcuda-allow-variadic-functions",
144 "-mllvm",
"-vectorize-loops=false",
"-mllvm",
"-vectorize-slp=false"});
148 if (!DriverArgs.hasArg(options::OPT_fvisibility_EQ,
149 options::OPT_fvisibility_ms_compat))
151 {
"-fvisibility=hidden",
"-fapply-global-visibility-to-externs"});
155 CC1Args.append({
"-mlink-builtin-bitcode",
156 DriverArgs.MakeArgString(BCFile.
Path)});
175 ArgStringList &CC1Args)
const {
180 const ArgList &Args, ArgStringList &CC1Args)
const {
185 ArgStringList &CC1Args)
const {
190 ArgStringList &CC1Args)
const {
191 if (DriverArgs.hasArg(options::OPT_nogpuinc))
194 StringRef hipPath = DriverArgs.getLastArgValue(options::OPT_hip_path_EQ);
195 if (hipPath.empty()) {
200 llvm::sys::path::append(
P,
"include");
201 CC1Args.append({
"-isystem", DriverArgs.MakeArgString(
P)});
207 if (DriverArgs.hasArg(options::OPT_nogpulib))
210 ArgStringList LibraryPaths;
212 auto HipDeviceLibPathArgs = DriverArgs.getAllArgValues(
214 clang::driver::options::OPT_rocm_device_lib_path_EQ);
215 for (
auto Path : HipDeviceLibPathArgs)
216 LibraryPaths.push_back(DriverArgs.MakeArgString(
Path));
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));
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());
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());
256 << 1 << (
"'" + TT +
"' target");
277 const ArgList &Args)
const {
282 llvm::codegenoptions::DebugInfoKind &DebugInfoKind,
283 const llvm::opt::ArgList &Args)
const {
287 DebugInfoKind = llvm::codegenoptions::NoDebugInfo;
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
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.