AMDGPUOpenMP.cpp 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. //===- AMDGPUOpenMP.cpp - AMDGPUOpenMP ToolChain Implementation -*- 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. #include "AMDGPUOpenMP.h"
  9. #include "AMDGPU.h"
  10. #include "CommonArgs.h"
  11. #include "ToolChains/ROCm.h"
  12. #include "clang/Basic/DiagnosticDriver.h"
  13. #include "clang/Driver/Compilation.h"
  14. #include "clang/Driver/Driver.h"
  15. #include "clang/Driver/DriverDiagnostic.h"
  16. #include "clang/Driver/InputInfo.h"
  17. #include "clang/Driver/Options.h"
  18. #include "clang/Driver/Tool.h"
  19. #include "llvm/ADT/STLExtras.h"
  20. #include "llvm/Support/FileSystem.h"
  21. #include "llvm/Support/FormatAdapters.h"
  22. #include "llvm/Support/FormatVariadic.h"
  23. #include "llvm/Support/Path.h"
  24. using namespace clang::driver;
  25. using namespace clang::driver::toolchains;
  26. using namespace clang::driver::tools;
  27. using namespace clang;
  28. using namespace llvm::opt;
  29. AMDGPUOpenMPToolChain::AMDGPUOpenMPToolChain(const Driver &D,
  30. const llvm::Triple &Triple,
  31. const ToolChain &HostTC,
  32. const ArgList &Args)
  33. : ROCMToolChain(D, Triple, Args), HostTC(HostTC) {
  34. // Lookup binaries into the driver directory, this is used to
  35. // discover the clang-offload-bundler executable.
  36. getProgramPaths().push_back(getDriver().Dir);
  37. }
  38. void AMDGPUOpenMPToolChain::addClangTargetOptions(
  39. const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args,
  40. Action::OffloadKind DeviceOffloadingKind) const {
  41. HostTC.addClangTargetOptions(DriverArgs, CC1Args, DeviceOffloadingKind);
  42. StringRef GPUArch = DriverArgs.getLastArgValue(options::OPT_march_EQ);
  43. assert(!GPUArch.empty() && "Must have an explicit GPU arch.");
  44. assert(DeviceOffloadingKind == Action::OFK_OpenMP &&
  45. "Only OpenMP offloading kinds are supported.");
  46. CC1Args.push_back("-target-cpu");
  47. CC1Args.push_back(DriverArgs.MakeArgStringRef(GPUArch));
  48. CC1Args.push_back("-fcuda-is-device");
  49. if (DriverArgs.hasArg(options::OPT_nogpulib))
  50. return;
  51. for (auto BCFile : getDeviceLibs(DriverArgs)) {
  52. CC1Args.push_back(BCFile.ShouldInternalize ? "-mlink-builtin-bitcode"
  53. : "-mlink-bitcode-file");
  54. CC1Args.push_back(DriverArgs.MakeArgString(BCFile.Path));
  55. }
  56. // Link the bitcode library late if we're using device LTO.
  57. if (getDriver().isUsingLTO(/* IsOffload */ true))
  58. return;
  59. }
  60. llvm::opt::DerivedArgList *AMDGPUOpenMPToolChain::TranslateArgs(
  61. const llvm::opt::DerivedArgList &Args, StringRef BoundArch,
  62. Action::OffloadKind DeviceOffloadKind) const {
  63. DerivedArgList *DAL =
  64. HostTC.TranslateArgs(Args, BoundArch, DeviceOffloadKind);
  65. if (!DAL)
  66. DAL = new DerivedArgList(Args.getBaseArgs());
  67. const OptTable &Opts = getDriver().getOpts();
  68. if (DeviceOffloadKind == Action::OFK_OpenMP) {
  69. for (Arg *A : Args)
  70. if (!llvm::is_contained(*DAL, A))
  71. DAL->append(A);
  72. if (!DAL->hasArg(options::OPT_march_EQ)) {
  73. StringRef Arch = BoundArch;
  74. if (Arch.empty()) {
  75. auto ArchsOrErr = getSystemGPUArchs(Args);
  76. if (!ArchsOrErr) {
  77. std::string ErrMsg =
  78. llvm::formatv("{0}", llvm::fmt_consume(ArchsOrErr.takeError()));
  79. getDriver().Diag(diag::err_drv_undetermined_gpu_arch)
  80. << llvm::Triple::getArchTypeName(getArch()) << ErrMsg << "-march";
  81. Arch = CudaArchToString(CudaArch::HIPDefault);
  82. } else {
  83. Arch = Args.MakeArgString(ArchsOrErr->front());
  84. }
  85. }
  86. DAL->AddJoinedArg(nullptr, Opts.getOption(options::OPT_march_EQ), Arch);
  87. }
  88. return DAL;
  89. }
  90. for (Arg *A : Args) {
  91. DAL->append(A);
  92. }
  93. if (!BoundArch.empty()) {
  94. DAL->eraseArg(options::OPT_march_EQ);
  95. DAL->AddJoinedArg(nullptr, Opts.getOption(options::OPT_march_EQ),
  96. BoundArch);
  97. }
  98. return DAL;
  99. }
  100. void AMDGPUOpenMPToolChain::addClangWarningOptions(
  101. ArgStringList &CC1Args) const {
  102. HostTC.addClangWarningOptions(CC1Args);
  103. }
  104. ToolChain::CXXStdlibType
  105. AMDGPUOpenMPToolChain::GetCXXStdlibType(const ArgList &Args) const {
  106. return HostTC.GetCXXStdlibType(Args);
  107. }
  108. void AMDGPUOpenMPToolChain::AddClangSystemIncludeArgs(
  109. const ArgList &DriverArgs, ArgStringList &CC1Args) const {
  110. HostTC.AddClangSystemIncludeArgs(DriverArgs, CC1Args);
  111. }
  112. void AMDGPUOpenMPToolChain::AddIAMCUIncludeArgs(const ArgList &Args,
  113. ArgStringList &CC1Args) const {
  114. HostTC.AddIAMCUIncludeArgs(Args, CC1Args);
  115. }
  116. SanitizerMask AMDGPUOpenMPToolChain::getSupportedSanitizers() const {
  117. // The AMDGPUOpenMPToolChain only supports sanitizers in the sense that it
  118. // allows sanitizer arguments on the command line if they are supported by the
  119. // host toolchain. The AMDGPUOpenMPToolChain will actually ignore any command
  120. // line arguments for any of these "supported" sanitizers. That means that no
  121. // sanitization of device code is actually supported at this time.
  122. //
  123. // This behavior is necessary because the host and device toolchains
  124. // invocations often share the command line, so the device toolchain must
  125. // tolerate flags meant only for the host toolchain.
  126. return HostTC.getSupportedSanitizers();
  127. }
  128. VersionTuple
  129. AMDGPUOpenMPToolChain::computeMSVCVersion(const Driver *D,
  130. const ArgList &Args) const {
  131. return HostTC.computeMSVCVersion(D, Args);
  132. }
  133. llvm::SmallVector<ToolChain::BitCodeLibraryInfo, 12>
  134. AMDGPUOpenMPToolChain::getDeviceLibs(const llvm::opt::ArgList &Args) const {
  135. if (Args.hasArg(options::OPT_nogpulib))
  136. return {};
  137. if (!RocmInstallation.hasDeviceLibrary()) {
  138. getDriver().Diag(diag::err_drv_no_rocm_device_lib) << 0;
  139. return {};
  140. }
  141. StringRef GpuArch = getProcessorFromTargetID(
  142. getTriple(), Args.getLastArgValue(options::OPT_march_EQ));
  143. SmallVector<BitCodeLibraryInfo, 12> BCLibs;
  144. for (auto BCLib : getCommonDeviceLibNames(Args, GpuArch.str(),
  145. /*IsOpenMP=*/true))
  146. BCLibs.emplace_back(BCLib);
  147. return BCLibs;
  148. }