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/ADT/Triple.h" 20 #include "llvm/Support/Compiler.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 }; 49 50 /// The DWARF address class. Taken from 51 /// https://docs.nvidia.com/cuda/archive/10.0/ptx-writers-guide-to-interoperability/index.html#cuda-specific-dwarf 52 static const int NVPTXDWARFAddrSpaceMap[] = { 53 -1, // Default, opencl_private or opencl_generic - not defined 54 5, // opencl_global 55 -1, 56 8, // opencl_local or cuda_shared 57 4, // opencl_constant or cuda_constant 58 }; 59 60 class LLVM_LIBRARY_VISIBILITY NVPTXTargetInfo : public TargetInfo { 61 static const char *const GCCRegNames[]; 62 CudaArch GPU; 63 uint32_t PTXVersion; 64 std::unique_ptr<TargetInfo> HostTarget; 65 66 public: 67 NVPTXTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts, 68 unsigned TargetPointerWidth); 69 70 void getTargetDefines(const LangOptions &Opts, 71 MacroBuilder &Builder) const override; 72 73 ArrayRef<Builtin::Info> getTargetBuiltins() const override; 74 75 bool 76 initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, 77 StringRef CPU, 78 const std::vector<std::string> &FeaturesVec) const override { 79 Features[CudaArchToString(GPU)] = true; 80 Features["ptx" + std::to_string(PTXVersion)] = true; 81 return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec); 82 } 83 84 bool hasFeature(StringRef Feature) const override; 85 86 ArrayRef<const char *> getGCCRegNames() const override; 87 88 ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override { 89 // No aliases. 90 return std::nullopt; 91 } 92 93 bool validateAsmConstraint(const char *&Name, 94 TargetInfo::ConstraintInfo &Info) const override { 95 switch (*Name) { 96 default: 97 return false; 98 case 'c': 99 case 'h': 100 case 'r': 101 case 'l': 102 case 'f': 103 case 'd': 104 Info.setAllowsRegister(); 105 return true; 106 } 107 } 108 109 const char *getClobbers() const override { 110 // FIXME: Is this really right? 111 return ""; 112 } 113 114 BuiltinVaListKind getBuiltinVaListKind() const override { 115 // FIXME: implement 116 return TargetInfo::CharPtrBuiltinVaList; 117 } 118 119 bool isValidCPUName(StringRef Name) const override { 120 return StringToCudaArch(Name) != CudaArch::UNKNOWN; 121 } 122 123 void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override { 124 for (int i = static_cast<int>(CudaArch::SM_20); 125 i < static_cast<int>(CudaArch::Generic); ++i) 126 Values.emplace_back(CudaArchToString(static_cast<CudaArch>(i))); 127 } 128 129 bool setCPU(const std::string &Name) override { 130 GPU = StringToCudaArch(Name); 131 return GPU != CudaArch::UNKNOWN; 132 } 133 134 void setSupportedOpenCLOpts() override { 135 auto &Opts = getSupportedOpenCLOpts(); 136 Opts["cl_clang_storage_class_specifiers"] = true; 137 Opts["__cl_clang_function_pointers"] = true; 138 Opts["__cl_clang_variadic_functions"] = true; 139 Opts["__cl_clang_non_portable_kernel_param_types"] = true; 140 Opts["__cl_clang_bitfields"] = true; 141 142 Opts["cl_khr_fp64"] = true; 143 Opts["__opencl_c_fp64"] = true; 144 Opts["cl_khr_byte_addressable_store"] = true; 145 Opts["cl_khr_global_int32_base_atomics"] = true; 146 Opts["cl_khr_global_int32_extended_atomics"] = true; 147 Opts["cl_khr_local_int32_base_atomics"] = true; 148 Opts["cl_khr_local_int32_extended_atomics"] = true; 149 } 150 151 const llvm::omp::GV &getGridValue() const override { 152 return llvm::omp::NVPTXGridValues; 153 } 154 155 /// \returns If a target requires an address within a target specific address 156 /// space \p AddressSpace to be converted in order to be used, then return the 157 /// corresponding target specific DWARF address space. 158 /// 159 /// \returns Otherwise return std::nullopt and no conversion will be emitted 160 /// in the DWARF. 161 std::optional<unsigned> 162 getDWARFAddressSpace(unsigned AddressSpace) const override { 163 if (AddressSpace >= std::size(NVPTXDWARFAddrSpaceMap) || 164 NVPTXDWARFAddrSpaceMap[AddressSpace] < 0) 165 return std::nullopt; 166 return NVPTXDWARFAddrSpaceMap[AddressSpace]; 167 } 168 169 CallingConvCheckResult checkCallingConvention(CallingConv CC) const override { 170 // CUDA compilations support all of the host's calling conventions. 171 // 172 // TODO: We should warn if you apply a non-default CC to anything other than 173 // a host function. 174 if (HostTarget) 175 return HostTarget->checkCallingConvention(CC); 176 return CCCR_Warning; 177 } 178 179 bool hasBitIntType() const override { return true; } 180 bool hasBFloat16Type() const override { return true; } 181 const char *getBFloat16Mangling() const override { return "u6__bf16"; }; 182 }; 183 } // namespace targets 184 } // namespace clang 185 #endif // LLVM_CLANG_LIB_BASIC_TARGETS_NVPTX_H 186