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