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>
535 assert((Features.
test(FEAT_LDS_ALLOC_GRANULARITY_256) ||
536 Features.
test(FEAT_LDS_ALLOC_GRANULARITY_512) ||
537 Features.
test(FEAT_LDS_ALLOC_GRANULARITY_1024) ||
538 Features.
test(FEAT_LDS_ALLOC_GRANULARITY_1280) ||
539 Features.
test(FEAT_LDS_ALLOC_GRANULARITY_2048)) &&
540 "missing LDS allocation granularity feature");
541 if (Features.
test(FEAT_LDS_ALLOC_GRANULARITY_256))
543 if (Features.
test(FEAT_LDS_ALLOC_GRANULARITY_512))
545 if (Features.
test(FEAT_LDS_ALLOC_GRANULARITY_1024))
547 if (Features.
test(FEAT_LDS_ALLOC_GRANULARITY_1280))
549 if (Features.
test(FEAT_LDS_ALLOC_GRANULARITY_2048))
560 const GPUInfo *Info = getAMDGPUInfo(AK);
561 return Info ? Info->MaxWavesPerEU : 10;
584 FEAT_FAST_DENORMAL_F32,
585 FEAT_SUPPORTS_WAVE32,
588 FEAT_SRAMECC_SUPPORT,
589 FEAT_XNACK_ON_OFF_MODES,
591 FEAT_GET_DOORBELL_ID,
593 FEAT_1536_PHYSICAL_VGPRS,
594 FEAT_HALF_ADDRESSABLE_PHYSICAL_LOCAL_MEMORY,
595 FEAT_1024_ADDRESSABLE_VGPRS,
596 FEAT_LDS_ALLOC_GRANULARITY_256,
597 FEAT_LDS_ALLOC_GRANULARITY_512,
598 FEAT_LDS_ALLOC_GRANULARITY_1024,
599 FEAT_LDS_ALLOC_GRANULARITY_1280,
600 FEAT_LDS_ALLOC_GRANULARITY_2048};
610 Features[Name] =
true;
612 Features.
insert({Name,
true});
618static std::pair<FeatureError, StringRef>
625 const GPUInfo *Info = getAMDGPUInfo(Kind);
631 const bool TargetHasWave32 =
632 Info && Info->Features.test(FEAT_WAVEFRONTSIZE32);
633 const bool TargetHasWave64 =
634 Info && Info->Features.test(FEAT_WAVEFRONTSIZE64);
636 auto Wave32Itr = Features.
find(
"wavefrontsize32");
637 auto Wave64Itr = Features.
find(
"wavefrontsize64");
638 const bool EnableWave32 =
639 Wave32Itr != Features.
end() && Wave32Itr->getValue();
640 const bool EnableWave64 =
641 Wave64Itr != Features.
end() && Wave64Itr->getValue();
642 const bool DisableWave32 =
643 Wave32Itr != Features.
end() && !Wave32Itr->getValue();
644 const bool DisableWave64 =
645 Wave64Itr != Features.
end() && !Wave64Itr->getValue();
647 if (EnableWave32 && EnableWave64)
649 "'+wavefrontsize32' and '+wavefrontsize64' are mutually exclusive"};
650 if (DisableWave32 && DisableWave64)
652 "'-wavefrontsize32' and '-wavefrontsize64' are mutually exclusive"};
655 if (TargetHasWave64) {
662 if (TargetHasWave32) {
672 if (!IsNullGPU && !EnableWave32 && !EnableWave64 && !TargetHasWave32 &&
674 Features.
insert({
"wavefrontsize32",
true});
686std::pair<FeatureError, StringRef>
697 Features[
"wavefrontsize32"] =
true;
698 Features[
"wavefrontsize64"] =
true;
699 }
else if (
T.isAMDGCN()) {
735 TargetTripleString(TT.normalize(
Triple::CanonicalForm::FOUR_IDENT)),
736 XnackSetting(XnackSetting), SramEccSetting(SramEccSetting),
737 IsAMDHSA(TT.getOS() ==
Triple::AMDHSA) {}
743 return TargetIDSetting::On;
745 return TargetIDSetting::Off;
747 return TargetIDSetting::Unsupported;
754 return (CPUName.
empty() || CPUName ==
"generic")
767 if (!Features.
test(FEAT_XNACK_SUPPORT))
769 else if (Features.
test(FEAT_XNACK_ON_OFF_MODES))
774 ? TargetIDSetting::Any
775 : TargetIDSetting::Unsupported;
792 TargetIDStr.
split(Split,
':');
793 bool SeenXnack =
false;
794 bool SeenSramEcc =
false;
796 for (
unsigned I = 1,
E = Split.size();
I !=
E; ++
I) {
802 if (SeenXnack || !Features.
test(FEAT_XNACK_ON_OFF_MODES) ||
803 Sign == TargetIDSetting::Unsupported)
810 if (SeenSramEcc ||
SramEccSetting == TargetIDSetting::Unsupported ||
811 Sign == TargetIDSetting::Unsupported)
840 bool XnackToggleable = XnackSetting == TargetIDSetting::Any;
841 bool SramEccToggleable = SramEccSetting == TargetIDSetting::Any;
843 FeatureString.
split(Features,
',', -1,
false);
847 if (Sign == TargetIDSetting::Unsupported)
850 if (Name ==
"xnack" && XnackToggleable)
852 else if (Name ==
"sramecc" && SramEccToggleable)
853 SramEccSetting = Sign;
856 return TargetID(Arch, TT, XnackSetting, SramEccSetting);
872 if (!CPUName.
empty() && CPUName !=
"generic" &&
884 return TargetID(Arch, TT, XnackSetting, SramEccSetting);
887std::optional<TargetID>
893 TargetIDDirective.
split(Parts,
'-', 4);
894 if (Parts.
size() < 5)
897 return parse(
Triple(Parts[0], Parts[1], Parts[2], Parts[3]), Parts[4]);
904 return Features.
test(FEAT_XNACK_SUPPORT) &&
905 !Features.
test(FEAT_XNACK_ON_OFF_MODES);
913 bool XnackHardwiredOn) {
914 if (SramEcc == TargetIDSetting::Off)
916 else if (SramEcc == TargetIDSetting::On)
919 if (XnackHardwiredOn)
922 if (Xnack == TargetIDSetting::Off)
924 else if (Xnack == TargetIDSetting::On)
958 return Arch ==
Other.Arch && XnackSetting ==
Other.XnackSetting &&
959 SramEccSetting ==
Other.SramEccSetting && IsAMDHSA ==
Other.IsAMDHSA &&
960 TargetTripleString ==
Other.TargetTripleString;
965 return Provided == TargetIDSetting::Any ||
966 Provided == TargetIDSetting::Unsupported || Provided == Requested;
971 if (Arch !=
Other.Arch || XnackSetting !=
Other.XnackSetting ||
972 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 none() 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 getLDSAllocGranule(GPUKind AK)
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.