summaryrefslogtreecommitdiff
path: root/clang/lib/Driver/ToolChains/Cuda.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Driver/ToolChains/Cuda.cpp')
-rw-r--r--clang/lib/Driver/ToolChains/Cuda.cpp121
1 files changed, 56 insertions, 65 deletions
diff --git a/clang/lib/Driver/ToolChains/Cuda.cpp b/clang/lib/Driver/ToolChains/Cuda.cpp
index 769eae14df51..5397c7a9a0e6 100644
--- a/clang/lib/Driver/ToolChains/Cuda.cpp
+++ b/clang/lib/Driver/ToolChains/Cuda.cpp
@@ -17,6 +17,7 @@
#include "clang/Driver/InputInfo.h"
#include "clang/Driver/Options.h"
#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/Option/ArgList.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Host.h"
@@ -34,25 +35,6 @@ using namespace clang;
using namespace llvm::opt;
namespace {
-struct CudaVersionInfo {
- std::string DetectedVersion;
- CudaVersion Version;
-};
-// Parses the contents of version.txt in an CUDA installation. It should
-// contain one line of the from e.g. "CUDA Version 7.5.2".
-CudaVersionInfo parseCudaVersionFile(llvm::StringRef V) {
- V = V.trim();
- if (!V.startswith("CUDA Version "))
- return {V.str(), CudaVersion::UNKNOWN};
- V = V.substr(strlen("CUDA Version "));
- SmallVector<StringRef,4> VersionParts;
- V.split(VersionParts, '.');
- return {"version.txt: " + V.str() + ".",
- VersionParts.size() < 2
- ? CudaVersion::UNKNOWN
- : CudaStringToVersion(
- join_items(".", VersionParts[0], VersionParts[1]))};
-}
CudaVersion getCudaVersion(uint32_t raw_version) {
if (raw_version < 7050)
@@ -77,10 +59,18 @@ CudaVersion getCudaVersion(uint32_t raw_version) {
return CudaVersion::CUDA_110;
if (raw_version < 11020)
return CudaVersion::CUDA_111;
- return CudaVersion::LATEST;
+ if (raw_version < 11030)
+ return CudaVersion::CUDA_112;
+ if (raw_version < 11040)
+ return CudaVersion::CUDA_113;
+ if (raw_version < 11050)
+ return CudaVersion::CUDA_114;
+ if (raw_version < 11060)
+ return CudaVersion::CUDA_115;
+ return CudaVersion::NEW;
}
-CudaVersionInfo parseCudaHFile(llvm::StringRef Input) {
+CudaVersion parseCudaHFile(llvm::StringRef Input) {
// Helper lambda which skips the words if the line starts with them or returns
// None otherwise.
auto StartsWithWords =
@@ -100,21 +90,27 @@ CudaVersionInfo parseCudaHFile(llvm::StringRef Input) {
StartsWithWords(Input.ltrim(), {"#", "define", "CUDA_VERSION"})) {
uint32_t RawVersion;
Line->consumeInteger(10, RawVersion);
- return {"cuda.h: CUDA_VERSION=" + Twine(RawVersion).str() + ".",
- getCudaVersion(RawVersion)};
+ return getCudaVersion(RawVersion);
}
// Find next non-empty line.
Input = Input.drop_front(Input.find_first_of("\n\r")).ltrim();
}
- return {"cuda.h: CUDA_VERSION not found.", CudaVersion::UNKNOWN};
+ return CudaVersion::UNKNOWN;
}
} // namespace
void CudaInstallationDetector::WarnIfUnsupportedVersion() {
- if (DetectedVersionIsNotSupported)
- D.Diag(diag::warn_drv_unknown_cuda_version)
- << DetectedVersion
- << CudaVersionToString(CudaVersion::LATEST_SUPPORTED);
+ if (Version > CudaVersion::PARTIALLY_SUPPORTED) {
+ std::string VersionString = CudaVersionToString(Version);
+ if (!VersionString.empty())
+ VersionString.insert(0, " ");
+ D.Diag(diag::warn_drv_new_cuda_version)
+ << VersionString
+ << (CudaVersion::PARTIALLY_SUPPORTED != CudaVersion::FULLY_SUPPORTED)
+ << CudaVersionToString(CudaVersion::PARTIALLY_SUPPORTED);
+ } else if (Version > CudaVersion::FULLY_SUPPORTED)
+ D.Diag(diag::warn_drv_partially_supported_cuda_version)
+ << CudaVersionToString(Version);
}
CudaInstallationDetector::CudaInstallationDetector(
@@ -206,31 +202,17 @@ CudaInstallationDetector::CudaInstallationDetector(
else
continue;
- CudaVersionInfo VersionInfo = {"", CudaVersion::UNKNOWN};
- if (auto VersionFile = FS.getBufferForFile(InstallPath + "/version.txt"))
- VersionInfo = parseCudaVersionFile((*VersionFile)->getBuffer());
- // If version file didn't give us the version, try to find it in cuda.h
- if (VersionInfo.Version == CudaVersion::UNKNOWN)
- if (auto CudaHFile = FS.getBufferForFile(InstallPath + "/include/cuda.h"))
- VersionInfo = parseCudaHFile((*CudaHFile)->getBuffer());
- // As the last resort, make an educated guess between CUDA-7.0, (which had
- // no version.txt file and had old-style libdevice bitcode ) and an unknown
- // recent CUDA version (no version.txt, new style bitcode).
- if (VersionInfo.Version == CudaVersion::UNKNOWN) {
- VersionInfo.Version = (FS.exists(LibDevicePath + "/libdevice.10.bc"))
- ? Version = CudaVersion::LATEST
- : Version = CudaVersion::CUDA_70;
- VersionInfo.DetectedVersion =
- "No version found in version.txt or cuda.h.";
+ Version = CudaVersion::UNKNOWN;
+ if (auto CudaHFile = FS.getBufferForFile(InstallPath + "/include/cuda.h"))
+ Version = parseCudaHFile((*CudaHFile)->getBuffer());
+ // As the last resort, make an educated guess between CUDA-7.0, which had
+ // old-style libdevice bitcode, and an unknown recent CUDA version.
+ if (Version == CudaVersion::UNKNOWN) {
+ Version = FS.exists(LibDevicePath + "/libdevice.10.bc")
+ ? CudaVersion::NEW
+ : CudaVersion::CUDA_70;
}
- Version = VersionInfo.Version;
- DetectedVersion = VersionInfo.DetectedVersion;
-
- // TODO(tra): remove the warning once we have all features of 10.2
- // and 11.0 implemented.
- DetectedVersionIsNotSupported = Version > CudaVersion::LATEST_SUPPORTED;
-
if (Version >= CudaVersion::CUDA_90) {
// CUDA-9+ uses single libdevice file for all GPU variants.
std::string FilePath = LibDevicePath + "/libdevice.10.bc";
@@ -319,8 +301,6 @@ void CudaInstallationDetector::AddCudaIncludeArgs(
return;
}
- CC1Args.push_back("-internal-isystem");
- CC1Args.push_back(DriverArgs.MakeArgString(getIncludePath()));
CC1Args.push_back("-include");
CC1Args.push_back("__clang_cuda_runtime_wrapper.h");
}
@@ -632,8 +612,16 @@ void NVPTX::OpenMPLinker::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back(CubinF);
}
+ AddStaticDeviceLibsLinking(C, *this, JA, Inputs, Args, CmdArgs, "nvptx", GPUArch,
+ false, false);
+
+ // Find nvlink and pass it as "--nvlink-path=" argument of
+ // clang-nvlink-wrapper.
+ CmdArgs.push_back(Args.MakeArgString(
+ Twine("--nvlink-path=" + getToolChain().GetProgramPath("nvlink"))));
+
const char *Exec =
- Args.MakeArgString(getToolChain().GetProgramPath("nvlink"));
+ Args.MakeArgString(getToolChain().GetProgramPath("clang-nvlink-wrapper"));
C.addCommand(std::make_unique<Command>(
JA, *this,
ResponseFileSupport{ResponseFileSupport::RF_Full, llvm::sys::WEM_UTF8,
@@ -686,7 +674,8 @@ void CudaToolChain::addClangTargetOptions(
"Only OpenMP or CUDA offloading kinds are supported for NVIDIA GPUs.");
if (DeviceOffloadingKind == Action::OFK_Cuda) {
- CC1Args.push_back("-fcuda-is-device");
+ CC1Args.append(
+ {"-fcuda-is-device", "-mllvm", "-enable-memcpyopt-without-libcalls"});
if (DriverArgs.hasFlag(options::OPT_fcuda_approx_transcendentals,
options::OPT_fno_cuda_approx_transcendentals, false))
@@ -720,6 +709,9 @@ void CudaToolChain::addClangTargetOptions(
case CudaVersion::CUDA_##CUDA_VER: \
PtxFeature = "+ptx" #PTX_VER; \
break;
+ CASE_CUDA_VERSION(115, 75);
+ CASE_CUDA_VERSION(114, 74);
+ CASE_CUDA_VERSION(113, 73);
CASE_CUDA_VERSION(112, 72);
CASE_CUDA_VERSION(111, 71);
CASE_CUDA_VERSION(110, 70);
@@ -760,6 +752,8 @@ void CudaToolChain::addClangTargetOptions(
addOpenMPDeviceRTL(getDriver(), DriverArgs, CC1Args, BitcodeSuffix,
getTriple());
+ AddStaticDeviceLibsPostLinking(getDriver(), DriverArgs, CC1Args, "nvptx", GpuArch,
+ /* bitcode SDL?*/ true, /* PostClang Link? */ true);
}
}
@@ -831,17 +825,9 @@ CudaToolChain::TranslateArgs(const llvm::opt::DerivedArgList &Args,
// flags are not duplicated.
// Also append the compute capability.
if (DeviceOffloadKind == Action::OFK_OpenMP) {
- for (Arg *A : Args) {
- bool IsDuplicate = false;
- for (Arg *DALArg : *DAL) {
- if (A == DALArg) {
- IsDuplicate = true;
- break;
- }
- }
- if (!IsDuplicate)
+ for (Arg *A : Args)
+ if (!llvm::is_contained(*DAL, A))
DAL->append(A);
- }
StringRef Arch = DAL->getLastArgValue(options::OPT_march_EQ);
if (Arch.empty())
@@ -884,6 +870,11 @@ CudaToolChain::GetCXXStdlibType(const ArgList &Args) const {
void CudaToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
ArgStringList &CC1Args) const {
HostTC.AddClangSystemIncludeArgs(DriverArgs, CC1Args);
+
+ if (!DriverArgs.hasArg(options::OPT_nogpuinc) && CudaInstallation.isValid())
+ CC1Args.append(
+ {"-internal-isystem",
+ DriverArgs.MakeArgString(CudaInstallation.getIncludePath())});
}
void CudaToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &Args,