Coverage Report

Created: 2019-07-24 05:18

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