Skip to content

Commit 5889190

Browse files
author
Justin Lebar
committedJan 5, 2017
[Driver] Driver changes to support CUDA compilation on Windows.
Summary: For the most part this is straightforward: Just add a CudaInstallation object to the MSVC and MinGW toolchains. CudaToolChain has to override computeMSVCVersion so that Clang::constructJob passes the right version flag to cc1. We have to modify IsWindowsMSVC and friends in Clang::constructJob to be true when compiling CUDA device code on Windows for the same reason. Depends on: D28319 Reviewers: tra Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D28320 llvm-svn: 291131
1 parent dda1d84 commit 5889190

File tree

12 files changed

+98
-15
lines changed

12 files changed

+98
-15
lines changed
 

‎clang/include/clang/Driver/ToolChain.h

+7
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,13 @@ class ToolChain {
139139
vfs::FileSystem &getVFS() const;
140140
const llvm::Triple &getTriple() const { return Triple; }
141141

142+
/// Get the toolchain's aux triple, if it has one.
143+
///
144+
/// Exactly what the aux triple represents depends on the toolchain, but for
145+
/// example when compiling CUDA code for the GPU, the triple might be NVPTX,
146+
/// while the aux triple is the host (CPU) toolchain, e.g. x86-linux-gnu.
147+
virtual const llvm::Triple *getAuxTriple() const { return nullptr; }
148+
142149
llvm::Triple::ArchType getArch() const { return Triple.getArch(); }
143150
StringRef getArchName() const { return Triple.getArchName(); }
144151
StringRef getPlatform() const { return Triple.getVendorName(); }

‎clang/lib/Driver/MSVCToolChain.cpp

+11-2
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,9 @@ using namespace clang::driver::toolchains;
4747
using namespace clang;
4848
using namespace llvm::opt;
4949

50-
MSVCToolChain::MSVCToolChain(const Driver &D, const llvm::Triple& Triple,
50+
MSVCToolChain::MSVCToolChain(const Driver &D, const llvm::Triple &Triple,
5151
const ArgList &Args)
52-
: ToolChain(D, Triple, Args) {
52+
: ToolChain(D, Triple, Args), CudaInstallation(D, Triple, Args) {
5353
getProgramPaths().push_back(getDriver().getInstalledDir());
5454
if (getDriver().getInstalledDir() != getDriver().Dir)
5555
getProgramPaths().push_back(getDriver().Dir);
@@ -94,6 +94,15 @@ bool MSVCToolChain::isPICDefaultForced() const {
9494
return getArch() == llvm::Triple::x86_64;
9595
}
9696

97+
void MSVCToolChain::AddCudaIncludeArgs(const ArgList &DriverArgs,
98+
ArgStringList &CC1Args) const {
99+
CudaInstallation.AddCudaIncludeArgs(DriverArgs, CC1Args);
100+
}
101+
102+
void MSVCToolChain::printVerboseInfo(raw_ostream &OS) const {
103+
CudaInstallation.print(OS);
104+
}
105+
97106
#ifdef USE_WIN32
98107
static bool readFullStringValue(HKEY hkey, const char *valueName,
99108
std::string &value) {

‎clang/lib/Driver/MinGWToolChain.cpp

+10-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ void MinGW::findGccLibDir() {
6363
}
6464

6565
MinGW::MinGW(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
66-
: ToolChain(D, Triple, Args) {
66+
: ToolChain(D, Triple, Args), CudaInstallation(D, Triple, Args) {
6767
getProgramPaths().push_back(getDriver().getInstalledDir());
6868

6969
// In Windows there aren't any standard install locations, we search
@@ -135,6 +135,15 @@ bool MinGW::UseSEHExceptions() const {
135135
return getArch() == llvm::Triple::x86_64;
136136
}
137137

138+
void MinGW::AddCudaIncludeArgs(const ArgList &DriverArgs,
139+
ArgStringList &CC1Args) const {
140+
CudaInstallation.AddCudaIncludeArgs(DriverArgs, CC1Args);
141+
}
142+
143+
void MinGW::printVerboseInfo(raw_ostream &OS) const {
144+
CudaInstallation.print(OS);
145+
}
146+
138147
// Include directories for various hosts:
139148

140149
// Windows, mingw.org

‎clang/lib/Driver/ToolChains.cpp

+17-5
Original file line numberDiff line numberDiff line change
@@ -1810,14 +1810,21 @@ CudaInstallationDetector::CudaInstallationDetector(
18101810
: D(D) {
18111811
SmallVector<std::string, 4> CudaPathCandidates;
18121812

1813-
if (Args.hasArg(options::OPT_cuda_path_EQ))
1813+
// In decreasing order so we prefer newer versions to older versions.
1814+
std::initializer_list<const char *> Versions = {"8.0", "7.5", "7.0"};
1815+
1816+
if (Args.hasArg(options::OPT_cuda_path_EQ)) {
18141817
CudaPathCandidates.push_back(
18151818
Args.getLastArgValue(options::OPT_cuda_path_EQ));
1816-
else {
1819+
} else if (HostTriple.isOSWindows()) {
1820+
for (const char *Ver : Versions)
1821+
CudaPathCandidates.push_back(
1822+
D.SysRoot + "/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v" +
1823+
Ver);
1824+
} else {
18171825
CudaPathCandidates.push_back(D.SysRoot + "/usr/local/cuda");
1818-
CudaPathCandidates.push_back(D.SysRoot + "/usr/local/cuda-8.0");
1819-
CudaPathCandidates.push_back(D.SysRoot + "/usr/local/cuda-7.5");
1820-
CudaPathCandidates.push_back(D.SysRoot + "/usr/local/cuda-7.0");
1826+
for (const char *Ver : Versions)
1827+
CudaPathCandidates.push_back(D.SysRoot + "/usr/local/cuda-" + Ver);
18211828
}
18221829

18231830
for (const auto &CudaPath : CudaPathCandidates) {
@@ -5021,6 +5028,11 @@ SanitizerMask CudaToolChain::getSupportedSanitizers() const {
50215028
return HostTC.getSupportedSanitizers();
50225029
}
50235030

5031+
VersionTuple CudaToolChain::computeMSVCVersion(const Driver *D,
5032+
const ArgList &Args) const {
5033+
return HostTC.computeMSVCVersion(D, Args);
5034+
}
5035+
50245036
/// XCore tool chain
50255037
XCoreToolChain::XCoreToolChain(const Driver &D, const llvm::Triple &Triple,
50265038
const ArgList &Args)

‎clang/lib/Driver/ToolChains.h

+22
Original file line numberDiff line numberDiff line change
@@ -709,12 +709,19 @@ class LLVM_LIBRARY_VISIBILITY MinGW : public ToolChain {
709709
const llvm::opt::ArgList &DriverArgs,
710710
llvm::opt::ArgStringList &CC1Args) const override;
711711

712+
void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs,
713+
llvm::opt::ArgStringList &CC1Args) const override;
714+
715+
void printVerboseInfo(raw_ostream &OS) const override;
716+
712717
protected:
713718
Tool *getTool(Action::ActionClass AC) const override;
714719
Tool *buildLinker() const override;
715720
Tool *buildAssembler() const override;
716721

717722
private:
723+
CudaInstallationDetector CudaInstallation;
724+
718725
std::string Base;
719726
std::string GccLibDir;
720727
std::string Ver;
@@ -892,6 +899,10 @@ class LLVM_LIBRARY_VISIBILITY CudaToolChain : public ToolChain {
892899
CudaToolChain(const Driver &D, const llvm::Triple &Triple,
893900
const ToolChain &HostTC, const llvm::opt::ArgList &Args);
894901

902+
virtual const llvm::Triple *getAuxTriple() const override {
903+
return &HostTC.getTriple();
904+
}
905+
895906
llvm::opt::DerivedArgList *
896907
TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch,
897908
Action::OffloadKind DeviceOffloadKind) const override;
@@ -924,6 +935,10 @@ class LLVM_LIBRARY_VISIBILITY CudaToolChain : public ToolChain {
924935

925936
SanitizerMask getSupportedSanitizers() const override;
926937

938+
VersionTuple
939+
computeMSVCVersion(const Driver *D,
940+
const llvm::opt::ArgList &Args) const override;
941+
927942
const ToolChain &HostTC;
928943
CudaInstallationDetector CudaInstallation;
929944

@@ -1147,6 +1162,9 @@ class LLVM_LIBRARY_VISIBILITY MSVCToolChain : public ToolChain {
11471162
const llvm::opt::ArgList &DriverArgs,
11481163
llvm::opt::ArgStringList &CC1Args) const override;
11491164

1165+
void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs,
1166+
llvm::opt::ArgStringList &CC1Args) const override;
1167+
11501168
bool getWindowsSDKDir(std::string &path, int &major,
11511169
std::string &windowsSDKIncludeVersion,
11521170
std::string &windowsSDKLibVersion) const;
@@ -1166,6 +1184,8 @@ class LLVM_LIBRARY_VISIBILITY MSVCToolChain : public ToolChain {
11661184
types::ID InputType) const override;
11671185
SanitizerMask getSupportedSanitizers() const override;
11681186

1187+
void printVerboseInfo(raw_ostream &OS) const override;
1188+
11691189
protected:
11701190
void AddSystemIncludeWithSubfolder(const llvm::opt::ArgList &DriverArgs,
11711191
llvm::opt::ArgStringList &CC1Args,
@@ -1179,6 +1199,8 @@ class LLVM_LIBRARY_VISIBILITY MSVCToolChain : public ToolChain {
11791199
private:
11801200
VersionTuple getMSVCVersionFromTriple() const;
11811201
VersionTuple getMSVCVersionFromExe() const;
1202+
1203+
CudaInstallationDetector CudaInstallation;
11821204
};
11831205

11841206
class LLVM_LIBRARY_VISIBILITY CrossWindowsToolChain : public Generic_GCC {

‎clang/lib/Driver/Tools.cpp

+17-7
Original file line numberDiff line numberDiff line change
@@ -4086,13 +4086,6 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
40864086
const Driver &D = getToolChain().getDriver();
40874087
ArgStringList CmdArgs;
40884088

4089-
bool IsWindowsGNU = getToolChain().getTriple().isWindowsGNUEnvironment();
4090-
bool IsWindowsCygnus =
4091-
getToolChain().getTriple().isWindowsCygwinEnvironment();
4092-
bool IsWindowsMSVC = getToolChain().getTriple().isWindowsMSVCEnvironment();
4093-
bool IsPS4CPU = getToolChain().getTriple().isPS4CPU();
4094-
bool IsIAMCU = getToolChain().getTriple().isOSIAMCU();
4095-
40964089
// Check number of inputs for sanity. We need at least one input.
40974090
assert(Inputs.size() >= 1 && "Must have at least one input.");
40984091
const InputInfo &Input = Inputs[0];
@@ -4106,6 +4099,23 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
41064099
Inputs.size() == 1) &&
41074100
"Unable to handle multiple inputs.");
41084101

4102+
bool IsWindowsGNU = getToolChain().getTriple().isWindowsGNUEnvironment();
4103+
bool IsWindowsCygnus =
4104+
getToolChain().getTriple().isWindowsCygwinEnvironment();
4105+
bool IsWindowsMSVC = getToolChain().getTriple().isWindowsMSVCEnvironment();
4106+
bool IsPS4CPU = getToolChain().getTriple().isPS4CPU();
4107+
bool IsIAMCU = getToolChain().getTriple().isOSIAMCU();
4108+
4109+
// Adjust IsWindowsXYZ for CUDA compilations. Even when compiling in device
4110+
// mode (i.e., getToolchain().getTriple() is NVPTX, not Windows), we need to
4111+
// pass Windows-specific flags to cc1.
4112+
if (IsCuda) {
4113+
const llvm::Triple *AuxTriple = getToolChain().getAuxTriple();
4114+
IsWindowsMSVC |= AuxTriple && AuxTriple->isWindowsMSVCEnvironment();
4115+
IsWindowsGNU |= AuxTriple && AuxTriple->isWindowsGNUEnvironment();
4116+
IsWindowsCygnus |= AuxTriple && AuxTriple->isWindowsCygwinEnvironment();
4117+
}
4118+
41094119
// C++ is not supported for IAMCU.
41104120
if (IsIAMCU && types::isCXX(Input.getType()))
41114121
D.Diag(diag::err_drv_clang_unsupported) << "C++ for IAMCU";

‎clang/test/Driver/Inputs/CUDA-windows/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v8.0/bin/.keep

Whitespace-only changes.

‎clang/test/Driver/Inputs/CUDA-windows/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v8.0/include/.keep

Whitespace-only changes.

‎clang/test/Driver/Inputs/CUDA-windows/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v8.0/lib/.keep

Whitespace-only changes.

‎clang/test/Driver/Inputs/CUDA-windows/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v8.0/nvvm/libdevice/libdevice.compute_30.10.bc

Whitespace-only changes.

‎clang/test/Driver/Inputs/CUDA-windows/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v8.0/nvvm/libdevice/libdevice.compute_35.10.bc

Whitespace-only changes.

‎clang/test/Driver/cuda-windows.cu

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// REQUIRES: clang-driver
2+
// REQUIRES: x86-registered-target
3+
// REQUIRES: nvptx-registered-target
4+
//
5+
// RUN: %clang -v --target=i386-pc-windows-msvc \
6+
// RUN: --sysroot=%S/Inputs/CUDA-windows 2>&1 %s -### | FileCheck %s
7+
// RUN: %clang -v --target=i386-pc-windows-mingw32 \
8+
// RUN: --sysroot=%S/Inputs/CUDA-windows 2>&1 %s -### | FileCheck %s
9+
10+
// CHECK: Found CUDA installation: {{.*}}/Inputs/CUDA-windows/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v8.0
11+
// CHECK: "-cc1" "-triple" "nvptx-nvidia-cuda"
12+
// CHECK-SAME: "-fms-extensions"
13+
// CHECK-SAME: "-fms-compatibility"
14+
// CHECK-SAME: "-fms-compatibility-version=

0 commit comments

Comments
 (0)
Please sign in to comment.