[clang] [AMDGPU] Use the AMDGPUToolChain when targeting C/C++ directly (PR #99687)
Joseph Huber via cfe-commits
cfe-commits at lists.llvm.org
Fri Jul 19 13:33:52 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/2] [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 c867366e3c1733faee3bce8eb736d2061ff8717f 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/2] Refactor to use inputlist
---
clang/include/clang/Driver/Driver.h | 7 ++--
clang/lib/Driver/Driver.cpp | 62 +++++++++++++++++------------
2 files changed, 40 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..a776369397c20 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,7 @@ 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 +5591,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 +6354,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 +6422,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);
More information about the cfe-commits
mailing list