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