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