1 /*========================== begin_copyright_notice ============================
2 
3 Copyright (C) 2017-2021 Intel Corporation
4 
5 SPDX-License-Identifier: MIT
6 
7 ============================= end_copyright_notice ===========================*/
8 
9 //
10 // This file declares a class to access a table of extra information about the
11 // llvm.genx.* intrinsics, used by the vISA register allocator and function
12 // writer to decide exactly what operand type to use. The more usual approach
13 // in an LLVM target is to have an intrinsic map to an instruction in
14 // instruction selection, then have register category information on the
15 // instruction. But we are not using the target independent code generator, we
16 // are generating code directly from LLVM IR.
17 //
18 //===----------------------------------------------------------------------===//
19 #ifndef GENXINTRINSICS_H
20 #define GENXINTRINSICS_H
21 #include "GenX.h"
22 #include "GenXVisa.h"
23 #include "Probe/Assertion.h"
24 
25 #define GENX_ITR_CATVAL(v) ((v) << CATBASE)
26 #define GENX_ITR_FLAGENUM(o, v) ((v) << ((o) + FLAGBASE))
27 #define GENX_ITR_FLAGMASK(o, w) (((1 << (w)) - 1) << ((o) + FLAGBASE))
28 #define GENX_ITR_FLAGVAL(o) GENX_ITR_FLAGENUM(o, 1)
29 
30 namespace llvm {
31   class CallInst;
32 
33 class GenXIntrinsicInfo {
34 public:
35   typedef uint32_t DescrElementType;
36 private:
37   const DescrElementType *Args;
38   static const DescrElementType Table[];
39 public:
40   enum {
41     // General format of intrinsic descriptor words:
42     //   Bits 31..24: Category enumeration
43     //   Bits 23..8:  Flags, if any, meaning and layout depends on category
44     //   Bits 7..0:   Operand or literal, if any
45     //
46     // One exception to the above is LITERAL, where everything that isn't
47     // the category field is assumed to be the literal value.
48     //
49     // If you want to re-apportion space in the descriptor word (typically
50     // because you need another flag and you can't express what you need to
51     // do without creating one) then just modify FLAGBASE and FLAGWIDTH
52     // below, and everything else will shake itself out appropriately.
53     // Currently 8 bits are allocated for the category enumaration bitfield,
54     // although the actual enumeration values defined only require 6 bits -
55     // and there is still plenty of space left over even within that.
56     // Similarly, there are 8 bits allocated to the operand bitfield, and
57     // currently the maximum needed is 5.
58     //
59     // At the moment, the GENERAL category has 4 unused flag bits available
60     // to it, the RAW category has 13 unused bits, and the ARGCOUNT category
61     // has 13 unused bits. No other categories make use of the flags yet,
62     // so it should be a good while yet before it's necessary to resize
63     // the bitfields.
64 
65     FLAGBASE = 8,
66     FLAGWIDTH = 16,
67     CATBASE = FLAGBASE + FLAGWIDTH,
68 
69     CATMASK = ~((1 << CATBASE) - 1),
70     FLAGMASK = ((~((1 << FLAGBASE) - 1)) ^ CATMASK),
71     OPNDMASK = ~(CATMASK | FLAGMASK),
72 
73     // A field that does not contain an operand number or literal value:
74     END =                   0, // end of instruction description
75     IMPLICITPRED =          GENX_ITR_CATVAL(0x01), // implicit predication field
76     NULLRAW =               GENX_ITR_CATVAL(0x02), // null raw operand
77     ISBARRIER =             GENX_ITR_CATVAL(0x03), // intrinsic is barrier: suppress nobarrier attribute
78 
79     EXECSIZE =              GENX_ITR_CATVAL(0x04), // execution size
80     EXECSIZE_GE2 =          GENX_ITR_CATVAL(0x05), // execution size (must be >= 2)
81     EXECSIZE_GE4 =          GENX_ITR_CATVAL(0x06), // execution size (must be >= 4)
82     EXECSIZE_GE8 =          GENX_ITR_CATVAL(0x07), // execution size (must be >= 8)
83     EXECSIZE_NOT2 =         GENX_ITR_CATVAL(0x08), // execution size (cannot be 2)
84 
85     // A field that contains a literal value the operand field
86     LITERAL =               GENX_ITR_CATVAL(0x09), // literal byte (usually opcode)
87     LITMASK =               ~CATMASK,
88 
89     // A field that contains an operand number, other than general:
90     FIRST_OPERAND =         GENX_ITR_CATVAL(0x10),
91     LOG2OWORDS =            GENX_ITR_CATVAL(0x10), // log2 number of owords
92     NUMGRFS =               GENX_ITR_CATVAL(0x11), // rounded up number of GRFs
93     EXECSIZE_FROM_ARG =     GENX_ITR_CATVAL(0x12), // exec_size field inferred from width of
94                                                    // predication arg
95     SVMGATHERBLOCKSIZE =    GENX_ITR_CATVAL(0x13), // svm gather block size, inferred from data type
96     LOG2OWORDS_PLUS_8 =     GENX_ITR_CATVAL(0x14), // log2 number of owords, plus 8
97     GATHERNUMELTS =         GENX_ITR_CATVAL(0x15), // gather/scatter "num elements" field
98     TRANSPOSEHEIGHT =       GENX_ITR_CATVAL(0x16), // block_height field in transpose
99     LOG2ELTSIZE =           GENX_ITR_CATVAL(0x17), // log2 element size in gather/scatter
100     ARGCOUNT =              GENX_ITR_CATVAL(0x18), // Byte containing number of non-undef operands
101     EXECSIZE_FROM_BYTE =    GENX_ITR_CATVAL(0x19), // exec_size specified in byte
102       ARGCOUNTMASK =        GENX_ITR_FLAGMASK(0, 3), // Space for minumum argument count
103       ARGCOUNTMIN1 =        GENX_ITR_FLAGENUM(0, 1), // Must have at least one argument
104     BITWIDTH =              GENX_ITR_CATVAL(0x1a), // bit width of svm atomic instructions
105 
106     // A field that contains an operand number, other than general, and it
107     // is the "real" use of the operand, rather than an auxiliary use
108     // such as a "number of GRFs" field relating to this operand.
109     FIRST_REAL_OPERAND =    GENX_ITR_CATVAL(0x20),
110     BYTE =                  GENX_ITR_CATVAL(0x20), // constant byte operand
111     SHORT =                 GENX_ITR_CATVAL(0x21), // constant short operand
112     INT =                   GENX_ITR_CATVAL(0x22), // constant int operand
113     ADDRESS =               GENX_ITR_CATVAL(0x23), // address operand
114     PREDICATE =             GENX_ITR_CATVAL(0x24), // predicate operand
115       PREDICATE_ZEROED =    GENX_ITR_FLAGVAL(0),
116     Z_PREDICATE = PREDICATE | PREDICATE_ZEROED,
117     SAMPLER =               GENX_ITR_CATVAL(0x25), // sampler operand
118     SURFACE =               GENX_ITR_CATVAL(0x26), // surface operand
119     // byte height of media 2D block, inferred from the width operand
120     // pointed at and the size of the return type or final operand type
121     MEDIAHEIGHT =           GENX_ITR_CATVAL(0x27),
122     // predication control field from explicit predicate arg
123     PREDICATION =           GENX_ITR_CATVAL(0x28),
124     // chmask field in load/sample, with exec size bit
125     SAMPLECHMASK =          GENX_ITR_CATVAL(0x29),
126     // does not appear in the vISA output, but needs to be two address
127     // coalesced with result
128     TWOADDR =               GENX_ITR_CATVAL(0x2a),
129     CONSTVI1ASI32 =         GENX_ITR_CATVAL(0x2b), // constant vXi1 written as i32 (used in setp)
130     RAW =                   GENX_ITR_CATVAL(0x2c), // raw operand or result,
131       // Raw descriptor flags, 3 bits used
132       RAW_UNSIGNED =        GENX_ITR_FLAGVAL(0),   // raw operand/result must be unsigned
133       RAW_SIGNED =          GENX_ITR_FLAGVAL(1),   // raw operand/result must be signed
134       RAW_NULLALLOWED =     GENX_ITR_FLAGVAL(2),   // raw operand or result can be null (V0)
135     URAW =                  RAW | RAW_UNSIGNED,
136     SRAW =                  RAW | RAW_SIGNED,
137     EXECSIZE_NOMASK =       GENX_ITR_CATVAL(0x2d), // execution size with NoMask
138 
139     // A general operand
140     GENERAL =               GENX_ITR_CATVAL(0x2e),
141     // A general operand with compile-time signedness choosing
142     GENERAL_CTSIGN =        GENERAL,
143     // A predefined surface operand
144     PREDEF_SURFACE =        GENX_ITR_CATVAL(0x2f),
145     // Modifiers for destination or source, 7 bits used
146     UNSIGNED =              GENX_ITR_FLAGVAL(0), // int type forced to unsigned
147     SIGNED =                GENX_ITR_FLAGVAL(1), // int type forced to signed
148     OWALIGNED =             GENX_ITR_FLAGVAL(2), // must be oword aligned
149     GRFALIGNED =            GENX_ITR_FLAGVAL(3), // must be grf aligned
150     RESTRICTION =           GENX_ITR_FLAGMASK(4, 3), // field with operand width restriction
151       FIXED4 =              GENX_ITR_FLAGENUM(4, 1), // operand is fixed size 4 vector and contiguous
152       CONTIGUOUS =          GENX_ITR_FLAGENUM(4, 2), // operand must be contiguous
153       SCALARORCONTIGUOUS =  GENX_ITR_FLAGENUM(4, 3), // operand must be stride 0 or contiguous
154       TWICEWIDTH =          GENX_ITR_FLAGENUM(4, 4), // operand is twice the execution width
155       STRIDE1 =             GENX_ITR_FLAGENUM(4, 5), // horizontal stride must be 1
156     // Modifiers for destination only, 2 bits used
157     SATURATION =            GENX_ITR_FLAGMASK(7, 2),
158     SATURATION_DEFAULT =    GENX_ITR_FLAGENUM(7, 0), // saturation default: not saturated, fp is
159                                                      //  allowed to bale in to saturate inst
160     SATURATION_SATURATE =   GENX_ITR_FLAGENUM(7, 1), // saturated
161     SATURATION_NOSAT =      GENX_ITR_FLAGENUM(7, 2), // fp not allowed to bale in to saturate inst
162     SATURATION_INTALLOWED = GENX_ITR_FLAGENUM(7, 3), // int is allowed to bale in to saturate,
163                                    // because inst cannot overflow so
164                                    // saturation only required on destination
165                                    // truncation
166     // Modifiers for source only, 3 bits used
167     NOIMM =                 GENX_ITR_FLAGVAL(7), // source not allowed to be immediate
168     MODIFIER =              GENX_ITR_FLAGMASK(8, 2),
169     MODIFIER_DEFAULT =      GENX_ITR_FLAGENUM(8, 0), // src modifier default: none
170     MODIFIER_ARITH =        GENX_ITR_FLAGENUM(8, 1), // src modifier: arithmetic
171     MODIFIER_LOGIC =        GENX_ITR_FLAGENUM(8, 2), // src modifier: logic
172     MODIFIER_EXTONLY =      GENX_ITR_FLAGENUM(8, 3), // src modifier: extend only
173     DIRECTONLY =            GENX_ITR_FLAGVAL(10), // indirect region not allowed
174   };
175   struct ArgInfo {
176     unsigned Info;
177     // Default constructor, used in GenXBaling to construct an ArgInfo that
178     // represents an arg of a non-call instruction.
ArgInfoArgInfo179     ArgInfo() : Info(GENERAL) {}
180     // Construct from a field read from the intrinsics info table.
ArgInfoArgInfo181     ArgInfo(unsigned Info) : Info(Info) {}
182     // getCategory : return field category
getCategoryArgInfo183     unsigned getCategory() const { return Info & CATMASK; }
184     // getAlignment : get any special alignment requirement, else align to 1
185     // byte
getAlignmentArgInfo186     VISA_Align getAlignment() const {
187       if (isGeneral()) {
188         if (Info & GRFALIGNED)
189           return VISA_Align::ALIGN_GRF;
190         if (Info & OWALIGNED)
191           return VISA_Align::ALIGN_OWORD;
192         return VISA_Align::ALIGN_BYTE;
193       }
194       if (isRaw())
195         return VISA_Align::ALIGN_GRF;
196       return VISA_Align::ALIGN_BYTE;
197     }
198     // isGeneral : test whether this is a general operand
isGeneralArgInfo199     bool isGeneral() const { return getCategory() == GENERAL; }
needsSignedArgInfo200     bool needsSigned() const {
201       if (isGeneral())
202         return Info & SIGNED;
203       if (isRaw())
204         return Info & RAW_SIGNED;
205       return false;
206     }
needsUnsignedArgInfo207     bool needsUnsigned() const {
208       if (isGeneral())
209         return Info & UNSIGNED;
210       if (isRaw())
211         return Info & RAW_UNSIGNED;
212       return false;
213     }
isDirectOnlyArgInfo214     bool isDirectOnly() const { return Info & DIRECTONLY; }
rawNullAllowedArgInfo215     bool rawNullAllowed() const {
216       IGC_ASSERT(isRaw());
217       return Info & RAW_NULLALLOWED;
218     }
219     // isArgOrRet : test whether this field has an arg index
isArgOrRetArgInfo220     bool isArgOrRet() const {
221       if (isGeneral()) return true;
222       if ((Info & CATMASK) >= FIRST_OPERAND)
223         return true;
224       return false;
225     }
226     // isRealArgOrRet : test whether this field has an arg index, and is
227     // a "real" use of the arg
isRealArgOrRetArgInfo228     bool isRealArgOrRet() const {
229       if (isGeneral()) return true;
230       if ((Info & CATMASK) >= FIRST_REAL_OPERAND)
231         return true;
232       return false;
233     }
234     // getArgCountMin : return minimum number of arguments
getArgCountMinArgInfo235     int getArgCountMin() const {
236       IGC_ASSERT(getCategory() == ARGCOUNT);
237       return (Info & ARGCOUNTMASK) >> FLAGBASE;
238     }
239     // getArgIdx : return argument index for this field, or -1 for return value
240     //  (assuming isArgOrRet())
getArgIdxArgInfo241     int getArgIdx() const {
242       IGC_ASSERT(isArgOrRet());
243       return (Info & OPNDMASK) - 1;
244     }
245     // getLiteral : for a LITERAL or EXECSIZE field, return the literal value
getLiteralArgInfo246     unsigned getLiteral() const { return Info & LITMASK; }
247     // isRet : test whether this is the field for the return value
248     //  (assuming isArgOrRet())
isRetArgInfo249     bool isRet() const { return getArgIdx() < 0; }
250     // isRaw : test whether this is a raw arg or return value
isRawArgInfo251     bool isRaw() const { return getCategory() == RAW; }
252     // getSaturation : return saturation info for the arg
getSaturationArgInfo253     unsigned getSaturation() const { return Info & SATURATION; }
254     // getRestriction : return operand width/region restriction, one of
255     // 0 (no restriction), FIXED4, CONTIGUOUS, TWICEWIDTH
getRestrictionArgInfo256     unsigned getRestriction() const { return Info & RESTRICTION; }
257     // isImmediateDisallowed : test whether immediate disallowed
258     //  (assuming isArgOrRet())
isImmediateDisallowedArgInfo259     bool isImmediateDisallowed() const {
260       IGC_ASSERT(isArgOrRet());
261       if (isGeneral())
262         return Info & NOIMM;
263       if (isRaw())
264         return true;
265       switch (Info & CATMASK) {
266         case TWOADDR:
267         case PREDICATION:
268         case SURFACE:
269         case SAMPLER:
270           return true;
271         default: break;
272       }
273       return false;
274     }
275     // getModifier : get what source modifier is allowed
getModifierArgInfo276     unsigned getModifier() const {
277       IGC_ASSERT(isGeneral());
278       IGC_ASSERT(isArgOrRet());
279       IGC_ASSERT(!isRet());
280       return Info & MODIFIER;
281     }
282   };
283   // GenXIntrinsics::iterator : iterate through the fields
284   class iterator {
285     const DescrElementType *p;
286   public:
iterator(const DescrElementType * p)287     iterator(const DescrElementType *p) : p(p) {}
288     iterator &operator++() { ++p; if (*p == END) p = 0; return *this; }
289     ArgInfo operator*() { return ArgInfo(*p); }
290     bool operator!=(iterator i) { return p != i.p; }
291   };
begin()292   iterator begin() {
293     IGC_ASSERT_MESSAGE(isNotNull(), "iterating an intrinsic without info");
294     return iterator(Args);
295   }
end()296   iterator end() { return iterator(0); }
297   // Construct a GenXIntrinsicInfo for a particular intrinsic
298   GenXIntrinsicInfo(unsigned IntrinId);
isNull()299   bool isNull() const { return *getInstDesc() == GenXIntrinsicInfo::END; }
isNotNull()300   bool isNotNull() const { return !isNull(); }
301   // Return instruction description.
getInstDesc()302   const DescrElementType *getInstDesc() const { return Args; }
303   // Get the category and modifier for an arg idx
304   ArgInfo getArgInfo(int Idx);
305   // Get the trailing null zone, if any.
306   unsigned getTrailingNullZoneStart(CallInst *CI);
307   // Get the category and modifier for the return value
getRetInfo()308   ArgInfo getRetInfo() { return getArgInfo(-1); }
309   // Get bitmap of allowed execution sizes
310   unsigned getExecSizeAllowedBits();
311   // Determine if a predicated destination mask is permitted
312   bool getPredAllowed();
313   // Get The overrided execution size or 0.
314   static unsigned getOverridedExecSize(CallInst *CI,
315                                        const GenXSubtarget *ST = nullptr);
316 };
317 
318 } // namespace llvm
319 #endif // ndef GENXINTRINSICS_H
320