10b57cec5SDimitry Andric //===--- NVPTX.h - Declare NVPTX target feature support ---------*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file declares NVPTX TargetInfo objects. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #ifndef LLVM_CLANG_LIB_BASIC_TARGETS_NVPTX_H 140b57cec5SDimitry Andric #define LLVM_CLANG_LIB_BASIC_TARGETS_NVPTX_H 150b57cec5SDimitry Andric 160b57cec5SDimitry Andric #include "clang/Basic/Cuda.h" 170b57cec5SDimitry Andric #include "clang/Basic/TargetInfo.h" 180b57cec5SDimitry Andric #include "clang/Basic/TargetOptions.h" 190b57cec5SDimitry Andric #include "llvm/Support/Compiler.h" 2006c3fb27SDimitry Andric #include "llvm/TargetParser/Triple.h" 21bdd1243dSDimitry Andric #include <optional> 220b57cec5SDimitry Andric 230b57cec5SDimitry Andric namespace clang { 240b57cec5SDimitry Andric namespace targets { 250b57cec5SDimitry Andric 260b57cec5SDimitry Andric static const unsigned NVPTXAddrSpaceMap[] = { 270b57cec5SDimitry Andric 0, // Default 280b57cec5SDimitry Andric 1, // opencl_global 290b57cec5SDimitry Andric 3, // opencl_local 300b57cec5SDimitry Andric 4, // opencl_constant 310b57cec5SDimitry Andric 0, // opencl_private 320b57cec5SDimitry Andric // FIXME: generic has to be added to the target 330b57cec5SDimitry Andric 0, // opencl_generic 34e8d8bef9SDimitry Andric 1, // opencl_global_device 35e8d8bef9SDimitry Andric 1, // opencl_global_host 360b57cec5SDimitry Andric 1, // cuda_device 370b57cec5SDimitry Andric 4, // cuda_constant 380b57cec5SDimitry Andric 3, // cuda_shared 39fe6060f1SDimitry Andric 1, // sycl_global 40fe6060f1SDimitry Andric 1, // sycl_global_device 41fe6060f1SDimitry Andric 1, // sycl_global_host 42fe6060f1SDimitry Andric 3, // sycl_local 43fe6060f1SDimitry Andric 0, // sycl_private 44480093f4SDimitry Andric 0, // ptr32_sptr 45480093f4SDimitry Andric 0, // ptr32_uptr 46bdd1243dSDimitry Andric 0, // ptr64 47bdd1243dSDimitry Andric 0, // hlsl_groupshared 4806c3fb27SDimitry Andric // Wasm address space values for this target are dummy values, 4906c3fb27SDimitry Andric // as it is only enabled for Wasm targets. 5006c3fb27SDimitry Andric 20, // wasm_funcref 510b57cec5SDimitry Andric }; 520b57cec5SDimitry Andric 530b57cec5SDimitry Andric /// The DWARF address class. Taken from 540b57cec5SDimitry Andric /// https://docs.nvidia.com/cuda/archive/10.0/ptx-writers-guide-to-interoperability/index.html#cuda-specific-dwarf 550b57cec5SDimitry Andric static const int NVPTXDWARFAddrSpaceMap[] = { 560b57cec5SDimitry Andric -1, // Default, opencl_private or opencl_generic - not defined 570b57cec5SDimitry Andric 5, // opencl_global 580b57cec5SDimitry Andric -1, 590b57cec5SDimitry Andric 8, // opencl_local or cuda_shared 600b57cec5SDimitry Andric 4, // opencl_constant or cuda_constant 610b57cec5SDimitry Andric }; 620b57cec5SDimitry Andric 630b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY NVPTXTargetInfo : public TargetInfo { 640b57cec5SDimitry Andric static const char *const GCCRegNames[]; 65*0fca6ea1SDimitry Andric OffloadArch GPU; 660b57cec5SDimitry Andric uint32_t PTXVersion; 670b57cec5SDimitry Andric std::unique_ptr<TargetInfo> HostTarget; 680b57cec5SDimitry Andric 690b57cec5SDimitry Andric public: 700b57cec5SDimitry Andric NVPTXTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts, 710b57cec5SDimitry Andric unsigned TargetPointerWidth); 720b57cec5SDimitry Andric 730b57cec5SDimitry Andric void getTargetDefines(const LangOptions &Opts, 740b57cec5SDimitry Andric MacroBuilder &Builder) const override; 750b57cec5SDimitry Andric 760b57cec5SDimitry Andric ArrayRef<Builtin::Info> getTargetBuiltins() const override; 770b57cec5SDimitry Andric 78*0fca6ea1SDimitry Andric bool useFP16ConversionIntrinsics() const override { return false; } 79*0fca6ea1SDimitry Andric 800b57cec5SDimitry Andric bool 810b57cec5SDimitry Andric initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, 820b57cec5SDimitry Andric StringRef CPU, 830b57cec5SDimitry Andric const std::vector<std::string> &FeaturesVec) const override { 84*0fca6ea1SDimitry Andric if (GPU != OffloadArch::UNUSED) 85*0fca6ea1SDimitry Andric Features[OffloadArchToString(GPU)] = true; 860b57cec5SDimitry Andric Features["ptx" + std::to_string(PTXVersion)] = true; 870b57cec5SDimitry Andric return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec); 880b57cec5SDimitry Andric } 890b57cec5SDimitry Andric 900b57cec5SDimitry Andric bool hasFeature(StringRef Feature) const override; 910b57cec5SDimitry Andric 920b57cec5SDimitry Andric ArrayRef<const char *> getGCCRegNames() const override; 930b57cec5SDimitry Andric 940b57cec5SDimitry Andric ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override { 950b57cec5SDimitry Andric // No aliases. 96bdd1243dSDimitry Andric return std::nullopt; 970b57cec5SDimitry Andric } 980b57cec5SDimitry Andric 990b57cec5SDimitry Andric bool validateAsmConstraint(const char *&Name, 1000b57cec5SDimitry Andric TargetInfo::ConstraintInfo &Info) const override { 1010b57cec5SDimitry Andric switch (*Name) { 1020b57cec5SDimitry Andric default: 1030b57cec5SDimitry Andric return false; 1040b57cec5SDimitry Andric case 'c': 1050b57cec5SDimitry Andric case 'h': 1060b57cec5SDimitry Andric case 'r': 1070b57cec5SDimitry Andric case 'l': 1080b57cec5SDimitry Andric case 'f': 1090b57cec5SDimitry Andric case 'd': 110*0fca6ea1SDimitry Andric case 'q': 1110b57cec5SDimitry Andric Info.setAllowsRegister(); 1120b57cec5SDimitry Andric return true; 1130b57cec5SDimitry Andric } 1140b57cec5SDimitry Andric } 1150b57cec5SDimitry Andric 11606c3fb27SDimitry Andric std::string_view getClobbers() const override { 1170b57cec5SDimitry Andric // FIXME: Is this really right? 1180b57cec5SDimitry Andric return ""; 1190b57cec5SDimitry Andric } 1200b57cec5SDimitry Andric 1210b57cec5SDimitry Andric BuiltinVaListKind getBuiltinVaListKind() const override { 122*0fca6ea1SDimitry Andric return TargetInfo::VoidPtrBuiltinVaList; 1230b57cec5SDimitry Andric } 1240b57cec5SDimitry Andric 1250b57cec5SDimitry Andric bool isValidCPUName(StringRef Name) const override { 126*0fca6ea1SDimitry Andric return StringToOffloadArch(Name) != OffloadArch::UNKNOWN; 1270b57cec5SDimitry Andric } 1280b57cec5SDimitry Andric 1290b57cec5SDimitry Andric void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override { 130*0fca6ea1SDimitry Andric for (int i = static_cast<int>(OffloadArch::SM_20); 131*0fca6ea1SDimitry Andric i < static_cast<int>(OffloadArch::Generic); ++i) 132*0fca6ea1SDimitry Andric Values.emplace_back(OffloadArchToString(static_cast<OffloadArch>(i))); 1330b57cec5SDimitry Andric } 1340b57cec5SDimitry Andric 1350b57cec5SDimitry Andric bool setCPU(const std::string &Name) override { 136*0fca6ea1SDimitry Andric GPU = StringToOffloadArch(Name); 137*0fca6ea1SDimitry Andric return GPU != OffloadArch::UNKNOWN; 1380b57cec5SDimitry Andric } 1390b57cec5SDimitry Andric 1400b57cec5SDimitry Andric void setSupportedOpenCLOpts() override { 1410b57cec5SDimitry Andric auto &Opts = getSupportedOpenCLOpts(); 142e8d8bef9SDimitry Andric Opts["cl_clang_storage_class_specifiers"] = true; 143e8d8bef9SDimitry Andric Opts["__cl_clang_function_pointers"] = true; 144e8d8bef9SDimitry Andric Opts["__cl_clang_variadic_functions"] = true; 145fe6060f1SDimitry Andric Opts["__cl_clang_non_portable_kernel_param_types"] = true; 146fe6060f1SDimitry Andric Opts["__cl_clang_bitfields"] = true; 1470b57cec5SDimitry Andric 148e8d8bef9SDimitry Andric Opts["cl_khr_fp64"] = true; 149fe6060f1SDimitry Andric Opts["__opencl_c_fp64"] = true; 150e8d8bef9SDimitry Andric Opts["cl_khr_byte_addressable_store"] = true; 151e8d8bef9SDimitry Andric Opts["cl_khr_global_int32_base_atomics"] = true; 152e8d8bef9SDimitry Andric Opts["cl_khr_global_int32_extended_atomics"] = true; 153e8d8bef9SDimitry Andric Opts["cl_khr_local_int32_base_atomics"] = true; 154e8d8bef9SDimitry Andric Opts["cl_khr_local_int32_extended_atomics"] = true; 1550b57cec5SDimitry Andric } 1560b57cec5SDimitry Andric 157349cc55cSDimitry Andric const llvm::omp::GV &getGridValue() const override { 158349cc55cSDimitry Andric return llvm::omp::NVPTXGridValues; 159349cc55cSDimitry Andric } 160349cc55cSDimitry Andric 1610b57cec5SDimitry Andric /// \returns If a target requires an address within a target specific address 1620b57cec5SDimitry Andric /// space \p AddressSpace to be converted in order to be used, then return the 1630b57cec5SDimitry Andric /// corresponding target specific DWARF address space. 1640b57cec5SDimitry Andric /// 165bdd1243dSDimitry Andric /// \returns Otherwise return std::nullopt and no conversion will be emitted 166bdd1243dSDimitry Andric /// in the DWARF. 167bdd1243dSDimitry Andric std::optional<unsigned> 1680b57cec5SDimitry Andric getDWARFAddressSpace(unsigned AddressSpace) const override { 169bdd1243dSDimitry Andric if (AddressSpace >= std::size(NVPTXDWARFAddrSpaceMap) || 1700b57cec5SDimitry Andric NVPTXDWARFAddrSpaceMap[AddressSpace] < 0) 171bdd1243dSDimitry Andric return std::nullopt; 1720b57cec5SDimitry Andric return NVPTXDWARFAddrSpaceMap[AddressSpace]; 1730b57cec5SDimitry Andric } 1740b57cec5SDimitry Andric 1750b57cec5SDimitry Andric CallingConvCheckResult checkCallingConvention(CallingConv CC) const override { 1760b57cec5SDimitry Andric // CUDA compilations support all of the host's calling conventions. 1770b57cec5SDimitry Andric // 1780b57cec5SDimitry Andric // TODO: We should warn if you apply a non-default CC to anything other than 1790b57cec5SDimitry Andric // a host function. 1800b57cec5SDimitry Andric if (HostTarget) 1810b57cec5SDimitry Andric return HostTarget->checkCallingConvention(CC); 1820b57cec5SDimitry Andric return CCCR_Warning; 1830b57cec5SDimitry Andric } 1845ffd83dbSDimitry Andric 1850eae32dcSDimitry Andric bool hasBitIntType() const override { return true; } 186bdd1243dSDimitry Andric bool hasBFloat16Type() const override { return true; } 1875f757f3fSDimitry Andric 188*0fca6ea1SDimitry Andric OffloadArch getGPU() const { return GPU; } 1890b57cec5SDimitry Andric }; 1900b57cec5SDimitry Andric } // namespace targets 1910b57cec5SDimitry Andric } // namespace clang 1920b57cec5SDimitry Andric #endif // LLVM_CLANG_LIB_BASIC_TARGETS_NVPTX_H 193