https://github.com/Pierre-vh updated https://github.com/llvm/llvm-project/pull/195612
>From 276a3ad76713cb9343cde88e81e7c3978329d4f4 Mon Sep 17 00:00:00 2001 From: pvanhout <[email protected]> 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 236738e9975d3..2319b2139f224 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -6114,7 +6114,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 || @@ -6149,7 +6151,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 89ea27b748aa9..df7a7899b0fc5 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 0d36f166328c7..04cd41d80e6b9 100644 --- a/clang/lib/CodeGen/Targets/AMDGPU.cpp +++ b/clang/lib/CodeGen/Targets/AMDGPU.cpp @@ -380,8 +380,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, @@ -549,20 +549,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) && @@ -570,6 +570,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 _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
