13#ifndef LLVM_CLANG_LIB_BASIC_TARGETS_AMDGPU_H
14#define LLVM_CLANG_LIB_BASIC_TARGETS_AMDGPU_H
19#include "llvm/ADT/StringSet.h"
20#include "llvm/Support/AMDGPUAddrSpace.h"
21#include "llvm/Support/Compiler.h"
22#include "llvm/TargetParser/TargetParser.h"
23#include "llvm/TargetParser/Triple.h"
31 static const char *
const GCCRegNames[];
34 static const LangASMap AMDGPUDefIsPrivMap;
36 llvm::AMDGPU::GPUKind GPUKind;
38 unsigned WavefrontSize;
44 bool HasImage =
false;
51 llvm::StringMap<bool> OffloadArchFeatures;
54 bool hasFP64()
const {
55 return getTriple().getArch() == llvm::Triple::amdgcn ||
56 !!(GPUFeatures & llvm::AMDGPU::FEATURE_FP64);
60 bool hasFastFMAF()
const {
61 return !!(GPUFeatures & llvm::AMDGPU::FEATURE_FAST_FMA_F32);
65 bool hasFastFMA()
const {
66 return getTriple().getArch() == llvm::Triple::amdgcn;
69 bool hasFMAF()
const {
70 return getTriple().getArch() == llvm::Triple::amdgcn ||
71 !!(GPUFeatures & llvm::AMDGPU::FEATURE_FMA);
74 bool hasFullRateDenormalsF32()
const {
75 return !!(GPUFeatures & llvm::AMDGPU::FEATURE_FAST_DENORMAL_F32);
78 bool hasLDEXPF()
const {
79 return getTriple().getArch() == llvm::Triple::amdgcn ||
80 !!(GPUFeatures & llvm::AMDGPU::FEATURE_LDEXP);
83 static bool isAMDGCN(
const llvm::Triple &TT) {
84 return TT.getArch() == llvm::Triple::amdgcn;
87 static bool isR600(
const llvm::Triple &TT) {
88 return TT.getArch() == llvm::Triple::r600;
94 void setAddressSpaceMap(
bool DefaultIsPrivate);
99 if (isR600(getTriple()))
101 unsigned TargetAS = getTargetAddressSpace(AS);
103 if (TargetAS == llvm::AMDGPUAS::PRIVATE_ADDRESS ||
104 TargetAS == llvm::AMDGPUAS::LOCAL_ADDRESS)
111 return getPointerWidthV(AddrSpace);
118 ((A == LangAS::Default ||
128 return getTriple().getArch() == llvm::Triple::amdgcn ? 64 : 32;
154 static const ::llvm::StringSet<> SpecialRegs({
155 "exec",
"vcc",
"flat_scratch",
"m0",
"scc",
"tba",
"tma",
156 "flat_scratch_lo",
"flat_scratch_hi",
"vcc_lo",
"vcc_hi",
"exec_lo",
157 "exec_hi",
"tma_lo",
"tma_hi",
"tba_lo",
"tba_hi",
178 if (S ==
"DA" || S ==
"DB") {
184 bool HasLeftParen = S.consume_front(
"{");
187 if (S.front() !=
'v' && S.front() !=
's' && S.front() !=
'a') {
190 auto E = S.find(
'}');
191 if (!SpecialRegs.count(S.substr(0,
E)))
193 S = S.drop_front(
E + 1);
210 bool HasLeftBracket = S.consume_front(
"[");
211 unsigned long long N;
212 if (S.empty() || consumeUnsignedInteger(S, 10, N))
214 if (S.consume_front(
":")) {
217 unsigned long long M;
218 if (consumeUnsignedInteger(S, 10, M) || N >= M)
221 if (HasLeftBracket) {
222 if (!S.consume_front(
"]"))
225 if (!S.consume_front(
"}"))
241 StringRef S(Constraint);
242 if (S ==
"DA" || S ==
"DB") {
243 return std::string(
"^") + std::string(Constraint++, 2);
246 const char *
Begin = Constraint;
248 if (validateAsmConstraint(Constraint, Info))
249 return std::string(
Begin).substr(0, Constraint -
Begin + 1);
252 return std::string(1, *Constraint);
258 const std::vector<std::string> &FeatureVec)
const override;
268 return TargetInfo::CharPtrBuiltinVaList;
272 if (getTriple().getArch() == llvm::Triple::amdgcn)
273 return llvm::AMDGPU::parseArchAMDGCN(Name) != llvm::AMDGPU::GK_NONE;
274 return llvm::AMDGPU::parseArchR600(Name) != llvm::AMDGPU::GK_NONE;
279 bool setCPU(
const std::string &Name)
override {
280 if (getTriple().getArch() == llvm::Triple::amdgcn) {
281 GPUKind = llvm::AMDGPU::parseArchAMDGCN(Name);
282 GPUFeatures = llvm::AMDGPU::getArchAttrAMDGCN(GPUKind);
284 GPUKind = llvm::AMDGPU::parseArchR600(Name);
285 GPUFeatures = llvm::AMDGPU::getArchAttrR600(GPUKind);
288 return GPUKind != llvm::AMDGPU::GK_NONE;
292 auto &Opts = getSupportedOpenCLOpts();
293 Opts[
"cl_clang_storage_class_specifiers"] =
true;
294 Opts[
"__cl_clang_variadic_functions"] =
true;
295 Opts[
"__cl_clang_function_pointers"] =
true;
296 Opts[
"__cl_clang_non_portable_kernel_param_types"] =
true;
297 Opts[
"__cl_clang_bitfields"] =
true;
299 bool IsAMDGCN = isAMDGCN(getTriple());
301 Opts[
"cl_khr_fp64"] = hasFP64();
302 Opts[
"__opencl_c_fp64"] = hasFP64();
304 if (IsAMDGCN || GPUKind >= llvm::AMDGPU::GK_CEDAR) {
305 Opts[
"cl_khr_byte_addressable_store"] =
true;
306 Opts[
"cl_khr_global_int32_base_atomics"] =
true;
307 Opts[
"cl_khr_global_int32_extended_atomics"] =
true;
308 Opts[
"cl_khr_local_int32_base_atomics"] =
true;
309 Opts[
"cl_khr_local_int32_extended_atomics"] =
true;
313 Opts[
"cl_khr_fp16"] =
true;
314 Opts[
"cl_khr_int64_base_atomics"] =
true;
315 Opts[
"cl_khr_int64_extended_atomics"] =
true;
316 Opts[
"cl_khr_mipmap_image"] =
true;
317 Opts[
"cl_khr_mipmap_image_writes"] =
true;
318 Opts[
"cl_khr_subgroups"] =
true;
319 Opts[
"cl_amd_media_ops"] =
true;
320 Opts[
"cl_amd_media_ops2"] =
true;
322 Opts[
"__opencl_c_images"] =
true;
323 Opts[
"__opencl_c_3d_image_writes"] =
true;
324 Opts[
"cl_khr_3d_image_writes"] =
true;
331 return LangAS::opencl_constant;
336 return LangAS::opencl_global;
339 return TargetInfo::getOpenCLTypeAddrSpace(TK);
346 return LangAS::opencl_generic;
348 return LangAS::opencl_global;
350 return LangAS::opencl_local;
352 return LangAS::opencl_constant;
354 return LangAS::opencl_private;
363 return LangAS::Default;
365 return LangAS::cuda_device;
367 return LangAS::cuda_shared;
369 return LangAS::cuda_constant;
380 switch (WavefrontSize) {
382 return llvm::omp::getAMDGPUGridValues<32>();
384 return llvm::omp::getAMDGPUGridValues<64>();
386 llvm_unreachable(
"getGridValue not implemented for this wavesize");
392 return static_cast<unsigned>(llvm::AMDGPUAS::CONSTANT_ADDRESS);
401 std::optional<unsigned>
403 const unsigned DWARF_Private = 1;
404 const unsigned DWARF_Local = 2;
405 if (AddressSpace == llvm::AMDGPUAS::PRIVATE_ADDRESS) {
406 return DWARF_Private;
407 }
else if (AddressSpace == llvm::AMDGPUAS::LOCAL_ADDRESS) {
430 return (AS == LangAS::opencl_local || AS == LangAS::opencl_private ||
431 AS == LangAS::sycl_local || AS == LangAS::sycl_private)
436 void setAuxTarget(
const TargetInfo *Aux)
override;
444 auto TargetIDFeatures =
446 for (
const auto &F : Features) {
447 assert(F.front() ==
'+' || F.front() ==
'-');
448 if (F ==
"+wavefrontsize64")
450 else if (F ==
"+cumode")
452 else if (F ==
"-cumode")
454 else if (F ==
"+image-insts")
456 bool IsOn = F.front() ==
'+';
457 StringRef Name = StringRef(F).drop_front();
458 if (!llvm::is_contained(TargetIDFeatures, Name))
460 assert(!OffloadArchFeatures.contains(Name));
461 OffloadArchFeatures[Name] = IsOn;
467 if (!isAMDGCN(getTriple()))
471 if (GPUKind == llvm::AMDGPU::GK_NONE)
472 return std::string(
"");
474 OffloadArchFeatures);
484 return std::make_pair(128, 128);
Defines the clang::TargetOptions class.
Concrete class used by the front-end to report problems and issues.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Exposes information about the current target.
BuiltinVaListKind
The different kinds of __builtin_va_list types defined by the target implementation.
Options for controlling the target.
const llvm::omp::GV & getGridValue() const override
std::string_view getClobbers() const override
Returns a string of target-specific clobbers, in LLVM format.
uint64_t getPointerAlignV(LangAS AddrSpace) const override
LangAS getOpenCLBuiltinAddressSpace(unsigned AS) const override
Map from the address space field in builtin description strings to the language address space.
uint64_t getPointerWidthV(LangAS AS) const override
bool setCPU(const std::string &Name) override
Target the specified CPU.
ArrayRef< TargetInfo::GCCRegAlias > getGCCRegAliases() const override
bool hasBFloat16Type() const override
Determine whether the _BFloat16 type is supported on this target.
uint64_t getNullPointerValue(LangAS AS) const override
Get integer value for null pointer.
LangAS getCUDABuiltinAddressSpace(unsigned AS) const override
Map from the address space field in builtin description strings to the language address space.
virtual bool isAddressSpaceSupersetOf(LangAS A, LangAS B) const override
Returns true if an address space can be safely converted to another.
bool useFP16ConversionIntrinsics() const override
Check whether llvm intrinsics such as llvm.convert.to.fp16 should be used to convert to and from __fp...
bool handleTargetFeatures(std::vector< std::string > &Features, DiagnosticsEngine &Diags) override
Perform initialization based on the user configured set of features (e.g., +sse4).
bool validateAsmConstraint(const char *&Name, TargetInfo::ConstraintInfo &Info) const override
Accepted register names: (n, m is unsigned integer, n < m) v s a {vn}, {v[n]} {sn},...
std::optional< std::string > getTargetID() const override
Returns the target ID if supported.
std::optional< unsigned > getDWARFAddressSpace(unsigned AddressSpace) const override
std::string convertConstraint(const char *&Constraint) const override
std::pair< unsigned, unsigned > hardwareInterferenceSizes() const override
The first value in the pair is the minimum offset between two objects to avoid false sharing (destruc...
unsigned getVtblPtrAddressSpace() const override
std::optional< LangAS > getConstantAddressSpace() const override
Return an AST address space which can be used opportunistically for constant global memory.
bool isValidCPUName(StringRef Name) const override
Determine whether this TargetInfo supports the given CPU name.
bool hasBitIntType() const override
Determine whether the _BitInt type is supported on this target.
bool hasHIPImageSupport() const override
Whether to support HIP image/texture API's.
uint64_t getMaxPointerWidth() const override
Return the maximum width of pointers on this target.
CallingConvCheckResult checkCallingConvention(CallingConv CC) const override
Determines whether a given calling convention is valid for the target.
LangAS getOpenCLTypeAddrSpace(OpenCLTypeKind TK) const override
Get address space for OpenCL type.
void setSupportedOpenCLOpts() override
Set supported OpenCL extensions and optional core features.
BuiltinVaListKind getBuiltinVaListKind() const override
Returns the kind of __builtin_va_list type that should be used with this target.
Defines the clang::TargetInfo interface.
The JSON file list parser is used to communicate input to InstallAPI.
unsigned[(unsigned) LangAS::FirstTargetAddressSpace] LangASMap
The type of a lookup table which maps from language-specific address spaces to target-specific ones.
bool isTargetAddressSpace(LangAS AS)
OpenCLTypeKind
OpenCL type kinds.
unsigned toTargetAddressSpace(LangAS AS)
llvm::SmallVector< llvm::StringRef, 4 > getAllPossibleTargetIDFeatures(const llvm::Triple &T, llvm::StringRef Processor)
Get all feature strings that can be used in target ID for Processor.
LangAS
Defines the address space values used by the address space qualifier of QualType.
std::string getCanonicalTargetID(llvm::StringRef Processor, const llvm::StringMap< bool > &Features)
Returns canonical target ID, assuming Processor is canonical and all entries in Features are valid.
CallingConv
CallingConv - Specifies the calling convention that a function uses.
LangAS getLangASFromTargetAS(unsigned TargetAS)
void setRequiresImmediate(int Min, int Max)