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