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