[clang] [AMDGPU] Use the AMDGPUToolChain when targeting C/C++ directly (PR #99687)

Joseph Huber via cfe-commits cfe-commits at lists.llvm.org
Mon Jul 29 05:15:18 PDT 2024


https://github.com/jhuber6 updated https://github.com/llvm/llvm-project/pull/99687

>From 59901100a2c11d37947938dfb9db5dd1164cbbf5 Mon Sep 17 00:00:00 2001
From: Joseph Huber <huberjn at outlook.com>
Date: Fri, 19 Jul 2024 14:07:18 -0500
Subject: [PATCH 1/4] [AMDGPU] Use the AMDGPUToolChain when targeting C/C++
 directly

Summary:
The `getToolChain` pass uses the triple to determine which toolchain to
create. Currently the `amdgcn-amd-amdhsa` triple maps to the
`ROCmToolChain` which uses things expected to be provided by `ROCm`.
This is neded for OpenCL, but directly targeting C++ does not want this
since it's primarily being used for creating GPU runtime code. As far as
I know I'm the only user of this, so this shouldn't change anything.

Unfortunately, there's no good logic for detercting this, so I simply
checked ahead of time if the input is either `foo.cl` or `-x cl foo.c`
to choose between the two. This allows us to use the AMDGPU target
normally, as otherwise it will error without passing `-nogpulib`.
---
 clang/lib/Driver/Driver.cpp          | 17 +++++++++++++++--
 clang/test/Driver/amdgpu-toolchain.c |  3 +++
 2 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 8e44d5afa40e0..8e28097dbf1a1 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -6404,9 +6404,22 @@ const ToolChain &Driver::getToolChain(const ArgList &Args,
     case llvm::Triple::CUDA:
       TC = std::make_unique<toolchains::NVPTXToolChain>(*this, Target, Args);
       break;
-    case llvm::Triple::AMDHSA:
-      TC = std::make_unique<toolchains::ROCMToolChain>(*this, Target, Args);
+    case llvm::Triple::AMDHSA: {
+      bool IsOpenCL =
+          Target.getEnvironment() == llvm::Triple::EnvironmentType::OpenCL ||
+          llvm::any_of(Args.filtered(options::OPT_INPUT, options::OPT_x),
+                       [](auto &Arg) {
+                         if (Arg->getOption().matches(options::OPT_INPUT))
+                           return StringRef(Arg->getValue()).ends_with(".cl");
+                         return StringRef(Arg->getValue()).ends_with("cl");
+                       });
+      TC =
+          IsOpenCL
+              ? std::make_unique<toolchains::ROCMToolChain>(*this, Target, Args)
+              : std::make_unique<toolchains::AMDGPUToolChain>(*this, Target,
+                                                              Args);
       break;
+    }
     case llvm::Triple::AMDPAL:
     case llvm::Triple::Mesa3D:
       TC = std::make_unique<toolchains::AMDGPUToolChain>(*this, Target, Args);
diff --git a/clang/test/Driver/amdgpu-toolchain.c b/clang/test/Driver/amdgpu-toolchain.c
index 8ab6a07131474..d12f4fe903f87 100644
--- a/clang/test/Driver/amdgpu-toolchain.c
+++ b/clang/test/Driver/amdgpu-toolchain.c
@@ -28,3 +28,6 @@
 // RUN: %clang -### --target=amdgcn-amd-amdhsa -mcpu=gfx906 -nogpulib \
 // RUN:   -fuse-ld=ld %s 2>&1 | FileCheck -check-prefixes=LD %s
 // LD: ld.lld
+
+// RUN: %clang -### --target=amdgcn-amd-amdhsa -mcpu=gfx906 %s 2>&1 | FileCheck -check-prefix=ROCM %s
+// ROCM-NOT: -mlink-builtin-bitcode

>From 51a4697f60d0d42404f0ee9405d25e1c24b43208 Mon Sep 17 00:00:00 2001
From: Joseph Huber <huberjn at outlook.com>
Date: Fri, 19 Jul 2024 15:33:41 -0500
Subject: [PATCH 2/4] Refactor to use inputlist

---
 clang/include/clang/Driver/Driver.h |  7 ++--
 clang/lib/Driver/Driver.cpp         | 63 +++++++++++++++++------------
 2 files changed, 41 insertions(+), 29 deletions(-)

diff --git a/clang/include/clang/Driver/Driver.h b/clang/include/clang/Driver/Driver.h
index 04b46782467d6..e2c713a12567e 100644
--- a/clang/include/clang/Driver/Driver.h
+++ b/clang/include/clang/Driver/Driver.h
@@ -469,11 +469,11 @@ class Driver {
   /// BuildInputs - Construct the list of inputs and their types from
   /// the given arguments.
   ///
-  /// \param TC - The default host tool chain.
+  /// \param TT - The target triple.
   /// \param Args - The input arguments.
   /// \param Inputs - The list to store the resulting compilation
   /// inputs onto.
-  void BuildInputs(const ToolChain &TC, llvm::opt::DerivedArgList &Args,
+  void BuildInputs(const llvm::Triple &TT, llvm::opt::DerivedArgList &Args,
                    InputList &Inputs) const;
 
   /// BuildActions - Construct the list of actions to perform for the
@@ -757,7 +757,8 @@ class Driver {
   /// Will cache ToolChains for the life of the driver object, and create them
   /// on-demand.
   const ToolChain &getToolChain(const llvm::opt::ArgList &Args,
-                                const llvm::Triple &Target) const;
+                                const llvm::Triple &Target,
+                                const InputList &Inputs) const;
 
   /// @}
 
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 8e28097dbf1a1..0cd201b2bc444 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -965,7 +965,7 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C,
 
           TC = DeviceTC.get();
         } else
-          TC = &getToolChain(C.getInputArgs(), TT);
+          TC = &getToolChain(C.getInputArgs(), TT, Inputs);
         C.addOffloadDeviceToolChain(TC, Action::OFK_OpenMP);
         if (DerivedArchs.contains(TT.getTriple()))
           KnownArchs[TC] = DerivedArchs[TT.getTriple()];
@@ -1455,12 +1455,17 @@ Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) {
   std::unique_ptr<llvm::opt::InputArgList> UArgs =
       std::make_unique<InputArgList>(std::move(Args));
 
+  llvm::Triple TT = computeTargetTriple(*this, TargetTriple, *UArgs);
+
   // Perform the default argument translations.
   DerivedArgList *TranslatedArgs = TranslateInputArgs(*UArgs);
 
+  // Construct the list of inputs.
+  InputList Inputs;
+  BuildInputs(TT, *TranslatedArgs, Inputs);
+
   // Owned by the host.
-  const ToolChain &TC = getToolChain(
-      *UArgs, computeTargetTriple(*this, TargetTriple, *UArgs));
+  const ToolChain &TC = getToolChain(*UArgs, TT, Inputs);
 
   // Check if the environment version is valid except wasm case.
   llvm::Triple Triple = TC.getTriple();
@@ -1521,10 +1526,6 @@ Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) {
   if (!HandleImmediateArgs(*C))
     return C;
 
-  // Construct the list of inputs.
-  InputList Inputs;
-  BuildInputs(C->getDefaultToolChain(), *TranslatedArgs, Inputs);
-
   // Populate the tool chains for the offloading devices, if any.
   CreateOffloadingDeviceToolChains(*C, Inputs);
 
@@ -1738,7 +1739,7 @@ void Driver::generateCompilationDiagnostics(
 
   // Construct the list of inputs.
   InputList Inputs;
-  BuildInputs(C.getDefaultToolChain(), C.getArgs(), Inputs);
+  BuildInputs(C.getDefaultToolChain().getTriple(), C.getArgs(), Inputs);
 
   for (InputList::iterator it = Inputs.begin(), ie = Inputs.end(); it != ie;) {
     bool IgnoreInput = false;
@@ -2630,8 +2631,24 @@ static types::ID CXXHeaderUnitType(ModuleHeaderMode HM) {
   return types::TY_CXXHUHeader;
 }
 
+static types::ID lookupTypeForExtension(const Driver &D, const llvm::Triple &TT,
+                                        llvm::StringRef Ext) {
+  types::ID Ty = types::lookupTypeForExtension(Ext);
+
+  // Flang always runs the preprocessor and has no notion of "preprocessed
+  // fortran". Here, TY_PP_Fortran is coerced to TY_Fortran to avoid treating
+  // them differently.
+  if (D.IsFlangMode() && Ty == types::TY_PP_Fortran)
+    Ty = types::TY_Fortran;
+
+  // Darwin always preprocesses assembly files (unless -x is used explicitly).
+  if (TT.isOSBinFormatMachO() && Ty == types::TY_PP_Asm)
+    Ty = types::TY_Asm;
+  return Ty;
+}
+
 // Construct a the list of inputs and their types.
-void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args,
+void Driver::BuildInputs(const llvm::Triple &TT, DerivedArgList &Args,
                          InputList &Inputs) const {
   const llvm::opt::OptTable &Opts = getOpts();
   // Track the current user specified (-x) input. We also explicitly track the
@@ -2709,7 +2726,7 @@ void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args,
           // We use a host hook here because Darwin at least has its own
           // idea of what .s is.
           if (const char *Ext = strrchr(Value, '.'))
-            Ty = TC.LookupTypeForExtension(Ext + 1);
+            Ty = lookupTypeForExtension(*this, TT, Ext + 1);
 
           if (Ty == types::TY_INVALID) {
             if (IsCLMode() && (Args.hasArgNoClaim(options::OPT_E) || CCGenDiagnostics))
@@ -2765,7 +2782,8 @@ void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args,
           // If emulating cl.exe, make sure that /TC and /TP don't affect input
           // object files.
           const char *Ext = strrchr(Value, '.');
-          if (Ext && TC.LookupTypeForExtension(Ext + 1) == types::TY_Object)
+          if (Ext &&
+              lookupTypeForExtension(*this, TT, Ext + 1) == types::TY_Object)
             Ty = types::TY_Object;
         }
         if (Ty == types::TY_INVALID) {
@@ -5574,9 +5592,9 @@ InputInfoList Driver::BuildJobsForActionNoCache(
     StringRef ArchName = BAA->getArchName();
 
     if (!ArchName.empty())
-      TC = &getToolChain(C.getArgs(),
-                         computeTargetTriple(*this, TargetTriple,
-                                             C.getArgs(), ArchName));
+      TC = &getToolChain(
+          C.getArgs(),
+          computeTargetTriple(*this, TargetTriple, C.getArgs(), ArchName), {});
     else
       TC = &C.getDefaultToolChain();
 
@@ -6337,7 +6355,8 @@ std::string Driver::GetClPchPath(Compilation &C, StringRef BaseName) const {
 }
 
 const ToolChain &Driver::getToolChain(const ArgList &Args,
-                                      const llvm::Triple &Target) const {
+                                      const llvm::Triple &Target,
+                                      const InputList &Inputs) const {
 
   auto &TC = ToolChains[Target.str()];
   if (!TC) {
@@ -6404,22 +6423,14 @@ const ToolChain &Driver::getToolChain(const ArgList &Args,
     case llvm::Triple::CUDA:
       TC = std::make_unique<toolchains::NVPTXToolChain>(*this, Target, Args);
       break;
-    case llvm::Triple::AMDHSA: {
-      bool IsOpenCL =
-          Target.getEnvironment() == llvm::Triple::EnvironmentType::OpenCL ||
-          llvm::any_of(Args.filtered(options::OPT_INPUT, options::OPT_x),
-                       [](auto &Arg) {
-                         if (Arg->getOption().matches(options::OPT_INPUT))
-                           return StringRef(Arg->getValue()).ends_with(".cl");
-                         return StringRef(Arg->getValue()).ends_with("cl");
-                       });
+    case llvm::Triple::AMDHSA:
       TC =
-          IsOpenCL
+          llvm::any_of(Inputs,
+                       [](auto &Input) { return types::isOpenCL(Input.first); })
               ? std::make_unique<toolchains::ROCMToolChain>(*this, Target, Args)
               : std::make_unique<toolchains::AMDGPUToolChain>(*this, Target,
                                                               Args);
       break;
-    }
     case llvm::Triple::AMDPAL:
     case llvm::Triple::Mesa3D:
       TC = std::make_unique<toolchains::AMDGPUToolChain>(*this, Target, Args);

>From c3b3891c7cfb955a1d0fb8313c6fafe82556cc20 Mon Sep 17 00:00:00 2001
From: Joseph Huber <huberjn at outlook.com>
Date: Fri, 19 Jul 2024 15:43:19 -0500
Subject: [PATCH 3/4] delete old

---
 clang/include/clang/Driver/ToolChain.h |  4 ----
 clang/lib/Driver/ToolChain.cpp         | 12 ------------
 clang/lib/Driver/ToolChains/Darwin.cpp | 10 ----------
 clang/lib/Driver/ToolChains/Darwin.h   |  2 --
 4 files changed, 28 deletions(-)

diff --git a/clang/include/clang/Driver/ToolChain.h b/clang/include/clang/Driver/ToolChain.h
index ece1384d5d3c0..8f8cfc192114c 100644
--- a/clang/include/clang/Driver/ToolChain.h
+++ b/clang/include/clang/Driver/ToolChain.h
@@ -423,10 +423,6 @@ class ToolChain {
   /// native LLVM support.
   virtual bool HasNativeLLVMSupport() const;
 
-  /// LookupTypeForExtension - Return the default language type to use for the
-  /// given extension.
-  virtual types::ID LookupTypeForExtension(StringRef Ext) const;
-
   /// IsBlocksDefault - Does this tool chain enable -fblocks by default.
   virtual bool IsBlocksDefault() const { return false; }
 
diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp
index 85ae4d2a26fee..8e6e614d9a78b 100644
--- a/clang/lib/Driver/ToolChain.cpp
+++ b/clang/lib/Driver/ToolChain.cpp
@@ -954,18 +954,6 @@ std::string ToolChain::GetStaticLibToolPath() const {
   return GetProgramPath("llvm-ar");
 }
 
-types::ID ToolChain::LookupTypeForExtension(StringRef Ext) const {
-  types::ID id = types::lookupTypeForExtension(Ext);
-
-  // Flang always runs the preprocessor and has no notion of "preprocessed
-  // fortran". Here, TY_PP_Fortran is coerced to TY_Fortran to avoid treating
-  // them differently.
-  if (D.IsFlangMode() && id == types::TY_PP_Fortran)
-    id = types::TY_Fortran;
-
-  return id;
-}
-
 bool ToolChain::HasNativeLLVMSupport() const {
   return false;
 }
diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp
index c6f9d7beffb1d..de5341e4b94ed 100644
--- a/clang/lib/Driver/ToolChains/Darwin.cpp
+++ b/clang/lib/Driver/ToolChains/Darwin.cpp
@@ -933,16 +933,6 @@ Darwin::Darwin(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
     : MachO(D, Triple, Args), TargetInitialized(false),
       CudaInstallation(D, Triple, Args), RocmInstallation(D, Triple, Args) {}
 
-types::ID MachO::LookupTypeForExtension(StringRef Ext) const {
-  types::ID Ty = ToolChain::LookupTypeForExtension(Ext);
-
-  // Darwin always preprocesses assembly files (unless -x is used explicitly).
-  if (Ty == types::TY_PP_Asm)
-    return types::TY_Asm;
-
-  return Ty;
-}
-
 bool MachO::HasNativeLLVMSupport() const { return true; }
 
 ToolChain::CXXStdlibType Darwin::GetDefaultCXXStdlibType() const {
diff --git a/clang/lib/Driver/ToolChains/Darwin.h b/clang/lib/Driver/ToolChains/Darwin.h
index 2e55b49682a7e..209ca5f7273c8 100644
--- a/clang/lib/Driver/ToolChains/Darwin.h
+++ b/clang/lib/Driver/ToolChains/Darwin.h
@@ -234,8 +234,6 @@ class LLVM_LIBRARY_VISIBILITY MachO : public ToolChain {
   /// @name ToolChain Implementation
   /// {
 
-  types::ID LookupTypeForExtension(StringRef Ext) const override;
-
   bool HasNativeLLVMSupport() const override;
 
   llvm::opt::DerivedArgList *

>From 76a617d599f108d87699215236f0bbf55c8da2a7 Mon Sep 17 00:00:00 2001
From: Joseph Huber <huberjn at outlook.com>
Date: Mon, 29 Jul 2024 07:15:08 -0500
Subject: [PATCH 4/4] Update clang/test/Driver/amdgpu-toolchain.c

---
 clang/test/Driver/amdgpu-toolchain.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/test/Driver/amdgpu-toolchain.c b/clang/test/Driver/amdgpu-toolchain.c
index 366f4b7d7e850..edddca26e2488 100644
--- a/clang/test/Driver/amdgpu-toolchain.c
+++ b/clang/test/Driver/amdgpu-toolchain.c
@@ -34,4 +34,4 @@
 
 // RUN: %clang -### --target=amdgcn-amd-amdhsa -mcpu=gfx906 -nogpulib \
 // RUN:   -r %s 2>&1 | FileCheck -check-prefixes=RELO %s
-// RELO-NOT: -shared
\ No newline at end of file
+// RELO-NOT: -shared



More information about the cfe-commits mailing list