@@ -20,6 +20,68 @@ static bool testIfIsVoidTy(QualType Ty) {
20
20
return k == BuiltinType::Void;
21
21
}
22
22
23
+ static bool isAggregateTypeForABI (QualType T) {
24
+ return !CIRGenFunction::hasScalarEvaluationKind (T) ||
25
+ T->isMemberFunctionPointerType ();
26
+ }
27
+
28
+ // / Pass transparent unions as if they were the type of the first element. Sema
29
+ // / should ensure that all elements of the union have the same "machine type".
30
+ static QualType useFirstFieldIfTransparentUnion (QualType Ty) {
31
+ assert (!Ty->getAsUnionType () && " NYI" );
32
+ return Ty;
33
+ }
34
+
35
+ namespace {
36
+
37
+ // / The default implementation for ABI specific
38
+ // / details. This implementation provides information which results in
39
+ // / self-consistent and sensible LLVM IR generation, but does not
40
+ // / conform to any particular ABI.
41
+ class DefaultABIInfo : public ABIInfo {
42
+ public:
43
+ DefaultABIInfo (CIRGenTypes &CGT) : ABIInfo(CGT) {}
44
+
45
+ virtual ~DefaultABIInfo () = default ;
46
+
47
+ ABIArgInfo classifyReturnType (QualType RetTy) const {
48
+ if (RetTy->isVoidType ())
49
+ return ABIArgInfo::getIgnore ();
50
+
51
+ llvm_unreachable (" Non-void return type NYI" );
52
+ }
53
+
54
+ ABIArgInfo classifyArgumentType (QualType Ty) const {
55
+ Ty = useFirstFieldIfTransparentUnion (Ty);
56
+
57
+ if (isAggregateTypeForABI (Ty)) {
58
+ llvm_unreachable (" NYI" );
59
+ }
60
+
61
+ // Treat an enum type as its underlying type.
62
+ if (const EnumType *EnumTy = Ty->getAs <EnumType>())
63
+ llvm_unreachable (" NYI" );
64
+
65
+ ASTContext &Context = getContext ();
66
+ if (const auto *EIT = Ty->getAs <BitIntType>())
67
+ llvm_unreachable (" NYI" );
68
+
69
+ if (isPromotableIntegerTypeForABI (Ty)) {
70
+ llvm_unreachable (" ArgInfo integer extend NYI" );
71
+ } else {
72
+ return ABIArgInfo::getDirect ();
73
+ }
74
+ }
75
+
76
+ void computeInfo (CIRGenFunctionInfo &FI) const override {
77
+ if (!getCXXABI ().classifyReturnType (FI))
78
+ FI.getReturnInfo () = classifyReturnType (FI.getReturnType ());
79
+ for (auto &I : FI.arguments ())
80
+ I.info = classifyArgumentType (I.type );
81
+ }
82
+ };
83
+ } // namespace
84
+
23
85
// ===----------------------------------------------------------------------===//
24
86
// AArch64 ABI Implementation
25
87
// ===----------------------------------------------------------------------===//
@@ -151,6 +213,66 @@ class X86_64TargetCIRGenInfo : public TargetCIRGenInfo {
151
213
};
152
214
} // namespace
153
215
216
+ // ===----------------------------------------------------------------------===//
217
+ // Base ABI and target codegen info implementation common between SPIR and
218
+ // SPIR-V.
219
+ // ===----------------------------------------------------------------------===//
220
+
221
+ namespace {
222
+ class CommonSPIRABIInfo : public DefaultABIInfo {
223
+ public:
224
+ CommonSPIRABIInfo (CIRGenTypes &CGT) : DefaultABIInfo(CGT) {}
225
+ };
226
+
227
+ class SPIRVABIInfo : public CommonSPIRABIInfo {
228
+ public:
229
+ SPIRVABIInfo (CIRGenTypes &CGT) : CommonSPIRABIInfo(CGT) {}
230
+ void computeInfo (CIRGenFunctionInfo &FI) const override {
231
+ // The logic is same as in DefaultABIInfo with an exception on the kernel
232
+ // arguments handling.
233
+ llvm::CallingConv::ID CC = FI.getCallingConvention ();
234
+
235
+ bool cxxabiHit = getCXXABI ().classifyReturnType (FI);
236
+ assert (!cxxabiHit && " C++ ABI not considered" );
237
+
238
+ FI.getReturnInfo () = classifyReturnType (FI.getReturnType ());
239
+
240
+ for (auto &I : FI.arguments ()) {
241
+ if (CC == llvm::CallingConv::SPIR_KERNEL) {
242
+ I.info = classifyKernelArgumentType (I.type );
243
+ } else {
244
+ I.info = classifyArgumentType (I.type );
245
+ }
246
+ }
247
+ }
248
+
249
+ private:
250
+ ABIArgInfo classifyKernelArgumentType (QualType Ty) const {
251
+ assert (!getContext ().getLangOpts ().CUDAIsDevice && " NYI" );
252
+ return classifyArgumentType (Ty);
253
+ }
254
+ };
255
+ } // namespace
256
+ namespace {
257
+
258
+ class CommonSPIRTargetCIRGenInfo : public TargetCIRGenInfo {
259
+ public:
260
+ CommonSPIRTargetCIRGenInfo (std::unique_ptr<ABIInfo> ABIInfo)
261
+ : TargetCIRGenInfo(std::move(ABIInfo)) {}
262
+
263
+ unsigned getOpenCLKernelCallingConv () const override {
264
+ return llvm::CallingConv::SPIR_KERNEL;
265
+ }
266
+ };
267
+
268
+ class SPIRVTargetCIRGenInfo : public CommonSPIRTargetCIRGenInfo {
269
+ public:
270
+ SPIRVTargetCIRGenInfo (CIRGenTypes &CGT)
271
+ : CommonSPIRTargetCIRGenInfo(std::make_unique<SPIRVABIInfo>(CGT)) {}
272
+ };
273
+
274
+ } // namespace
275
+
154
276
// TODO(cir): remove the attribute once this gets used.
155
277
LLVM_ATTRIBUTE_UNUSED
156
278
static bool classifyReturnType (const CIRGenCXXABI &CXXABI,
@@ -189,13 +311,6 @@ void X86_64ABIInfo::computeInfo(CIRGenFunctionInfo &FI) const {
189
311
FI.getReturnInfo () = ABIArgInfo::getDirect (CGT.ConvertType (RetTy));
190
312
}
191
313
192
- // / Pass transparent unions as if they were the type of the first element. Sema
193
- // / should ensure that all elements of the union have the same "machine type".
194
- static QualType useFirstFieldIfTransparentUnion (QualType Ty) {
195
- assert (!Ty->getAsUnionType () && " NYI" );
196
- return Ty;
197
- }
198
-
199
314
// / GetINTEGERTypeAtOffset - The ABI specifies that a value should be passed in
200
315
// / an 8-byte GPR. This means that we either have a scalar or we are talking
201
316
// / about the high or low part of an up-to-16-byte struct. This routine picks
@@ -459,5 +574,9 @@ const TargetCIRGenInfo &CIRGenModule::getTargetCIRGenInfo() {
459
574
return SetCIRGenInfo (new X86_64TargetCIRGenInfo (genTypes, AVXLevel));
460
575
}
461
576
}
577
+
578
+ case llvm::Triple::spirv64: {
579
+ return SetCIRGenInfo (new SPIRVTargetCIRGenInfo (genTypes));
580
+ }
462
581
}
463
582
}
0 commit comments