Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/clang/lib/Basic/Targets/AMDGPU.h
Line
Count
Source (jump to first uncovered line)
1
//===--- AMDGPU.h - Declare AMDGPU 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 AMDGPU TargetInfo objects.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#ifndef LLVM_CLANG_LIB_BASIC_TARGETS_AMDGPU_H
14
#define LLVM_CLANG_LIB_BASIC_TARGETS_AMDGPU_H
15
16
#include "clang/Basic/TargetInfo.h"
17
#include "clang/Basic/TargetOptions.h"
18
#include "llvm/ADT/StringSet.h"
19
#include "llvm/ADT/Triple.h"
20
#include "llvm/Support/Compiler.h"
21
#include "llvm/Support/TargetParser.h"
22
23
namespace clang {
24
namespace targets {
25
26
class LLVM_LIBRARY_VISIBILITY AMDGPUTargetInfo final : public TargetInfo {
27
28
  static const Builtin::Info BuiltinInfo[];
29
  static const char *const GCCRegNames[];
30
31
  enum AddrSpace {
32
    Generic = 0,
33
    Global = 1,
34
    Local = 3,
35
    Constant = 4,
36
    Private = 5
37
  };
38
  static const LangASMap AMDGPUDefIsGenMap;
39
  static const LangASMap AMDGPUDefIsPrivMap;
40
41
  llvm::AMDGPU::GPUKind GPUKind;
42
  unsigned GPUFeatures;
43
44
858
  bool hasFP64() const {
45
858
    return getTriple().getArch() == llvm::Triple::amdgcn ||
46
858
           
!!(GPUFeatures & llvm::AMDGPU::FEATURE_FP64)197
;
47
858
  }
48
49
  /// Has fast fma f32
50
568
  bool hasFastFMAF() const {
51
568
    return !!(GPUFeatures & llvm::AMDGPU::FEATURE_FAST_FMA_F32);
52
568
  }
53
54
  /// Has fast fma f64
55
287
  bool hasFastFMA() const {
56
287
    return getTriple().getArch() == llvm::Triple::amdgcn;
57
287
  }
58
59
287
  bool hasFMAF() const {
60
287
    return getTriple().getArch() == llvm::Triple::amdgcn ||
61
287
           
!!(GPUFeatures & llvm::AMDGPU::FEATURE_FMA)65
;
62
287
  }
63
64
176
  bool hasFullRateDenormalsF32() const {
65
176
    return !!(GPUFeatures & llvm::AMDGPU::FEATURE_FAST_DENORMAL_F32);
66
176
  }
67
68
287
  bool hasLDEXPF() const {
69
287
    return getTriple().getArch() == llvm::Triple::amdgcn ||
70
287
           
!!(GPUFeatures & llvm::AMDGPU::FEATURE_LDEXP)65
;
71
287
  }
72
73
2.47k
  static bool isAMDGCN(const llvm::Triple &TT) {
74
2.47k
    return TT.getArch() == llvm::Triple::amdgcn;
75
2.47k
  }
76
77
958
  static bool isR600(const llvm::Triple &TT) {
78
958
    return TT.getArch() == llvm::Triple::r600;
79
958
  }
80
81
public:
82
  AMDGPUTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts);
83
84
  void setAddressSpaceMap(bool DefaultIsPrivate);
85
86
  void adjust(LangOptions &Opts) override;
87
88
958
  uint64_t getPointerWidthV(unsigned AddrSpace) const override {
89
958
    if (isR600(getTriple()))
90
46
      return 32;
91
912
92
912
    if (AddrSpace == Private || 
AddrSpace == Local796
)
93
518
      return 32;
94
394
95
394
    return 64;
96
394
  }
97
98
468
  uint64_t getPointerAlignV(unsigned AddrSpace) const override {
99
468
    return getPointerWidthV(AddrSpace);
100
468
  }
101
102
2.11k
  uint64_t getMaxPointerWidth() const override {
103
2.11k
    return getTriple().getArch() == llvm::Triple::amdgcn ? 
641.89k
:
32214
;
104
2.11k
  }
105
106
4
  const char *getClobbers() const override { return ""; }
107
108
  ArrayRef<const char *> getGCCRegNames() const override;
109
110
6
  ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
111
6
    return None;
112
6
  }
113
114
  /// Accepted register names: (n, m is unsigned integer, n < m)
115
  /// v
116
  /// s
117
  /// {vn}, {v[n]}
118
  /// {sn}, {s[n]}
119
  /// {S} , where S is a special register name
120
  ////{v[n:m]}
121
  /// {s[n:m]}
122
  bool validateAsmConstraint(const char *&Name,
123
60
                             TargetInfo::ConstraintInfo &Info) const override {
124
60
    static const ::llvm::StringSet<> SpecialRegs({
125
60
        "exec", "vcc", "flat_scratch", "m0", "scc", "tba", "tma",
126
60
        "flat_scratch_lo", "flat_scratch_hi", "vcc_lo", "vcc_hi", "exec_lo",
127
60
        "exec_hi", "tma_lo", "tma_hi", "tba_lo", "tba_hi",
128
60
    });
129
60
130
60
    StringRef S(Name);
131
60
    bool HasLeftParen = false;
132
60
    if (S.front() == '{') {
133
45
      HasLeftParen = true;
134
45
      S = S.drop_front();
135
45
    }
136
60
    if (S.empty())
137
1
      return false;
138
59
    if (S.front() != 'v' && 
S.front() != 's'14
) {
139
8
      if (!HasLeftParen)
140
0
        return false;
141
8
      auto E = S.find('}');
142
8
      if (!SpecialRegs.count(S.substr(0, E)))
143
5
        return false;
144
3
      S = S.drop_front(E + 1);
145
3
      if (!S.empty())
146
2
        return false;
147
1
      // Found {S} where S is a special register.
148
1
      Info.setAllowsRegister();
149
1
      Name = S.data() - 1;
150
1
      return true;
151
1
    }
152
51
    S = S.drop_front();
153
51
    if (!HasLeftParen) {
154
15
      if (!S.empty())
155
4
        return false;
156
11
      // Found s or v.
157
11
      Info.setAllowsRegister();
158
11
      Name = S.data() - 1;
159
11
      return true;
160
11
    }
161
36
    bool HasLeftBracket = false;
162
36
    if (!S.empty() && 
S.front() == '['35
) {
163
21
      HasLeftBracket = true;
164
21
      S = S.drop_front();
165
21
    }
166
36
    unsigned long long N;
167
36
    if (S.empty() || 
consumeUnsignedInteger(S, 10, N)35
)
168
4
      return false;
169
32
    if (!S.empty() && 
S.front() == ':'31
) {
170
14
      if (!HasLeftBracket)
171
0
        return false;
172
14
      S = S.drop_front();
173
14
      unsigned long long M;
174
14
      if (consumeUnsignedInteger(S, 10, M) || 
N >= M12
)
175
3
        return false;
176
29
    }
177
29
    if (HasLeftBracket) {
178
16
      if (S.empty() || S.front() != ']')
179
2
        return false;
180
14
      S = S.drop_front();
181
14
    }
182
29
    
if (27
S.empty()27
||
S.front() != '}'24
)
183
5
      return false;
184
22
    S = S.drop_front();
185
22
    if (!S.empty())
186
2
      return false;
187
20
    // Found {vn}, {sn}, {v[n]}, {s[n]}, {v[n:m]}, or {s[n:m]}.
188
20
    Info.setAllowsRegister();
189
20
    Name = S.data() - 1;
190
20
    return true;
191
20
  }
192
193
  // \p Constraint will be left pointing at the last character of
194
  // the constraint.  In practice, it won't be changed unless the
195
  // constraint is longer than one character.
196
2
  std::string convertConstraint(const char *&Constraint) const override {
197
2
    const char *Begin = Constraint;
198
2
    TargetInfo::ConstraintInfo Info("", "");
199
2
    if (validateAsmConstraint(Constraint, Info))
200
2
      return std::string(Begin).substr(0, Constraint - Begin + 1);
201
0
202
0
    Constraint = Begin;
203
0
    return std::string(1, *Constraint);
204
0
  }
205
206
  bool
207
  initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
208
                 StringRef CPU,
209
                 const std::vector<std::string> &FeatureVec) const override;
210
211
  void adjustTargetOptions(const CodeGenOptions &CGOpts,
212
                           TargetOptions &TargetOpts) const override;
213
214
  ArrayRef<Builtin::Info> getTargetBuiltins() const override;
215
216
  void getTargetDefines(const LangOptions &Opts,
217
                        MacroBuilder &Builder) const override;
218
219
214
  BuiltinVaListKind getBuiltinVaListKind() const override {
220
214
    return TargetInfo::CharPtrBuiltinVaList;
221
214
  }
222
223
16
  bool isValidCPUName(StringRef Name) const override {
224
16
    if (getTriple().getArch() == llvm::Triple::amdgcn)
225
16
      return llvm::AMDGPU::parseArchAMDGCN(Name) != llvm::AMDGPU::GK_NONE;
226
0
    return llvm::AMDGPU::parseArchR600(Name) != llvm::AMDGPU::GK_NONE;
227
0
  }
228
229
  void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
230
231
171
  bool setCPU(const std::string &Name) override {
232
171
    if (getTriple().getArch() == llvm::Triple::amdgcn) {
233
110
      GPUKind = llvm::AMDGPU::parseArchAMDGCN(Name);
234
110
      GPUFeatures = llvm::AMDGPU::getArchAttrAMDGCN(GPUKind);
235
110
    } else {
236
61
      GPUKind = llvm::AMDGPU::parseArchR600(Name);
237
61
      GPUFeatures = llvm::AMDGPU::getArchAttrR600(GPUKind);
238
61
    }
239
171
240
171
    return GPUKind != llvm::AMDGPU::GK_NONE;
241
171
  }
242
243
288
  void setSupportedOpenCLOpts() override {
244
288
    auto &Opts = getSupportedOpenCLOpts();
245
288
    Opts.support("cl_clang_storage_class_specifiers");
246
288
    Opts.support("cl_khr_icd");
247
288
248
288
    bool IsAMDGCN = isAMDGCN(getTriple());
249
288
250
288
    if (hasFP64())
251
222
      Opts.support("cl_khr_fp64");
252
288
253
288
    if (IsAMDGCN || 
GPUKind >= llvm::AMDGPU::GK_CEDAR66
) {
254
263
      Opts.support("cl_khr_byte_addressable_store");
255
263
      Opts.support("cl_khr_global_int32_base_atomics");
256
263
      Opts.support("cl_khr_global_int32_extended_atomics");
257
263
      Opts.support("cl_khr_local_int32_base_atomics");
258
263
      Opts.support("cl_khr_local_int32_extended_atomics");
259
263
    }
260
288
261
288
    if (IsAMDGCN) {
262
222
      Opts.support("cl_khr_fp16");
263
222
      Opts.support("cl_khr_int64_base_atomics");
264
222
      Opts.support("cl_khr_int64_extended_atomics");
265
222
      Opts.support("cl_khr_mipmap_image");
266
222
      Opts.support("cl_khr_subgroups");
267
222
      Opts.support("cl_khr_3d_image_writes");
268
222
      Opts.support("cl_amd_media_ops");
269
222
      Opts.support("cl_amd_media_ops2");
270
222
    }
271
288
  }
272
273
40
  LangAS getOpenCLTypeAddrSpace(OpenCLTypeKind TK) const override {
274
40
    switch (TK) {
275
40
    case OCLTK_Image:
276
18
      return LangAS::opencl_constant;
277
40
278
40
    case OCLTK_ClkEvent:
279
12
    case OCLTK_Queue:
280
12
    case OCLTK_ReserveID:
281
12
      return LangAS::opencl_global;
282
12
283
12
    default:
284
10
      return TargetInfo::getOpenCLTypeAddrSpace(TK);
285
40
    }
286
40
  }
287
288
75
  LangAS getOpenCLBuiltinAddressSpace(unsigned AS) const override {
289
75
    switch (AS) {
290
75
    case 0:
291
0
      return LangAS::opencl_generic;
292
75
    case 1:
293
0
      return LangAS::opencl_global;
294
75
    case 3:
295
60
      return LangAS::opencl_local;
296
75
    case 4:
297
12
      return LangAS::opencl_constant;
298
75
    case 5:
299
0
      return LangAS::opencl_private;
300
75
    default:
301
3
      return getLangASFromTargetAS(AS);
302
75
    }
303
75
  }
304
305
6
  LangAS getCUDABuiltinAddressSpace(unsigned AS) const override {
306
6
    return LangAS::Default;
307
6
  }
308
309
21
  llvm::Optional<LangAS> getConstantAddressSpace() const override {
310
21
    return getLangASFromTargetAS(Constant);
311
21
  }
312
313
  /// \returns Target specific vtbl ptr address space.
314
0
  unsigned getVtblPtrAddressSpace() const override {
315
0
    return static_cast<unsigned>(Constant);
316
0
  }
317
318
  /// \returns If a target requires an address within a target specific address
319
  /// space \p AddressSpace to be converted in order to be used, then return the
320
  /// corresponding target specific DWARF address space.
321
  ///
322
  /// \returns Otherwise return None and no conversion will be emitted in the
323
  /// DWARF.
324
  Optional<unsigned>
325
203
  getDWARFAddressSpace(unsigned AddressSpace) const override {
326
203
    const unsigned DWARF_Private = 1;
327
203
    const unsigned DWARF_Local = 2;
328
203
    if (AddressSpace == Private) {
329
78
      return DWARF_Private;
330
125
    } else if (AddressSpace == Local) {
331
26
      return DWARF_Local;
332
99
    } else {
333
99
      return None;
334
99
    }
335
203
  }
336
337
  CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
338
    switch (CC) {
339
    default:
340
      return CCCR_Warning;
341
    case CC_C:
342
    case CC_OpenCLKernel:
343
      return CCCR_OK;
344
    }
345
  }
346
347
  // In amdgcn target the null pointer in global, constant, and generic
348
  // address space has value 0 but in private and local address space has
349
  // value ~0.
350
2.22k
  uint64_t getNullPointerValue(LangAS AS) const override {
351
2.22k
    return AS == LangAS::opencl_local ? 
~0332
:
01.89k
;
352
2.22k
  }
353
354
  void setAuxTarget(const TargetInfo *Aux) override;
355
};
356
357
} // namespace targets
358
} // namespace clang
359
360
#endif // LLVM_CLANG_LIB_BASIC_TARGETS_AMDGPU_H