[llvm-branch-commits] [clang] [NFCI][clang] Allow overriding any global variable address space (PR #195612)
Pierre van Houtryve via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Fri Jun 12 04:05:42 PDT 2026
https://github.com/Pierre-vh updated https://github.com/llvm/llvm-project/pull/195612
>From 56e520c9d239eb3d007610c8e9faebced1f767d3 Mon Sep 17 00:00:00 2001
From: pvanhout <pierre.vanhoutryve at amd.com>
Date: Mon, 20 Apr 2026 14:14:16 +0200
Subject: [PATCH] [NFCI][clang] Allow overriding any global variable address
space
Allow the target to change the AS of a global variable at will, not just whenever Clang cannot assign one.
This enables the next patch that will specialize LDS GVs for barriers as a separate address space.
---
clang/lib/CodeGen/CodeGenModule.cpp | 13 +++++++++++--
clang/lib/CodeGen/TargetInfo.cpp | 11 +++++------
clang/lib/CodeGen/TargetInfo.h | 18 ++++++++++++------
clang/lib/CodeGen/Targets/AMDGPU.cpp | 19 ++++++++++---------
clang/lib/CodeGen/Targets/AVR.cpp | 9 ++++++---
clang/lib/CodeGen/Targets/SPIR.cpp | 15 +++++++--------
6 files changed, 51 insertions(+), 34 deletions(-)
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 41049d85121be..627fc1f18e526 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -6140,7 +6140,9 @@ CharUnits CodeGenModule::GetTargetTypeStoreSize(llvm::Type *Ty) const {
getDataLayout().getTypeStoreSizeInBits(Ty));
}
-LangAS CodeGenModule::GetGlobalVarAddressSpace(const VarDecl *D) {
+static std::optional<LangAS>
+getGlobalVarDefaultAddressSpace(const VarDecl *D, const LangOptions &LangOpts,
+ CGOpenMPRuntime *OpenMPRuntime) {
if (LangOpts.OpenCL) {
LangAS AS = D ? D->getType().getAddressSpace() : LangAS::opencl_global;
assert(AS == LangAS::opencl_global ||
@@ -6175,7 +6177,14 @@ LangAS CodeGenModule::GetGlobalVarAddressSpace(const VarDecl *D) {
if (OpenMPRuntime->hasAllocateAttributeForGlobalVar(D, AS))
return AS;
}
- return getTargetCodeGenInfo().getGlobalVarAddressSpace(*this, D);
+
+ return std::nullopt;
+}
+
+LangAS CodeGenModule::GetGlobalVarAddressSpace(const VarDecl *D) {
+ std::optional<LangAS> AS =
+ getGlobalVarDefaultAddressSpace(D, LangOpts, OpenMPRuntime.get());
+ return getTargetCodeGenInfo().adjustGlobalVarAddressSpace(*this, D, AS);
}
LangAS CodeGenModule::GetGlobalConstantAddressSpace() const {
diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp
index 641caf6d5cd4b..cffdaf8948934 100644
--- a/clang/lib/CodeGen/TargetInfo.cpp
+++ b/clang/lib/CodeGen/TargetInfo.cpp
@@ -136,12 +136,11 @@ llvm::Constant *TargetCodeGenInfo::getNullPointer(const CodeGen::CodeGenModule &
return llvm::ConstantPointerNull::get(T);
}
-LangAS TargetCodeGenInfo::getGlobalVarAddressSpace(CodeGenModule &CGM,
- const VarDecl *D) const {
- assert(!CGM.getLangOpts().OpenCL &&
- !(CGM.getLangOpts().CUDA && CGM.getLangOpts().CUDAIsDevice) &&
- "Address space agnostic languages only");
- return D ? D->getType().getAddressSpace() : LangAS::Default;
+LangAS TargetCodeGenInfo::adjustGlobalVarAddressSpace(
+ CodeGenModule &CGM, const VarDecl *D, std::optional<LangAS> AS) const {
+ if (!AS)
+ return D ? D->getType().getAddressSpace() : LangAS::Default;
+ return *AS;
}
StringRef
diff --git a/clang/lib/CodeGen/TargetInfo.h b/clang/lib/CodeGen/TargetInfo.h
index 9405cf0124b29..5e32a7f8c176a 100644
--- a/clang/lib/CodeGen/TargetInfo.h
+++ b/clang/lib/CodeGen/TargetInfo.h
@@ -312,12 +312,18 @@ class TargetCodeGenInfo {
virtual llvm::Constant *getNullPointer(const CodeGen::CodeGenModule &CGM,
llvm::PointerType *T, QualType QT) const;
- /// Get target favored AST address space of a global variable for languages
- /// other than OpenCL and CUDA.
- /// If \p D is nullptr, returns the default target favored address space
- /// for global variable.
- virtual LangAS getGlobalVarAddressSpace(CodeGenModule &CGM,
- const VarDecl *D) const;
+ /// Adjust the address space proposed by the code generator for \p D.
+ /// If \p AS is empty, it means language semantics did not specify any address
+ /// space for this \p D.
+ ///
+ /// Can be used by targets to further refine the chosen address space for a
+ /// declaration.
+ virtual LangAS adjustGlobalVarAddressSpace(CodeGenModule &CGM,
+ const VarDecl *D,
+ std::optional<LangAS> AS) const;
+
+ /// Get the AST address space for alloca.
+ virtual LangAS getASTAllocaAddressSpace() const { return LangAS::Default; }
/// Get the address space for an indirect (sret) return of the given type.
/// The default falls back to the alloca AS.
diff --git a/clang/lib/CodeGen/Targets/AMDGPU.cpp b/clang/lib/CodeGen/Targets/AMDGPU.cpp
index a3a596bb9d822..5a65d23ec4938 100644
--- a/clang/lib/CodeGen/Targets/AMDGPU.cpp
+++ b/clang/lib/CodeGen/Targets/AMDGPU.cpp
@@ -307,8 +307,8 @@ class AMDGPUTargetCodeGenInfo : public TargetCodeGenInfo {
LangAS getSRetAddrSpace(const CXXRecordDecl *RD) const override;
- LangAS getGlobalVarAddressSpace(CodeGenModule &CGM,
- const VarDecl *D) const override;
+ LangAS adjustGlobalVarAddressSpace(CodeGenModule &CGM, const VarDecl *D,
+ std::optional<LangAS> AS) const override;
StringRef getLLVMSyncScopeStr(const LangOptions &LangOpts, SyncScope Scope,
llvm::AtomicOrdering Ordering) const override;
void setTargetAtomicMetadata(CodeGenFunction &CGF,
@@ -476,20 +476,20 @@ AMDGPUTargetCodeGenInfo::getSRetAddrSpace(const CXXRecordDecl *RD) const {
getABIInfo().getDataLayout().getAllocaAddrSpace());
}
-LangAS
-AMDGPUTargetCodeGenInfo::getGlobalVarAddressSpace(CodeGenModule &CGM,
- const VarDecl *D) const {
- assert(!CGM.getLangOpts().OpenCL &&
- !(CGM.getLangOpts().CUDA && CGM.getLangOpts().CUDAIsDevice) &&
- "Address space agnostic languages only");
+LangAS AMDGPUTargetCodeGenInfo::adjustGlobalVarAddressSpace(
+ CodeGenModule &CGM, const VarDecl *D, std::optional<LangAS> AS) const {
+ if (AS)
+ return *AS;
+
LangAS DefaultGlobalAS = getLangASFromTargetAS(
CGM.getContext().getTargetAddressSpace(LangAS::opencl_global));
if (!D)
return DefaultGlobalAS;
LangAS AddrSpace = D->getType().getAddressSpace();
- if (AddrSpace != LangAS::Default)
+ if (AddrSpace != LangAS::Default) {
return AddrSpace;
+ }
// Only promote to address space 4 if VarDecl has constant initialization.
if (D->getType().isConstantStorage(CGM.getContext(), false, false) &&
@@ -497,6 +497,7 @@ AMDGPUTargetCodeGenInfo::getGlobalVarAddressSpace(CodeGenModule &CGM,
if (auto ConstAS = CGM.getTarget().getConstantAddressSpace())
return *ConstAS;
}
+
return DefaultGlobalAS;
}
diff --git a/clang/lib/CodeGen/Targets/AVR.cpp b/clang/lib/CodeGen/Targets/AVR.cpp
index 5399d12f7ce80..a9643d7eea438 100644
--- a/clang/lib/CodeGen/Targets/AVR.cpp
+++ b/clang/lib/CodeGen/Targets/AVR.cpp
@@ -114,8 +114,11 @@ class AVRTargetCodeGenInfo : public TargetCodeGenInfo {
AVRTargetCodeGenInfo(CodeGenTypes &CGT, unsigned NPR, unsigned NRR)
: TargetCodeGenInfo(std::make_unique<AVRABIInfo>(CGT, NPR, NRR)) {}
- LangAS getGlobalVarAddressSpace(CodeGenModule &CGM,
- const VarDecl *D) const override {
+ LangAS adjustGlobalVarAddressSpace(CodeGenModule &CGM, const VarDecl *D,
+ std::optional<LangAS> AS) const override {
+ if (AS)
+ return *AS;
+
// Check if global/static variable is defined in address space
// 1~6 (__flash, __flash1, __flash2, __flash3, __flash4, __flash5)
// but not constant.
@@ -127,7 +130,7 @@ class AVRTargetCodeGenInfo : public TargetCodeGenInfo {
diag::err_verify_nonconst_addrspace)
<< "__flash*";
}
- return TargetCodeGenInfo::getGlobalVarAddressSpace(CGM, D);
+ return TargetCodeGenInfo::adjustGlobalVarAddressSpace(CGM, D, std::nullopt);
}
void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
diff --git a/clang/lib/CodeGen/Targets/SPIR.cpp b/clang/lib/CodeGen/Targets/SPIR.cpp
index 0a96d612c8a87..3da8c377e635a 100644
--- a/clang/lib/CodeGen/Targets/SPIR.cpp
+++ b/clang/lib/CodeGen/Targets/SPIR.cpp
@@ -127,8 +127,8 @@ class SPIRVTargetCodeGenInfo : public CommonSPIRTargetCodeGenInfo {
? std::make_unique<AMDGCNSPIRVABIInfo>(CGT)
: std::make_unique<SPIRVABIInfo>(CGT)) {}
void setCUDAKernelCallingConvention(const FunctionType *&FT) const override;
- LangAS getGlobalVarAddressSpace(CodeGenModule &CGM,
- const VarDecl *D) const override;
+ LangAS adjustGlobalVarAddressSpace(CodeGenModule &CGM, const VarDecl *D,
+ std::optional<LangAS> AS) const override;
void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
CodeGen::CodeGenModule &M) const override;
StringRef getLLVMSyncScopeStr(const LangOptions &LangOpts, SyncScope Scope,
@@ -500,12 +500,11 @@ CommonSPIRTargetCodeGenInfo::getNullPointer(const CodeGen::CodeGenModule &CGM,
llvm::ConstantPointerNull::get(NPT), PT);
}
-LangAS
-SPIRVTargetCodeGenInfo::getGlobalVarAddressSpace(CodeGenModule &CGM,
- const VarDecl *D) const {
- assert(!CGM.getLangOpts().OpenCL &&
- !(CGM.getLangOpts().CUDA && CGM.getLangOpts().CUDAIsDevice) &&
- "Address space agnostic languages only");
+LangAS SPIRVTargetCodeGenInfo::adjustGlobalVarAddressSpace(
+ CodeGenModule &CGM, const VarDecl *D, std::optional<LangAS> AS) const {
+ if (AS)
+ return *AS;
+
// If we're here it means that we're using the SPIRDefIsGen ASMap, hence for
// the global AS we can rely on either cuda_device or sycl_global to be
// correct; however, since this is not a CUDA Device context, we use
More information about the llvm-branch-commits
mailing list