]> granicus.if.org Git - clang/commitdiff
[CUDA] added include paths for both sides of CUDA compilation.
authorArtem Belevich <tra@google.com>
Tue, 17 Nov 2015 22:28:46 +0000 (22:28 +0000)
committerArtem Belevich <tra@google.com>
Tue, 17 Nov 2015 22:28:46 +0000 (22:28 +0000)
In order to compile a CUDA file clang must be able to find
include files for both both host and device.

This patch passes AuxToolchain to AddPreprocessingOptions and
uses it to add include paths for the opposite side of compilation.

We also must be able to find CUDA include files. If the driver
found CUDA installation, it adds appropriate include path
to CUDA headers. This can be disabled with '-nocudainc'.

- Added include paths for the opposite side of compilation.
- Added include paths to detected CUDA installation.
- Added -nocudainc to prevent adding CUDA include path.
- Added test cases to verify new functionality.

Differential Revision: http://reviews.llvm.org/D13170

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@253386 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Driver/Options.td
include/clang/Driver/ToolChain.h
lib/Driver/ToolChain.cpp
lib/Driver/ToolChains.cpp
lib/Driver/ToolChains.h
lib/Driver/Tools.cpp
lib/Driver/Tools.h
test/Driver/cuda-detect.cu

index 4ebde1f7979b5451d7e1aae7f0408d30b2949e07..0e1d3035e42426bcb8e925a0fc866d5e0d4fad01 100644 (file)
@@ -1596,6 +1596,7 @@ def no_pedantic : Flag<["-", "--"], "no-pedantic">, Group<pedantic_Group>;
 def no__dead__strip__inits__and__terms : Flag<["-"], "no_dead_strip_inits_and_terms">;
 def nobuiltininc : Flag<["-"], "nobuiltininc">, Flags<[CC1Option]>,
   HelpText<"Disable builtin #include directories">;
+def nocudainc : Flag<["-"], "nocudainc">;
 def nodefaultlibs : Flag<["-"], "nodefaultlibs">;
 def nofixprebinding : Flag<["-"], "nofixprebinding">;
 def nolibc : Flag<["-"], "nolibc">;
index 7626af8fb423fa2efa5807aa2a60bcab1b2289c7..79fe149fec857bcebcaef858a9e60e60a78db887 100644 (file)
@@ -397,6 +397,10 @@ public:
   virtual void addProfileRTLibs(const llvm::opt::ArgList &Args,
                                 llvm::opt::ArgStringList &CmdArgs) const;
 
+  /// \brief Add arguments to use system-specific CUDA includes.
+  virtual void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs,
+                                  llvm::opt::ArgStringList &CC1Args) const;
+
   /// \brief Return sanitizers which are available in this toolchain.
   virtual SanitizerMask getSupportedSanitizers() const;
 };
index 221bed0bf118731b2401d7dd5fe0bacf6c4ce51a..80783bdcc4a2be60b7fa5b9d980dd466e1cdaf48 100644 (file)
@@ -662,3 +662,6 @@ SanitizerMask ToolChain::getSupportedSanitizers() const {
     Res |= CFIICall;
   return Res;
 }
+
+void ToolChain::AddCudaIncludeArgs(const ArgList &DriverArgs,
+                                   ArgStringList &CC1Args) const {}
index ed223219f65bebe045d17bca88c2b0265ddfd0ef..34504732a122d590af603aba75e7c88aaba627ee 100644 (file)
@@ -4104,6 +4104,15 @@ void Linux::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
   }
 }
 
+void Linux::AddCudaIncludeArgs(const ArgList &DriverArgs,
+                               ArgStringList &CC1Args) const {
+  if (DriverArgs.hasArg(options::OPT_nocudainc))
+    return;
+
+  if (CudaInstallation.isValid())
+    addSystemInclude(DriverArgs, CC1Args, CudaInstallation.getIncludePath());
+}
+
 bool Linux::isPIEDefault() const { return getSanitizerArgs().requiresPIE(); }
 
 SanitizerMask Linux::getSupportedSanitizers() const {
index 17e790ffd25ac64cdccf4cf272960aed498a0e17..b1b670feb85296cae270e5cc79959478a38f34e4 100644 (file)
@@ -784,6 +784,8 @@ public:
   void AddClangCXXStdlibIncludeArgs(
       const llvm::opt::ArgList &DriverArgs,
       llvm::opt::ArgStringList &CC1Args) const override;
+  void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs,
+                          llvm::opt::ArgStringList &CC1Args) const override;
   bool isPIEDefault() const override;
   SanitizerMask getSupportedSanitizers() const override;
   void addProfileRTLibs(const llvm::opt::ArgList &Args,
index 3c593fc66b87f7a465b66fa280f63cbe98d59e6d..5df8efafd5a7905b5e54d1cef2684d296d0985d9 100644 (file)
@@ -278,7 +278,8 @@ void Clang::AddPreprocessingOptions(Compilation &C, const JobAction &JA,
                                     const Driver &D, const ArgList &Args,
                                     ArgStringList &CmdArgs,
                                     const InputInfo &Output,
-                                    const InputInfoList &Inputs) const {
+                                    const InputInfoList &Inputs,
+                                    const ToolChain *AuxToolChain) const {
   Arg *A;
 
   CheckPreprocessingOptions(D, Args);
@@ -470,12 +471,26 @@ void Clang::AddPreprocessingOptions(Compilation &C, const JobAction &JA,
   // OBJCPLUS_INCLUDE_PATH - system includes enabled when compiling ObjC++.
   addDirectoryList(Args, CmdArgs, "-objcxx-isystem", "OBJCPLUS_INCLUDE_PATH");
 
+  // Optional AuxToolChain indicates that we need to include headers
+  // for more than one target. If that's the case, add include paths
+  // from AuxToolChain right after include paths of the same kind for
+  // the current target.
+
   // Add C++ include arguments, if needed.
-  if (types::isCXX(Inputs[0].getType()))
+  if (types::isCXX(Inputs[0].getType())) {
     getToolChain().AddClangCXXStdlibIncludeArgs(Args, CmdArgs);
+    if (AuxToolChain)
+      AuxToolChain->AddClangCXXStdlibIncludeArgs(Args, CmdArgs);
+  }
 
   // Add system include arguments.
   getToolChain().AddClangSystemIncludeArgs(Args, CmdArgs);
+  if (AuxToolChain)
+      AuxToolChain->AddClangCXXStdlibIncludeArgs(Args, CmdArgs);
+
+  // Add CUDA include arguments, if needed.
+  if (types::isCuda(Inputs[0].getType()))
+    getToolChain().AddCudaIncludeArgs(Args, CmdArgs);
 }
 
 // FIXME: Move to target hook.
@@ -3262,12 +3277,12 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
   CmdArgs.push_back("-triple");
   CmdArgs.push_back(Args.MakeArgString(TripleStr));
 
+  const ToolChain *AuxToolChain = nullptr;
   if (IsCuda) {
     // FIXME: We need a (better) way to pass information about
     // particular compilation pass we're constructing here. For now we
     // can check which toolchain we're using and pick the other one to
     // extract the triple.
-    const ToolChain *AuxToolChain;
     if (&getToolChain() == C.getCudaDeviceToolChain())
       AuxToolChain = C.getCudaHostToolChain();
     else if (&getToolChain() == C.getCudaHostToolChain())
@@ -4085,7 +4100,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
   //
   // FIXME: Support -fpreprocessed
   if (types::getPreprocessedType(InputType) != types::TY_INVALID)
-    AddPreprocessingOptions(C, JA, D, Args, CmdArgs, Output, Inputs);
+    AddPreprocessingOptions(C, JA, D, Args, CmdArgs, Output, Inputs,
+                            AuxToolChain);
 
   // Don't warn about "clang -c -DPIC -fPIC test.i" because libtool.m4 assumes
   // that "The compiler can only warn and ignore the option if not recognized".
index 7a7c642e3560dabc0d980108358bf2392479daf2..95c2063695ccab1d81d9da25e4a1d81dd3e90090 100644 (file)
@@ -57,7 +57,8 @@ private:
                                const Driver &D, const llvm::opt::ArgList &Args,
                                llvm::opt::ArgStringList &CmdArgs,
                                const InputInfo &Output,
-                               const InputInfoList &Inputs) const;
+                               const InputInfoList &Inputs,
+                               const ToolChain *AuxToolChain) const;
 
   void AddAArch64TargetArgs(const llvm::opt::ArgList &Args,
                             llvm::opt::ArgStringList &CmdArgs) const;
index 31e8494027a61622ad5a2234498480ccccd6d8cb..182e379df5bc1d015528bf141e5d54bf780bcf2f 100644 (file)
@@ -1,10 +1,34 @@
 // REQUIRES: clang-driver
 // REQUIRES: x86-registered-target
+// REQUIRES: nvptx-registered-target
 //
+// # Check that we properly detect CUDA installation.
 // RUN: %clang -v --target=i386-unknown-linux \
-// RUN:   --sysroot=/tmp/no-cuda-there 2>&1 | FileCheck %s -check-prefix NOCUDA
+// RUN:   --sysroot=%S/no-cuda-there 2>&1 | FileCheck %s -check-prefix NOCUDA
+// RUN: %clang -v --target=i386-unknown-linux \
+// RUN:   --sysroot=%S/Inputs/CUDA 2>&1 | FileCheck %s
 // RUN: %clang -v --target=i386-unknown-linux \
 // RUN:   --cuda-path=%S/Inputs/CUDA/usr/local/cuda 2>&1 | FileCheck %s
 
+// Verify that CUDA include path gets added
+// RUN: %clang -### -v --target=i386-unknown-linux --cuda-gpu-arch=sm_35 \
+// RUN:   --cuda-path=%S/Inputs/CUDA/usr/local/cuda %s 2>&1 \
+// RUN:   | FileCheck %s -check-prefix COMMON -check-prefix CUDAINC
+// Verify that -nocudainc disables CUDA include paths.
+// RUN: %clang -### -v --target=i386-unknown-linux --cuda-gpu-arch=sm_35 \
+// RUN:   -nocudainc --cuda-path=%S/Inputs/CUDA/usr/local/cuda %s 2>&1 \
+// RUN:   | FileCheck %s -check-prefix COMMON -check-prefix NOCUDAINC
+// We should not add any CUDA include paths if there's no valid CUDA installation
+// RUN: %clang -### -v --target=i386-unknown-linux --cuda-gpu-arch=sm_35 \
+// RUN:   --cuda-path=%S/no-cuda-there %s 2>&1 \
+// RUN:   | FileCheck %s -check-prefix COMMON -check-prefix NOCUDAINC
+
 // CHECK: Found CUDA installation: {{.*}}/Inputs/CUDA/usr/local/cuda
 // NOCUDA-NOT: Found CUDA installation:
+
+// COMMON: "-triple" "nvptx-nvidia-cuda"
+// COMMON-SAME: "-fcuda-is-device"
+// CUDAINC-SAME: "-internal-isystem" "{{.*}}/Inputs/CUDA/usr/local/cuda/include"
+// NOCUDAINC-NOT: "-internal-isystem" "{{.*}}/cuda/include"
+// COMMON-SAME: "-x" "cuda"
+