1 //===--- NVPTX.h - Declare NVPTX target feature support ---------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file declares NVPTX TargetInfo objects. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef LLVM_CLANG_LIB_BASIC_TARGETS_NVPTX_H 14 #define LLVM_CLANG_LIB_BASIC_TARGETS_NVPTX_H 15 16 #include "clang/Basic/Cuda.h" 17 #include "clang/Basic/TargetInfo.h" 18 #include "clang/Basic/TargetOptions.h" 19 #include "llvm/Support/Compiler.h" 20 #include "llvm/TargetParser/Triple.h" 21 #include <optional> 22 23 namespace clang { 24 namespace targets { 25 26 static const unsigned NVPTXAddrSpaceMap[] = { 27 0, // Default 28 1, // opencl_global 29 3, // opencl_local 30 4, // opencl_constant 31 0, // opencl_private 32 // FIXME: generic has to be added to the target 33 0, // opencl_generic 34 1, // opencl_global_device 35 1, // opencl_global_host 36 1, // cuda_device 37 4, // cuda_constant 38 3, // cuda_shared 39 1, // sycl_global 40 1, // sycl_global_device 41 1, // sycl_global_host 42 3, // sycl_local 43 0, // sycl_private 44 0, // ptr32_sptr 45 0, // ptr32_uptr 46 0, // ptr64 47 0, // hlsl_groupshared 48 // Wasm address space values for this target are dummy values, 49 // as it is only enabled for Wasm targets. 50 20, // wasm_funcref 51 }; 52 53 /// The DWARF address class. Taken from 54 /// https://docs.nvidia.com/cuda/archive/10.0/ptx-writers-guide-to-interoperability/index.html#cuda-specific-dwarf 55 static const int NVPTXDWARFAddrSpaceMap[] = { 56 -1, // Default, opencl_private or opencl_generic - not defined 57 5, // opencl_global 58 -1, 59 8, // opencl_local or cuda_shared 60 4, // opencl_constant or cuda_constant 61 }; 62 63 class LLVM_LIBRARY_VISIBILITY NVPTXTargetInfo : public TargetInfo { 64 static const char *const GCCRegNames[]; 65 CudaArch GPU; 66 uint32_t PTXVersion; 67 std::unique_ptr<TargetInfo> HostTarget; 68 69 public: 70 NVPTXTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts, 71 unsigned TargetPointerWidth); 72 73 void getTargetDefines(const LangOptions &Opts, 74 MacroBuilder &Builder) const override; 75 76 ArrayRef<Builtin::Info> getTargetBuiltins() const override; 77 78 bool 79 initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, 80 StringRef CPU, 81 const std::vector<std::string> &FeaturesVec) const override { 82 Features[CudaArchToString(GPU)] = true; 83 Features["ptx" + std::to_string(PTXVersion)] = true; 84 return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec); 85 } 86 87 bool hasFeature(StringRef Feature) const override; 88 89 ArrayRef<const char *> getGCCRegNames() const override; 90 91 ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override { 92 // No aliases. 93 return std::nullopt; 94 } 95 96 bool validateAsmConstraint(const char *&Name, 97 TargetInfo::ConstraintInfo &Info) const override { 98 switch (*Name) { 99 default: 100 return false; 101 case 'c': 102 case 'h': 103 case 'r': 104 case 'l': 105 case 'f': 106 case 'd': 107 Info.setAllowsRegister(); 108 return true; 109 } 110 } 111 112 std::string_view getClobbers() const override { 113 // FIXME: Is this really right? 114 return ""; 115 } 116 117 BuiltinVaListKind getBuiltinVaListKind() const override { 118 // FIXME: implement 119 return TargetInfo::CharPtrBuiltinVaList; 120 } 121 122 bool isValidCPUName(StringRef Name) const override { 123 return StringToCudaArch(Name) != CudaArch::UNKNOWN; 124 } 125 126 void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override { 127 for (int i = static_cast<int>(CudaArch::SM_20); 128 i < static_cast<int>(CudaArch::Generic); ++i) 129 Values.emplace_back(CudaArchToString(static_cast<CudaArch>(i))); 130 } 131 132 bool setCPU(const std::string &Name) override { 133 GPU = StringToCudaArch(Name); 134 return GPU != CudaArch::UNKNOWN; 135 } 136 137 void setSupportedOpenCLOpts() override { 138 auto &Opts = getSupportedOpenCLOpts(); 139 Opts["cl_clang_storage_class_specifiers"] = true; 140 Opts["__cl_clang_function_pointers"] = true; 141 Opts["__cl_clang_variadic_functions"] = true; 142 Opts["__cl_clang_non_portable_kernel_param_types"] = true; 143 Opts["__cl_clang_bitfields"] = true; 144 145 Opts["cl_khr_fp64"] = true; 146 Opts["__opencl_c_fp64"] = true; 147 Opts["cl_khr_byte_addressable_store"] = true; 148 Opts["cl_khr_global_int32_base_atomics"] = true; 149 Opts["cl_khr_global_int32_extended_atomics"] = true; 150 Opts["cl_khr_local_int32_base_atomics"] = true; 151 Opts["cl_khr_local_int32_extended_atomics"] = true; 152 } 153 154 const llvm::omp::GV &getGridValue() const override { 155 return llvm::omp::NVPTXGridValues; 156 } 157 158 /// \returns If a target requires an address within a target specific address 159 /// space \p AddressSpace to be converted in order to be used, then return the 160 /// corresponding target specific DWARF address space. 161 /// 162 /// \returns Otherwise return std::nullopt and no conversion will be emitted 163 /// in the DWARF. 164 std::optional<unsigned> 165 getDWARFAddressSpace(unsigned AddressSpace) const override { 166 if (AddressSpace >= std::size(NVPTXDWARFAddrSpaceMap) || 167 NVPTXDWARFAddrSpaceMap[AddressSpace] < 0) 168 return std::nullopt; 169 return NVPTXDWARFAddrSpaceMap[AddressSpace]; 170 } 171 172 CallingConvCheckResult checkCallingConvention(CallingConv CC) const override { 173 // CUDA compilations support all of the host's calling conventions. 174 // 175 // TODO: We should warn if you apply a non-default CC to anything other than 176 // a host function. 177 if (HostTarget) 178 return HostTarget->checkCallingConvention(CC); 179 return CCCR_Warning; 180 } 181 182 bool hasBitIntType() const override { return true; } 183 bool hasBFloat16Type() const override { return true; } 184 185 CudaArch getGPU() const { return GPU; } 186 }; 187 } // namespace targets 188 } // namespace clang 189 #endif // LLVM_CLANG_LIB_BASIC_TARGETS_NVPTX_H 190