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 (Path.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.