1 /*========================== begin_copyright_notice ============================
2
3 Copyright (C) 2019-2021 Intel Corporation
4
5 SPDX-License-Identifier: MIT
6
7 ============================= end_copyright_notice ===========================*/
8
9 //===----------------------------------------------------------------------===//
10 //
11 // This file defines a set of enums which allow processing of intrinsic
12 // functions. Values of these enum types are returned by
13 // GenXIntrinsic::getGenXIntrinsicID.
14 //
15 //===----------------------------------------------------------------------===//
16
17 #ifndef GENX_INTRINSIC_INTERFACE_H
18 #define GENX_INTRINSIC_INTERFACE_H
19
20 #include "llvm/IR/Module.h"
21
22 #include "llvm/IR/Attributes.h"
23 #include "llvm/IR/Function.h"
24 #include "llvm/IR/Intrinsics.h"
25 #include "llvm/IR/Instructions.h"
26 #include "llvm/GenXIntrinsics/GenXVersion.h"
27
28 namespace llvm {
29
30 namespace GenXIntrinsic {
31 enum ID : unsigned {
32 not_genx_intrinsic = Intrinsic::num_intrinsics,
33 #define GET_INTRINSIC_ENUM_VALUES
34 #include "llvm/GenXIntrinsics/GenXIntrinsicDescription.gen"
35 #undef GET_INTRINSIC_ENUM_VALUES
36 num_genx_intrinsics,
37 // note that Intrinsic::not_intrinsic means that it is not a LLVM intrinsic
38 not_any_intrinsic
39 };
40
41 namespace GenXResult {
42 enum ResultIndexes {
43 IdxAddc_Add = 1,
44 IdxAddc_Carry = 0,
45 IdxSubb_Sub = 1,
46 IdxSubb_Borrow = 0
47 };
48 }
49
50 // The number of elements to load per address (vector size)
51 // NOTE: taken from cmc/support
52 enum class LSCVectorSize : uint8_t {
53 N0 = 0,
54 N1 = 1, // 1 element
55 N2 = 2, // 2 element
56 N3 = 3, // 3 element
57 N4 = 4, // 4 element
58 N8 = 5, // 8 element
59 N16 = 6, // 16 element
60 N32 = 7, // 32 element
61 N64 = 8 // 64 element
62 };
63
64 enum class LSCDataSize : uint8_t {
65 Invalid,
66 D8,
67 D16,
68 D32,
69 D64,
70 D8U32,
71 D16U32,
72 D16U32H,
73 };
74
75 enum class LSCDataOrder : uint8_t {
76 Invalid,
77 NonTranspose,
78 Transpose
79 };
80
81 enum class LSCCategory : uint8_t {
82 Load,
83 Load2D,
84 Prefetch,
85 Prefetch2D,
86 Store,
87 Store2D,
88 Fence,
89 LegacyAtomic,
90 Atomic,
91 NotLSC
92 };
93
94 namespace GenXRegion {
95 enum {
96 // Operands in both rdregion and wrregion:
97 OldValueOperandNum = 0,
98 // Operands in rdregion:
99 RdVStrideOperandNum = 1,
100 RdWidthOperandNum = 2,
101 RdStrideOperandNum = 3,
102 RdIndexOperandNum = 4,
103 // Operands in wrregion:
104 NewValueOperandNum = 1,
105 WrVStrideOperandNum = 2,
106 WrWidthOperandNum = 3,
107 WrStrideOperandNum = 4,
108 WrIndexOperandNum = 5,
109 PredicateOperandNum = 7
110 };
111 } // namespace GenXRegion
112
getGenXIntrinsicPrefix()113 inline const char *getGenXIntrinsicPrefix() { return "llvm.genx."; }
114
115 ID getGenXIntrinsicID(const Function *F);
116
117 /// Utility function to get the genx_intrinsic ID if V is a GenXIntrinsic call.
118 /// V is allowed to be 0.
getGenXIntrinsicID(const Value * V)119 inline ID getGenXIntrinsicID(const Value *V) {
120 if (V)
121 if (const CallInst *CI = dyn_cast<CallInst>(V))
122 if (Function *Callee = CI->getCalledFunction())
123 return getGenXIntrinsicID(Callee);
124 return GenXIntrinsic::not_genx_intrinsic;
125 }
126
127 /// GenXIntrinsic::isGenXIntrinsic(ID) - Is GenX intrinsic
128 /// NOTE that this is include not_genx_intrinsic
129 /// BUT DOES NOT include not_any_intrinsic
isGenXIntrinsic(unsigned ID)130 inline bool isGenXIntrinsic(unsigned ID) {
131 return ID >= not_genx_intrinsic && ID < num_genx_intrinsics;
132 }
133
134 /// GenXIntrinsic::isGenXIntrinsic(CF) - Returns true if
135 /// the function's name starts with "llvm.genx.".
136 /// It's possible for this function to return true while getGenXIntrinsicID()
137 /// returns GenXIntrinsic::not_genx_intrinsic!
isGenXIntrinsic(const Function * CF)138 inline bool isGenXIntrinsic(const Function *CF) {
139 return CF->getName().startswith(getGenXIntrinsicPrefix());
140 }
141
142 /// GenXIntrinsic::isGenXIntrinsic(V) - Returns true if
143 /// the function's name starts with "llvm.genx.".
144 /// It's possible for this function to return true while getGenXIntrinsicID()
145 /// returns GenXIntrinsic::not_genx_intrinsic!
isGenXIntrinsic(const Value * V)146 inline bool isGenXIntrinsic(const Value *V) {
147 if (V)
148 if (const CallInst *CI = dyn_cast<CallInst>(V))
149 if (Function *Callee = CI->getCalledFunction())
150 return isGenXIntrinsic(Callee);
151 return false;
152 }
153
154 /// GenXIntrinsic::isGenXNonTrivialIntrinsic(ID) - Is GenX intrinsic,
155 /// which is not equal to not_genx_intrinsic or not_any_intrinsic
isGenXNonTrivialIntrinsic(unsigned ID)156 inline bool isGenXNonTrivialIntrinsic(unsigned ID) {
157 return ID > not_genx_intrinsic && ID < num_genx_intrinsics;
158 }
159
160 /// GenXIntrinsic::isGenXNonTrivialIntrinsic(CF) - Returns true if
161 /// CF is genx intrinsic, not equal to not_any_intrinsic or not_genx_intrinsic
isGenXNonTrivialIntrinsic(const Function * CF)162 inline bool isGenXNonTrivialIntrinsic(const Function *CF) {
163 return isGenXNonTrivialIntrinsic(getGenXIntrinsicID(CF));
164 }
165
166 /// GenXIntrinsic::isGenXNonTrivialIntrinsic(V) - Returns true if
167 /// V is genx intrinsic, not equal to not_any_intrinsic or not_genx_intrinsic
isGenXNonTrivialIntrinsic(const Value * V)168 inline bool isGenXNonTrivialIntrinsic(const Value *V) {
169 return isGenXNonTrivialIntrinsic(getGenXIntrinsicID(V));
170 }
171
172 /// GenXIntrinsic::getGenXName(ID) - Return the LLVM name for a GenX intrinsic,
173 /// such as "llvm.genx.lane.id".
174 std::string getGenXName(ID id, ArrayRef<Type *> Tys = None);
175
176 ID lookupGenXIntrinsicID(StringRef Name);
177
178 AttributeList getAttributes(LLVMContext &C, ID id);
179
180 /// GenXIntrinsic::getGenXType(ID) - Return the function type for an intrinsic.
181 FunctionType *getGenXType(LLVMContext &Context, GenXIntrinsic::ID id,
182 ArrayRef<Type *> Tys = None);
183
184 /// GenXIntrinsic::getGenXDeclaration(M, ID) - Create or insert a GenX LLVM
185 /// Function declaration for an intrinsic, and return it.
186 ///
187 /// The Tys parameter is for intrinsics with overloaded types (e.g., those
188 /// using iAny, fAny, vAny, or iPTRAny). For a declaration of an overloaded
189 /// intrinsic, Tys must provide exactly one type for each overloaded type in
190 /// the intrinsic.
191 Function *getGenXDeclaration(Module *M, ID id, ArrayRef<Type *> Tys = None);
192
193 void getIntrinsicInfoTableEntries(
194 GenXIntrinsic::ID id,
195 SmallVectorImpl<Intrinsic::IITDescriptor> &T);
196
197 /// GenXIntrinsic::resetGenXAttributes(F) - recalculates attributes
198 /// of a CM intrinsic by setting the default values (as per
199 /// intrinsic definition).
200 ///
201 /// F is required to be a GenX intrinsic function
202 void resetGenXAttributes(Function* F);
203
204 /// GenXIntrinsic::getAnyIntrinsicID(F) - Return LLVM or GenX intrinsic ID
205 /// If is not intrinsic returns not_any_intrinsic
206 /// Note that Function::getIntrinsicID returns ONLY LLVM intrinsics
getAnyIntrinsicID(const Function * F)207 inline unsigned getAnyIntrinsicID(const Function *F) {
208 if (isGenXNonTrivialIntrinsic(F))
209 return getGenXIntrinsicID(F);
210 else {
211 assert(F);
212 unsigned IID = F->getIntrinsicID();
213 if (IID == Intrinsic::not_intrinsic)
214 return GenXIntrinsic::not_any_intrinsic;
215 else
216 return IID;
217 }
218 }
219
220 /// Utility function to get the LLVM or GenX intrinsic ID if V is an intrinsic
221 /// call.
222 /// V is allowed to be 0.
getAnyIntrinsicID(const Value * V)223 inline unsigned getAnyIntrinsicID(const Value *V) {
224 if (V)
225 if (const CallInst *CI = dyn_cast<CallInst>(V))
226 if (Function *Callee = CI->getCalledFunction())
227 return getAnyIntrinsicID(Callee);
228 return GenXIntrinsic::not_any_intrinsic;
229 }
230
231 /// GenXIntrinsic::isAnyIntrinsic(ID) - Is any intrinsic
232 /// including not_any_intrinsic
isAnyIntrinsic(unsigned id)233 inline bool isAnyIntrinsic(unsigned id) {
234 assert(id != not_genx_intrinsic && id != Intrinsic::not_intrinsic &&
235 "Do not use this method with getGenXIntrinsicID or getIntrinsicID!");
236 return id < num_genx_intrinsics || id == not_any_intrinsic;
237 }
238
239 /// GenXIntrinsic::isAnyNonTrivialIntrinsic(id) - Is GenX or LLVM intrinsic,
240 /// which is not equal to not_any_intrinsic
isAnyNonTrivialIntrinsic(unsigned id)241 inline bool isAnyNonTrivialIntrinsic(unsigned id) {
242 assert(id != not_genx_intrinsic && id != Intrinsic::not_intrinsic &&
243 "Do not use this method with getGenXIntrinsicID or getIntrinsicID!");
244 return id < num_genx_intrinsics &&
245 id != not_any_intrinsic;
246 }
247
248 /// GenXIntrinsic::isAnyNonTrivialIntrinsic(ID) - Is GenX or LLVM intrinsic,
249 /// which is not equal to not_genx_intrinsic, not_any_intrinsic or not_intrinsic
isAnyNonTrivialIntrinsic(const Function * CF)250 inline bool isAnyNonTrivialIntrinsic(const Function *CF) {
251 return isAnyNonTrivialIntrinsic(getAnyIntrinsicID(CF));
252 }
253
254 /// Utility function to check if V is LLVM or GenX intrinsic call,
255 /// which is not not_intrinsic, not_genx_intrinsic or not_any_intrinsic
256 /// V is allowed to be 0.
isAnyNonTrivialIntrinsic(const Value * V)257 inline bool isAnyNonTrivialIntrinsic(const Value *V) {
258 return isAnyNonTrivialIntrinsic(getAnyIntrinsicID(V));
259 }
260
261 /// GenXIntrinsic::getAnyName(ID) - Return the LLVM name for LLVM or GenX
262 /// intrinsic, such as "llvm.genx.lane.id".
263 std::string getAnyName(unsigned id, ArrayRef<Type *> Tys = None);
264
265 /// GenXIntrinsic::getAnyType(ID) - Return the function type for an intrinsic.
266 inline FunctionType *getAnyType(LLVMContext &Context, unsigned id,
267 ArrayRef<Type *> Tys = None) {
268 assert(isAnyNonTrivialIntrinsic(id));
269 if (isGenXIntrinsic(id))
270 return getGenXType(Context, (ID)id, Tys);
271 else
272 return Intrinsic::getType(Context, (Intrinsic::ID)id, Tys);
273 }
274
275 /// GenXIntrinsic::isSupportedPlatform(CPU, ID) - Return true if GenxIntrinsic
276 // is supported by current platform
277 bool isSupportedPlatform(const std::string &CPU, unsigned id);
278
279 /// GenXIntrinsic::isOverloadedArg(ID, ArgNum) - Return true if ArgNum
280 /// in intrinsic overloaded
281 bool isOverloadedArg(unsigned IntrinID, unsigned ArgNum);
282
283 /// GenXIntrinsic::isOverloadedRet(ID) - Return true if return type
284 /// in intrinsic is overloaded
285 bool isOverloadedRet(unsigned IntrinID);
286
287 /// GenXIntrinsic::getAnyDeclaration(M, ID) - Create or insert a LLVM
288 /// Function declaration for an intrinsic, and return it.
289 ///
290 /// The Tys parameter is for intrinsics with overloaded types (e.g., those
291 /// using iAny, fAny, vAny, or iPTRAny). For a declaration of an overloaded
292 /// intrinsic, Tys must provide exactly one type for each overloaded type in
293 /// the intrinsic.
294 inline Function *getAnyDeclaration(Module *M, unsigned id,
295 ArrayRef<Type *> Tys = None) {
296 assert(isAnyNonTrivialIntrinsic(id));
297 if (isGenXIntrinsic(id)) {
298 return getGenXDeclaration(M, (ID)id, Tys);
299 } else {
300 return Intrinsic::getDeclaration(M, (Intrinsic::ID)id, Tys);
301 }
302 }
303
304 /// GenXIntrinsic::getGenXMulIID(S1, S2) - returns GenXIntrinsic::ID for
305 /// the enx_XXmul opertation, where XX is is defined by the input arguments
306 /// which represent signs of the operands
getGenXMulIID(bool LHSign,bool RHSign)307 inline GenXIntrinsic::ID getGenXMulIID(bool LHSign, bool RHSign) {
308 return LHSign
309 ? (RHSign ? GenXIntrinsic::genx_ssmul : GenXIntrinsic::genx_sumul)
310 : (RHSign ? GenXIntrinsic::genx_usmul : GenXIntrinsic::genx_uumul);
311 }
312
isRdRegion(unsigned IntrinID)313 inline bool isRdRegion(unsigned IntrinID) {
314 switch (IntrinID) {
315 case GenXIntrinsic::genx_rdregioni:
316 case GenXIntrinsic::genx_rdregionf:
317 return true;
318 default:
319 return false;
320 }
321 }
322
isRdRegion(const Function * F)323 inline bool isRdRegion(const Function *F) {
324 return isRdRegion(getGenXIntrinsicID(F));
325 }
326
isRdRegion(const Value * V)327 inline bool isRdRegion(const Value *V) {
328 return isRdRegion(getGenXIntrinsicID(V));
329 }
330
isWrRegion(unsigned IntrinID)331 inline bool isWrRegion(unsigned IntrinID) {
332 switch (IntrinID) {
333 case GenXIntrinsic::genx_wrregioni:
334 case GenXIntrinsic::genx_wrregionf:
335 case GenXIntrinsic::genx_wrconstregion:
336 return true;
337 default:
338 return false;
339 }
340 }
341
isWrRegion(const Function * F)342 inline bool isWrRegion(const Function *F) {
343 return isWrRegion(getGenXIntrinsicID(F));
344 }
345
isWrRegion(const Value * V)346 inline bool isWrRegion(const Value *V) {
347 return isWrRegion(getGenXIntrinsicID(V));
348 }
349
isAbs(unsigned IntrinID)350 inline bool isAbs(unsigned IntrinID) {
351 if (IntrinID == GenXIntrinsic::genx_absf || IntrinID == GenXIntrinsic::genx_absi)
352 return true;
353 return false;
354 }
355
isAbs(const Function * F)356 inline bool isAbs(const Function *F) {
357 return isAbs(getGenXIntrinsicID(F));
358 }
359
isAbs(const Value * V)360 inline bool isAbs(const Value *V) {
361 return isAbs(getGenXIntrinsicID(V));
362 }
363
isIntegerSat(unsigned IID)364 inline bool isIntegerSat(unsigned IID) {
365 switch (IID) {
366 case GenXIntrinsic::genx_sstrunc_sat:
367 case GenXIntrinsic::genx_sutrunc_sat:
368 case GenXIntrinsic::genx_ustrunc_sat:
369 case GenXIntrinsic::genx_uutrunc_sat:
370 return true;
371 default:
372 return false;
373 }
374 }
375
isIntegerSat(const Function * F)376 inline bool isIntegerSat(const Function *F) {
377 return isIntegerSat(getGenXIntrinsicID(F));
378 }
379
isIntegerSat(const Value * V)380 inline bool isIntegerSat(const Value *V) {
381 return isIntegerSat(getGenXIntrinsicID(V));
382 }
383
isVLoad(unsigned IntrinID)384 inline bool isVLoad(unsigned IntrinID) {
385 return IntrinID == GenXIntrinsic::genx_vload;
386 }
387
isVLoad(const Function * F)388 inline bool isVLoad(const Function *F) {
389 return isVLoad(getGenXIntrinsicID(F));
390 }
391
isVLoad(const Value * V)392 inline bool isVLoad(const Value *V) {
393 return isVLoad(getGenXIntrinsicID(V));
394 }
395
isVStore(unsigned IntrinID)396 inline bool isVStore(unsigned IntrinID) {
397 return IntrinID == GenXIntrinsic::genx_vstore;
398 }
399
isVStore(const Function * F)400 inline bool isVStore(const Function *F) {
401 return isVStore(getGenXIntrinsicID(F));
402 }
403
isVStore(const Value * V)404 inline bool isVStore(const Value *V) {
405 return isVStore(getGenXIntrinsicID(V));
406 }
407
isVLoadStore(unsigned IntrinID)408 inline bool isVLoadStore(unsigned IntrinID) {
409 return isVLoad(IntrinID) || isVStore(IntrinID);
410 }
411
isVLoadStore(const Function * F)412 inline bool isVLoadStore(const Function *F) {
413 return isVLoadStore(getGenXIntrinsicID(F));
414 }
415
isVLoadStore(const Value * V)416 inline bool isVLoadStore(const Value *V) {
417 return isVLoadStore(getGenXIntrinsicID(V));
418 }
419
isReadPredefReg(unsigned IntrinID)420 inline bool isReadPredefReg(unsigned IntrinID) {
421 return IntrinID == GenXIntrinsic::genx_read_predef_reg;
422 }
423
isReadPredefReg(const Function * F)424 inline bool isReadPredefReg(const Function *F) {
425 return isReadPredefReg(getGenXIntrinsicID(F));
426 }
427
isReadPredefReg(const Value * V)428 inline bool isReadPredefReg(const Value *V) {
429 return isReadPredefReg(getGenXIntrinsicID(V));
430 }
431
isWritePredefReg(unsigned IntrinID)432 inline bool isWritePredefReg(unsigned IntrinID) {
433 return IntrinID == GenXIntrinsic::genx_write_predef_reg;
434 }
435
isWritePredefReg(const Function * F)436 inline bool isWritePredefReg(const Function *F) {
437 return isWritePredefReg(getGenXIntrinsicID(F));
438 }
439
isWritePredefReg(const Value * V)440 inline bool isWritePredefReg(const Value *V) {
441 return isWritePredefReg(getGenXIntrinsicID(V));
442 }
443
isReadWritePredefReg(unsigned IntrinID)444 inline bool isReadWritePredefReg(unsigned IntrinID) {
445 return isWritePredefReg(IntrinID) || isReadPredefReg(IntrinID);
446 }
447
isReadWritePredefReg(const Value * V)448 inline bool isReadWritePredefReg(const Value *V) {
449 return isWritePredefReg(getGenXIntrinsicID(V)) ||
450 isReadPredefReg(getGenXIntrinsicID(V));
451 }
452
isReadWritePredefReg(const Function * F)453 inline bool isReadWritePredefReg(const Function *F) {
454 return isWritePredefReg(getGenXIntrinsicID(F)) ||
455 isReadPredefReg(getGenXIntrinsicID(F));
456 }
457
getLSCCategory(unsigned IntrinID)458 inline LSCCategory getLSCCategory(unsigned IntrinID) {
459 switch(IntrinID) {
460 case GenXIntrinsic::genx_lsc_load_bti:
461 case GenXIntrinsic::genx_lsc_load_stateless:
462 case GenXIntrinsic::genx_lsc_load_slm:
463 case GenXIntrinsic::genx_lsc_load_bindless:
464 case GenXIntrinsic::genx_lsc_load_quad_bti:
465 case GenXIntrinsic::genx_lsc_load_quad_slm:
466 case GenXIntrinsic::genx_lsc_load_quad_stateless:
467 return LSCCategory::Load;
468 case GenXIntrinsic::genx_lsc_load2d_stateless:
469 return LSCCategory::Load2D;
470 case GenXIntrinsic::genx_lsc_prefetch_bti:
471 case GenXIntrinsic::genx_lsc_prefetch_stateless:
472 return LSCCategory::Prefetch;
473 case GenXIntrinsic::genx_lsc_prefetch2d_stateless:
474 return LSCCategory::Prefetch2D;
475 case GenXIntrinsic::genx_lsc_store_bti:
476 case GenXIntrinsic::genx_lsc_store_stateless:
477 case GenXIntrinsic::genx_lsc_store_slm:
478 case GenXIntrinsic::genx_lsc_store_bindless:
479 case GenXIntrinsic::genx_lsc_store_quad_bti:
480 case GenXIntrinsic::genx_lsc_store_quad_slm:
481 case GenXIntrinsic::genx_lsc_store_quad_stateless:
482 return LSCCategory::Store;
483 case GenXIntrinsic::genx_lsc_store2d_stateless:
484 return LSCCategory::Store2D;
485 case GenXIntrinsic::genx_lsc_fence:
486 return LSCCategory::Fence;
487 case GenXIntrinsic::genx_lsc_atomic_bti:
488 case GenXIntrinsic::genx_lsc_atomic_stateless:
489 case GenXIntrinsic::genx_lsc_atomic_slm:
490 case GenXIntrinsic::genx_lsc_atomic_bindless:
491 return LSCCategory::LegacyAtomic;
492 case GenXIntrinsic::genx_lsc_xatomic_bti:
493 case GenXIntrinsic::genx_lsc_xatomic_stateless:
494 case GenXIntrinsic::genx_lsc_xatomic_slm:
495 case GenXIntrinsic::genx_lsc_xatomic_bindless:
496 return LSCCategory::Atomic;
497 default:
498 return LSCCategory::NotLSC;
499 }
500 }
501
getLSCCategory(const Value * V)502 inline LSCCategory getLSCCategory(const Value *V) {
503 return getLSCCategory(getGenXIntrinsicID(V));
504 }
505
getLSCCategory(const Function * F)506 inline LSCCategory getLSCCategory(const Function *F) {
507 return getLSCCategory(getGenXIntrinsicID(F));
508 }
509
isLSCLoad(unsigned IntrinID)510 inline bool isLSCLoad(unsigned IntrinID) {
511 return getLSCCategory(IntrinID) == LSCCategory::Load;
512 }
513
isLSCLoad(const Value * V)514 inline bool isLSCLoad(const Value *V) {
515 return isLSCLoad(getGenXIntrinsicID(V));
516 }
517
isLSCLoad(const Function * F)518 inline bool isLSCLoad(const Function *F) {
519 return isLSCLoad(getGenXIntrinsicID(F));
520 }
521
isLSCLoad2D(unsigned IntrinID)522 inline bool isLSCLoad2D(unsigned IntrinID) {
523 return getLSCCategory(IntrinID) == LSCCategory::Load2D;
524 }
525
isLSCLoad2D(const Value * V)526 inline bool isLSCLoad2D(const Value *V) {
527 return isLSCLoad2D(getGenXIntrinsicID(V));
528 }
529
isLSCLoad2D(const Function * F)530 inline bool isLSCLoad2D(const Function *F) {
531 return isLSCLoad2D(getGenXIntrinsicID(F));
532 }
533
534
isLSCPrefetch(unsigned IntrinID)535 inline bool isLSCPrefetch(unsigned IntrinID) {
536 return getLSCCategory(IntrinID) == LSCCategory::Prefetch;
537 }
538
isLSCPrefetch(const Value * V)539 inline bool isLSCPrefetch(const Value *V) {
540 return isLSCPrefetch(getGenXIntrinsicID(V));
541 }
542
isLSCPrefetch(const Function * F)543 inline bool isLSCPrefetch(const Function *F) {
544 return isLSCPrefetch(getGenXIntrinsicID(F));
545 }
546
isLSCPrefetch2D(unsigned IntrinID)547 inline bool isLSCPrefetch2D(unsigned IntrinID) {
548 return getLSCCategory(IntrinID) == LSCCategory::Prefetch2D;
549 }
550
isLSCPrefetch2D(const Value * V)551 inline bool isLSCPrefetch2D(const Value *V) {
552 return isLSCPrefetch2D(getGenXIntrinsicID(V));
553 }
554
isLSCPrefetch2D(const Function * F)555 inline bool isLSCPrefetch2D(const Function *F) {
556 return isLSCPrefetch2D(getGenXIntrinsicID(F));
557 }
558
isLSCStore(unsigned IntrinID)559 inline bool isLSCStore(unsigned IntrinID) {
560 return getLSCCategory(IntrinID) == LSCCategory::Store;
561 }
562
isLSCStore(const Value * V)563 inline bool isLSCStore(const Value *V) {
564 return isLSCStore(getGenXIntrinsicID(V));
565 }
566
isLSCStore(const Function * F)567 inline bool isLSCStore(const Function *F) {
568 return isLSCStore(getGenXIntrinsicID(F));
569 }
570
isLSCStore2D(unsigned IntrinID)571 inline bool isLSCStore2D(unsigned IntrinID) {
572 return getLSCCategory(IntrinID) == LSCCategory::Store2D;
573 }
574
isLSCStore2D(const Value * V)575 inline bool isLSCStore2D(const Value *V) {
576 return isLSCStore2D(getGenXIntrinsicID(V));
577 }
578
isLSCStore2D(const Function * F)579 inline bool isLSCStore2D(const Function *F) {
580 return isLSCStore2D(getGenXIntrinsicID(F));
581 }
582
583
isLSCFence(unsigned IntrinID)584 inline bool isLSCFence(unsigned IntrinID) {
585 return getLSCCategory(IntrinID) == LSCCategory::Fence;
586 }
587
isLSCFence(const Value * V)588 inline bool isLSCFence(const Value *V) {
589 return isLSCFence(getGenXIntrinsicID(V));
590 }
591
isLSCFence(const Function * F)592 inline bool isLSCFence(const Function *F) {
593 return isLSCFence(getGenXIntrinsicID(F));
594 }
595
isLSCLegacyAtomic(unsigned IntrinID)596 inline bool isLSCLegacyAtomic(unsigned IntrinID) {
597 return getLSCCategory(IntrinID) == LSCCategory::LegacyAtomic;
598 }
599
isLSCLegacyAtomic(const Value * V)600 inline bool isLSCLegacyAtomic(const Value *V) {
601 return isLSCLegacyAtomic(getGenXIntrinsicID(V));
602 }
603
isLSCLegacyAtomic(const Function * F)604 inline bool isLSCLegacyAtomic(const Function *F) {
605 return isLSCLegacyAtomic(getGenXIntrinsicID(F));
606 }
607
isLSCAtomic(unsigned IntrinID)608 inline bool isLSCAtomic(unsigned IntrinID) {
609 return getLSCCategory(IntrinID) == LSCCategory::Atomic;
610 }
611
isLSCAtomic(const Value * V)612 inline bool isLSCAtomic(const Value *V) {
613 return isLSCAtomic(getGenXIntrinsicID(V));
614 }
615
isLSCAtomic(const Function * F)616 inline bool isLSCAtomic(const Function *F) {
617 return isLSCAtomic(getGenXIntrinsicID(F));
618 }
619
isLSC(unsigned IntrinID)620 inline bool isLSC(unsigned IntrinID) {
621 return getLSCCategory(IntrinID) != LSCCategory::NotLSC;
622 }
623
isLSC(const Value * V)624 inline bool isLSC(const Value *V) {
625 return isLSC(getGenXIntrinsicID(V));
626 }
627
isLSC(const Function * F)628 inline bool isLSC(const Function *F) {
629 return isLSC(getGenXIntrinsicID(F));
630 }
631
isLSC2D(unsigned IntrinID)632 inline bool isLSC2D(unsigned IntrinID) {
633 switch (getLSCCategory(IntrinID)) {
634 case LSCCategory::Load2D:
635 case LSCCategory::Prefetch2D:
636 case LSCCategory::Store2D:
637 return true;
638 case LSCCategory::Load:
639 case LSCCategory::Prefetch:
640 case LSCCategory::Store:
641 case LSCCategory::Fence:
642 case LSCCategory::LegacyAtomic:
643 case LSCCategory::Atomic:
644 case LSCCategory::NotLSC:
645 return false;
646 }
647 llvm_unreachable("Unknown LSC category");
648 }
649
isLSC2D(const Value * V)650 inline bool isLSC2D(const Value *V) {
651 return isLSC2D(getGenXIntrinsicID(V));
652 }
653
isLSC2D(const Function * F)654 inline bool isLSC2D(const Function *F) {
655 return isLSC2D(getGenXIntrinsicID(F));
656 }
657
getLSCNumVectorElements(LSCVectorSize VS)658 inline unsigned getLSCNumVectorElements(LSCVectorSize VS) {
659 switch (VS) {
660 case LSCVectorSize::N0:
661 break;
662 case LSCVectorSize::N1:
663 return 1;
664 case LSCVectorSize::N2:
665 return 2;
666 case LSCVectorSize::N3:
667 return 3;
668 case LSCVectorSize::N4:
669 return 4;
670 case LSCVectorSize::N8:
671 return 8;
672 case LSCVectorSize::N16:
673 return 16;
674 case LSCVectorSize::N32:
675 return 32;
676 case LSCVectorSize::N64:
677 return 64;
678 }
679 llvm_unreachable("Unknown vector size");
680 }
681
682 LSCVectorSize getLSCVectorSize(const Instruction *I);
683
getLSCNumVectorElements(const Instruction * I)684 inline unsigned getLSCNumVectorElements(const Instruction *I) {
685 return GenXIntrinsic::getLSCNumVectorElements(getLSCVectorSize(I));
686 }
687
getLSCDataBitsRegister(LSCDataSize DS)688 inline unsigned getLSCDataBitsRegister(LSCDataSize DS) {
689 switch(DS) {
690 case LSCDataSize::Invalid:
691 break;
692 case LSCDataSize::D8:
693 return 8;
694 case LSCDataSize::D16:
695 return 16;
696 case LSCDataSize::D32:
697 case LSCDataSize::D8U32:
698 case LSCDataSize::D16U32:
699 case LSCDataSize::D16U32H:
700 return 32;
701 case LSCDataSize::D64:
702 return 64;
703 }
704 llvm_unreachable("Unknown data size");
705 }
706
getLSCDataBitsMemory(LSCDataSize DS)707 inline unsigned getLSCDataBitsMemory(LSCDataSize DS) {
708 switch(DS) {
709 case LSCDataSize::Invalid:
710 break;
711 case LSCDataSize::D8:
712 case LSCDataSize::D8U32:
713 return 8;
714 case LSCDataSize::D16:
715 case LSCDataSize::D16U32:
716 case LSCDataSize::D16U32H:
717 return 16;
718 case LSCDataSize::D32:
719 return 32;
720 case LSCDataSize::D64:
721 return 64;
722 }
723 llvm_unreachable("Unknown data size");
724 }
725
726 LSCDataSize getLSCDataSize(const Instruction *I);
727
getLSCDataBitsRegister(const Instruction * I)728 inline unsigned getLSCDataBitsRegister(const Instruction *I) {
729 return getLSCDataBitsRegister(getLSCDataSize(I));
730 }
731
getLSCDataBitsMemory(const Instruction * I)732 inline unsigned getLSCDataBitsMemory(const Instruction *I) {
733 return getLSCDataBitsMemory(getLSCDataSize(I));
734 }
735
736 LSCDataOrder getLSCDataOrder(const Instruction *I);
737
isLSCNonTransposed(const Instruction * I)738 inline bool isLSCNonTransposed(const Instruction *I) {
739 return getLSCDataOrder(I) == LSCDataOrder::NonTranspose;
740 }
741
isLSCTransposed(const Instruction * I)742 inline bool isLSCTransposed(const Instruction *I) {
743 return getLSCDataOrder(I) == LSCDataOrder::Transpose;
744 }
745
746 unsigned getLSCWidth(const Instruction *I);
747
748 } // namespace GenXIntrinsic
749
750 // todo: delete this
751 namespace GenXIntrinsic {
752 AttributeList getAttributes(LLVMContext &C, ID id);
753
754 } // namespace GenXIntrinsic
755
756 } // namespace llvm
757
758 #endif
759