https://github.com/arsenm updated https://github.com/llvm/llvm-project/pull/212207
>From 74c1dcc89079c78b235106c77ca9acbb3d8a7923 Mon Sep 17 00:00:00 2001 From: Matt Arsenault <[email protected]> Date: Fri, 26 Jun 2026 12:50:09 +0200 Subject: [PATCH] AMDGPU: Start using subarch in attributor instead of subtarget Avoid querying the subtarget for functions when the relevant properties are known from the triple. The various subtarget group size functions should also be decoupled from the subtarget, but those are trickier to untangle. Co-authored-by: Claude (Opus 4.8) <[email protected]> --- .../llvm/TargetParser/AMDGPUTargetParser.h | 16 ++++++- llvm/lib/Target/AMDGPU/AMDGPUAttributor.cpp | 44 +++++++++++-------- llvm/lib/Target/AMDGPU/AMDGPUTargetParser.td | 2 + llvm/lib/Target/AMDGPU/GCNProcessors.td | 18 ++++---- llvm/lib/TargetParser/AMDGPUTargetParser.cpp | 10 +++++ 5 files changed, 62 insertions(+), 28 deletions(-) diff --git a/llvm/include/llvm/TargetParser/AMDGPUTargetParser.h b/llvm/include/llvm/TargetParser/AMDGPUTargetParser.h index f8e283db55fec..8de830d01b1e4 100644 --- a/llvm/include/llvm/TargetParser/AMDGPUTargetParser.h +++ b/llvm/include/llvm/TargetParser/AMDGPUTargetParser.h @@ -98,7 +98,13 @@ enum ArchFeatureKind : uint32_t { FEATURE_XNACK_ON_OFF_MODES = 1 << 6, // VI SGPR initialization bug requiring a fixed SGPR allocation size. - FEATURE_SGPR_INIT_BUG = 1 << 7 + FEATURE_SGPR_INIT_BUG = 1 << 7, + + // Clusters are supported. + FEATURE_CLUSTERS = 1 << 8, + + // AGPR allocation is supported. + FEATURE_AGPR_ALLOC = 1 << 9 }; enum FeatureError : uint32_t { @@ -194,6 +200,14 @@ LLVM_ABI unsigned getAddressableNumSGPRs(Triple::SubArchType SubArch); LLVM_ABI unsigned getSGPRAllocGranule(GPUKind AK); LLVM_ABI unsigned getSGPRAllocGranule(Triple::SubArchType SubArch); +/// \returns true if the target identified by \p SubArch has memory aperture +/// base and size registers. +LLVM_ABI bool hasApertureRegs(Triple::SubArchType SubArch); + +/// \returns true if the target identified by \p SubArch supports reading the +/// doorbell ID through S_GETREG. +LLVM_ABI bool supportsGetDoorbellID(Triple::SubArchType SubArch); + /// Fills Features map with default values for given target GPU. /// \p Features contains overriding target features and this function returns /// default target features with entries overridden by \p Features. diff --git a/llvm/lib/Target/AMDGPU/AMDGPUAttributor.cpp b/llvm/lib/Target/AMDGPU/AMDGPUAttributor.cpp index 630ffad96e451..e007e22a5986b 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUAttributor.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUAttributor.cpp @@ -153,7 +153,13 @@ class AMDGPUInformationCache : public InformationCache { BumpPtrAllocator &Allocator, SetVector<Function *> *CGSCC, TargetMachine &TM) : InformationCache(M, AG, Allocator, CGSCC), TM(TM), - CodeObjectVersion(AMDGPU::getAMDHSACodeObjectVersion(M)) {} + CodeObjectVersion(AMDGPU::getAMDHSACodeObjectVersion(M)), + HasApertureRegs( + AMDGPU::hasApertureRegs(M.getTargetTriple().getSubArch())), + SupportsGetDoorbellID( + AMDGPU::supportsGetDoorbellID(M.getTargetTriple().getSubArch())), + ArchAttr(AMDGPU::getArchAttrAMDGCN( + AMDGPU::getGPUKindFromSubArch(M.getTargetTriple().getSubArch()))) {} TargetMachine &TM; @@ -167,17 +173,17 @@ class AMDGPUInformationCache : public InformationCache { CS_WORST = DS_GLOBAL | ADDR_SPACE_CAST_BOTH_TO_FLAT, }; - /// Check if the subtarget has aperture regs. - bool hasApertureRegs(Function &F) { - const GCNSubtarget &ST = TM.getSubtarget<GCNSubtarget>(F); - return ST.hasApertureRegs(); - } + /// Check if the module target has aperture regs. + bool hasApertureRegs() const { return HasApertureRegs; } - /// Check if the subtarget supports GetDoorbellID. - bool supportsGetDoorbellID(Function &F) { - const GCNSubtarget &ST = TM.getSubtarget<GCNSubtarget>(F); - return ST.supportsGetDoorbellID(); - } + /// Check if the module target supports GetDoorbellID. + bool supportsGetDoorbellID() const { return SupportsGetDoorbellID; } + + /// Check if the module target supports clusters. + bool hasClusters() const { return ArchAttr & AMDGPU::FEATURE_CLUSTERS; } + + /// Check if the module target supports AGPR allocation. + bool hasAGPRAlloc() const { return ArchAttr & AMDGPU::FEATURE_AGPR_ALLOC; } std::optional<std::pair<unsigned, unsigned>> getFlatWorkGroupSizeAttr(const Function &F) const { @@ -288,7 +294,7 @@ class AMDGPUInformationCache : public InformationCache { /// Returns true if \p Fn needs the queue pointer because of \p C. bool needsQueuePtr(const Constant *C, Function &Fn) { bool IsNonEntryFunc = !AMDGPU::isEntryFunctionCC(Fn.getCallingConv()); - bool HasAperture = hasApertureRegs(Fn); + bool HasAperture = hasApertureRegs(); // No need to explore the constants. if (!IsNonEntryFunc && HasAperture) @@ -312,6 +318,9 @@ class AMDGPUInformationCache : public InformationCache { /// Used to determine if the Constant needs the queue pointer. DenseMap<const Constant *, std::optional<uint8_t>> ConstantStatus; const unsigned CodeObjectVersion; + const bool HasApertureRegs; + const bool SupportsGetDoorbellID; + const unsigned ArchAttr; }; struct AAAMDAttributes @@ -503,8 +512,8 @@ struct AAAMDAttributesFunction : public AAAMDAttributes { bool NeedsImplicit = false; auto &InfoCache = static_cast<AMDGPUInformationCache &>(A.getInfoCache()); - bool HasApertureRegs = InfoCache.hasApertureRegs(*F); - bool SupportsGetDoorbellID = InfoCache.supportsGetDoorbellID(*F); + bool HasApertureRegs = InfoCache.hasApertureRegs(); + bool SupportsGetDoorbellID = InfoCache.supportsGetDoorbellID(); unsigned COV = InfoCache.getCodeObjectVersion(); for (Function *Callee : AAEdges->getOptimisticEdges()) { @@ -639,7 +648,7 @@ struct AAAMDAttributesFunction : public AAAMDAttributes { return true; }; - bool HasApertureRegs = InfoCache.hasApertureRegs(*F); + bool HasApertureRegs = InfoCache.hasApertureRegs(); // `checkForAllInstructions` is much more cheaper than going through all // instructions, try it first. @@ -1638,11 +1647,10 @@ static bool runImpl(SetVector<Function *> &Functions, bool IsModulePass, A.getOrCreateAAFor<AAAMDWavesPerEU>(IRPosition::function(*F)); } - const GCNSubtarget &ST = TM.getSubtarget<GCNSubtarget>(*F); - if (!F->isDeclaration() && ST.hasClusters()) + if (!F->isDeclaration() && InfoCache.hasClusters()) A.getOrCreateAAFor<AAAMDGPUClusterDims>(IRPosition::function(*F)); - if (ST.hasGFX90AInsts()) + if (InfoCache.hasAGPRAlloc()) A.getOrCreateAAFor<AAAMDGPUMinAGPRAlloc>(IRPosition::function(*F)); for (auto &I : instructions(F)) { diff --git a/llvm/lib/Target/AMDGPU/AMDGPUTargetParser.td b/llvm/lib/Target/AMDGPU/AMDGPUTargetParser.td index e6ea319017436..6600277e31dd3 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUTargetParser.td +++ b/llvm/lib/Target/AMDGPU/AMDGPUTargetParser.td @@ -29,6 +29,8 @@ def FEATURE_SRAMECC : AMDGPUArchFeature<"FEATURE_SRAMECC">; def FEATURE_WGP : AMDGPUArchFeature<"FEATURE_WGP">; def FEATURE_XNACK_ON_OFF_MODES : AMDGPUArchFeature<"FEATURE_XNACK_ON_OFF_MODES">; def FEATURE_SGPR_INIT_BUG : AMDGPUArchFeature<"FEATURE_SGPR_INIT_BUG">; +def FEATURE_CLUSTERS : AMDGPUArchFeature<"FEATURE_CLUSTERS">; +def FEATURE_AGPR_ALLOC : AMDGPUArchFeature<"FEATURE_AGPR_ALLOC">; // Marks a Processor/ProcessorModel record as a canonical GPU. // diff --git a/llvm/lib/Target/AMDGPU/GCNProcessors.td b/llvm/lib/Target/AMDGPU/GCNProcessors.td index 47dc1f182c7b4..4251f6f59cdc8 100644 --- a/llvm/lib/Target/AMDGPU/GCNProcessors.td +++ b/llvm/lib/Target/AMDGPU/GCNProcessors.td @@ -170,7 +170,7 @@ def GFX909 : AMDGPUProcessorModel<"gfx909", SIQuarterSpeedModel, def GFX90A : AMDGPUProcessorModel<"gfx90a", SIDPFullSpeedModel, FeatureISAVersion9_0_A.Features, [9, 0, 0xa]> { - let ArchFeatures = ArchFeaturesW64XnackSramEcc; + let ArchFeatures = ArchFeaturesW64XnackSramEcc # [FEATURE_AGPR_ALLOC]; } def GFX90C : AMDGPUProcessorModel<"gfx90c", SIQuarterSpeedModel, @@ -180,12 +180,12 @@ def GFX90C : AMDGPUProcessorModel<"gfx90c", SIQuarterSpeedModel, def GFX942 : AMDGPUProcessorModel<"gfx942", SIDPGFX942FullSpeedModel, FeatureISAVersion9_4_2.Features, [9, 4, 2]> { - let ArchFeatures = ArchFeaturesW64XnackSramEcc; + let ArchFeatures = ArchFeaturesW64XnackSramEcc # [FEATURE_AGPR_ALLOC]; } def GFX950 : AMDGPUProcessorModel<"gfx950", SIDPGFX950FullSpeedModel, FeatureISAVersion9_5_0.Features, [9, 5, 0]> { - let ArchFeatures = ArchFeaturesW64XnackSramEcc; + let ArchFeatures = ArchFeaturesW64XnackSramEcc # [FEATURE_AGPR_ALLOC]; } def GFX9_GENERIC : AMDGPUProcessorModel<"gfx9-generic", SIQuarterSpeedModel, @@ -196,7 +196,7 @@ def GFX9_GENERIC : AMDGPUProcessorModel<"gfx9-generic", SIQuarterSpeedModel, def GFX9_4_GENERIC : AMDGPUProcessorModel<"gfx9-4-generic", SIDPGFX942FullSpeedModel, FeatureISAVersion9_4_Generic.Features, [9, 4, 0]> { - let ArchFeatures = ArchFeaturesW64XnackSramEcc; + let ArchFeatures = ArchFeaturesW64XnackSramEcc # [FEATURE_AGPR_ALLOC]; let CoveredGPUs = [GFX942, GFX950]; } @@ -370,17 +370,17 @@ def GFX12_GENERIC : AMDGPUProcessorModel<"gfx12-generic", GFX12SpeedModel, def GFX1250 : AMDGPUProcessorModel<"gfx1250", GFX1250SpeedModel, FeatureISAVersion12_50.Features, [12, 5, 0]> { - let ArchFeatures = [FEATURE_FAST_FMA_F32, FEATURE_FAST_DENORMAL_F32, FEATURE_WAVE32, FEATURE_XNACK, FEATURE_SRAMECC]; + let ArchFeatures = [FEATURE_FAST_FMA_F32, FEATURE_FAST_DENORMAL_F32, FEATURE_WAVE32, FEATURE_XNACK, FEATURE_SRAMECC, FEATURE_CLUSTERS]; } def GFX1251 : AMDGPUProcessorModel<"gfx1251", GFX1251SpeedModel, FeatureISAVersion12_51.Features, [12, 5, 1]> { - let ArchFeatures = [FEATURE_FAST_FMA_F32, FEATURE_FAST_DENORMAL_F32, FEATURE_WAVE32, FEATURE_XNACK, FEATURE_SRAMECC]; + let ArchFeatures = [FEATURE_FAST_FMA_F32, FEATURE_FAST_DENORMAL_F32, FEATURE_WAVE32, FEATURE_XNACK, FEATURE_SRAMECC, FEATURE_CLUSTERS]; } def GFX12_5_GENERIC : AMDGPUProcessorModel<"gfx12-5-generic", GFX125xGenericSpeedModel, FeatureISAVersion12_5_Generic.Features, [12, 5, 0]> { - let ArchFeatures = [FEATURE_FAST_FMA_F32, FEATURE_FAST_DENORMAL_F32, FEATURE_WAVE32, FEATURE_XNACK, FEATURE_SRAMECC]; + let ArchFeatures = [FEATURE_FAST_FMA_F32, FEATURE_FAST_DENORMAL_F32, FEATURE_WAVE32, FEATURE_XNACK, FEATURE_SRAMECC, FEATURE_CLUSTERS]; let CoveredGPUs = [GFX1250, GFX1251]; } @@ -390,12 +390,12 @@ def GFX12_5_GENERIC : AMDGPUProcessorModel<"gfx12-5-generic", GFX125xGenericSpee def GFX1310 : AMDGPUProcessorModel<"gfx1310", GFX12SpeedModel, FeatureISAVersion13.Features, [13, 1, 0]> { - let ArchFeatures = ArchFeaturesW32Wgp; + let ArchFeatures = ArchFeaturesW32Wgp # [FEATURE_CLUSTERS]; } def GFX13_GENERIC : AMDGPUProcessorModel<"gfx13-generic", GFX12SpeedModel, FeatureISAVersion13_Generic.Features, [13, 1, 0]> { - let ArchFeatures = ArchFeaturesW32Wgp; + let ArchFeatures = ArchFeaturesW32Wgp # [FEATURE_CLUSTERS]; let CoveredGPUs = [GFX1310]; } diff --git a/llvm/lib/TargetParser/AMDGPUTargetParser.cpp b/llvm/lib/TargetParser/AMDGPUTargetParser.cpp index d8abaf7474cd6..841fec53b698e 100644 --- a/llvm/lib/TargetParser/AMDGPUTargetParser.cpp +++ b/llvm/lib/TargetParser/AMDGPUTargetParser.cpp @@ -422,6 +422,16 @@ unsigned AMDGPU::getSGPRAllocGranule(Triple::SubArchType SubArch) { return 8; } +bool AMDGPU::hasApertureRegs(Triple::SubArchType SubArch) { + // Memory aperture registers were introduced on GFX9. + return getIsaVersion(SubArch).Major >= 9; +} + +bool AMDGPU::supportsGetDoorbellID(Triple::SubArchType SubArch) { + // The S_GETREG DOORBELL_ID is supported by all GFX9 onward targets. + return getIsaVersion(SubArch).Major >= 9; +} + StringRef AMDGPU::getCanonicalArchName(const Triple &T, StringRef Arch) { assert(T.isAMDGPU()); auto ProcKind = T.isAMDGCN() ? parseArchAMDGCN(Arch) : parseArchR600(Arch); _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
