clang: lib/Driver/ToolChains/HIPAMD.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

22#include "llvm/Support/Alignment.h"

23#include "llvm/Support/FileSystem.h"

24#include "llvm/Support/Path.h"

25#include "llvm/TargetParser/TargetParser.h"

26

30using namespace clang;

32

33#if defined(_WIN32) || defined(_WIN64)

34#define NULL_FILE "nul"

35#else

36#define NULL_FILE "/dev/null"

37#endif

38

39void AMDGCN::Linker::constructLlvmLinkCommand(Compilation &C,

43 const llvm::opt::ArgList &Args) const {

44

45

46 ArgStringList LlvmLinkArgs;

47

48 assert(!Inputs.empty() && "Must have at least one input.");

49

50 LlvmLinkArgs.append({"-o", Output.getFilename()});

51 for (auto Input : Inputs)

52 LlvmLinkArgs.push_back(Input.getFilename());

53

54

55

56 auto TargetID = Args.getLastArgValue(options::OPT_mcpu_EQ);

58 TargetID, true);

59

60 const char *LlvmLink =

61 Args.MakeArgString(getToolChain().GetProgramPath("llvm-link"));

63 LlvmLink, LlvmLinkArgs, Inputs,

64 Output));

65}

66

70 const llvm::opt::ArgList &Args) const {

71

72

73 ArgStringList LldArgs{"-flavor",

74 "gnu",

75 "-m",

76 "elf64_amdgpu",

77 "--no-undefined",

78 "-shared",

79 "-plugin-opt=-amdgpu-internalize-symbols"};

80 if (Args.hasArg(options::OPT_hipstdpar))

81 LldArgs.push_back("-plugin-opt=-amdgpu-enable-hipstdpar");

82

83 auto &TC = getToolChain();

84 auto &D = TC.getDriver();

85 assert(!Inputs.empty() && "Must have at least one input.");

86 bool IsThinLTO = D.getOffloadLTOMode() == LTOK_Thin;

87 addLTOOptions(TC, Args, LldArgs, Output, Inputs[0], IsThinLTO);

88

89

90 std::vectorllvm::StringRef Features;

92

93

94 std::string MAttrString = "-plugin-opt=-mattr=";

96 MAttrString.append(Args.MakeArgString(OneFeature));

97 if (OneFeature != Features.back())

98 MAttrString.append(",");

99 }

100 if (!Features.empty())

101 LldArgs.push_back(Args.MakeArgString(MAttrString));

102

103

104

105

106 if (IsThinLTO)

107 LldArgs.push_back(Args.MakeArgString("-plugin-opt=-force-import-all"));

108

109 for (const Arg *A : Args.filtered(options::OPT_mllvm)) {

110 LldArgs.push_back(

111 Args.MakeArgString(Twine("-plugin-opt=") + A->getValue(0)));

112 }

113

114 if (C.getDriver().isSaveTempsEnabled())

115 LldArgs.push_back("-save-temps");

116

118

119

120

121

122

123

124

125

126

127

128

129 LldArgs.push_back("--whole-archive");

130

131 for (auto *Arg : Args.filtered(options::OPT_Xoffload_linker)) {

132 StringRef ArgVal = Arg->getValue(1);

133 auto SplitArg = ArgVal.split("-mllvm=");

134 if (!SplitArg.second.empty()) {

135 LldArgs.push_back(

136 Args.MakeArgString(Twine("-plugin-opt=") + SplitArg.second));

137 } else {

138 LldArgs.push_back(Args.MakeArgString(ArgVal));

139 }

140 Arg->claim();

141 }

142

143 LldArgs.append({"-o", Output.getFilename()});

144 for (auto Input : Inputs)

145 LldArgs.push_back(Input.getFilename());

146

147

148

149 auto TargetID = Args.getLastArgValue(options::OPT_mcpu_EQ);

151 TargetID, true);

152

153 LldArgs.push_back("--no-whole-archive");

154

155 const char *Lld = Args.MakeArgString(getToolChain().GetProgramPath("lld"));

157 Lld, LldArgs, Inputs, Output));

158}

159

160

161

162

163

164

165

166void AMDGCN::Linker::constructLinkAndEmitSpirvCommand(

168 const InputInfo &Output, const llvm::opt::ArgList &Args) const {

169 assert(!Inputs.empty() && "Must have at least one input.");

170

171 constructLlvmLinkCommand(C, JA, Inputs, Output, Args);

172

173

174

175

176 llvm::opt::ArgStringList TrArgs{

177 "--spirv-max-version=1.6",

178 "--spirv-ext=+all",

179 "--spirv-allow-unknown-intrinsics",

180 "--spirv-lower-const-expr",

181 "--spirv-preserve-auxdata",

182 "--spirv-debug-info-version=nonsemantic-shader-200"};

184}

185

186

187

188

192 const ArgList &Args,

193 const char *LinkingOutput) const {

194 if (Inputs.size() > 0 &&

195 Inputs[0].getType() == types::TY_Image &&

196 JA.getType() == types::TY_Object)

198 Args, JA, *this);

199

200 if (JA.getType() == types::TY_HIP_FATBIN)

202 Args, *this);

203

204 if (JA.getType() == types::TY_LLVM_BC)

205 return constructLlvmLinkCommand(C, JA, Inputs, Output, Args);

206

207 if (getToolChain().getEffectiveTriple().isSPIRV())

208 return constructLinkAndEmitSpirvCommand(C, JA, Inputs, Output, Args);

209

210 return constructLldCommand(C, JA, Inputs, Output, Args);

211}

212

214 const ToolChain &HostTC, const ArgList &Args)

216

217

219

220

221 if (!Args.hasFlag(options::OPT_fgpu_sanitize, options::OPT_fno_gpu_sanitize,

222 true))

223 return;

224 for (auto *A : Args.filtered(options::OPT_fsanitize_EQ)) {

226 if (K != SanitizerKind::Address)

227 D.getDiags().Report(clang::diag::warn_drv_unsupported_option_for_target)

228 << A->getAsString(Args) << getTriple().str();

229 }

230}

231

233 const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args,

236

238 "Only HIP offloading kinds are supported for GPUs.");

239

240 CC1Args.append({"-fcuda-is-device", "-fno-threadsafe-statics"});

241

242 if (!DriverArgs.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,

243 false))

244 CC1Args.append({"-mllvm", "-amdgpu-internalize-symbols"});

245 if (DriverArgs.hasArgNoClaim(options::OPT_hipstdpar))

246 CC1Args.append({"-mllvm", "-amdgpu-enable-hipstdpar"});

247

248 StringRef MaxThreadsPerBlock =

249 DriverArgs.getLastArgValue(options::OPT_gpu_max_threads_per_block_EQ);

250 if (!MaxThreadsPerBlock.empty()) {

251 std::string ArgStr =

252 (Twine("--gpu-max-threads-per-block=") + MaxThreadsPerBlock).str();

253 CC1Args.push_back(DriverArgs.MakeArgStringRef(ArgStr));

254 }

255

256 CC1Args.push_back("-fcuda-allow-variadic-functions");

257

258

259

260 if (!DriverArgs.hasArg(options::OPT_fvisibility_EQ,

261 options::OPT_fvisibility_ms_compat)) {

262 CC1Args.append({"-fvisibility=hidden"});

263 CC1Args.push_back("-fapply-global-visibility-to-externs");

264 }

265

267

268

269

270 if (!DriverArgs.hasArg(options::OPT_fembed_bitcode_marker))

271 CC1Args.push_back("-fembed-bitcode=marker");

272 return;

273 }

274

276 CC1Args.push_back(BCFile.ShouldInternalize ? "-mlink-builtin-bitcode"

277 : "-mlink-bitcode-file");

278 CC1Args.push_back(DriverArgs.MakeArgString(BCFile.Path));

279 }

280}

281

282llvm::opt::DerivedArgList *

284 StringRef BoundArch,

286 DerivedArgList *DAL =

288 if (!DAL)

289 DAL = new DerivedArgList(Args.getBaseArgs());

290

292

293 for (Arg *A : Args) {

295 DAL->append(A);

296 }

297

298 if (!BoundArch.empty()) {

299 DAL->eraseArg(options::OPT_mcpu_EQ);

300 DAL->AddJoinedArg(nullptr, Opts.getOption(options::OPT_mcpu_EQ), BoundArch);

302 }

303

304 return DAL;

305}

306

311}

312

316}

317

321}

322

324 ArgStringList &CC1Args) const {

326}

327

329 const ArgList &Args, ArgStringList &CC1Args) const {

331}

332

334 ArgStringList &CC1Args) const {

336}

337

339 ArgStringList &CC1Args) const {

341}

342

344

345

346

347

348

349

350

351

352

354}

355

357 const ArgList &Args) const {

359}

360

364 if (DriverArgs.hasArg(options::OPT_nogpulib) ||

365 getGPUArch(DriverArgs) == "amdgcnspirv")

366 return {};

367 ArgStringList LibraryPaths;

368

369

371 LibraryPaths.push_back(DriverArgs.MakeArgString(Path));

372

373 addDirectoryList(DriverArgs, LibraryPaths, "", "HIP_DEVICE_LIB_PATH");

374

375

376 auto BCLibArgs = DriverArgs.getAllArgValues(options::OPT_hip_device_lib_EQ);

377 if (!BCLibArgs.empty()) {

378 llvm::for_each(BCLibArgs, [&](StringRef BCName) {

380 for (StringRef LibraryPath : LibraryPaths) {

382 llvm::sys::path::append(Path, BCName);

384 if (llvm::sys::fs::exists(FullName)) {

386 return;

387 }

388 }

389 getDriver().Diag(diag::err_drv_no_such_file) << BCName;

390 });

391 } else {

393 getDriver().Diag(diag::err_drv_no_rocm_device_lib) << 0;

394 return {};

395 }

396 StringRef GpuArch = getGPUArch(DriverArgs);

397 assert(!GpuArch.empty() && "Must have an explicit GPU arch.");

398

399

400 if (DriverArgs.hasFlag(options::OPT_fgpu_sanitize,

401 options::OPT_fno_gpu_sanitize, true) &&

404 if (AsanRTL.empty()) {

407 "AMDGPU address sanitizer runtime library (asanrtl) is not found. "

408 "Please install ROCm device library which supports address "

409 "sanitizer");

411 return {};

412 } else

413 BCLibs.emplace_back(AsanRTL, false);

414 }

415

416

418

419

421 BCLibs.emplace_back(N);

422

423

424 auto InstLib =

425 DriverArgs.getLastArgValue(options::OPT_gpu_instrument_lib_EQ);

426 if (InstLib.empty())

427 return BCLibs;

428 if (llvm::sys::fs::exists(InstLib))

429 BCLibs.push_back(InstLib);

430 else

431 getDriver().Diag(diag::err_drv_no_such_file) << InstLib;

432 }

433

434 return BCLibs;

435}

436

438 const llvm::opt::ArgList &DriverArgs) const {

440 if (PTID.OptionalTargetID && !PTID.OptionalGPUArch &&

441 PTID.OptionalTargetID != "amdgcnspirv")

442 getDriver().Diag(clang::diag::err_drv_bad_target_id)

443 << *PTID.OptionalTargetID;

444}

unsigned getCustomDiagID(Level L, const char(&FormatString)[N])

Return an ID for a diagnostic with the specified format string and level.

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

DiagnosticsEngine & getDiags() const

DiagnosticBuilder Diag(unsigned DiagID) const

const llvm::opt::OptTable & getOpts() 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.

SanitizerMask parseSanitizerValue(StringRef Value, bool AllowGroups)

Parse a single value from a -fsanitize= or -fno-sanitize= value list.

static constexpr ResponseFileSupport None()

Returns a ResponseFileSupport indicating that response files are not supported.