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 OffloadArch 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 useFP16ConversionIntrinsics()78 bool useFP16ConversionIntrinsics() const override { return false; } 79 80 bool initFeatureMap(llvm::StringMap<bool> & Features,DiagnosticsEngine & Diags,StringRef CPU,const std::vector<std::string> & FeaturesVec)81 initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, 82 StringRef CPU, 83 const std::vector<std::string> &FeaturesVec) const override { 84 if (GPU != OffloadArch::UNUSED) 85 Features[OffloadArchToString(GPU)] = true; 86 Features["ptx" + std::to_string(PTXVersion)] = true; 87 return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec); 88 } 89 90 bool hasFeature(StringRef Feature) const override; 91 92 ArrayRef<const char *> getGCCRegNames() const override; 93 getGCCRegAliases()94 ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override { 95 // No aliases. 96 return std::nullopt; 97 } 98 validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & Info)99 bool validateAsmConstraint(const char *&Name, 100 TargetInfo::ConstraintInfo &Info) const override { 101 switch (*Name) { 102 default: 103 return false; 104 case 'c': 105 case 'h': 106 case 'r': 107 case 'l': 108 case 'f': 109 case 'd': 110 case 'q': 111 Info.setAllowsRegister(); 112 return true; 113 } 114 } 115 getClobbers()116 std::string_view getClobbers() const override { 117 // FIXME: Is this really right? 118 return ""; 119 } 120 getBuiltinVaListKind()121 BuiltinVaListKind getBuiltinVaListKind() const override { 122 return TargetInfo::VoidPtrBuiltinVaList; 123 } 124 isValidCPUName(StringRef Name)125 bool isValidCPUName(StringRef Name) const override { 126 return StringToOffloadArch(Name) != OffloadArch::UNKNOWN; 127 } 128 fillValidCPUList(SmallVectorImpl<StringRef> & Values)129 void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override { 130 for (int i = static_cast<int>(OffloadArch::SM_20); 131 i < static_cast<int>(OffloadArch::Generic); ++i) 132 Values.emplace_back(OffloadArchToString(static_cast<OffloadArch>(i))); 133 } 134 setCPU(const std::string & Name)135 bool setCPU(const std::string &Name) override { 136 GPU = StringToOffloadArch(Name); 137 return GPU != OffloadArch::UNKNOWN; 138 } 139 setSupportedOpenCLOpts()140 void setSupportedOpenCLOpts() override { 141 auto &Opts = getSupportedOpenCLOpts(); 142 Opts["cl_clang_storage_class_specifiers"] = true; 143 Opts["__cl_clang_function_pointers"] = true; 144 Opts["__cl_clang_variadic_functions"] = true; 145 Opts["__cl_clang_non_portable_kernel_param_types"] = true; 146 Opts["__cl_clang_bitfields"] = true; 147 148 Opts["cl_khr_fp64"] = true; 149 Opts["__opencl_c_fp64"] = true; 150 Opts["cl_khr_byte_addressable_store"] = true; 151 Opts["cl_khr_global_int32_base_atomics"] = true; 152 Opts["cl_khr_global_int32_extended_atomics"] = true; 153 Opts["cl_khr_local_int32_base_atomics"] = true; 154 Opts["cl_khr_local_int32_extended_atomics"] = true; 155 } 156 getGridValue()157 const llvm::omp::GV &getGridValue() const override { 158 return llvm::omp::NVPTXGridValues; 159 } 160 161 /// \returns If a target requires an address within a target specific address 162 /// space \p AddressSpace to be converted in order to be used, then return the 163 /// corresponding target specific DWARF address space. 164 /// 165 /// \returns Otherwise return std::nullopt and no conversion will be emitted 166 /// in the DWARF. 167 std::optional<unsigned> getDWARFAddressSpace(unsigned AddressSpace)168 getDWARFAddressSpace(unsigned AddressSpace) const override { 169 if (AddressSpace >= std::size(NVPTXDWARFAddrSpaceMap) || 170 NVPTXDWARFAddrSpaceMap[AddressSpace] < 0) 171 return std::nullopt; 172 return NVPTXDWARFAddrSpaceMap[AddressSpace]; 173 } 174 checkCallingConvention(CallingConv CC)175 CallingConvCheckResult checkCallingConvention(CallingConv CC) const override { 176 // CUDA compilations support all of the host's calling conventions. 177 // 178 // TODO: We should warn if you apply a non-default CC to anything other than 179 // a host function. 180 if (HostTarget) 181 return HostTarget->checkCallingConvention(CC); 182 return CCCR_Warning; 183 } 184 hasBitIntType()185 bool hasBitIntType() const override { return true; } hasBFloat16Type()186 bool hasBFloat16Type() const override { return true; } 187 getGPU()188 OffloadArch getGPU() const { return GPU; } 189 }; 190 } // namespace targets 191 } // namespace clang 192 #endif // LLVM_CLANG_LIB_BASIC_TARGETS_NVPTX_H 193