NVPTX.h revision 1.1.1.4
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
23namespace clang {
24namespace targets {
25
26static 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
52static 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
60class 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
66public:
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