clang  17.0.0git
AMDGPU.cpp
Go to the documentation of this file.
1 //===--- AMDGPU.cpp - AMDGPU ToolChain Implementations ----------*- 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 "AMDGPU.h"
10 #include "CommonArgs.h"
11 #include "clang/Basic/TargetID.h"
12 #include "clang/Config/config.h"
14 #include "clang/Driver/Distro.h"
16 #include "clang/Driver/InputInfo.h"
17 #include "clang/Driver/Options.h"
18 #include "llvm/Option/ArgList.h"
19 #include "llvm/Support/Error.h"
20 #include "llvm/Support/Host.h"
21 #include "llvm/Support/LineIterator.h"
22 #include "llvm/Support/Path.h"
23 #include "llvm/Support/Process.h"
24 #include "llvm/Support/VirtualFileSystem.h"
25 #include <optional>
26 #include <system_error>
27 
28 using namespace clang::driver;
29 using namespace clang::driver::tools;
30 using namespace clang::driver::toolchains;
31 using namespace clang;
32 using namespace llvm::opt;
33 
34 // Look for sub-directory starts with PackageName under ROCm candidate path.
35 // If there is one and only one matching sub-directory found, append the
36 // sub-directory to Path. If there is no matching sub-directory or there are
37 // more than one matching sub-directories, diagnose them. Returns the full
38 // path of the package if there is only one matching sub-directory, otherwise
39 // returns an empty string.
41 RocmInstallationDetector::findSPACKPackage(const Candidate &Cand,
42  StringRef PackageName) {
43  if (!Cand.isSPACK())
44  return {};
45  std::error_code EC;
46  std::string Prefix = Twine(PackageName + "-" + Cand.SPACKReleaseStr).str();
48  for (llvm::vfs::directory_iterator File = D.getVFS().dir_begin(Cand.Path, EC),
49  FileEnd;
50  File != FileEnd && !EC; File.increment(EC)) {
51  llvm::StringRef FileName = llvm::sys::path::filename(File->path());
52  if (FileName.startswith(Prefix)) {
53  SubDirs.push_back(FileName);
54  if (SubDirs.size() > 1)
55  break;
56  }
57  }
58  if (SubDirs.size() == 1) {
59  auto PackagePath = Cand.Path;
60  llvm::sys::path::append(PackagePath, SubDirs[0]);
61  return PackagePath;
62  }
63  if (SubDirs.size() == 0 && Verbose) {
64  llvm::errs() << "SPACK package " << Prefix << " not found at " << Cand.Path
65  << '\n';
66  return {};
67  }
68 
69  if (SubDirs.size() > 1 && Verbose) {
70  llvm::errs() << "Cannot use SPACK package " << Prefix << " at " << Cand.Path
71  << " due to multiple installations for the same version\n";
72  }
73  return {};
74 }
75 
76 void RocmInstallationDetector::scanLibDevicePath(llvm::StringRef Path) {
77  assert(!Path.empty());
78 
79  const StringRef Suffix(".bc");
80  const StringRef Suffix2(".amdgcn.bc");
81 
82  std::error_code EC;
83  for (llvm::vfs::directory_iterator LI = D.getVFS().dir_begin(Path, EC), LE;
84  !EC && LI != LE; LI = LI.increment(EC)) {
85  StringRef FilePath = LI->path();
86  StringRef FileName = llvm::sys::path::filename(FilePath);
87  if (!FileName.endswith(Suffix))
88  continue;
89 
90  StringRef BaseName;
91  if (FileName.endswith(Suffix2))
92  BaseName = FileName.drop_back(Suffix2.size());
93  else if (FileName.endswith(Suffix))
94  BaseName = FileName.drop_back(Suffix.size());
95 
96  const StringRef ABIVersionPrefix = "oclc_abi_version_";
97  if (BaseName == "ocml") {
98  OCML = FilePath;
99  } else if (BaseName == "ockl") {
100  OCKL = FilePath;
101  } else if (BaseName == "opencl") {
102  OpenCL = FilePath;
103  } else if (BaseName == "hip") {
104  HIP = FilePath;
105  } else if (BaseName == "asanrtl") {
106  AsanRTL = FilePath;
107  } else if (BaseName == "oclc_finite_only_off") {
108  FiniteOnly.Off = FilePath;
109  } else if (BaseName == "oclc_finite_only_on") {
110  FiniteOnly.On = FilePath;
111  } else if (BaseName == "oclc_daz_opt_on") {
112  DenormalsAreZero.On = FilePath;
113  } else if (BaseName == "oclc_daz_opt_off") {
114  DenormalsAreZero.Off = FilePath;
115  } else if (BaseName == "oclc_correctly_rounded_sqrt_on") {
116  CorrectlyRoundedSqrt.On = FilePath;
117  } else if (BaseName == "oclc_correctly_rounded_sqrt_off") {
118  CorrectlyRoundedSqrt.Off = FilePath;
119  } else if (BaseName == "oclc_unsafe_math_on") {
120  UnsafeMath.On = FilePath;
121  } else if (BaseName == "oclc_unsafe_math_off") {
122  UnsafeMath.Off = FilePath;
123  } else if (BaseName == "oclc_wavefrontsize64_on") {
124  WavefrontSize64.On = FilePath;
125  } else if (BaseName == "oclc_wavefrontsize64_off") {
126  WavefrontSize64.Off = FilePath;
127  } else if (BaseName.startswith(ABIVersionPrefix)) {
128  unsigned ABIVersionNumber;
129  if (BaseName.drop_front(ABIVersionPrefix.size())
130  .getAsInteger(/*Redex=*/0, ABIVersionNumber))
131  continue;
132  ABIVersionMap[ABIVersionNumber] = FilePath.str();
133  } else {
134  // Process all bitcode filenames that look like
135  // ocl_isa_version_XXX.amdgcn.bc
136  const StringRef DeviceLibPrefix = "oclc_isa_version_";
137  if (!BaseName.startswith(DeviceLibPrefix))
138  continue;
139 
140  StringRef IsaVersionNumber =
141  BaseName.drop_front(DeviceLibPrefix.size());
142 
143  llvm::Twine GfxName = Twine("gfx") + IsaVersionNumber;
144  SmallString<8> Tmp;
145  LibDeviceMap.insert(
146  std::make_pair(GfxName.toStringRef(Tmp), FilePath.str()));
147  }
148  }
149 }
150 
151 // Parse and extract version numbers from `.hipVersion`. Return `true` if
152 // the parsing fails.
153 bool RocmInstallationDetector::parseHIPVersionFile(llvm::StringRef V) {
154  SmallVector<StringRef, 4> VersionParts;
155  V.split(VersionParts, '\n');
156  unsigned Major = ~0U;
157  unsigned Minor = ~0U;
158  for (auto Part : VersionParts) {
159  auto Splits = Part.rtrim().split('=');
160  if (Splits.first == "HIP_VERSION_MAJOR") {
161  if (Splits.second.getAsInteger(0, Major))
162  return true;
163  } else if (Splits.first == "HIP_VERSION_MINOR") {
164  if (Splits.second.getAsInteger(0, Minor))
165  return true;
166  } else if (Splits.first == "HIP_VERSION_PATCH")
167  VersionPatch = Splits.second.str();
168  }
169  if (Major == ~0U || Minor == ~0U)
170  return true;
171  VersionMajorMinor = llvm::VersionTuple(Major, Minor);
172  DetectedVersion =
173  (Twine(Major) + "." + Twine(Minor) + "." + VersionPatch).str();
174  return false;
175 }
176 
177 /// \returns a list of candidate directories for ROCm installation, which is
178 /// cached and populated only once.
180 RocmInstallationDetector::getInstallationPathCandidates() {
181 
182  // Return the cached candidate list if it has already been populated.
183  if (!ROCmSearchDirs.empty())
184  return ROCmSearchDirs;
185 
186  auto DoPrintROCmSearchDirs = [&]() {
187  if (PrintROCmSearchDirs)
188  for (auto Cand : ROCmSearchDirs) {
189  llvm::errs() << "ROCm installation search path";
190  if (Cand.isSPACK())
191  llvm::errs() << " (Spack " << Cand.SPACKReleaseStr << ")";
192  llvm::errs() << ": " << Cand.Path << '\n';
193  }
194  };
195 
196  // For candidate specified by --rocm-path we do not do strict check, i.e.,
197  // checking existence of HIP version file and device library files.
198  if (!RocmPathArg.empty()) {
199  ROCmSearchDirs.emplace_back(RocmPathArg.str());
200  DoPrintROCmSearchDirs();
201  return ROCmSearchDirs;
202  } else if (std::optional<std::string> RocmPathEnv =
203  llvm::sys::Process::GetEnv("ROCM_PATH")) {
204  if (!RocmPathEnv->empty()) {
205  ROCmSearchDirs.emplace_back(std::move(*RocmPathEnv));
206  DoPrintROCmSearchDirs();
207  return ROCmSearchDirs;
208  }
209  }
210 
211  // Try to find relative to the compiler binary.
212  const char *InstallDir = D.getInstalledDir();
213 
214  // Check both a normal Unix prefix position of the clang binary, as well as
215  // the Windows-esque layout the ROCm packages use with the host architecture
216  // subdirectory of bin.
217  auto DeduceROCmPath = [](StringRef ClangPath) {
218  // Strip off directory (usually bin)
219  StringRef ParentDir = llvm::sys::path::parent_path(ClangPath);
220  StringRef ParentName = llvm::sys::path::filename(ParentDir);
221 
222  // Some builds use bin/{host arch}, so go up again.
223  if (ParentName == "bin") {
224  ParentDir = llvm::sys::path::parent_path(ParentDir);
225  ParentName = llvm::sys::path::filename(ParentDir);
226  }
227 
228  // Detect ROCm packages built with SPACK.
229  // clang is installed at
230  // <rocm_root>/llvm-amdgpu-<rocm_release_string>-<hash>/bin directory.
231  // We only consider the parent directory of llvm-amdgpu package as ROCm
232  // installation candidate for SPACK.
233  if (ParentName.startswith("llvm-amdgpu-")) {
234  auto SPACKPostfix =
235  ParentName.drop_front(strlen("llvm-amdgpu-")).split('-');
236  auto SPACKReleaseStr = SPACKPostfix.first;
237  if (!SPACKReleaseStr.empty()) {
238  ParentDir = llvm::sys::path::parent_path(ParentDir);
239  return Candidate(ParentDir.str(), /*StrictChecking=*/true,
240  SPACKReleaseStr);
241  }
242  }
243 
244  // Some versions of the rocm llvm package install to /opt/rocm/llvm/bin
245  // Some versions of the aomp package install to /opt/rocm/aomp/bin
246  if (ParentName == "llvm" || ParentName.startswith("aomp"))
247  ParentDir = llvm::sys::path::parent_path(ParentDir);
248 
249  return Candidate(ParentDir.str(), /*StrictChecking=*/true);
250  };
251 
252  // Deduce ROCm path by the path used to invoke clang. Do not resolve symbolic
253  // link of clang itself.
254  ROCmSearchDirs.emplace_back(DeduceROCmPath(InstallDir));
255 
256  // Deduce ROCm path by the real path of the invoked clang, resolving symbolic
257  // link of clang itself.
258  llvm::SmallString<256> RealClangPath;
259  llvm::sys::fs::real_path(D.getClangProgramPath(), RealClangPath);
260  auto ParentPath = llvm::sys::path::parent_path(RealClangPath);
261  if (ParentPath != InstallDir)
262  ROCmSearchDirs.emplace_back(DeduceROCmPath(ParentPath));
263 
264  // Device library may be installed in clang or resource directory.
265  auto ClangRoot = llvm::sys::path::parent_path(InstallDir);
266  auto RealClangRoot = llvm::sys::path::parent_path(ParentPath);
267  ROCmSearchDirs.emplace_back(ClangRoot.str(), /*StrictChecking=*/true);
268  if (RealClangRoot != ClangRoot)
269  ROCmSearchDirs.emplace_back(RealClangRoot.str(), /*StrictChecking=*/true);
270  ROCmSearchDirs.emplace_back(D.ResourceDir,
271  /*StrictChecking=*/true);
272 
273  ROCmSearchDirs.emplace_back(D.SysRoot + "/opt/rocm",
274  /*StrictChecking=*/true);
275 
276  // Find the latest /opt/rocm-{release} directory.
277  std::error_code EC;
278  std::string LatestROCm;
279  llvm::VersionTuple LatestVer;
280  // Get ROCm version from ROCm directory name.
281  auto GetROCmVersion = [](StringRef DirName) {
282  llvm::VersionTuple V;
283  std::string VerStr = DirName.drop_front(strlen("rocm-")).str();
284  // The ROCm directory name follows the format of
285  // rocm-{major}.{minor}.{subMinor}[-{build}]
286  std::replace(VerStr.begin(), VerStr.end(), '-', '.');
287  V.tryParse(VerStr);
288  return V;
289  };
290  for (llvm::vfs::directory_iterator
291  File = D.getVFS().dir_begin(D.SysRoot + "/opt", EC),
292  FileEnd;
293  File != FileEnd && !EC; File.increment(EC)) {
294  llvm::StringRef FileName = llvm::sys::path::filename(File->path());
295  if (!FileName.startswith("rocm-"))
296  continue;
297  if (LatestROCm.empty()) {
298  LatestROCm = FileName.str();
299  LatestVer = GetROCmVersion(LatestROCm);
300  continue;
301  }
302  auto Ver = GetROCmVersion(FileName);
303  if (LatestVer < Ver) {
304  LatestROCm = FileName.str();
305  LatestVer = Ver;
306  }
307  }
308  if (!LatestROCm.empty())
309  ROCmSearchDirs.emplace_back(D.SysRoot + "/opt/" + LatestROCm,
310  /*StrictChecking=*/true);
311 
312  Distro Dist(D.getVFS(), llvm::Triple(llvm::sys::getProcessTriple()));
313  if (Dist.IsDebian() || Dist.IsRedhat()) {
314  ROCmSearchDirs.emplace_back(D.SysRoot + "/usr/local",
315  /*StrictChecking=*/true);
316  ROCmSearchDirs.emplace_back(D.SysRoot + "/usr",
317  /*StrictChecking=*/true);
318  }
319 
320  DoPrintROCmSearchDirs();
321  return ROCmSearchDirs;
322 }
323 
325  const Driver &D, const llvm::Triple &HostTriple,
326  const llvm::opt::ArgList &Args, bool DetectHIPRuntime, bool DetectDeviceLib)
327  : D(D) {
328  Verbose = Args.hasArg(options::OPT_v);
329  RocmPathArg = Args.getLastArgValue(clang::driver::options::OPT_rocm_path_EQ);
330  PrintROCmSearchDirs =
331  Args.hasArg(clang::driver::options::OPT_print_rocm_search_dirs);
332  RocmDeviceLibPathArg =
333  Args.getAllArgValues(clang::driver::options::OPT_rocm_device_lib_path_EQ);
334  HIPPathArg = Args.getLastArgValue(clang::driver::options::OPT_hip_path_EQ);
335  if (auto *A = Args.getLastArg(clang::driver::options::OPT_hip_version_EQ)) {
336  HIPVersionArg = A->getValue();
337  unsigned Major = ~0U;
338  unsigned Minor = ~0U;
340  HIPVersionArg.split(Parts, '.');
341  if (Parts.size())
342  Parts[0].getAsInteger(0, Major);
343  if (Parts.size() > 1)
344  Parts[1].getAsInteger(0, Minor);
345  if (Parts.size() > 2)
346  VersionPatch = Parts[2].str();
347  if (VersionPatch.empty())
348  VersionPatch = "0";
349  if (Major != ~0U && Minor == ~0U)
350  Minor = 0;
351  if (Major == ~0U || Minor == ~0U)
352  D.Diag(diag::err_drv_invalid_value)
353  << A->getAsString(Args) << HIPVersionArg;
354 
355  VersionMajorMinor = llvm::VersionTuple(Major, Minor);
356  DetectedVersion =
357  (Twine(Major) + "." + Twine(Minor) + "." + VersionPatch).str();
358  } else {
359  VersionPatch = DefaultVersionPatch;
360  VersionMajorMinor =
361  llvm::VersionTuple(DefaultVersionMajor, DefaultVersionMinor);
362  DetectedVersion = (Twine(DefaultVersionMajor) + "." +
363  Twine(DefaultVersionMinor) + "." + VersionPatch)
364  .str();
365  }
366 
367  if (DetectHIPRuntime)
369  if (DetectDeviceLib)
371 }
372 
374  assert(LibDevicePath.empty());
375 
376  if (!RocmDeviceLibPathArg.empty())
377  LibDevicePath = RocmDeviceLibPathArg[RocmDeviceLibPathArg.size() - 1];
378  else if (std::optional<std::string> LibPathEnv =
379  llvm::sys::Process::GetEnv("HIP_DEVICE_LIB_PATH"))
380  LibDevicePath = std::move(*LibPathEnv);
381 
382  auto &FS = D.getVFS();
383  if (!LibDevicePath.empty()) {
384  // Maintain compatability with HIP flag/envvar pointing directly at the
385  // bitcode library directory. This points directly at the library path instead
386  // of the rocm root installation.
387  if (!FS.exists(LibDevicePath))
388  return;
389 
390  scanLibDevicePath(LibDevicePath);
391  HasDeviceLibrary = allGenericLibsValid() && !LibDeviceMap.empty();
392  return;
393  }
394 
395  // Check device library exists at the given path.
396  auto CheckDeviceLib = [&](StringRef Path, bool StrictChecking) {
397  bool CheckLibDevice = (!NoBuiltinLibs || StrictChecking);
398  if (CheckLibDevice && !FS.exists(Path))
399  return false;
400 
401  scanLibDevicePath(Path);
402 
403  if (!NoBuiltinLibs) {
404  // Check that the required non-target libraries are all available.
405  if (!allGenericLibsValid())
406  return false;
407 
408  // Check that we have found at least one libdevice that we can link in
409  // if -nobuiltinlib hasn't been specified.
410  if (LibDeviceMap.empty())
411  return false;
412  }
413  return true;
414  };
415 
416  // Find device libraries in <LLVM_DIR>/lib/clang/<ver>/lib/amdgcn/bitcode
417  LibDevicePath = D.ResourceDir;
418  llvm::sys::path::append(LibDevicePath, CLANG_INSTALL_LIBDIR_BASENAME,
419  "amdgcn", "bitcode");
420  HasDeviceLibrary = CheckDeviceLib(LibDevicePath, true);
421  if (HasDeviceLibrary)
422  return;
423 
424  // Find device libraries in a legacy ROCm directory structure
425  // ${ROCM_ROOT}/amdgcn/bitcode/*
426  auto &ROCmDirs = getInstallationPathCandidates();
427  for (const auto &Candidate : ROCmDirs) {
428  LibDevicePath = Candidate.Path;
429  llvm::sys::path::append(LibDevicePath, "amdgcn", "bitcode");
430  HasDeviceLibrary = CheckDeviceLib(LibDevicePath, Candidate.StrictChecking);
431  if (HasDeviceLibrary)
432  return;
433  }
434 }
435 
437  SmallVector<Candidate, 4> HIPSearchDirs;
438  if (!HIPPathArg.empty())
439  HIPSearchDirs.emplace_back(HIPPathArg.str(), /*StrictChecking=*/true);
440  else
441  HIPSearchDirs.append(getInstallationPathCandidates());
442  auto &FS = D.getVFS();
443 
444  for (const auto &Candidate : HIPSearchDirs) {
445  InstallPath = Candidate.Path;
446  if (InstallPath.empty() || !FS.exists(InstallPath))
447  continue;
448  // HIP runtime built by SPACK is installed to
449  // <rocm_root>/hip-<rocm_release_string>-<hash> directory.
450  auto SPACKPath = findSPACKPackage(Candidate, "hip");
451  InstallPath = SPACKPath.empty() ? InstallPath : SPACKPath;
452 
453  BinPath = InstallPath;
454  llvm::sys::path::append(BinPath, "bin");
455  IncludePath = InstallPath;
456  llvm::sys::path::append(IncludePath, "include");
457  LibPath = InstallPath;
458  llvm::sys::path::append(LibPath, "lib");
459  SharePath = InstallPath;
460  llvm::sys::path::append(SharePath, "share");
461 
462  // If HIP version file can be found and parsed, use HIP version from there.
463  for (const auto &VersionFilePath :
464  {std::string(SharePath) + "/hip/version",
465  std::string(BinPath) + "/.hipVersion"}) {
466  llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> VersionFile =
467  FS.getBufferForFile(VersionFilePath);
468  if (!VersionFile)
469  continue;
470  if (HIPVersionArg.empty() && VersionFile)
471  if (parseHIPVersionFile((*VersionFile)->getBuffer()))
472  continue;
473 
474  HasHIPRuntime = true;
475  return;
476  }
477  // Otherwise, if -rocm-path is specified (no strict checking), use the
478  // default HIP version or specified by --hip-version.
479  if (!Candidate.StrictChecking) {
480  HasHIPRuntime = true;
481  return;
482  }
483  }
484  HasHIPRuntime = false;
485 }
486 
487 void RocmInstallationDetector::print(raw_ostream &OS) const {
488  if (hasHIPRuntime())
489  OS << "Found HIP installation: " << InstallPath << ", version "
490  << DetectedVersion << '\n';
491 }
492 
493 void RocmInstallationDetector::AddHIPIncludeArgs(const ArgList &DriverArgs,
494  ArgStringList &CC1Args) const {
495  bool UsesRuntimeWrapper = VersionMajorMinor > llvm::VersionTuple(3, 5) &&
496  !DriverArgs.hasArg(options::OPT_nohipwrapperinc);
497 
498  if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
499  // HIP header includes standard library wrapper headers under clang
500  // cuda_wrappers directory. Since these wrapper headers include_next
501  // standard C++ headers, whereas libc++ headers include_next other clang
502  // headers. The include paths have to follow this order:
503  // - wrapper include path
504  // - standard C++ include path
505  // - other clang include path
506  // Since standard C++ and other clang include paths are added in other
507  // places after this function, here we only need to make sure wrapper
508  // include path is added.
509  //
510  // ROCm 3.5 does not fully support the wrapper headers. Therefore it needs
511  // a workaround.
513  if (UsesRuntimeWrapper)
514  llvm::sys::path::append(P, "include", "cuda_wrappers");
515  CC1Args.push_back("-internal-isystem");
516  CC1Args.push_back(DriverArgs.MakeArgString(P));
517  }
518 
519  if (DriverArgs.hasArg(options::OPT_nogpuinc))
520  return;
521 
522  if (!hasHIPRuntime()) {
523  D.Diag(diag::err_drv_no_hip_runtime);
524  return;
525  }
526 
527  CC1Args.push_back("-idirafter");
528  CC1Args.push_back(DriverArgs.MakeArgString(getIncludePath()));
529  if (UsesRuntimeWrapper)
530  CC1Args.append({"-include", "__clang_hip_runtime_wrapper.h"});
531 }
532 
533 void amdgpu::Linker::ConstructJob(Compilation &C, const JobAction &JA,
534  const InputInfo &Output,
535  const InputInfoList &Inputs,
536  const ArgList &Args,
537  const char *LinkingOutput) const {
538 
539  std::string Linker = getToolChain().GetProgramPath(getShortName());
540  ArgStringList CmdArgs;
541  addLinkerCompressDebugSectionsOption(getToolChain(), Args, CmdArgs);
542  AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);
543  CmdArgs.push_back("-shared");
544  CmdArgs.push_back("-o");
545  CmdArgs.push_back(Output.getFilename());
546  C.addCommand(std::make_unique<Command>(
547  JA, *this, ResponseFileSupport::AtFileCurCP(), Args.MakeArgString(Linker),
548  CmdArgs, Inputs, Output));
549 }
550 
552  const llvm::Triple &Triple,
553  const llvm::opt::ArgList &Args,
554  std::vector<StringRef> &Features) {
555  // Add target ID features to -target-feature options. No diagnostics should
556  // be emitted here since invalid target ID is diagnosed at other places.
557  StringRef TargetID = Args.getLastArgValue(options::OPT_mcpu_EQ);
558  if (!TargetID.empty()) {
559  llvm::StringMap<bool> FeatureMap;
560  auto OptionalGpuArch = parseTargetID(Triple, TargetID, &FeatureMap);
561  if (OptionalGpuArch) {
562  StringRef GpuArch = *OptionalGpuArch;
563  // Iterate through all possible target ID features for the given GPU.
564  // If it is mapped to true, add +feature.
565  // If it is mapped to false, add -feature.
566  // If it is not in the map (default), do not add it
567  for (auto &&Feature : getAllPossibleTargetIDFeatures(Triple, GpuArch)) {
568  auto Pos = FeatureMap.find(Feature);
569  if (Pos == FeatureMap.end())
570  continue;
571  Features.push_back(Args.MakeArgStringRef(
572  (Twine(Pos->second ? "+" : "-") + Feature).str()));
573  }
574  }
575  }
576 
577  if (Args.hasFlag(options::OPT_mwavefrontsize64,
578  options::OPT_mno_wavefrontsize64, false))
579  Features.push_back("+wavefrontsize64");
580 
582  Args, Features, options::OPT_m_amdgpu_Features_Group);
583 }
584 
585 /// AMDGPU Toolchain
586 AMDGPUToolChain::AMDGPUToolChain(const Driver &D, const llvm::Triple &Triple,
587  const ArgList &Args)
588  : Generic_ELF(D, Triple, Args),
589  OptionsDefault(
590  {{options::OPT_O, "3"}, {options::OPT_cl_std_EQ, "CL1.2"}}) {
591  // Check code object version options. Emit warnings for legacy options
592  // and errors for the last invalid code object version options.
593  // It is done here to avoid repeated warning or error messages for
594  // each tool invocation.
596 }
597 
599  return new tools::amdgpu::Linker(*this);
600 }
601 
602 DerivedArgList *
603 AMDGPUToolChain::TranslateArgs(const DerivedArgList &Args, StringRef BoundArch,
604  Action::OffloadKind DeviceOffloadKind) const {
605 
606  DerivedArgList *DAL =
607  Generic_ELF::TranslateArgs(Args, BoundArch, DeviceOffloadKind);
608 
609  const OptTable &Opts = getDriver().getOpts();
610 
611  if (!DAL)
612  DAL = new DerivedArgList(Args.getBaseArgs());
613 
614  for (Arg *A : Args) {
615  if (!shouldSkipArgument(A))
616  DAL->append(A);
617  }
618 
619  checkTargetID(*DAL);
620 
621  if (!Args.getLastArgValue(options::OPT_x).equals("cl"))
622  return DAL;
623 
624  // Phase 1 (.cl -> .bc)
625  if (Args.hasArg(options::OPT_c) && Args.hasArg(options::OPT_emit_llvm)) {
626  DAL->AddFlagArg(nullptr, Opts.getOption(getTriple().isArch64Bit()
627  ? options::OPT_m64
628  : options::OPT_m32));
629 
630  // Have to check OPT_O4, OPT_O0 & OPT_Ofast separately
631  // as they defined that way in Options.td
632  if (!Args.hasArg(options::OPT_O, options::OPT_O0, options::OPT_O4,
633  options::OPT_Ofast))
634  DAL->AddJoinedArg(nullptr, Opts.getOption(options::OPT_O),
635  getOptionDefault(options::OPT_O));
636  }
637 
638  return DAL;
639 }
640 
642  llvm::AMDGPU::GPUKind Kind) {
643 
644  // Assume nothing without a specific target.
645  if (Kind == llvm::AMDGPU::GK_NONE)
646  return false;
647 
648  const unsigned ArchAttr = llvm::AMDGPU::getArchAttrAMDGCN(Kind);
649 
650  // Default to enabling f32 denormals by default on subtargets where fma is
651  // fast with denormals
652  const bool BothDenormAndFMAFast =
653  (ArchAttr & llvm::AMDGPU::FEATURE_FAST_FMA_F32) &&
654  (ArchAttr & llvm::AMDGPU::FEATURE_FAST_DENORMAL_F32);
655  return !BothDenormAndFMAFast;
656 }
657 
659  const llvm::opt::ArgList &DriverArgs, const JobAction &JA,
660  const llvm::fltSemantics *FPType) const {
661  // Denormals should always be enabled for f16 and f64.
662  if (!FPType || FPType != &llvm::APFloat::IEEEsingle())
663  return llvm::DenormalMode::getIEEE();
664 
668  auto Kind = llvm::AMDGPU::parseArchAMDGCN(Arch);
669  if (FPType && FPType == &llvm::APFloat::IEEEsingle() &&
670  DriverArgs.hasFlag(options::OPT_fgpu_flush_denormals_to_zero,
671  options::OPT_fno_gpu_flush_denormals_to_zero,
673  return llvm::DenormalMode::getPreserveSign();
674 
675  return llvm::DenormalMode::getIEEE();
676  }
677 
678  const StringRef GpuArch = getGPUArch(DriverArgs);
679  auto Kind = llvm::AMDGPU::parseArchAMDGCN(GpuArch);
680 
681  // TODO: There are way too many flags that change this. Do we need to check
682  // them all?
683  bool DAZ = DriverArgs.hasArg(options::OPT_cl_denorms_are_zero) ||
685 
686  // Outputs are flushed to zero (FTZ), preserving sign. Denormal inputs are
687  // also implicit treated as zero (DAZ).
688  return DAZ ? llvm::DenormalMode::getPreserveSign() :
689  llvm::DenormalMode::getIEEE();
690 }
691 
692 bool AMDGPUToolChain::isWave64(const llvm::opt::ArgList &DriverArgs,
693  llvm::AMDGPU::GPUKind Kind) {
694  const unsigned ArchAttr = llvm::AMDGPU::getArchAttrAMDGCN(Kind);
695  bool HasWave32 = (ArchAttr & llvm::AMDGPU::FEATURE_WAVE32);
696 
697  return !HasWave32 || DriverArgs.hasFlag(
698  options::OPT_mwavefrontsize64, options::OPT_mno_wavefrontsize64, false);
699 }
700 
701 
702 /// ROCM Toolchain
703 ROCMToolChain::ROCMToolChain(const Driver &D, const llvm::Triple &Triple,
704  const ArgList &Args)
705  : AMDGPUToolChain(D, Triple, Args) {
707 }
708 
710  const llvm::opt::ArgList &DriverArgs,
711  llvm::opt::ArgStringList &CC1Args,
712  Action::OffloadKind DeviceOffloadingKind) const {
713  // Default to "hidden" visibility, as object level linking will not be
714  // supported for the foreseeable future.
715  if (!DriverArgs.hasArg(options::OPT_fvisibility_EQ,
716  options::OPT_fvisibility_ms_compat)) {
717  CC1Args.push_back("-fvisibility=hidden");
718  CC1Args.push_back("-fapply-global-visibility-to-externs");
719  }
720 }
721 
722 StringRef
723 AMDGPUToolChain::getGPUArch(const llvm::opt::ArgList &DriverArgs) const {
725  getTriple(), DriverArgs.getLastArgValue(options::OPT_mcpu_EQ));
726 }
727 
729 AMDGPUToolChain::getParsedTargetID(const llvm::opt::ArgList &DriverArgs) const {
730  StringRef TargetID = DriverArgs.getLastArgValue(options::OPT_mcpu_EQ);
731  if (TargetID.empty())
732  return {std::nullopt, std::nullopt, std::nullopt};
733 
734  llvm::StringMap<bool> FeatureMap;
735  auto OptionalGpuArch = parseTargetID(getTriple(), TargetID, &FeatureMap);
736  if (!OptionalGpuArch)
737  return {TargetID.str(), std::nullopt, std::nullopt};
738 
739  return {TargetID.str(), OptionalGpuArch->str(), FeatureMap};
740 }
741 
743  const llvm::opt::ArgList &DriverArgs) const {
744  auto PTID = getParsedTargetID(DriverArgs);
745  if (PTID.OptionalTargetID && !PTID.OptionalGPUArch) {
746  getDriver().Diag(clang::diag::err_drv_bad_target_id)
747  << *PTID.OptionalTargetID;
748  }
749 }
750 
752 AMDGPUToolChain::getSystemGPUArchs(const ArgList &Args) const {
753  // Detect AMD GPUs availible on the system.
754  std::string Program;
755  if (Arg *A = Args.getLastArg(options::OPT_amdgpu_arch_tool_EQ))
756  Program = A->getValue();
757  else
758  Program = GetProgramPath("amdgpu-arch");
759 
760  auto StdoutOrErr = executeToolChainProgram(Program);
761  if (!StdoutOrErr)
762  return StdoutOrErr.takeError();
763 
765  for (StringRef Arch : llvm::split((*StdoutOrErr)->getBuffer(), "\n"))
766  if (!Arch.empty())
767  GPUArchs.push_back(Arch.str());
768 
769  if (GPUArchs.empty())
770  return llvm::createStringError(std::error_code(),
771  "No AMD GPU detected in the system");
772 
773  return std::move(GPUArchs);
774 }
775 
777  const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args,
778  Action::OffloadKind DeviceOffloadingKind) const {
779  AMDGPUToolChain::addClangTargetOptions(DriverArgs, CC1Args,
780  DeviceOffloadingKind);
781 
782  // For the OpenCL case where there is no offload target, accept -nostdlib to
783  // disable bitcode linking.
784  if (DeviceOffloadingKind == Action::OFK_None &&
785  DriverArgs.hasArg(options::OPT_nostdlib))
786  return;
787 
788  if (DriverArgs.hasArg(options::OPT_nogpulib))
789  return;
790 
791  // Get the device name and canonicalize it
792  const StringRef GpuArch = getGPUArch(DriverArgs);
793  auto Kind = llvm::AMDGPU::parseArchAMDGCN(GpuArch);
794  const StringRef CanonArch = llvm::AMDGPU::getArchNameAMDGCN(Kind);
795  StringRef LibDeviceFile = RocmInstallation.getLibDeviceFile(CanonArch);
797  getAMDGPUCodeObjectVersion(getDriver(), DriverArgs));
798  if (!RocmInstallation.checkCommonBitcodeLibs(CanonArch, LibDeviceFile,
799  ABIVer))
800  return;
801 
802  bool Wave64 = isWave64(DriverArgs, Kind);
803 
804  // TODO: There are way too many flags that change this. Do we need to check
805  // them all?
806  bool DAZ = DriverArgs.hasArg(options::OPT_cl_denorms_are_zero) ||
808  bool FiniteOnly = DriverArgs.hasArg(options::OPT_cl_finite_math_only);
809 
810  bool UnsafeMathOpt =
811  DriverArgs.hasArg(options::OPT_cl_unsafe_math_optimizations);
812  bool FastRelaxedMath = DriverArgs.hasArg(options::OPT_cl_fast_relaxed_math);
813  bool CorrectSqrt =
814  DriverArgs.hasArg(options::OPT_cl_fp32_correctly_rounded_divide_sqrt);
815 
816  // Add the OpenCL specific bitcode library.
818  BCLibs.push_back(RocmInstallation.getOpenCLPath().str());
819 
820  // Add the generic set of libraries.
822  DriverArgs, LibDeviceFile, Wave64, DAZ, FiniteOnly, UnsafeMathOpt,
823  FastRelaxedMath, CorrectSqrt, ABIVer, false));
824 
825  for (StringRef BCFile : BCLibs) {
826  CC1Args.push_back("-mlink-builtin-bitcode");
827  CC1Args.push_back(DriverArgs.MakeArgString(BCFile));
828  }
829 }
830 
832  StringRef GPUArch, StringRef LibDeviceFile,
833  DeviceLibABIVersion ABIVer) const {
834  if (!hasDeviceLibrary()) {
835  D.Diag(diag::err_drv_no_rocm_device_lib) << 0;
836  return false;
837  }
838  if (LibDeviceFile.empty()) {
839  D.Diag(diag::err_drv_no_rocm_device_lib) << 1 << GPUArch;
840  return false;
841  }
842  if (ABIVer.requiresLibrary() && getABIVersionPath(ABIVer).empty()) {
843  D.Diag(diag::err_drv_no_rocm_device_lib) << 2 << ABIVer.toString();
844  return false;
845  }
846  return true;
847 }
848 
851  const llvm::opt::ArgList &DriverArgs, StringRef LibDeviceFile, bool Wave64,
852  bool DAZ, bool FiniteOnly, bool UnsafeMathOpt, bool FastRelaxedMath,
853  bool CorrectSqrt, DeviceLibABIVersion ABIVer, bool isOpenMP = false) const {
855 
856  auto AddBCLib = [&](StringRef BCFile) { BCLibs.push_back(BCFile.str()); };
857 
858  AddBCLib(getOCMLPath());
859  AddBCLib(getOCKLPath());
860  AddBCLib(getDenormalsAreZeroPath(DAZ));
861  AddBCLib(getUnsafeMathPath(UnsafeMathOpt || FastRelaxedMath));
862  AddBCLib(getFiniteOnlyPath(FiniteOnly || FastRelaxedMath));
863  AddBCLib(getCorrectlyRoundedSqrtPath(CorrectSqrt));
864  AddBCLib(getWavefrontSize64Path(Wave64));
865  AddBCLib(LibDeviceFile);
866  auto ABIVerPath = getABIVersionPath(ABIVer);
867  if (!ABIVerPath.empty())
868  AddBCLib(ABIVerPath);
869 
870  return BCLibs;
871 }
872 
873 bool AMDGPUToolChain::shouldSkipArgument(const llvm::opt::Arg *A) const {
874  Option O = A->getOption();
875  if (O.matches(options::OPT_fPIE) || O.matches(options::OPT_fpie))
876  return true;
877  return false;
878 }
879 
881 ROCMToolChain::getCommonDeviceLibNames(const llvm::opt::ArgList &DriverArgs,
882  const std::string &GPUArch,
883  bool isOpenMP) const {
884  auto Kind = llvm::AMDGPU::parseArchAMDGCN(GPUArch);
885  const StringRef CanonArch = llvm::AMDGPU::getArchNameAMDGCN(Kind);
886 
887  StringRef LibDeviceFile = RocmInstallation.getLibDeviceFile(CanonArch);
889  getAMDGPUCodeObjectVersion(getDriver(), DriverArgs));
890  if (!RocmInstallation.checkCommonBitcodeLibs(CanonArch, LibDeviceFile,
891  ABIVer))
892  return {};
893 
894  // If --hip-device-lib is not set, add the default bitcode libraries.
895  // TODO: There are way too many flags that change this. Do we need to check
896  // them all?
897  bool DAZ = DriverArgs.hasFlag(options::OPT_fgpu_flush_denormals_to_zero,
898  options::OPT_fno_gpu_flush_denormals_to_zero,
900  bool FiniteOnly = DriverArgs.hasFlag(
901  options::OPT_ffinite_math_only, options::OPT_fno_finite_math_only, false);
902  bool UnsafeMathOpt =
903  DriverArgs.hasFlag(options::OPT_funsafe_math_optimizations,
904  options::OPT_fno_unsafe_math_optimizations, false);
905  bool FastRelaxedMath = DriverArgs.hasFlag(options::OPT_ffast_math,
906  options::OPT_fno_fast_math, false);
907  bool CorrectSqrt = DriverArgs.hasFlag(
908  options::OPT_fhip_fp32_correctly_rounded_divide_sqrt,
909  options::OPT_fno_hip_fp32_correctly_rounded_divide_sqrt, true);
910  bool Wave64 = isWave64(DriverArgs, Kind);
911 
913  DriverArgs, LibDeviceFile, Wave64, DAZ, FiniteOnly, UnsafeMathOpt,
914  FastRelaxedMath, CorrectSqrt, ABIVer, isOpenMP);
915 }
clang::OpenCL
@ OpenCL
Definition: LangStandard.h:62
clang::driver::RocmInstallationDetector::detectHIPRuntime
void detectHIPRuntime()
Definition: AMDGPU.cpp:436
clang::driver::toolchains
Definition: AIX.h:55
clang::driver::toolchains::AMDGPUToolChain::getGPUArch
StringRef getGPUArch(const llvm::opt::ArgList &DriverArgs) const
Get GPU arch from -mcpu without checking.
Definition: AMDGPU.cpp:723
clang::driver::toolchains::AMDGPUToolChain::ParsedTargetIDType
The struct type returned by getParsedTargetID.
Definition: AMDGPU.h:113
clang::driver::Action::getOffloadingArch
const char * getOffloadingArch() const
Definition: Action.h:210
clang::driver::toolchains::AMDGPUToolChain::getParsedTargetID
ParsedTargetIDType getParsedTargetID(const llvm::opt::ArgList &DriverArgs) const
Get target ID, GPU arch, and target ID features if the target ID is specified and valid.
Definition: AMDGPU.cpp:729
clang::driver::toolchains::AMDGPUToolChain::shouldSkipArgument
bool shouldSkipArgument(const llvm::opt::Arg *Arg) const
Should skip argument.
Definition: AMDGPU.cpp:873
clang::driver::RocmInstallationDetector::hasHIPRuntime
bool hasHIPRuntime() const
Check whether we detected a valid HIP runtime.
Definition: ROCm.h:178
clang::driver::RocmInstallationDetector::AddHIPIncludeArgs
void AddHIPIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const
Definition: AMDGPU.cpp:493
clang::DeclaratorContext::File
@ File
string
string(SUBSTRING ${CMAKE_CURRENT_BINARY_DIR} 0 ${PATH_LIB_START} PATH_HEAD) string(SUBSTRING $
Definition: CMakeLists.txt:23
clang::driver::Action::OFK_Cuda
@ OFK_Cuda
Definition: Action.h:93
clang::driver::toolchains::Generic_GCC::TranslateArgs
llvm::opt::DerivedArgList * TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch, Action::OffloadKind DeviceOffloadKind) const override
TranslateArgs - Create a new derived argument list for any argument translations this ToolChain may w...
Definition: Gnu.cpp:3205
llvm::SmallVector
Definition: LLVM.h:38
clang::driver::ToolChain::GetProgramPath
std::string GetProgramPath(const char *Name) const
Definition: ToolChain.cpp:642
clang::parseTargetID
std::optional< llvm::StringRef > parseTargetID(const llvm::Triple &T, llvm::StringRef OffloadArch, llvm::StringMap< bool > *FeatureMap)
Parse a target ID to get processor and feature map.
Definition: TargetID.cpp:105
clang::driver::RocmInstallationDetector::detectDeviceLibrary
void detectDeviceLibrary()
Definition: AMDGPU.cpp:373
clang::driver::tools
Definition: AIX.h:17
clang::driver::ToolChain::getDriver
const Driver & getDriver() const
Definition: ToolChain.h:236
clang::driver::DeviceLibABIVersion::fromCodeObjectVersion
static DeviceLibABIVersion fromCodeObjectVersion(unsigned CodeObjectVersion)
Definition: ROCm.h:29
clang::driver::Action::OFK_HIP
@ OFK_HIP
Definition: Action.h:95
clang::driver::RocmInstallationDetector::RocmInstallationDetector
RocmInstallationDetector(const Driver &D, const llvm::Triple &HostTriple, const llvm::opt::ArgList &Args, bool DetectHIPRuntime=true, bool DetectDeviceLib=false)
Definition: AMDGPU.cpp:324
llvm::Expected
Definition: LLVM.h:41
clang::driver::Driver::getOpts
const llvm::opt::OptTable & getOpts() const
Definition: Driver.h:373
clang::driver::RocmInstallationDetector::checkCommonBitcodeLibs
bool checkCommonBitcodeLibs(StringRef GPUArch, StringRef LibDeviceFile, DeviceLibABIVersion ABIVer) const
Check file paths of default bitcode libraries common to AMDGPU based toolchains.
Definition: AMDGPU.cpp:831
clang::driver::InputInfo
InputInfo - Wrapper for information about an input source.
Definition: InputInfo.h:22
clang::driver::toolchains::ROCMToolChain::addClangTargetOptions
void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, Action::OffloadKind DeviceOffloadKind) const override
Add options that need to be passed to cc1 for this target.
Definition: AMDGPU.cpp:776
clang::driver::DeviceLibABIVersion
ABI version of device library.
Definition: ROCm.h:26
InputInfo.h
clang::driver::RocmInstallationDetector::getIncludePath
StringRef getIncludePath() const
Get the detected path to Rocm's bin directory.
Definition: ROCm.h:196
clang::driver::tools::AddLinkerInputs
void AddLinkerInputs(const ToolChain &TC, const InputInfoList &Inputs, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs, const JobAction &JA)
U
V
#define V(N, I)
Definition: ASTContext.h:3211
clang::driver::Driver::Diag
DiagnosticBuilder Diag(unsigned DiagID) const
Definition: Driver.h:143
clang::driver::Tool
Tool - Information on a specific compilation tool.
Definition: Tool.h:32
clang::driver::toolchains::Generic_ELF
Definition: Gnu.h:363
Options.h
clang::interp::LE
bool LE(InterpState &S, CodePtr OpPC)
Definition: Interp.h:580
clang::driver::RocmInstallationDetector::getOpenCLPath
StringRef getOpenCLPath() const
Definition: ROCm.h:214
llvm::opt
Definition: DiagnosticOptions.h:19
DriverDiagnostic.h
clang::driver::ResponseFileSupport::AtFileCurCP
static constexpr ResponseFileSupport AtFileCurCP()
Definition: Job.h:92
clang::getProcessorFromTargetID
llvm::StringRef getProcessorFromTargetID(const llvm::Triple &T, llvm::StringRef OffloadArch)
Get processor name from target ID.
Definition: TargetID.cpp:54
clang::driver::toolchains::AMDGPUToolChain::isWave64
static bool isWave64(const llvm::opt::ArgList &DriverArgs, llvm::AMDGPU::GPUKind Kind)
Definition: AMDGPU.cpp:692
clang::driver::toolchains::AMDGPUToolChain::getOptionDefault
StringRef getOptionDefault(options::ID OptID) const
Definition: AMDGPU.h:54
llvm::SmallString< 0 >
clang::driver::ToolChain::getTriple
const llvm::Triple & getTriple() const
Definition: ToolChain.h:238
TargetID.h
clang::driver::toolchains::AMDGPUToolChain::buildLinker
Tool * buildLinker() const override
Definition: AMDGPU.cpp:598
clang::driver::tools::handleTargetFeaturesGroup
void handleTargetFeaturesGroup(const llvm::opt::ArgList &Args, std::vector< StringRef > &Features, llvm::opt::OptSpecifier Group)
Iterate Args and convert -mxxx to +xxx and -mno-xxx to -xxx and append it to Features.
clang::driver::Action::OFK_None
@ OFK_None
Definition: Action.h:87
AMDGPU.h
clang::driver::toolchains::ROCMToolChain::ROCMToolChain
ROCMToolChain(const Driver &D, const llvm::Triple &Triple, const llvm::opt::ArgList &Args)
ROCM Toolchain.
Definition: AMDGPU.cpp:703
clang::driver::tools::getAMDGPUCodeObjectVersion
unsigned getAMDGPUCodeObjectVersion(const Driver &D, const llvm::opt::ArgList &Args)
Definition: CommonArgs.cpp:2216
clang::driver::RocmInstallationDetector::getLibDeviceFile
StringRef getLibDeviceFile(StringRef Gpu) const
Get libdevice file for given architecture.
Definition: ROCm.h:255
clang::driver::Driver::ResourceDir
std::string ResourceDir
The path to the compiler resource directory.
Definition: Driver.h:166
clang::driver::RocmInstallationDetector::print
void print(raw_ostream &OS) const
Print information about the detected ROCm installation.
Definition: AMDGPU.cpp:487
clang::driver::toolchains::Generic_GCC::RocmInstallation
RocmInstallationDetector RocmInstallation
Definition: Gnu.h:290
clang::driver::ToolChain::executeToolChainProgram
llvm::Expected< std::unique_ptr< llvm::MemoryBuffer > > executeToolChainProgram(StringRef Executable) const
Executes the given Executable and returns the stdout.
Definition: ToolChain.cpp:93
P
StringRef P
Definition: ASTMatchersInternal.cpp:564
Compilation.h
clang::driver::Distro
Distro - Helper class for detecting and classifying Linux distributions.
Definition: Distro.h:23
clang::driver::toolchains::ROCMToolChain::getCommonDeviceLibNames
llvm::SmallVector< std::string, 12 > getCommonDeviceLibNames(const llvm::opt::ArgList &DriverArgs, const std::string &GPUArch, bool isOpenMP=false) const
Definition: AMDGPU.cpp:881
clang::driver::Action::getOffloadingDeviceKind
OffloadKind getOffloadingDeviceKind() const
Definition: Action.h:209
clang::driver::Compilation
Compilation - A set of tasks to perform for a single driver invocation.
Definition: Compilation.h:45
clang::ObjCPropertyAttribute::Kind
Kind
Definition: DeclObjCCommon.h:22
clang::driver::toolchains::AMDGPUToolChain::TranslateArgs
llvm::opt::DerivedArgList * TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch, Action::OffloadKind DeviceOffloadKind) const override
TranslateArgs - Create a new derived argument list for any argument translations this ToolChain may w...
Definition: AMDGPU.cpp:603
clang::getAllPossibleTargetIDFeatures
llvm::SmallVector< llvm::StringRef, 4 > getAllPossibleTargetIDFeatures(const llvm::Triple &T, llvm::StringRef Processor)
Get all feature strings that can be used in target ID for Processor.
Definition: TargetID.cpp:38
clang::driver::tools::amdgpu::getAMDGPUTargetFeatures
void getAMDGPUTargetFeatures(const Driver &D, const llvm::Triple &Triple, const llvm::opt::ArgList &Args, std::vector< StringRef > &Features)
Definition: AMDGPU.cpp:551
clang::driver::InputInfo::getFilename
const char * getFilename() const
Definition: InputInfo.h:83
CommonArgs.h
clang
Definition: CalledOnceCheck.h:17
clang::driver::Driver
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
Definition: Driver.h:76
clang::driver::toolchains::AMDGPUToolChain::checkTargetID
virtual void checkTargetID(const llvm::opt::ArgList &DriverArgs) const
Check and diagnose invalid target ID specified by -mcpu.
Definition: AMDGPU.cpp:742
clang::driver::tools::amdgpu::Linker
Definition: AMDGPU.h:29
clang::driver::toolchains::AMDGPUToolChain::addClangTargetOptions
void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, Action::OffloadKind DeviceOffloadKind) const override
Add options that need to be passed to cc1 for this target.
Definition: AMDGPU.cpp:709
clang::driver::tools::checkAMDGPUCodeObjectVersion
void checkAMDGPUCodeObjectVersion(const Driver &D, const llvm::opt::ArgList &Args)
Definition: CommonArgs.cpp:2189
clang::driver::Driver::getVFS
llvm::vfs::FileSystem & getVFS() const
Definition: Driver.h:377
clang::driver::toolchains::AMDGPUToolChain::getDefaultDenormalModeForType
llvm::DenormalMode getDefaultDenormalModeForType(const llvm::opt::ArgList &DriverArgs, const JobAction &JA, const llvm::fltSemantics *FPType=nullptr) const override
Returns the output denormal handling type in the default floating point environment for the given FPT...
Definition: AMDGPU.cpp:658
clang::driver::DeviceLibABIVersion::requiresLibrary
bool requiresLibrary()
Whether ABI version bc file is requested.
Definition: ROCm.h:38
Distro.h
clang::driver::tools::addLinkerCompressDebugSectionsOption
void addLinkerCompressDebugSectionsOption(const ToolChain &TC, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs)
Definition: CommonArgs.cpp:289
clang::driver::Action::OffloadKind
OffloadKind
Definition: Action.h:86
clang::Language::HIP
@ HIP
clang::driver
Definition: Action.h:31
llvm::SmallVectorImpl
Definition: Randstruct.h:18
clang::driver::JobAction
Definition: Action.h:398
clang::driver::DeviceLibABIVersion::toString
std::string toString()
Definition: ROCm.h:39
clang::driver::toolchains::AMDGPUToolChain::getSystemGPUArchs
virtual Expected< SmallVector< std::string > > getSystemGPUArchs(const llvm::opt::ArgList &Args) const override
Uses amdgpu-arch tool to get arch of the system GPU.
Definition: AMDGPU.cpp:752
clang::driver::RocmInstallationDetector::getCommonBitcodeLibs
llvm::SmallVector< std::string, 12 > getCommonBitcodeLibs(const llvm::opt::ArgList &DriverArgs, StringRef LibDeviceFile, bool Wave64, bool DAZ, bool FiniteOnly, bool UnsafeMathOpt, bool FastRelaxedMath, bool CorrectSqrt, DeviceLibABIVersion ABIVer, bool isOpenMP) const
Get file paths of default bitcode libraries common to AMDGPU based toolchains.
Definition: AMDGPU.cpp:850
clang::driver::toolchains::AMDGPUToolChain
Definition: AMDGPU.h:49
clang::driver::toolchains::AMDGPUToolChain::getDefaultDenormsAreZeroForTarget
static bool getDefaultDenormsAreZeroForTarget(llvm::AMDGPU::GPUKind GPUKind)
Return whether denormals should be flushed, and treated as 0 by default for the subtarget.
Definition: AMDGPU.cpp:641