Coverage Report

Created: 2021-09-21 08:58

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