clang  12.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 "InputInfo.h"
14 #include "llvm/Option/ArgList.h"
15 #include "llvm/Support/Path.h"
16 #include "llvm/Support/VirtualFileSystem.h"
17 
18 using namespace clang::driver;
19 using namespace clang::driver::tools;
20 using namespace clang::driver::toolchains;
21 using namespace clang;
22 using namespace llvm::opt;
23 
24 void RocmInstallationDetector::scanLibDevicePath(llvm::StringRef Path) {
25  assert(!Path.empty());
26 
27  const StringRef Suffix(".bc");
28  const StringRef Suffix2(".amdgcn.bc");
29 
30  std::error_code EC;
31  for (llvm::vfs::directory_iterator LI = D.getVFS().dir_begin(Path, EC), LE;
32  !EC && LI != LE; LI = LI.increment(EC)) {
33  StringRef FilePath = LI->path();
34  StringRef FileName = llvm::sys::path::filename(FilePath);
35  if (!FileName.endswith(Suffix))
36  continue;
37 
38  StringRef BaseName;
39  if (FileName.endswith(Suffix2))
40  BaseName = FileName.drop_back(Suffix2.size());
41  else if (FileName.endswith(Suffix))
42  BaseName = FileName.drop_back(Suffix.size());
43 
44  if (BaseName == "ocml") {
45  OCML = FilePath;
46  } else if (BaseName == "ockl") {
47  OCKL = FilePath;
48  } else if (BaseName == "opencl") {
49  OpenCL = FilePath;
50  } else if (BaseName == "hip") {
51  HIP = FilePath;
52  } else if (BaseName == "oclc_finite_only_off") {
53  FiniteOnly.Off = FilePath;
54  } else if (BaseName == "oclc_finite_only_on") {
55  FiniteOnly.On = FilePath;
56  } else if (BaseName == "oclc_daz_opt_on") {
57  DenormalsAreZero.On = FilePath;
58  } else if (BaseName == "oclc_daz_opt_off") {
59  DenormalsAreZero.Off = FilePath;
60  } else if (BaseName == "oclc_correctly_rounded_sqrt_on") {
61  CorrectlyRoundedSqrt.On = FilePath;
62  } else if (BaseName == "oclc_correctly_rounded_sqrt_off") {
63  CorrectlyRoundedSqrt.Off = FilePath;
64  } else if (BaseName == "oclc_unsafe_math_on") {
65  UnsafeMath.On = FilePath;
66  } else if (BaseName == "oclc_unsafe_math_off") {
67  UnsafeMath.Off = FilePath;
68  } else if (BaseName == "oclc_wavefrontsize64_on") {
69  WavefrontSize64.On = FilePath;
70  } else if (BaseName == "oclc_wavefrontsize64_off") {
71  WavefrontSize64.Off = FilePath;
72  } else {
73  // Process all bitcode filenames that look like
74  // ocl_isa_version_XXX.amdgcn.bc
75  const StringRef DeviceLibPrefix = "oclc_isa_version_";
76  if (!BaseName.startswith(DeviceLibPrefix))
77  continue;
78 
79  StringRef IsaVersionNumber =
80  BaseName.drop_front(DeviceLibPrefix.size());
81 
82  llvm::Twine GfxName = Twine("gfx") + IsaVersionNumber;
83  SmallString<8> Tmp;
84  LibDeviceMap.insert(
85  std::make_pair(GfxName.toStringRef(Tmp), FilePath.str()));
86  }
87  }
88 }
89 
90 void RocmInstallationDetector::ParseHIPVersionFile(llvm::StringRef V) {
91  SmallVector<StringRef, 4> VersionParts;
92  V.split(VersionParts, '\n');
93  unsigned Major;
94  unsigned Minor;
95  for (auto Part : VersionParts) {
96  auto Splits = Part.split('=');
97  if (Splits.first == "HIP_VERSION_MAJOR")
98  Splits.second.getAsInteger(0, Major);
99  else if (Splits.first == "HIP_VERSION_MINOR")
100  Splits.second.getAsInteger(0, Minor);
101  else if (Splits.first == "HIP_VERSION_PATCH")
102  VersionPatch = Splits.second.str();
103  }
104  VersionMajorMinor = llvm::VersionTuple(Major, Minor);
105  DetectedVersion =
106  (Twine(Major) + "." + Twine(Minor) + "." + VersionPatch).str();
107 }
108 
109 // For candidate specified by --rocm-path we do not do strict check.
111 RocmInstallationDetector::getInstallationPathCandidates() {
112  SmallVector<Candidate, 4> Candidates;
113  if (!RocmPathArg.empty()) {
114  Candidates.emplace_back(RocmPathArg.str());
115  return Candidates;
116  }
117 
118  // Try to find relative to the compiler binary.
119  const char *InstallDir = D.getInstalledDir();
120 
121  // Check both a normal Unix prefix position of the clang binary, as well as
122  // the Windows-esque layout the ROCm packages use with the host architecture
123  // subdirectory of bin.
124 
125  // Strip off directory (usually bin)
126  StringRef ParentDir = llvm::sys::path::parent_path(InstallDir);
127  StringRef ParentName = llvm::sys::path::filename(ParentDir);
128 
129  // Some builds use bin/{host arch}, so go up again.
130  if (ParentName == "bin") {
131  ParentDir = llvm::sys::path::parent_path(ParentDir);
132  ParentName = llvm::sys::path::filename(ParentDir);
133  }
134 
135  // Some versions of the rocm llvm package install to /opt/rocm/llvm/bin
136  if (ParentName == "llvm")
137  ParentDir = llvm::sys::path::parent_path(ParentDir);
138 
139  Candidates.emplace_back(ParentDir.str(), /*StrictChecking=*/true);
140 
141  // Device library may be installed in clang resource directory.
142  Candidates.emplace_back(D.ResourceDir, /*StrictChecking=*/true);
143 
144  Candidates.emplace_back(D.SysRoot + "/opt/rocm", /*StrictChecking=*/true);
145  return Candidates;
146 }
147 
149  const Driver &D, const llvm::Triple &HostTriple,
150  const llvm::opt::ArgList &Args, bool DetectHIPRuntime, bool DetectDeviceLib)
151  : D(D) {
152  RocmPathArg = Args.getLastArgValue(clang::driver::options::OPT_rocm_path_EQ);
153  RocmDeviceLibPathArg =
154  Args.getAllArgValues(clang::driver::options::OPT_rocm_device_lib_path_EQ);
155  if (auto *A = Args.getLastArg(clang::driver::options::OPT_hip_version_EQ)) {
156  HIPVersionArg = A->getValue();
157  unsigned Major = 0;
158  unsigned Minor = 0;
160  HIPVersionArg.split(Parts, '.');
161  if (Parts.size())
162  Parts[0].getAsInteger(0, Major);
163  if (Parts.size() > 1)
164  Parts[1].getAsInteger(0, Minor);
165  if (Parts.size() > 2)
166  VersionPatch = Parts[2].str();
167  if (VersionPatch.empty())
168  VersionPatch = "0";
169  if (Major == 0 || Minor == 0)
170  D.Diag(diag::err_drv_invalid_value)
171  << A->getAsString(Args) << HIPVersionArg;
172 
173  VersionMajorMinor = llvm::VersionTuple(Major, Minor);
174  DetectedVersion =
175  (Twine(Major) + "." + Twine(Minor) + "." + VersionPatch).str();
176  } else {
177  VersionPatch = DefaultVersionPatch;
178  VersionMajorMinor =
179  llvm::VersionTuple(DefaultVersionMajor, DefaultVersionMinor);
180  DetectedVersion = (Twine(DefaultVersionMajor) + "." +
181  Twine(DefaultVersionMinor) + "." + VersionPatch)
182  .str();
183  }
184 
185  if (DetectHIPRuntime)
187  if (DetectDeviceLib)
189 }
190 
192  assert(LibDevicePath.empty());
193 
194  if (!RocmDeviceLibPathArg.empty())
195  LibDevicePath = RocmDeviceLibPathArg[RocmDeviceLibPathArg.size() - 1];
196  else if (const char *LibPathEnv = ::getenv("HIP_DEVICE_LIB_PATH"))
197  LibDevicePath = LibPathEnv;
198 
199  auto &FS = D.getVFS();
200  if (!LibDevicePath.empty()) {
201  // Maintain compatability with HIP flag/envvar pointing directly at the
202  // bitcode library directory. This points directly at the library path instead
203  // of the rocm root installation.
204  if (!FS.exists(LibDevicePath))
205  return;
206 
207  scanLibDevicePath(LibDevicePath);
208  HasDeviceLibrary = allGenericLibsValid() && !LibDeviceMap.empty();
209  return;
210  }
211 
212  // The install path situation in old versions of ROCm is a real mess, and
213  // use a different install layout. Multiple copies of the device libraries
214  // exist for each frontend project, and differ depending on which build
215  // system produced the packages. Standalone OpenCL builds also have a
216  // different directory structure from the ROCm OpenCL package.
217  auto Candidates = getInstallationPathCandidates();
218  for (const auto &Candidate : Candidates) {
219  auto CandidatePath = Candidate.Path;
220 
221  // Check device library exists at the given path.
222  auto CheckDeviceLib = [&](StringRef Path) {
223  bool CheckLibDevice = (!NoBuiltinLibs || Candidate.StrictChecking);
224  if (CheckLibDevice && !FS.exists(Path))
225  return false;
226 
227  scanLibDevicePath(Path);
228 
229  if (!NoBuiltinLibs) {
230  // Check that the required non-target libraries are all available.
231  if (!allGenericLibsValid())
232  return false;
233 
234  // Check that we have found at least one libdevice that we can link in
235  // if -nobuiltinlib hasn't been specified.
236  if (LibDeviceMap.empty())
237  return false;
238  }
239  return true;
240  };
241 
242  // The possible structures are:
243  // - ${ROCM_ROOT}/amdgcn/bitcode/*
244  // - ${ROCM_ROOT}/lib/*
245  // - ${ROCM_ROOT}/lib/bitcode/*
246  // so try to detect these layouts.
247  static llvm::SmallVector<const char *, 2> SubDirsList[] = {
248  {"amdgcn", "bitcode"},
249  {"lib"},
250  {"lib", "bitcode"},
251  };
252 
253  // Make a path by appending sub-directories to InstallPath.
254  auto MakePath = [&](const llvm::ArrayRef<const char *> &SubDirs) {
255  auto Path = CandidatePath;
256  for (auto SubDir : SubDirs)
257  llvm::sys::path::append(Path, SubDir);
258  return Path;
259  };
260 
261  for (auto SubDirs : SubDirsList) {
262  LibDevicePath = MakePath(SubDirs);
263  HasDeviceLibrary = CheckDeviceLib(LibDevicePath);
264  if (HasDeviceLibrary)
265  return;
266  }
267  }
268 }
269 
271  auto Candidates = getInstallationPathCandidates();
272  auto &FS = D.getVFS();
273 
274  for (const auto &Candidate : Candidates) {
275  InstallPath = Candidate.Path;
276  if (InstallPath.empty() || !FS.exists(InstallPath))
277  continue;
278 
279  BinPath = InstallPath;
280  llvm::sys::path::append(BinPath, "bin");
281  IncludePath = InstallPath;
282  llvm::sys::path::append(IncludePath, "include");
283  LibPath = InstallPath;
284  llvm::sys::path::append(LibPath, "lib");
285 
286  llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> VersionFile =
287  FS.getBufferForFile(BinPath + "/.hipVersion");
288  if (!VersionFile && Candidate.StrictChecking)
289  continue;
290 
291  if (HIPVersionArg.empty() && VersionFile)
292  ParseHIPVersionFile((*VersionFile)->getBuffer());
293 
294  HasHIPRuntime = true;
295  return;
296  }
297  HasHIPRuntime = false;
298 }
299 
300 void RocmInstallationDetector::print(raw_ostream &OS) const {
301  if (hasHIPRuntime())
302  OS << "Found HIP installation: " << InstallPath << ", version "
303  << DetectedVersion << '\n';
304 }
305 
306 void RocmInstallationDetector::AddHIPIncludeArgs(const ArgList &DriverArgs,
307  ArgStringList &CC1Args) const {
308  bool UsesRuntimeWrapper = VersionMajorMinor > llvm::VersionTuple(3, 5);
309 
310  if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
311  // HIP header includes standard library wrapper headers under clang
312  // cuda_wrappers directory. Since these wrapper headers include_next
313  // standard C++ headers, whereas libc++ headers include_next other clang
314  // headers. The include paths have to follow this order:
315  // - wrapper include path
316  // - standard C++ include path
317  // - other clang include path
318  // Since standard C++ and other clang include paths are added in other
319  // places after this function, here we only need to make sure wrapper
320  // include path is added.
321  //
322  // ROCm 3.5 does not fully support the wrapper headers. Therefore it needs
323  // a workaround.
325  if (UsesRuntimeWrapper)
326  llvm::sys::path::append(P, "include", "cuda_wrappers");
327  CC1Args.push_back("-internal-isystem");
328  CC1Args.push_back(DriverArgs.MakeArgString(P));
329  }
330 
331  if (DriverArgs.hasArg(options::OPT_nogpuinc))
332  return;
333 
334  if (!hasHIPRuntime()) {
335  D.Diag(diag::err_drv_no_hip_runtime);
336  return;
337  }
338 
339  CC1Args.push_back("-internal-isystem");
340  CC1Args.push_back(DriverArgs.MakeArgString(getIncludePath()));
341  if (UsesRuntimeWrapper)
342  CC1Args.append({"-include", "__clang_hip_runtime_wrapper.h"});
343 }
344 
345 void amdgpu::Linker::ConstructJob(Compilation &C, const JobAction &JA,
346  const InputInfo &Output,
347  const InputInfoList &Inputs,
348  const ArgList &Args,
349  const char *LinkingOutput) const {
350 
351  std::string Linker = getToolChain().GetProgramPath(getShortName());
352  ArgStringList CmdArgs;
353  AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);
354  CmdArgs.push_back("-shared");
355  CmdArgs.push_back("-o");
356  CmdArgs.push_back(Output.getFilename());
357  C.addCommand(
358  std::make_unique<Command>(JA, *this, ResponseFileSupport::AtFileCurCP(),
359  Args.MakeArgString(Linker), CmdArgs, Inputs));
360 }
361 
363  const llvm::opt::ArgList &Args,
364  std::vector<StringRef> &Features) {
365  if (const Arg *dAbi = Args.getLastArg(options::OPT_mamdgpu_debugger_abi))
366  D.Diag(diag::err_drv_clang_unsupported) << dAbi->getAsString(Args);
367 
368  if (Args.getLastArg(options::OPT_mwavefrontsize64)) {
369  Features.push_back("-wavefrontsize16");
370  Features.push_back("-wavefrontsize32");
371  Features.push_back("+wavefrontsize64");
372  }
373  if (Args.getLastArg(options::OPT_mno_wavefrontsize64)) {
374  Features.push_back("-wavefrontsize16");
375  Features.push_back("+wavefrontsize32");
376  Features.push_back("-wavefrontsize64");
377  }
378 
380  Args, Features, options::OPT_m_amdgpu_Features_Group);
381 }
382 
383 /// AMDGPU Toolchain
384 AMDGPUToolChain::AMDGPUToolChain(const Driver &D, const llvm::Triple &Triple,
385  const ArgList &Args)
386  : Generic_ELF(D, Triple, Args),
387  OptionsDefault({{options::OPT_O, "3"},
388  {options::OPT_cl_std_EQ, "CL1.2"}}) {}
389 
391  return new tools::amdgpu::Linker(*this);
392 }
393 
394 DerivedArgList *
395 AMDGPUToolChain::TranslateArgs(const DerivedArgList &Args, StringRef BoundArch,
396  Action::OffloadKind DeviceOffloadKind) const {
397 
398  DerivedArgList *DAL =
399  Generic_ELF::TranslateArgs(Args, BoundArch, DeviceOffloadKind);
400 
401  // Do nothing if not OpenCL (-x cl)
402  if (!Args.getLastArgValue(options::OPT_x).equals("cl"))
403  return DAL;
404 
405  if (!DAL)
406  DAL = new DerivedArgList(Args.getBaseArgs());
407  for (auto *A : Args)
408  DAL->append(A);
409 
410  const OptTable &Opts = getDriver().getOpts();
411 
412  // Phase 1 (.cl -> .bc)
413  if (Args.hasArg(options::OPT_c) && Args.hasArg(options::OPT_emit_llvm)) {
414  DAL->AddFlagArg(nullptr, Opts.getOption(getTriple().isArch64Bit()
415  ? options::OPT_m64
416  : options::OPT_m32));
417 
418  // Have to check OPT_O4, OPT_O0 & OPT_Ofast separately
419  // as they defined that way in Options.td
420  if (!Args.hasArg(options::OPT_O, options::OPT_O0, options::OPT_O4,
421  options::OPT_Ofast))
422  DAL->AddJoinedArg(nullptr, Opts.getOption(options::OPT_O),
423  getOptionDefault(options::OPT_O));
424  }
425 
426  return DAL;
427 }
428 
430  llvm::AMDGPU::GPUKind Kind) {
431 
432  // Assume nothing without a specific target.
433  if (Kind == llvm::AMDGPU::GK_NONE)
434  return false;
435 
436  const unsigned ArchAttr = llvm::AMDGPU::getArchAttrAMDGCN(Kind);
437 
438  // Default to enabling f32 denormals by default on subtargets where fma is
439  // fast with denormals
440  const bool BothDenormAndFMAFast =
441  (ArchAttr & llvm::AMDGPU::FEATURE_FAST_FMA_F32) &&
442  (ArchAttr & llvm::AMDGPU::FEATURE_FAST_DENORMAL_F32);
443  return !BothDenormAndFMAFast;
444 }
445 
447  const llvm::opt::ArgList &DriverArgs, const JobAction &JA,
448  const llvm::fltSemantics *FPType) const {
449  // Denormals should always be enabled for f16 and f64.
450  if (!FPType || FPType != &llvm::APFloat::IEEEsingle())
451  return llvm::DenormalMode::getIEEE();
452 
455  auto Kind = llvm::AMDGPU::parseArchAMDGCN(JA.getOffloadingArch());
456  if (FPType && FPType == &llvm::APFloat::IEEEsingle() &&
457  DriverArgs.hasFlag(options::OPT_fcuda_flush_denormals_to_zero,
458  options::OPT_fno_cuda_flush_denormals_to_zero,
460  return llvm::DenormalMode::getPreserveSign();
461 
462  return llvm::DenormalMode::getIEEE();
463  }
464 
465  const StringRef GpuArch = DriverArgs.getLastArgValue(options::OPT_mcpu_EQ);
466  auto Kind = llvm::AMDGPU::parseArchAMDGCN(GpuArch);
467 
468  // TODO: There are way too many flags that change this. Do we need to check
469  // them all?
470  bool DAZ = DriverArgs.hasArg(options::OPT_cl_denorms_are_zero) ||
472 
473  // Outputs are flushed to zero (FTZ), preserving sign. Denormal inputs are
474  // also implicit treated as zero (DAZ).
475  return DAZ ? llvm::DenormalMode::getPreserveSign() :
476  llvm::DenormalMode::getIEEE();
477 }
478 
479 bool AMDGPUToolChain::isWave64(const llvm::opt::ArgList &DriverArgs,
480  llvm::AMDGPU::GPUKind Kind) {
481  const unsigned ArchAttr = llvm::AMDGPU::getArchAttrAMDGCN(Kind);
482  static bool HasWave32 = (ArchAttr & llvm::AMDGPU::FEATURE_WAVE32);
483 
484  return !HasWave32 || DriverArgs.hasFlag(
485  options::OPT_mwavefrontsize64, options::OPT_mno_wavefrontsize64, false);
486 }
487 
488 
489 /// ROCM Toolchain
490 ROCMToolChain::ROCMToolChain(const Driver &D, const llvm::Triple &Triple,
491  const ArgList &Args)
492  : AMDGPUToolChain(D, Triple, Args) {
494 }
495 
497  const llvm::opt::ArgList &DriverArgs,
498  llvm::opt::ArgStringList &CC1Args,
499  Action::OffloadKind DeviceOffloadingKind) const {
500  // Default to "hidden" visibility, as object level linking will not be
501  // supported for the foreseeable future.
502  if (!DriverArgs.hasArg(options::OPT_fvisibility_EQ,
503  options::OPT_fvisibility_ms_compat)) {
504  CC1Args.push_back("-fvisibility");
505  CC1Args.push_back("hidden");
506  CC1Args.push_back("-fapply-global-visibility-to-externs");
507  }
508 }
509 
511  const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args,
512  Action::OffloadKind DeviceOffloadingKind) const {
513  AMDGPUToolChain::addClangTargetOptions(DriverArgs, CC1Args,
514  DeviceOffloadingKind);
515 
516  // For the OpenCL case where there is no offload target, accept -nostdlib to
517  // disable bitcode linking.
518  if (DeviceOffloadingKind == Action::OFK_None &&
519  DriverArgs.hasArg(options::OPT_nostdlib))
520  return;
521 
522  if (DriverArgs.hasArg(options::OPT_nogpulib))
523  return;
524 
526  getDriver().Diag(diag::err_drv_no_rocm_device_lib) << 0;
527  return;
528  }
529 
530  // Get the device name and canonicalize it
531  const StringRef GpuArch = DriverArgs.getLastArgValue(options::OPT_mcpu_EQ);
532  auto Kind = llvm::AMDGPU::parseArchAMDGCN(GpuArch);
533  const StringRef CanonArch = llvm::AMDGPU::getArchNameAMDGCN(Kind);
534  std::string LibDeviceFile = RocmInstallation.getLibDeviceFile(CanonArch);
535  if (LibDeviceFile.empty()) {
536  getDriver().Diag(diag::err_drv_no_rocm_device_lib) << 1 << GpuArch;
537  return;
538  }
539 
540  bool Wave64 = isWave64(DriverArgs, Kind);
541 
542  // TODO: There are way too many flags that change this. Do we need to check
543  // them all?
544  bool DAZ = DriverArgs.hasArg(options::OPT_cl_denorms_are_zero) ||
546  bool FiniteOnly = DriverArgs.hasArg(options::OPT_cl_finite_math_only);
547 
548  bool UnsafeMathOpt =
549  DriverArgs.hasArg(options::OPT_cl_unsafe_math_optimizations);
550  bool FastRelaxedMath = DriverArgs.hasArg(options::OPT_cl_fast_relaxed_math);
551  bool CorrectSqrt =
552  DriverArgs.hasArg(options::OPT_cl_fp32_correctly_rounded_divide_sqrt);
553 
554  // Add the OpenCL specific bitcode library.
555  CC1Args.push_back("-mlink-builtin-bitcode");
556  CC1Args.push_back(DriverArgs.MakeArgString(RocmInstallation.getOpenCLPath()));
557 
558  // Add the generic set of libraries.
560  DriverArgs, CC1Args, LibDeviceFile, Wave64, DAZ, FiniteOnly,
561  UnsafeMathOpt, FastRelaxedMath, CorrectSqrt);
562 }
563 
565  const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args,
566  StringRef LibDeviceFile, bool Wave64, bool DAZ, bool FiniteOnly,
567  bool UnsafeMathOpt, bool FastRelaxedMath, bool CorrectSqrt) const {
568  static const char LinkBitcodeFlag[] = "-mlink-builtin-bitcode";
569 
570  CC1Args.push_back(LinkBitcodeFlag);
571  CC1Args.push_back(DriverArgs.MakeArgString(getOCMLPath()));
572 
573  CC1Args.push_back(LinkBitcodeFlag);
574  CC1Args.push_back(DriverArgs.MakeArgString(getOCKLPath()));
575 
576  CC1Args.push_back(LinkBitcodeFlag);
577  CC1Args.push_back(DriverArgs.MakeArgString(getDenormalsAreZeroPath(DAZ)));
578 
579  CC1Args.push_back(LinkBitcodeFlag);
580  CC1Args.push_back(DriverArgs.MakeArgString(
581  getUnsafeMathPath(UnsafeMathOpt || FastRelaxedMath)));
582 
583  CC1Args.push_back(LinkBitcodeFlag);
584  CC1Args.push_back(DriverArgs.MakeArgString(
585  getFiniteOnlyPath(FiniteOnly || FastRelaxedMath)));
586 
587  CC1Args.push_back(LinkBitcodeFlag);
588  CC1Args.push_back(
589  DriverArgs.MakeArgString(getCorrectlyRoundedSqrtPath(CorrectSqrt)));
590 
591  CC1Args.push_back(LinkBitcodeFlag);
592  CC1Args.push_back(DriverArgs.MakeArgString(getWavefrontSize64Path(Wave64)));
593 
594  CC1Args.push_back(LinkBitcodeFlag);
595  CC1Args.push_back(DriverArgs.MakeArgString(LibDeviceFile));
596 }
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.
StringRef P
DiagnosticBuilder Diag(unsigned DiagID) const
Definition: Driver.h:109
Tool * buildLinker() const override
Definition: AMDGPU.cpp:390
bool hasHIPRuntime() const
Check whether we detected a valid HIP runtime.
Definition: ROCm.h:134
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:510
const char * getFilename() const
Definition: InputInfo.h:83
InputInfo - Wrapper for information about an input source.
Definition: InputInfo.h:22
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:395
void print(raw_ostream &OS) const
Print information about the detected ROCm installation.
Definition: AMDGPU.cpp:300
OffloadKind getOffloadingDeviceKind() const
Definition: Action.h:199
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
Definition: Driver.h:59
void getAMDGPUTargetFeatures(const Driver &D, const llvm::opt::ArgList &Args, std::vector< StringRef > &Features)
Definition: AMDGPU.cpp:362
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:496
void AddHIPIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const
Definition: AMDGPU.cpp:306
llvm::vfs::FileSystem & getVFS() const
Definition: Driver.h:319
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:446
#define V(N, I)
Definition: ASTContext.h:2899
static bool isWave64(const llvm::opt::ArgList &DriverArgs, llvm::AMDGPU::GPUKind Kind)
Definition: AMDGPU.cpp:479
void addCommand(std::unique_ptr< Command > C)
Definition: Compilation.h:205
bool hasDeviceLibrary() const
Check whether we detected a valid ROCm device library.
Definition: ROCm.h:137
StringRef getIncludePath() const
Get the detected path to Rocm&#39;s bin directory.
Definition: ROCm.h:152
Kind
ROCMToolChain(const Driver &D, const llvm::Triple &Triple, const llvm::opt::ArgList &Args)
ROCM Toolchain.
Definition: AMDGPU.cpp:490
RocmInstallationDetector RocmInstallation
Definition: Gnu.h:286
RocmInstallationDetector(const Driver &D, const llvm::Triple &HostTriple, const llvm::opt::ArgList &Args, bool DetectHIPRuntime=true, bool DetectDeviceLib=false)
Definition: AMDGPU.cpp:148
const Driver & getDriver() const
Definition: ToolChain.h:204
std::string getLibDeviceFile(StringRef Gpu) const
Get libdevice file for given architecture.
Definition: ROCm.h:201
Dataflow Directional Tag Classes.
void AddLinkerInputs(const ToolChain &TC, const InputInfoList &Inputs, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs, const JobAction &JA)
Tool - Information on a specific compilation tool.
Definition: Tool.h:32
const StringRef getOptionDefault(options::ID OptID) const
Definition: AMDGPU.h:52
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:3007
Compilation - A set of tasks to perform for a single driver invocation.
Definition: Compilation.h:45
const llvm::Triple & getTriple() const
Definition: ToolChain.h:206
static constexpr ResponseFileSupport AtFileCurCP()
Definition: Job.h:91
bool LE(InterpState &S, CodePtr OpPC)
Definition: Interp.h:237
StringRef getOpenCLPath() const
Definition: ROCm.h:170
const llvm::opt::OptTable & getOpts() const
Definition: Driver.h:315
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:429
const char * getOffloadingArch() const
Definition: Action.h:200
void addCommonBitcodeLibCC1Args(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, StringRef LibDeviceFile, bool Wave64, bool DAZ, bool FiniteOnly, bool UnsafeMathOpt, bool FastRelaxedMath, bool CorrectSqrt) const
Add arguments needed to link default bitcode libraries.
Definition: AMDGPU.cpp:564
std::string ResourceDir
The path to the compiler resource directory.
Definition: Driver.h:132