214 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8//9// This file declares NVPTX TargetInfo objects.10//11//===----------------------------------------------------------------------===//12 13#ifndef LLVM_CLANG_LIB_BASIC_TARGETS_NVPTX_H14#define LLVM_CLANG_LIB_BASIC_TARGETS_NVPTX_H15 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/Support/NVPTXAddrSpace.h"21#include "llvm/TargetParser/Triple.h"22#include <optional>23 24namespace clang {25namespace targets {26 27static const unsigned NVPTXAddrSpaceMap[] = {28 0, // Default29 1, // opencl_global30 3, // opencl_local31 4, // opencl_constant32 0, // opencl_private33 // FIXME: generic has to be added to the target34 0, // opencl_generic35 1, // opencl_global_device36 1, // opencl_global_host37 1, // cuda_device38 4, // cuda_constant39 3, // cuda_shared40 1, // sycl_global41 1, // sycl_global_device42 1, // sycl_global_host43 3, // sycl_local44 0, // sycl_private45 0, // ptr32_sptr46 0, // ptr32_uptr47 0, // ptr6448 0, // hlsl_groupshared49 0, // hlsl_constant50 0, // hlsl_private51 0, // hlsl_device52 0, // hlsl_input53 // Wasm address space values for this target are dummy values,54 // as it is only enabled for Wasm targets.55 20, // wasm_funcref56};57 58/// The DWARF address class. Taken from59/// https://docs.nvidia.com/cuda/archive/10.0/ptx-writers-guide-to-interoperability/index.html#cuda-specific-dwarf60static const int NVPTXDWARFAddrSpaceMap[] = {61 -1, // Default, opencl_private or opencl_generic - not defined62 5, // opencl_global63 -1,64 8, // opencl_local or cuda_shared65 4, // opencl_constant or cuda_constant66};67 68class LLVM_LIBRARY_VISIBILITY NVPTXTargetInfo : public TargetInfo {69 static const char *const GCCRegNames[];70 OffloadArch GPU;71 uint32_t PTXVersion;72 std::unique_ptr<TargetInfo> HostTarget;73 74public:75 NVPTXTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts,76 unsigned TargetPointerWidth);77 78 void getTargetDefines(const LangOptions &Opts,79 MacroBuilder &Builder) const override;80 81 llvm::SmallVector<Builtin::InfosShard> getTargetBuiltins() const override;82 83 bool useFP16ConversionIntrinsics() const override { return false; }84 85 bool86 initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,87 StringRef CPU,88 const std::vector<std::string> &FeaturesVec) const override {89 if (GPU != OffloadArch::UNUSED)90 Features[OffloadArchToString(GPU)] = true;91 Features["ptx" + std::to_string(PTXVersion)] = true;92 return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);93 }94 95 bool hasFeature(StringRef Feature) const override;96 97 virtual bool isAddressSpaceSupersetOf(LangAS A, LangAS B) const override {98 // The generic address space AS(0) is a superset of all the other address99 // spaces used by the backend target.100 return A == B ||101 ((A == LangAS::Default ||102 (isTargetAddressSpace(A) &&103 toTargetAddressSpace(A) ==104 llvm::NVPTXAS::ADDRESS_SPACE_GENERIC)) &&105 isTargetAddressSpace(B) &&106 toTargetAddressSpace(B) >= llvm::NVPTXAS::ADDRESS_SPACE_GENERIC &&107 toTargetAddressSpace(B) <= llvm::NVPTXAS::ADDRESS_SPACE_LOCAL &&108 toTargetAddressSpace(B) != 2);109 }110 111 ArrayRef<const char *> getGCCRegNames() const override;112 113 ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {114 // No aliases.115 return {};116 }117 118 bool validateAsmConstraint(const char *&Name,119 TargetInfo::ConstraintInfo &Info) const override {120 switch (*Name) {121 default:122 return false;123 case 'c':124 case 'h':125 case 'r':126 case 'l':127 case 'f':128 case 'd':129 case 'q':130 Info.setAllowsRegister();131 return true;132 }133 }134 135 std::string_view getClobbers() const override {136 // FIXME: Is this really right?137 return "";138 }139 140 BuiltinVaListKind getBuiltinVaListKind() const override {141 return TargetInfo::CharPtrBuiltinVaList;142 }143 144 bool isValidCPUName(StringRef Name) const override {145 return StringToOffloadArch(Name) != OffloadArch::UNKNOWN;146 }147 148 void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override {149 for (int i = static_cast<int>(OffloadArch::SM_20);150 i < static_cast<int>(OffloadArch::Generic); ++i)151 Values.emplace_back(OffloadArchToString(static_cast<OffloadArch>(i)));152 }153 154 bool setCPU(const std::string &Name) override {155 GPU = StringToOffloadArch(Name);156 return GPU != OffloadArch::UNKNOWN;157 }158 159 void setSupportedOpenCLOpts() override {160 auto &Opts = getSupportedOpenCLOpts();161 Opts["cl_clang_storage_class_specifiers"] = true;162 Opts["__cl_clang_function_pointers"] = true;163 Opts["__cl_clang_variadic_functions"] = true;164 Opts["__cl_clang_non_portable_kernel_param_types"] = true;165 Opts["__cl_clang_bitfields"] = true;166 167 Opts["cl_khr_fp64"] = true;168 Opts["__opencl_c_fp64"] = true;169 Opts["cl_khr_byte_addressable_store"] = true;170 Opts["cl_khr_global_int32_base_atomics"] = true;171 Opts["cl_khr_global_int32_extended_atomics"] = true;172 Opts["cl_khr_local_int32_base_atomics"] = true;173 Opts["cl_khr_local_int32_extended_atomics"] = true;174 175 Opts["__opencl_c_generic_address_space"] = true;176 }177 178 const llvm::omp::GV &getGridValue() const override {179 return llvm::omp::NVPTXGridValues;180 }181 182 /// \returns If a target requires an address within a target specific address183 /// space \p AddressSpace to be converted in order to be used, then return the184 /// corresponding target specific DWARF address space.185 ///186 /// \returns Otherwise return std::nullopt and no conversion will be emitted187 /// in the DWARF.188 std::optional<unsigned>189 getDWARFAddressSpace(unsigned AddressSpace) const override {190 if (AddressSpace >= std::size(NVPTXDWARFAddrSpaceMap) ||191 NVPTXDWARFAddrSpaceMap[AddressSpace] < 0)192 return std::nullopt;193 return NVPTXDWARFAddrSpaceMap[AddressSpace];194 }195 196 CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {197 // CUDA compilations support all of the host's calling conventions.198 //199 // TODO: We should warn if you apply a non-default CC to anything other than200 // a host function.201 if (HostTarget)202 return HostTarget->checkCallingConvention(CC);203 return CC == CC_DeviceKernel ? CCCR_OK : CCCR_Warning;204 }205 206 bool hasBitIntType() const override { return true; }207 bool hasBFloat16Type() const override { return true; }208 209 OffloadArch getGPU() const { return GPU; }210};211} // namespace targets212} // namespace clang213#endif // LLVM_CLANG_LIB_BASIC_TARGETS_NVPTX_H214