Coverage Report

Created: 2023-09-30 09:22

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/Basic/Targets/SPIR.h
Line
Count
Source (jump to first uncovered line)
1
//===--- SPIR.h - Declare SPIR and SPIR-V 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 SPIR and SPIR-V TargetInfo objects.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#ifndef LLVM_CLANG_LIB_BASIC_TARGETS_SPIR_H
14
#define LLVM_CLANG_LIB_BASIC_TARGETS_SPIR_H
15
16
#include "Targets.h"
17
#include "clang/Basic/TargetInfo.h"
18
#include "clang/Basic/TargetOptions.h"
19
#include "llvm/Support/Compiler.h"
20
#include "llvm/TargetParser/Triple.h"
21
#include <optional>
22
23
namespace clang {
24
namespace targets {
25
26
// Used by both the SPIR and SPIR-V targets.
27
static const unsigned SPIRDefIsPrivMap[] = {
28
    0, // Default
29
    1, // opencl_global
30
    3, // opencl_local
31
    2, // opencl_constant
32
    0, // opencl_private
33
    4, // opencl_generic
34
    5, // opencl_global_device
35
    6, // opencl_global_host
36
    0, // cuda_device
37
    0, // cuda_constant
38
    0, // cuda_shared
39
    // SYCL address space values for this map are dummy
40
    0, // sycl_global
41
    0, // sycl_global_device
42
    0, // sycl_global_host
43
    0, // sycl_local
44
    0, // sycl_private
45
    0, // ptr32_sptr
46
    0, // ptr32_uptr
47
    0, // ptr64
48
    0, // hlsl_groupshared
49
    // Wasm address space values for this target are dummy values,
50
    // as it is only enabled for Wasm targets.
51
    20, // wasm_funcref
52
};
53
54
// Used by both the SPIR and SPIR-V targets.
55
static const unsigned SPIRDefIsGenMap[] = {
56
    4, // Default
57
    // OpenCL address space values for this map are dummy and they can't be used
58
    0, // opencl_global
59
    0, // opencl_local
60
    0, // opencl_constant
61
    0, // opencl_private
62
    0, // opencl_generic
63
    0, // opencl_global_device
64
    0, // opencl_global_host
65
    // cuda_* address space mapping is intended for HIPSPV (HIP to SPIR-V
66
    // translation). This mapping is enabled when the language mode is HIP.
67
    1, // cuda_device
68
    // cuda_constant pointer can be casted to default/"flat" pointer, but in
69
    // SPIR-V casts between constant and generic pointers are not allowed. For
70
    // this reason cuda_constant is mapped to SPIR-V CrossWorkgroup.
71
    1, // cuda_constant
72
    3, // cuda_shared
73
    1, // sycl_global
74
    5, // sycl_global_device
75
    6, // sycl_global_host
76
    3, // sycl_local
77
    0, // sycl_private
78
    0, // ptr32_sptr
79
    0, // ptr32_uptr
80
    0, // ptr64
81
    0, // hlsl_groupshared
82
    // Wasm address space values for this target are dummy values,
83
    // as it is only enabled for Wasm targets.
84
    20, // wasm_funcref
85
};
86
87
// Base class for SPIR and SPIR-V target info.
88
class LLVM_LIBRARY_VISIBILITY BaseSPIRTargetInfo : public TargetInfo {
89
  std::unique_ptr<TargetInfo> HostTarget;
90
91
protected:
92
  BaseSPIRTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
93
346
      : TargetInfo(Triple) {
94
346
    assert((Triple.isSPIR() || Triple.isSPIRV()) &&
95
346
           "Invalid architecture for SPIR or SPIR-V.");
96
346
    TLSSupported = false;
97
346
    VLASupported = false;
98
346
    LongWidth = LongAlign = 64;
99
346
    AddrSpaceMap = &SPIRDefIsPrivMap;
100
346
    UseAddrSpaceMapMangling = true;
101
346
    HasLegalHalfType = true;
102
346
    HasFloat16 = true;
103
    // Define available target features
104
    // These must be defined in sorted order!
105
346
    NoAsmVariants = true;
106
107
346
    llvm::Triple HostTriple(Opts.HostTriple);
108
346
    if (!HostTriple.isSPIR() && !HostTriple.isSPIRV() &&
109
346
        HostTriple.getArch() != llvm::Triple::UnknownArch) {
110
15
      HostTarget = AllocateTarget(llvm::Triple(Opts.HostTriple), Opts);
111
112
      // Copy properties from host target.
113
15
      BoolWidth = HostTarget->getBoolWidth();
114
15
      BoolAlign = HostTarget->getBoolAlign();
115
15
      IntWidth = HostTarget->getIntWidth();
116
15
      IntAlign = HostTarget->getIntAlign();
117
15
      HalfWidth = HostTarget->getHalfWidth();
118
15
      HalfAlign = HostTarget->getHalfAlign();
119
15
      FloatWidth = HostTarget->getFloatWidth();
120
15
      FloatAlign = HostTarget->getFloatAlign();
121
15
      DoubleWidth = HostTarget->getDoubleWidth();
122
15
      DoubleAlign = HostTarget->getDoubleAlign();
123
15
      LongWidth = HostTarget->getLongWidth();
124
15
      LongAlign = HostTarget->getLongAlign();
125
15
      LongLongWidth = HostTarget->getLongLongWidth();
126
15
      LongLongAlign = HostTarget->getLongLongAlign();
127
15
      MinGlobalAlign = HostTarget->getMinGlobalAlign(/* TypeSize = */ 0);
128
15
      NewAlign = HostTarget->getNewAlign();
129
15
      DefaultAlignForAttributeAligned =
130
15
          HostTarget->getDefaultAlignForAttributeAligned();
131
15
      IntMaxType = HostTarget->getIntMaxType();
132
15
      WCharType = HostTarget->getWCharType();
133
15
      WIntType = HostTarget->getWIntType();
134
15
      Char16Type = HostTarget->getChar16Type();
135
15
      Char32Type = HostTarget->getChar32Type();
136
15
      Int64Type = HostTarget->getInt64Type();
137
15
      SigAtomicType = HostTarget->getSigAtomicType();
138
15
      ProcessIDType = HostTarget->getProcessIDType();
139
140
15
      UseBitFieldTypeAlignment = HostTarget->useBitFieldTypeAlignment();
141
15
      UseZeroLengthBitfieldAlignment =
142
15
          HostTarget->useZeroLengthBitfieldAlignment();
143
15
      UseExplicitBitFieldAlignment = HostTarget->useExplicitBitFieldAlignment();
144
15
      ZeroLengthBitfieldBoundary = HostTarget->getZeroLengthBitfieldBoundary();
145
146
      // This is a bit of a lie, but it controls __GCC_ATOMIC_XXX_LOCK_FREE, and
147
      // we need those macros to be identical on host and device, because (among
148
      // other things) they affect which standard library classes are defined,
149
      // and we need all classes to be defined on both the host and device.
150
15
      MaxAtomicInlineWidth = HostTarget->getMaxAtomicInlineWidth();
151
15
    }
152
346
  }
153
154
public:
155
  // SPIR supports the half type and the only llvm intrinsic allowed in SPIR is
156
  // memcpy as per section 3 of the SPIR spec.
157
245
  bool useFP16ConversionIntrinsics() const override { return false; }
158
159
332
  ArrayRef<Builtin::Info> getTargetBuiltins() const override {
160
332
    return std::nullopt;
161
332
  }
162
163
1
  std::string_view getClobbers() const override { return ""; }
164
165
0
  ArrayRef<const char *> getGCCRegNames() const override {
166
0
    return std::nullopt;
167
0
  }
168
169
  bool validateAsmConstraint(const char *&Name,
170
0
                             TargetInfo::ConstraintInfo &info) const override {
171
0
    return true;
172
0
  }
173
174
0
  ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
175
0
    return std::nullopt;
176
0
  }
177
178
302
  BuiltinVaListKind getBuiltinVaListKind() const override {
179
302
    return TargetInfo::VoidPtrBuiltinVaList;
180
302
  }
181
182
  std::optional<unsigned>
183
40
  getDWARFAddressSpace(unsigned AddressSpace) const override {
184
40
    return AddressSpace;
185
40
  }
186
187
0
  CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
188
0
    return (CC == CC_SpirFunction || CC == CC_OpenCLKernel) ? CCCR_OK
189
0
                                                            : CCCR_Warning;
190
0
  }
191
192
376k
  CallingConv getDefaultCallingConv() const override {
193
376k
    return CC_SpirFunction;
194
376k
  }
195
196
652
  void setAddressSpaceMap(bool DefaultIsGeneric) {
197
652
    AddrSpaceMap = DefaultIsGeneric ? 
&SPIRDefIsGenMap62
:
&SPIRDefIsPrivMap590
;
198
652
  }
199
200
652
  void adjust(DiagnosticsEngine &Diags, LangOptions &Opts) override {
201
652
    TargetInfo::adjust(Diags, Opts);
202
    // FIXME: SYCL specification considers unannotated pointers and references
203
    // to be pointing to the generic address space. See section 5.9.3 of
204
    // SYCL 2020 specification.
205
    // Currently, there is no way of representing SYCL's and HIP/CUDA's default
206
    // address space language semantic along with the semantics of embedded C's
207
    // default address space in the same address space map. Hence the map needs
208
    // to be reset to allow mapping to the desired value of 'Default' entry for
209
    // SYCL and HIP/CUDA.
210
652
    setAddressSpaceMap(
211
652
        /*DefaultIsGeneric=*/Opts.SYCLIsDevice ||
212
        // The address mapping from HIP/CUDA language for device code is only
213
        // defined for SPIR-V.
214
652
        
(618
getTriple().isSPIRV()618
&&
Opts.CUDAIsDevice42
));
215
652
  }
216
217
346
  void setSupportedOpenCLOpts() override {
218
    // Assume all OpenCL extensions and optional core features are supported
219
    // for SPIR and SPIR-V since they are generic targets.
220
346
    supportAllOpenCLOpts();
221
346
  }
222
223
20
  bool hasBitIntType() const override { return true; }
224
225
1.06k
  bool hasInt128Type() const override { return false; }
226
};
227
228
class LLVM_LIBRARY_VISIBILITY SPIRTargetInfo : public BaseSPIRTargetInfo {
229
public:
230
  SPIRTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
231
320
      : BaseSPIRTargetInfo(Triple, Opts) {
232
320
    assert(Triple.isSPIR() && "Invalid architecture for SPIR.");
233
320
    assert(getTriple().getOS() == llvm::Triple::UnknownOS &&
234
320
           "SPIR target must use unknown OS");
235
320
    assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment &&
236
320
           "SPIR target must use unknown environment type");
237
320
  }
238
239
  void getTargetDefines(const LangOptions &Opts,
240
                        MacroBuilder &Builder) const override;
241
242
252
  bool hasFeature(StringRef Feature) const override {
243
252
    return Feature == "spir";
244
252
  }
245
246
23
  bool checkArithmeticFenceSupported() const override { return true; }
247
};
248
249
class LLVM_LIBRARY_VISIBILITY SPIR32TargetInfo : public SPIRTargetInfo {
250
public:
251
  SPIR32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
252
266
      : SPIRTargetInfo(Triple, Opts) {
253
266
    assert(Triple.getArch() == llvm::Triple::spir &&
254
266
           "Invalid architecture for 32-bit SPIR.");
255
266
    PointerWidth = PointerAlign = 32;
256
266
    SizeType = TargetInfo::UnsignedInt;
257
266
    PtrDiffType = IntPtrType = TargetInfo::SignedInt;
258
266
    resetDataLayout("e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-"
259
266
                    "v96:128-v192:256-v256:256-v512:512-v1024:1024");
260
266
  }
261
262
  void getTargetDefines(const LangOptions &Opts,
263
                        MacroBuilder &Builder) const override;
264
};
265
266
class LLVM_LIBRARY_VISIBILITY SPIR64TargetInfo : public SPIRTargetInfo {
267
public:
268
  SPIR64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
269
54
      : SPIRTargetInfo(Triple, Opts) {
270
54
    assert(Triple.getArch() == llvm::Triple::spir64 &&
271
54
           "Invalid architecture for 64-bit SPIR.");
272
54
    PointerWidth = PointerAlign = 64;
273
54
    SizeType = TargetInfo::UnsignedLong;
274
54
    PtrDiffType = IntPtrType = TargetInfo::SignedLong;
275
54
    resetDataLayout("e-i64:64-v16:16-v24:32-v32:32-v48:64-"
276
54
                    "v96:128-v192:256-v256:256-v512:512-v1024:1024");
277
54
  }
278
279
  void getTargetDefines(const LangOptions &Opts,
280
                        MacroBuilder &Builder) const override;
281
};
282
283
class LLVM_LIBRARY_VISIBILITY BaseSPIRVTargetInfo : public BaseSPIRTargetInfo {
284
public:
285
  BaseSPIRVTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
286
26
      : BaseSPIRTargetInfo(Triple, Opts) {
287
26
    assert(Triple.isSPIRV() && "Invalid architecture for SPIR-V.");
288
26
  }
289
290
11
  bool hasFeature(StringRef Feature) const override {
291
11
    return Feature == "spirv";
292
11
  }
293
294
  void getTargetDefines(const LangOptions &Opts,
295
                        MacroBuilder &Builder) const override;
296
};
297
298
class LLVM_LIBRARY_VISIBILITY SPIRVTargetInfo : public BaseSPIRVTargetInfo {
299
public:
300
  SPIRVTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
301
0
      : BaseSPIRVTargetInfo(Triple, Opts) {
302
0
    assert(Triple.getArch() == llvm::Triple::spirv &&
303
0
           "Invalid architecture for Logical SPIR-V.");
304
0
    assert(Triple.getOS() == llvm::Triple::ShaderModel &&
305
0
           "Logical SPIR-V requires a valid ShaderModel.");
306
0
    assert(Triple.getEnvironment() >= llvm::Triple::Pixel &&
307
0
           Triple.getEnvironment() <= llvm::Triple::Amplification &&
308
0
           "Logical SPIR-V environment must be a valid shader stage.");
309
310
    // SPIR-V IDs are represented with a single 32-bit word.
311
0
    SizeType = TargetInfo::UnsignedInt;
312
0
    resetDataLayout("e-i64:64-v16:16-v24:32-v32:32-v48:64-"
313
0
                    "v96:128-v192:256-v256:256-v512:512-v1024:1024");
314
0
  }
315
316
  void getTargetDefines(const LangOptions &Opts,
317
                        MacroBuilder &Builder) const override;
318
};
319
320
class LLVM_LIBRARY_VISIBILITY SPIRV32TargetInfo : public BaseSPIRVTargetInfo {
321
public:
322
  SPIRV32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
323
11
      : BaseSPIRVTargetInfo(Triple, Opts) {
324
11
    assert(Triple.getArch() == llvm::Triple::spirv32 &&
325
11
           "Invalid architecture for 32-bit SPIR-V.");
326
11
    assert(getTriple().getOS() == llvm::Triple::UnknownOS &&
327
11
           "32-bit SPIR-V target must use unknown OS");
328
11
    assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment &&
329
11
           "32-bit SPIR-V target must use unknown environment type");
330
11
    PointerWidth = PointerAlign = 32;
331
11
    SizeType = TargetInfo::UnsignedInt;
332
11
    PtrDiffType = IntPtrType = TargetInfo::SignedInt;
333
11
    resetDataLayout("e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-"
334
11
                    "v96:128-v192:256-v256:256-v512:512-v1024:1024");
335
11
  }
336
337
  void getTargetDefines(const LangOptions &Opts,
338
                        MacroBuilder &Builder) const override;
339
};
340
341
class LLVM_LIBRARY_VISIBILITY SPIRV64TargetInfo : public BaseSPIRVTargetInfo {
342
public:
343
  SPIRV64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
344
15
      : BaseSPIRVTargetInfo(Triple, Opts) {
345
15
    assert(Triple.getArch() == llvm::Triple::spirv64 &&
346
15
           "Invalid architecture for 64-bit SPIR-V.");
347
15
    assert(getTriple().getOS() == llvm::Triple::UnknownOS &&
348
15
           "64-bit SPIR-V target must use unknown OS");
349
15
    assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment &&
350
15
           "64-bit SPIR-V target must use unknown environment type");
351
15
    PointerWidth = PointerAlign = 64;
352
15
    SizeType = TargetInfo::UnsignedLong;
353
15
    PtrDiffType = IntPtrType = TargetInfo::SignedLong;
354
15
    resetDataLayout("e-i64:64-v16:16-v24:32-v32:32-v48:64-"
355
15
                    "v96:128-v192:256-v256:256-v512:512-v1024:1024");
356
15
  }
357
358
  void getTargetDefines(const LangOptions &Opts,
359
                        MacroBuilder &Builder) const override;
360
};
361
362
} // namespace targets
363
} // namespace clang
364
#endif // LLVM_CLANG_LIB_BASIC_TARGETS_SPIR_H