Coverage Report

Created: 2021-01-23 06:44

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/Basic/Targets/NVPTX.cpp
Line
Count
Source (jump to first uncovered line)
1
//===--- NVPTX.cpp - Implement NVPTX target feature support ---------------===//
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 implements NVPTX TargetInfo objects.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "NVPTX.h"
14
#include "Targets.h"
15
#include "clang/Basic/Builtins.h"
16
#include "clang/Basic/MacroBuilder.h"
17
#include "clang/Basic/TargetBuiltins.h"
18
#include "llvm/ADT/StringSwitch.h"
19
#include "llvm/Frontend/OpenMP/OMPGridValues.h"
20
21
using namespace clang;
22
using namespace clang::targets;
23
24
const Builtin::Info NVPTXTargetInfo::BuiltinInfo[] = {
25
#define BUILTIN(ID, TYPE, ATTRS)                                               \
26
  {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
27
#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER)                                    \
28
  {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
29
#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE)                               \
30
  {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, FEATURE},
31
#include "clang/Basic/BuiltinsNVPTX.def"
32
};
33
34
const char *const NVPTXTargetInfo::GCCRegNames[] = {"r0"};
35
36
NVPTXTargetInfo::NVPTXTargetInfo(const llvm::Triple &Triple,
37
                                 const TargetOptions &Opts,
38
                                 unsigned TargetPointerWidth)
39
436
    : TargetInfo(Triple) {
40
436
  assert((TargetPointerWidth == 32 || TargetPointerWidth == 64) &&
41
436
         "NVPTX only supports 32- and 64-bit modes.");
42
43
436
  PTXVersion = 32;
44
8
  for (const StringRef Feature : Opts.FeaturesAsWritten) {
45
8
    if (!Feature.startswith("+ptx"))
46
0
      continue;
47
8
    PTXVersion = llvm::StringSwitch<unsigned>(Feature)
48
8
                     .Case("+ptx70", 70)
49
8
                     .Case("+ptx65", 65)
50
8
                     .Case("+ptx64", 64)
51
8
                     .Case("+ptx63", 63)
52
8
                     .Case("+ptx61", 61)
53
8
                     .Case("+ptx60", 60)
54
8
                     .Case("+ptx50", 50)
55
8
                     .Case("+ptx43", 43)
56
8
                     .Case("+ptx42", 42)
57
8
                     .Case("+ptx41", 41)
58
8
                     .Case("+ptx40", 40)
59
8
                     .Case("+ptx32", 32)
60
8
                     .Default(32);
61
8
  }
62
63
436
  TLSSupported = false;
64
436
  VLASupported = false;
65
436
  AddrSpaceMap = &NVPTXAddrSpaceMap;
66
436
  GridValues = llvm::omp::NVPTXGpuGridValues;
67
436
  UseAddrSpaceMapMangling = true;
68
69
  // Define available target features
70
  // These must be defined in sorted order!
71
436
  NoAsmVariants = true;
72
436
  GPU = CudaArch::SM_20;
73
74
436
  if (TargetPointerWidth == 32)
75
193
    resetDataLayout("e-p:32:32-i64:64-i128:128-v16:16-v32:32-n16:32:64");
76
243
  else if (Opts.NVPTXUseShortPointers)
77
0
    resetDataLayout(
78
0
        "e-p3:32:32-p4:32:32-p5:32:32-i64:64-i128:128-v16:16-v32:32-n16:32:64");
79
243
  else
80
243
    resetDataLayout("e-i64:64-i128:128-v16:16-v32:32-n16:32:64");
81
82
  // If possible, get a TargetInfo for our host triple, so we can match its
83
  // types.
84
436
  llvm::Triple HostTriple(Opts.HostTriple);
85
436
  if (!HostTriple.isNVPTX())
86
436
    HostTarget.reset(AllocateTarget(llvm::Triple(Opts.HostTriple), Opts));
87
88
  // If no host target, make some guesses about the data layout and return.
89
436
  if (!HostTarget) {
90
321
    LongWidth = LongAlign = TargetPointerWidth;
91
321
    PointerWidth = PointerAlign = TargetPointerWidth;
92
321
    switch (TargetPointerWidth) {
93
174
    case 32:
94
174
      SizeType = TargetInfo::UnsignedInt;
95
174
      PtrDiffType = TargetInfo::SignedInt;
96
174
      IntPtrType = TargetInfo::SignedInt;
97
174
      break;
98
147
    case 64:
99
147
      SizeType = TargetInfo::UnsignedLong;
100
147
      PtrDiffType = TargetInfo::SignedLong;
101
147
      IntPtrType = TargetInfo::SignedLong;
102
147
      break;
103
0
    default:
104
0
      llvm_unreachable("TargetPointerWidth must be 32 or 64");
105
321
    }
106
321
    return;
107
321
  }
108
109
  // Copy properties from host target.
110
115
  PointerWidth = HostTarget->getPointerWidth(/* AddrSpace = */ 0);
111
115
  PointerAlign = HostTarget->getPointerAlign(/* AddrSpace = */ 0);
112
115
  BoolWidth = HostTarget->getBoolWidth();
113
115
  BoolAlign = HostTarget->getBoolAlign();
114
115
  IntWidth = HostTarget->getIntWidth();
115
115
  IntAlign = HostTarget->getIntAlign();
116
115
  HalfWidth = HostTarget->getHalfWidth();
117
115
  HalfAlign = HostTarget->getHalfAlign();
118
115
  FloatWidth = HostTarget->getFloatWidth();
119
115
  FloatAlign = HostTarget->getFloatAlign();
120
115
  DoubleWidth = HostTarget->getDoubleWidth();
121
115
  DoubleAlign = HostTarget->getDoubleAlign();
122
115
  LongWidth = HostTarget->getLongWidth();
123
115
  LongAlign = HostTarget->getLongAlign();
124
115
  LongLongWidth = HostTarget->getLongLongWidth();
125
115
  LongLongAlign = HostTarget->getLongLongAlign();
126
115
  MinGlobalAlign = HostTarget->getMinGlobalAlign(/* TypeSize = */ 0);
127
115
  NewAlign = HostTarget->getNewAlign();
128
115
  DefaultAlignForAttributeAligned =
129
115
      HostTarget->getDefaultAlignForAttributeAligned();
130
115
  SizeType = HostTarget->getSizeType();
131
115
  IntMaxType = HostTarget->getIntMaxType();
132
115
  PtrDiffType = HostTarget->getPtrDiffType(/* AddrSpace = */ 0);
133
115
  IntPtrType = HostTarget->getIntPtrType();
134
115
  WCharType = HostTarget->getWCharType();
135
115
  WIntType = HostTarget->getWIntType();
136
115
  Char16Type = HostTarget->getChar16Type();
137
115
  Char32Type = HostTarget->getChar32Type();
138
115
  Int64Type = HostTarget->getInt64Type();
139
115
  SigAtomicType = HostTarget->getSigAtomicType();
140
115
  ProcessIDType = HostTarget->getProcessIDType();
141
142
115
  UseBitFieldTypeAlignment = HostTarget->useBitFieldTypeAlignment();
143
115
  UseZeroLengthBitfieldAlignment = HostTarget->useZeroLengthBitfieldAlignment();
144
115
  UseExplicitBitFieldAlignment = HostTarget->useExplicitBitFieldAlignment();
145
115
  ZeroLengthBitfieldBoundary = HostTarget->getZeroLengthBitfieldBoundary();
146
147
  // This is a bit of a lie, but it controls __GCC_ATOMIC_XXX_LOCK_FREE, and
148
  // we need those macros to be identical on host and device, because (among
149
  // other things) they affect which standard library classes are defined, and
150
  // we need all classes to be defined on both the host and device.
151
115
  MaxAtomicInlineWidth = HostTarget->getMaxAtomicInlineWidth();
152
153
  // Properties intentionally not copied from host:
154
  // - LargeArrayMinWidth, LargeArrayAlign: Not visible across the
155
  //   host/device boundary.
156
  // - SuitableAlign: Not visible across the host/device boundary, and may
157
  //   correctly be different on host/device, e.g. if host has wider vector
158
  //   types than device.
159
  // - LongDoubleWidth, LongDoubleAlign: nvptx's long double type is the same
160
  //   as its double type, but that's not necessarily true on the host.
161
  //   TODO: nvcc emits a warning when using long double on device; we should
162
  //   do the same.
163
115
}
Unexecuted instantiation: clang::targets::NVPTXTargetInfo::NVPTXTargetInfo(llvm::Triple const&, clang::TargetOptions const&, unsigned int)
clang::targets::NVPTXTargetInfo::NVPTXTargetInfo(llvm::Triple const&, clang::TargetOptions const&, unsigned int)
Line
Count
Source
39
436
    : TargetInfo(Triple) {
40
436
  assert((TargetPointerWidth == 32 || TargetPointerWidth == 64) &&
41
436
         "NVPTX only supports 32- and 64-bit modes.");
42
43
436
  PTXVersion = 32;
44
8
  for (const StringRef Feature : Opts.FeaturesAsWritten) {
45
8
    if (!Feature.startswith("+ptx"))
46
0
      continue;
47
8
    PTXVersion = llvm::StringSwitch<unsigned>(Feature)
48
8
                     .Case("+ptx70", 70)
49
8
                     .Case("+ptx65", 65)
50
8
                     .Case("+ptx64", 64)
51
8
                     .Case("+ptx63", 63)
52
8
                     .Case("+ptx61", 61)
53
8
                     .Case("+ptx60", 60)
54
8
                     .Case("+ptx50", 50)
55
8
                     .Case("+ptx43", 43)
56
8
                     .Case("+ptx42", 42)
57
8
                     .Case("+ptx41", 41)
58
8
                     .Case("+ptx40", 40)
59
8
                     .Case("+ptx32", 32)
60
8
                     .Default(32);
61
8
  }
62
63
436
  TLSSupported = false;
64
436
  VLASupported = false;
65
436
  AddrSpaceMap = &NVPTXAddrSpaceMap;
66
436
  GridValues = llvm::omp::NVPTXGpuGridValues;
67
436
  UseAddrSpaceMapMangling = true;
68
69
  // Define available target features
70
  // These must be defined in sorted order!
71
436
  NoAsmVariants = true;
72
436
  GPU = CudaArch::SM_20;
73
74
436
  if (TargetPointerWidth == 32)
75
193
    resetDataLayout("e-p:32:32-i64:64-i128:128-v16:16-v32:32-n16:32:64");
76
243
  else if (Opts.NVPTXUseShortPointers)
77
0
    resetDataLayout(
78
0
        "e-p3:32:32-p4:32:32-p5:32:32-i64:64-i128:128-v16:16-v32:32-n16:32:64");
79
243
  else
80
243
    resetDataLayout("e-i64:64-i128:128-v16:16-v32:32-n16:32:64");
81
82
  // If possible, get a TargetInfo for our host triple, so we can match its
83
  // types.
84
436
  llvm::Triple HostTriple(Opts.HostTriple);
85
436
  if (!HostTriple.isNVPTX())
86
436
    HostTarget.reset(AllocateTarget(llvm::Triple(Opts.HostTriple), Opts));
87
88
  // If no host target, make some guesses about the data layout and return.
89
436
  if (!HostTarget) {
90
321
    LongWidth = LongAlign = TargetPointerWidth;
91
321
    PointerWidth = PointerAlign = TargetPointerWidth;
92
321
    switch (TargetPointerWidth) {
93
174
    case 32:
94
174
      SizeType = TargetInfo::UnsignedInt;
95
174
      PtrDiffType = TargetInfo::SignedInt;
96
174
      IntPtrType = TargetInfo::SignedInt;
97
174
      break;
98
147
    case 64:
99
147
      SizeType = TargetInfo::UnsignedLong;
100
147
      PtrDiffType = TargetInfo::SignedLong;
101
147
      IntPtrType = TargetInfo::SignedLong;
102
147
      break;
103
0
    default:
104
0
      llvm_unreachable("TargetPointerWidth must be 32 or 64");
105
321
    }
106
321
    return;
107
321
  }
108
109
  // Copy properties from host target.
110
115
  PointerWidth = HostTarget->getPointerWidth(/* AddrSpace = */ 0);
111
115
  PointerAlign = HostTarget->getPointerAlign(/* AddrSpace = */ 0);
112
115
  BoolWidth = HostTarget->getBoolWidth();
113
115
  BoolAlign = HostTarget->getBoolAlign();
114
115
  IntWidth = HostTarget->getIntWidth();
115
115
  IntAlign = HostTarget->getIntAlign();
116
115
  HalfWidth = HostTarget->getHalfWidth();
117
115
  HalfAlign = HostTarget->getHalfAlign();
118
115
  FloatWidth = HostTarget->getFloatWidth();
119
115
  FloatAlign = HostTarget->getFloatAlign();
120
115
  DoubleWidth = HostTarget->getDoubleWidth();
121
115
  DoubleAlign = HostTarget->getDoubleAlign();
122
115
  LongWidth = HostTarget->getLongWidth();
123
115
  LongAlign = HostTarget->getLongAlign();
124
115
  LongLongWidth = HostTarget->getLongLongWidth();
125
115
  LongLongAlign = HostTarget->getLongLongAlign();
126
115
  MinGlobalAlign = HostTarget->getMinGlobalAlign(/* TypeSize = */ 0);
127
115
  NewAlign = HostTarget->getNewAlign();
128
115
  DefaultAlignForAttributeAligned =
129
115
      HostTarget->getDefaultAlignForAttributeAligned();
130
115
  SizeType = HostTarget->getSizeType();
131
115
  IntMaxType = HostTarget->getIntMaxType();
132
115
  PtrDiffType = HostTarget->getPtrDiffType(/* AddrSpace = */ 0);
133
115
  IntPtrType = HostTarget->getIntPtrType();
134
115
  WCharType = HostTarget->getWCharType();
135
115
  WIntType = HostTarget->getWIntType();
136
115
  Char16Type = HostTarget->getChar16Type();
137
115
  Char32Type = HostTarget->getChar32Type();
138
115
  Int64Type = HostTarget->getInt64Type();
139
115
  SigAtomicType = HostTarget->getSigAtomicType();
140
115
  ProcessIDType = HostTarget->getProcessIDType();
141
142
115
  UseBitFieldTypeAlignment = HostTarget->useBitFieldTypeAlignment();
143
115
  UseZeroLengthBitfieldAlignment = HostTarget->useZeroLengthBitfieldAlignment();
144
115
  UseExplicitBitFieldAlignment = HostTarget->useExplicitBitFieldAlignment();
145
115
  ZeroLengthBitfieldBoundary = HostTarget->getZeroLengthBitfieldBoundary();
146
147
  // This is a bit of a lie, but it controls __GCC_ATOMIC_XXX_LOCK_FREE, and
148
  // we need those macros to be identical on host and device, because (among
149
  // other things) they affect which standard library classes are defined, and
150
  // we need all classes to be defined on both the host and device.
151
115
  MaxAtomicInlineWidth = HostTarget->getMaxAtomicInlineWidth();
152
153
  // Properties intentionally not copied from host:
154
  // - LargeArrayMinWidth, LargeArrayAlign: Not visible across the
155
  //   host/device boundary.
156
  // - SuitableAlign: Not visible across the host/device boundary, and may
157
  //   correctly be different on host/device, e.g. if host has wider vector
158
  //   types than device.
159
  // - LongDoubleWidth, LongDoubleAlign: nvptx's long double type is the same
160
  //   as its double type, but that's not necessarily true on the host.
161
  //   TODO: nvcc emits a warning when using long double on device; we should
162
  //   do the same.
163
115
}
164
165
33
ArrayRef<const char *> NVPTXTargetInfo::getGCCRegNames() const {
166
33
  return llvm::makeArrayRef(GCCRegNames);
167
33
}
168
169
17
bool NVPTXTargetInfo::hasFeature(StringRef Feature) const {
170
17
  return llvm::StringSwitch<bool>(Feature)
171
17
      .Cases("ptx", "nvptx", true)
172
17
      .Default(false);
173
17
}
174
175
void NVPTXTargetInfo::getTargetDefines(const LangOptions &Opts,
176
434
                                       MacroBuilder &Builder) const {
177
434
  Builder.defineMacro("__PTX__");
178
434
  Builder.defineMacro("__NVPTX__");
179
434
  if (Opts.CUDAIsDevice) {
180
    // Set __CUDA_ARCH__ for the GPU specified.
181
123
    std::string CUDAArchCode = [this] {
182
123
      switch (GPU) {
183
0
      case CudaArch::GFX600:
184
0
      case CudaArch::GFX601:
185
0
      case CudaArch::GFX602:
186
0
      case CudaArch::GFX700:
187
0
      case CudaArch::GFX701:
188
0
      case CudaArch::GFX702:
189
0
      case CudaArch::GFX703:
190
0
      case CudaArch::GFX704:
191
0
      case CudaArch::GFX705:
192
0
      case CudaArch::GFX801:
193
0
      case CudaArch::GFX802:
194
0
      case CudaArch::GFX803:
195
0
      case CudaArch::GFX805:
196
0
      case CudaArch::GFX810:
197
0
      case CudaArch::GFX900:
198
0
      case CudaArch::GFX902:
199
0
      case CudaArch::GFX904:
200
0
      case CudaArch::GFX906:
201
0
      case CudaArch::GFX908:
202
0
      case CudaArch::GFX909:
203
0
      case CudaArch::GFX90c:
204
0
      case CudaArch::GFX1010:
205
0
      case CudaArch::GFX1011:
206
0
      case CudaArch::GFX1012:
207
0
      case CudaArch::GFX1030:
208
0
      case CudaArch::GFX1031:
209
0
      case CudaArch::GFX1032:
210
0
      case CudaArch::GFX1033:
211
0
      case CudaArch::LAST:
212
0
        break;
213
0
      case CudaArch::UNUSED:
214
0
      case CudaArch::UNKNOWN:
215
0
        assert(false && "No GPU arch when compiling CUDA device code.");
216
0
        return "";
217
99
      case CudaArch::SM_20:
218
99
        return "200";
219
0
      case CudaArch::SM_21:
220
0
        return "210";
221
2
      case CudaArch::SM_30:
222
2
        return "300";
223
0
      case CudaArch::SM_32:
224
0
        return "320";
225
5
      case CudaArch::SM_35:
226
5
        return "350";
227
0
      case CudaArch::SM_37:
228
0
        return "370";
229
1
      case CudaArch::SM_50:
230
1
        return "500";
231
0
      case CudaArch::SM_52:
232
0
        return "520";
233
1
      case CudaArch::SM_53:
234
1
        return "530";
235
8
      case CudaArch::SM_60:
236
8
        return "600";
237
1
      case CudaArch::SM_61:
238
1
        return "610";
239
0
      case CudaArch::SM_62:
240
0
        return "620";
241
3
      case CudaArch::SM_70:
242
3
        return "700";
243
0
      case CudaArch::SM_72:
244
0
        return "720";
245
1
      case CudaArch::SM_75:
246
1
        return "750";
247
2
      case CudaArch::SM_80:
248
2
        return "800";
249
0
      }
250
0
      llvm_unreachable("unhandled CudaArch");
251
0
    }();
252
123
    Builder.defineMacro("__CUDA_ARCH__", CUDAArchCode);
253
123
  }
254
434
}
255
256
434
ArrayRef<Builtin::Info> NVPTXTargetInfo::getTargetBuiltins() const {
257
434
  return llvm::makeArrayRef(BuiltinInfo, clang::NVPTX::LastTSBuiltin -
258
434
                                             Builtin::FirstTSBuiltin);
259
434
}