27constexpr unsigned NumAMDGPUSubArches =
32 StringTable::Offset AltName;
38 StringTable::Offset Name;
42 StringTable::Offset FamilyName;
43 uint8_t MaxWavesPerEU;
44 uint32_t MaxHWAddressableLocalMemorySize;
46 uint8_t BufferResourceNumRecordsWidth;
51 StringTable::Offset Name;
55#define GET_AMDGPU_NAME_TABLE
56#define GET_AMDGPU_GPU_TABLE
57#define GET_AMDGPU_GPU_ALIAS_TABLE
58#define GET_AMDGPU_MAJOR_SUBARCH
59#define GET_AMDGPU_SUBARCH_NAME
60#define GET_AMDGPU_FEATURE_NAME_TABLE
61#include "llvm/TargetParser/AMDGPUTargetParserDef.inc"
63#define GET_R600_NAME_TABLE
64#define GET_R600_GPU_TABLE
65#define GET_R600_GPU_ALIAS_TABLE
66#define GET_R600_FEATURE_NAME_TABLE
67#include "llvm/TargetParser/R600TargetParserDef.inc"
71constexpr StringTable AMDGPUNameStrTab = AMDGPUNameTable;
72constexpr StringTable R600NameStrTab = R600NameTable;
76const GPUInfo *getAMDGPUInfo(
GPUKind AK) {
77 if (AK < AMDGPUFirstGPUKind)
79 unsigned Idx = AK - AMDGPUFirstGPUKind;
80 if (Idx >= std::size(AMDGPUGPUTable))
82 return &AMDGPUGPUTable[Idx];
86const R600Info *getR600Info(
GPUKind AK) {
87 if (AK < R600FirstGPUKind)
89 unsigned Idx = AK - R600FirstGPUKind;
90 if (Idx >= std::size(R600GPUTable))
92 return &R600GPUTable[Idx];
96template <
typename InfoT,
size_t N,
size_t M>
99 const GPUNameAlias (&Aliases)[M]) {
100 for (
unsigned I = 0;
I !=
N; ++
I) {
101 if (CPU == StrTab[
Table[
I].Name])
102 return static_cast<GPUKind>(FirstKind +
I);
105 for (
const GPUNameAlias &
A : Aliases) {
106 if (CPU == StrTab[
A.AltName])
115constexpr std::array<GPUKind, NumAMDGPUSubArches> AMDGPUSubArchToGPUKind = [] {
116 std::array<GPUKind, NumAMDGPUSubArches>
Map{};
118 for (
unsigned I = 0;
I < std::size(AMDGPUGPUTable); ++
I) {
122 static_cast<GPUKind>(AMDGPUFirstGPUKind +
I);
129constexpr std::array<Triple::SubArchType, NumAMDGPUSubArches>
130 AMDGPUMajorFamilies = [] {
131 std::array<Triple::SubArchType, NumAMDGPUSubArches>
Map{};
133 for (
unsigned I = 0;
I < NumAMDGPUSubArches; ++
I) {
138 for (
const AMDGPUMajorSubArchEntry &Entry : AMDGPUMajorSubArch)
145constexpr std::array<StringTable::Offset, NumAMDGPUSubArches>
146 AMDGPUSubArchNameOffsets = [] {
147 std::array<StringTable::Offset, NumAMDGPUSubArches>
Map{};
148 for (
const AMDGPUSubArchNameEntry &Entry : AMDGPUSubArchNames)
155constexpr std::array<StringTable::Offset, NumAMDGPUSubArches>
156 AMDGPUSubArchTripleNameOffsets = [] {
157 std::array<StringTable::Offset, NumAMDGPUSubArches>
Map{};
158 for (
const AMDGPUSubArchNameEntry &Entry : AMDGPUSubArchNames)
160 Entry.TripleNameOffset;
166 const GPUInfo *Info = getAMDGPUInfo(AK);
167 return Info ? AMDGPUNameStrTab[Info->FamilyName] :
"";
171 const GPUInfo *Info = getAMDGPUInfo(AK);
202 return MajorA == MajorB;
204 return MajorA == MajorB;
230 const GPUInfo *Info = getAMDGPUInfo(AK);
244 return A.getArchName().size() == 6;
247 return B.getArchName().size() == 6;
262 if (
A.getSubArch() == MajorA) {
263 if (MajorA == MajorB)
267 if (
B.getSubArch() == MajorB) {
268 if (MajorA == MajorB)
277 const GPUInfo *Info = getAMDGPUInfo(AK);
278 return Info ? AMDGPUNameStrTab[Info->Name] :
"";
285 return AMDGPUNameStrTab[AMDGPUSubArchNameOffsets[SubArch -
291 return AMDGPUNameStrTab[AMDGPUNoSubArchNameOffset];
295 "expected an AMDGPU subarch or NoSubArch");
296 return AMDGPUNameStrTab
301 const R600Info *Info = getR600Info(AK);
302 return Info ? R600NameStrTab[Info->Name] :
"";
306 return parseArchImpl(CPU, AMDGPUGPUTable, AMDGPUFirstGPUKind,
307 AMDGPUNameStrTab, AMDGPUGPUAliases);
311 return parseArchImpl(CPU, R600GPUTable, R600FirstGPUKind, R600NameStrTab,
317 const GPUInfo *Info = getAMDGPUInfo(AK);
318 return Info ? Info->Features :
Empty;
323 const R600Info *Info = getR600Info(AK);
324 return Info ? Info->Features :
Empty;
329 for (
unsigned I = 0;
I != NUM_FEATURES; ++
I) {
330 if (Features.
test(
I))
331 Names.
push_back(AMDGPUNameStrTab[AMDGPUFeatureNames[
I]]);
339 for (
unsigned I = 0;
I != std::size(AMDGPUGPUTable); ++
I) {
343 Values.push_back(AMDGPUNameStrTab[AMDGPUGPUTable[
I].Name]);
346 for (
const GPUNameAlias &
A : AMDGPUGPUAliases) {
348 Values.push_back(AMDGPUNameStrTab[
A.AltName]);
353 for (
const R600Info &Info : R600GPUTable)
354 Values.push_back(R600NameStrTab[Info.Name]);
355 for (
const GPUNameAlias &
A : R600GPUAliases)
356 Values.push_back(R600NameStrTab[
A.AltName]);
361 return Info ? Info->Version :
IsaVersion{0, 0, 0};
366 return Info ? Info->Version :
IsaVersion{0, 0, 0};
427 if (Features.
test(FEAT_GFX90A_INSTS))
429 if (Features.
test(FEAT_1536_PHYSICAL_VGPRS))
430 return IsWave32 ? 24 : 12;
431 if (Features.
test(FEAT_GFX10_3_INSTS))
432 return IsWave32 ? 16 : 8;
433 return IsWave32 ? 8 : 4;
443 if (Features.
test(FEAT_GFX90A_INSTS))
445 if (!Features.
test(FEAT_GFX10_INSTS))
447 if (Features.
test(FEAT_1536_PHYSICAL_VGPRS))
448 return IsWave32 ? 1536 : 768;
449 return IsWave32 ? 1024 : 512;
459 if (Features.
test(FEAT_GFX90A_INSTS))
461 if (Features.
test(FEAT_1024_ADDRESSABLE_VGPRS))
462 return IsWave32 ? 1024 : 512;
472 const GPUInfo *Info = getAMDGPUInfo(AK);
473 return Info ? Info->MaxHWAddressableLocalMemorySize : 32768;
511 const GPUInfo *Info = getAMDGPUInfo(AK);
512 return Info ? Info->LDSBankCount : 32;
520 const GPUInfo *Info = getAMDGPUInfo(AK);
521 if (!Info || Info->BufferResourceNumRecordsWidth == 0)
523 return Info->BufferResourceNumRecordsWidth;
526std::optional<unsigned>
532 const GPUInfo *Info = getAMDGPUInfo(AK);
533 return Info ? Info->MaxWavesPerEU : 10;
556 FEAT_FAST_DENORMAL_F32,
557 FEAT_SUPPORTS_WAVE32,
560 FEAT_SRAMECC_SUPPORT,
561 FEAT_XNACK_ON_OFF_MODES,
563 FEAT_GET_DOORBELL_ID,
565 FEAT_1536_PHYSICAL_VGPRS,
566 FEAT_HALF_ADDRESSABLE_PHYSICAL_LOCAL_MEMORY,
567 FEAT_1024_ADDRESSABLE_VGPRS};
577 Features[Name] =
true;
579 Features.
insert({Name,
true});
585static std::pair<FeatureError, StringRef>
592 const GPUInfo *Info = getAMDGPUInfo(Kind);
598 const bool TargetHasWave32 =
599 Info && Info->Features.test(FEAT_WAVEFRONTSIZE32);
600 const bool TargetHasWave64 =
601 Info && Info->Features.test(FEAT_WAVEFRONTSIZE64);
603 auto Wave32Itr = Features.
find(
"wavefrontsize32");
604 auto Wave64Itr = Features.
find(
"wavefrontsize64");
605 const bool EnableWave32 =
606 Wave32Itr != Features.
end() && Wave32Itr->getValue();
607 const bool EnableWave64 =
608 Wave64Itr != Features.
end() && Wave64Itr->getValue();
609 const bool DisableWave32 =
610 Wave32Itr != Features.
end() && !Wave32Itr->getValue();
611 const bool DisableWave64 =
612 Wave64Itr != Features.
end() && !Wave64Itr->getValue();
614 if (EnableWave32 && EnableWave64)
616 "'+wavefrontsize32' and '+wavefrontsize64' are mutually exclusive"};
617 if (DisableWave32 && DisableWave64)
619 "'-wavefrontsize32' and '-wavefrontsize64' are mutually exclusive"};
622 if (TargetHasWave64) {
629 if (TargetHasWave32) {
639 if (!IsNullGPU && !EnableWave32 && !EnableWave64 && !TargetHasWave32 &&
641 Features.
insert({
"wavefrontsize32",
true});
653std::pair<FeatureError, StringRef>
664 Features[
"wavefrontsize32"] =
true;
665 Features[
"wavefrontsize64"] =
true;
666 }
else if (
T.isAMDGCN()) {
702 TargetTripleString(TT.normalize(
Triple::CanonicalForm::FOUR_IDENT)),
703 XnackSetting(XnackSetting), SramEccSetting(SramEccSetting),
704 IsAMDHSA(TT.getOS() ==
Triple::AMDHSA) {}
710 return TargetIDSetting::On;
712 return TargetIDSetting::Off;
714 return TargetIDSetting::Unsupported;
721 return (CPUName.
empty() || CPUName ==
"generic")
734 if (!Features.
test(FEAT_XNACK_SUPPORT))
736 else if (Features.
test(FEAT_XNACK_ON_OFF_MODES))
741 ? TargetIDSetting::Any
742 : TargetIDSetting::Unsupported;
759 TargetIDStr.
split(Split,
':');
760 bool SeenXnack =
false;
761 bool SeenSramEcc =
false;
763 for (
unsigned I = 1,
E = Split.size();
I !=
E; ++
I) {
769 if (SeenXnack || !Features.
test(FEAT_XNACK_ON_OFF_MODES) ||
770 Sign == TargetIDSetting::Unsupported)
777 if (SeenSramEcc ||
SramEccSetting == TargetIDSetting::Unsupported ||
778 Sign == TargetIDSetting::Unsupported)
807 bool XnackToggleable = XnackSetting == TargetIDSetting::Any;
808 bool SramEccToggleable = SramEccSetting == TargetIDSetting::Any;
810 FeatureString.
split(Features,
',', -1,
false);
814 if (Sign == TargetIDSetting::Unsupported)
817 if (Name ==
"xnack" && XnackToggleable)
819 else if (Name ==
"sramecc" && SramEccToggleable)
820 SramEccSetting = Sign;
823 return TargetID(Arch, TT, XnackSetting, SramEccSetting);
839 if (!CPUName.
empty() && CPUName !=
"generic" &&
851 return TargetID(Arch, TT, XnackSetting, SramEccSetting);
854std::optional<TargetID>
860 TargetIDDirective.
split(Parts,
'-', 4);
861 if (Parts.
size() < 5)
864 return parse(
Triple(Parts[0], Parts[1], Parts[2], Parts[3]), Parts[4]);
871 return Features.
test(FEAT_XNACK_SUPPORT) &&
872 !Features.
test(FEAT_XNACK_ON_OFF_MODES);
880 bool XnackHardwiredOn) {
881 if (SramEcc == TargetIDSetting::Off)
883 else if (SramEcc == TargetIDSetting::On)
886 if (XnackHardwiredOn)
889 if (Xnack == TargetIDSetting::Off)
891 else if (Xnack == TargetIDSetting::On)
925 return Arch ==
Other.Arch && XnackSetting ==
Other.XnackSetting &&
926 SramEccSetting ==
Other.SramEccSetting && IsAMDHSA ==
Other.IsAMDHSA &&
927 TargetTripleString ==
Other.TargetTripleString;
932 return Provided == TargetIDSetting::Any ||
933 Provided == TargetIDSetting::Unsupported || Provided == Requested;
938 if (Arch !=
Other.Arch || XnackSetting !=
Other.XnackSetting ||
939 SramEccSetting !=
Other.SramEccSetting)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static cl::opt< bool > SramEccSetting("amdgpu-sramecc", cl::desc("Force amdgpu.sramecc for testing"), cl::ReallyHidden)
static cl::opt< bool > XnackSetting("amdgpu-xnack", cl::desc("Force amdgpu.xnack value for testing"), cl::ReallyHidden)
static GPUKind getGPUKindFromTargetID(const Triple &TT, StringRef TargetIDStr)
static std::pair< FeatureError, StringRef > fillAMDGCNFeatureMap(StringRef GPU, const Triple &T, StringMap< bool > &Features)
Add a GPU's default features to Features (preserving user overrides) and validate any requested waves...
static bool computeTargetIDFeatures(GPUKind Arch, StringRef TargetIDStr, TargetIDSetting &XnackSetting, TargetIDSetting &SramEccSetting)
static void getDefaultTargetIDFeatures(GPUKind Arch, TargetIDSetting &XnackSetting, TargetIDSetting &SramEccSetting)
static TargetIDSetting getTargetIDSettingFromFeatureString(StringRef Sign)
static bool featureProvidesFor(TargetIDSetting Provided, TargetIDSetting Requested)
static bool isXnackHardwiredOn(GPUKind Arch)
static void addGPUFeatures(const GPUInfo &Info, bool Overwrite, StringMap< bool > &Features)
static const AMDGPUFeatureBitset FrontendOnlyFeatures
static void printFeatureModifiers(raw_ostream &OS, TargetIDSetting SramEcc, TargetIDSetting Xnack, bool XnackHardwiredOn)
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file defines the SmallVector class.
LocallyHashedType DenseMapInfo< LocallyHashedType >::Empty
static TargetID createFromSubtargetFeatures(const Triple &TT, StringRef CPU, StringRef FeatureString)
Construct a TargetID for triple TT and processor CPU, taking the xnack/sramecc modes from the subtarg...
void printCanonicalTargetIDString(raw_ostream &OS) const
Print the canonical processor name followed by any explicit xnack and sramecc feature modifiers (e....
static std::optional< TargetID > parseTargetIDString(StringRef TargetIDDirective)
Parse and validate a TargetID from a full "<triple>-<processor>:<features>" directive string.
void print(raw_ostream &OS) const
TargetIDSetting getXnackSetting() const
bool isEquivalent(const TargetID &Other) const
Returns true if Other denotes the same target as *this, i.e.
bool operator==(const TargetID &Other) const
bool providesFor(const TargetID &Other) const
Returns true if a device image for *this can provide the device code for a request for Other.
StringRef getTargetTripleString() const
std::string getCanonicalFeatureString() const
TargetID(GPUKind Arch, const Triple &TT, TargetIDSetting XnackSetting, TargetIDSetting SramEccSetting)
static std::optional< TargetID > parse(const Triple &TT, StringRef ProcAndFeatures)
Parse and validate a TargetID for triple TT from the processor+features string ProcAndFeatures (e....
std::string toString() const
TargetIDSetting getSramEccSetting() const
constexpr bool test(unsigned I) const
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
iterator find(StringRef Key)
bool insert(MapEntryTy *KeyValue)
insert - Insert the specified key/value pair into the map.
Represent a constant reference to a string, i.e.
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
constexpr bool empty() const
Check if the string is empty.
bool consume_front(char Prefix)
Returns true if this StringRef has the given prefix and removes that prefix.
A table of densely packed, null-terminated strings indexed by offset.
Triple - Helper class for working with autoconf configuration names.
LLVM_ABI bool isCompatibleWith(const Triple &Other) const
Test whether target triples are compatible.
This class implements an extremely fast bulk output stream that can only output to a stream.
A raw_ostream that writes to an std::string.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
LLVM_ABI StringRef getArchNameR600(GPUKind AK)
@ FIXED_NUM_SGPRS_FOR_INIT_BUG
LLVM_ABI void fillValidArchListAMDGCN(SmallVectorImpl< StringRef > &Values, Triple::SubArchType SubArch=Triple::NoSubArch)
Append the valid AMDGCN GPU names to Values.
LLVM_ABI unsigned getMaxWavesPerEU(GPUKind AK)
LLVM_ABI StringRef getCanonicalArchName(const Triple &T, StringRef Arch)
LLVM_ABI unsigned getAddressableLocalMemorySize(GPUKind AK, bool FullSIMDMode)
LLVM_ABI void fillValidArchListR600(SmallVectorImpl< StringRef > &Values)
LLVM_ABI std::string mergeSubArch(const Triple &A, const Triple &B)
Returns the effective triple appropriate to use when linking B into A by merging the subarches in cas...
LLVM_ABI bool isCPUValidForSubArch(Triple::SubArchType SubArch, GPUKind AK)
Return true if the GPU AK is usable with the triple subarch SubArch.
LLVM_ABI bool isSubArchCompatible(const Triple &A, const Triple &B)
Return true if subarch A is compatible with subarch B, i.e.
LLVM_ABI unsigned getLDSBankCount(GPUKind AK)
LLVM_ABI unsigned getMaxHWAddressableLocalMemorySize(GPUKind AK)
LDS size queries.
LLVM_ABI StringRef getArchFamilyNameAMDGCN(GPUKind AK)
LLVM_ABI StringRef getSubArchName(Triple::SubArchType SubArch)
Returns the triple subarch name for an AMDGPU subarch, e.g.
LLVM_ABI unsigned getAddressableNumSGPRs(GPUKind AK)
LLVM_ABI IsaVersion getIsaVersion(StringRef GPU)
LLVM_ABI unsigned getTotalNumVGPRs(GPUKind AK, bool IsWave32)
LLVM_ABI unsigned getTotalNumSGPRs(GPUKind AK)
LLVM_ABI std::optional< unsigned > getBufferResourceNumRecordsWidth(GPUKind AK)
GPUKind
GPU kinds supported by the AMDGPU target.
Bitset< NUM_FEATURES > AMDGPUFeatureBitset
LLVM_ABI Triple::SubArchType getSubArchFromGPUName(StringRef CPU)
Returns the preferred subarch for a GPU name CPU, or NoSubArch if unrecognized.
LLVM_ABI unsigned getLocalMemorySize(GPUKind AK, bool FullSIMDMode)
LLVM_ABI unsigned getSGPRAllocGranule(GPUKind AK)
LLVM_ABI Triple::SubArchType getSubArch(GPUKind AK)
LLVM_ABI StringRef getArchNameFromSubArch(Triple::SubArchType SubArch)
Returns the canonical GPU name for an AMDGPU subarch, e.g.
LLVM_ABI unsigned getVGPRAllocGranule(GPUKind AK, bool IsWave32)
LLVM_ABI GPUKind parseArchAMDGCN(StringRef CPU)
LLVM_ABI bool isPseudoTarget(GPUKind AK)
Return true if AK is a pseudo target (e.g.
@ UNSUPPORTED_TARGET_FEATURE
@ INVALID_FEATURE_COMBINATION
LLVM_ABI GPUKind getGPUKindFromSubArch(Triple::SubArchType SubArch)
AMDGPU::TargetID TargetID
LLVM_ABI std::pair< FeatureError, StringRef > fillAMDGPUFeatureMap(StringRef GPU, const Triple &T, StringMap< bool > &Features)
Fills Features map with default values for given target GPU.
LLVM_ABI unsigned getAddressableNumVGPRs(GPUKind AK, bool IsWave32)
LLVM_ABI void getFeatureNames(const AMDGPUFeatureBitset &Features, SmallVectorImpl< StringRef > &Names)
Appends the feature name of each bit set in Features to Names.
LLVM_ABI StringRef getArchNameAMDGCN(GPUKind AK)
LLVM_ABI Triple::SubArchType getMajorSubArch(Triple::SubArchType SubArch)
LLVM_ABI const AMDGPUFeatureBitset & getFeatureBitset(GPUKind AK)
Returns AK's feature bitset, or an empty bitset if unknown.
LLVM_ABI const R600FeatureBitset & getFeatureBitsetR600(GPUKind AK)
Returns R600 GPU AK's feature bitset, or an empty bitset if unknown.
Bitset< R600_NUM_FEATURES > R600FeatureBitset
LLVM_ABI GPUKind parseArchR600(StringRef CPU)
This is an optimization pass for GlobalISel generic memory operations.
RelativeUniformCounterPtr Values
Instruction set architecture version.