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 #pragma once 10 11 #include "Compiler/CISACodeGen/CISACodeGen.h" 12 #include "Compiler/CISACodeGen/WIAnalysis.hpp" 13 #include "Compiler/MetaDataApi/MetaDataApi.h" 14 #include "GenISAIntrinsics/GenIntrinsics.h" 15 16 #include <vector> 17 #include <set> 18 #include <map> 19 #include <string> 20 21 namespace llvm 22 { 23 class LLVMContext; 24 class Function; 25 class Type; 26 } 27 28 namespace IGC 29 { 30 /// @brief ImplicitArg is used for representing the implict information that is passed from the 31 /// OpenCL runtime to IGC, characterize it and allow IGC to use it. 32 /// @Author Marina Yatsina 33 class ImplicitArg { 34 public: 35 36 /// @brief Type of implicit information passed from the OpenCL runtime 37 enum ArgType { 38 R0, 39 START_ID = R0, 40 PAYLOAD_HEADER, 41 42 // WI information 43 WORK_DIM, 44 NUM_GROUPS, 45 GLOBAL_SIZE, 46 LOCAL_SIZE, 47 ENQUEUED_LOCAL_WORK_SIZE, 48 LOCAL_ID_X, 49 LOCAL_ID_Y, 50 LOCAL_ID_Z, 51 52 // Pointer bases and buffers 53 CONSTANT_BASE, 54 GLOBAL_BASE, 55 PRIVATE_BASE, 56 PRINTF_BUFFER, 57 58 // Buffer offset (for stateless to stateful optim) 59 BUFFER_OFFSET, 60 61 // Aggregates 62 STRUCT_START, 63 CONSTANT_REG_FP32 = STRUCT_START, 64 CONSTANT_REG_QWORD, 65 CONSTANT_REG_DWORD, 66 CONSTANT_REG_WORD, 67 CONSTANT_REG_BYTE, 68 STRUCT_END = CONSTANT_REG_BYTE, 69 70 // Images 71 IMAGES_START, 72 IMAGE_HEIGHT = IMAGES_START, 73 IMAGE_WIDTH, 74 IMAGE_DEPTH, 75 IMAGE_NUM_MIP_LEVELS, 76 IMAGE_CHANNEL_DATA_TYPE, 77 IMAGE_CHANNEL_ORDER, 78 IMAGE_SRGB_CHANNEL_ORDER, 79 IMAGE_ARRAY_SIZE, 80 IMAGE_NUM_SAMPLES, 81 SAMPLER_ADDRESS, 82 SAMPLER_NORMALIZED, 83 SAMPLER_SNAP_WA, 84 FLAT_IMAGE_BASEOFFSET, 85 FLAT_IMAGE_HEIGHT, 86 FLAT_IMAGE_WIDTH, 87 FLAT_IMAGE_PITCH, 88 IMAGES_END = FLAT_IMAGE_PITCH, 89 90 // VME 91 VME_MB_BLOCK_TYPE, 92 VME_SUBPIXEL_MODE, 93 VME_SAD_ADJUST_MODE, 94 VME_SEARCH_PATH_TYPE, 95 96 // Device Enqueue 97 DEVICE_ENQUEUE_DEFAULT_DEVICE_QUEUE, 98 DEVICE_ENQUEUE_EVENT_POOL, 99 DEVICE_ENQUEUE_MAX_WORKGROUP_SIZE, 100 DEVICE_ENQUEUE_PARENT_EVENT, 101 DEVICE_ENQUEUE_PREFERED_WORKGROUP_MULTIPLE, 102 GET_OBJECT_ID, 103 GET_BLOCK_SIMD_SIZE, 104 105 // GAS 106 LOCAL_MEMORY_STATELESS_WINDOW_START_ADDRESS, 107 LOCAL_MEMORY_STATELESS_WINDOW_SIZE, 108 PRIVATE_MEMORY_STATELESS_SIZE, 109 110 STAGE_IN_GRID_ORIGIN, 111 STAGE_IN_GRID_SIZE, 112 113 SYNC_BUFFER, 114 115 // Bindless buffer (for stateless to bindless optim) 116 BINDLESS_OFFSET, 117 118 // Pointer to implicit arguments prepared by runtime 119 IMPLICIT_ARG_BUFFER_PTR, 120 121 // Inlined local id buffer prepared by runtime 122 IMPLICIT_ARG_LOCALID, 123 124 NUM_IMPLICIT_ARGS 125 }; 126 127 /// @brief This set type is used to contain function arguments 128 typedef std::set<int> ArgValSet; 129 130 /// @brief This map type is used to map implicit argument types to 131 /// sets that contain the relevant Values. 132 typedef std::map<ImplicitArg::ArgType, ArgValSet> ArgMap; 133 134 typedef std::pair<ImplicitArg::ArgType, unsigned int> StructArgElement; 135 typedef std::vector<StructArgElement> StructArgList; 136 137 /// @brief LLVM Type 138 enum ValType { 139 BYTE, 140 SHORT, 141 INT, 142 LONG, 143 FP32, 144 CONSTPTR, 145 PRIVATEPTR, 146 GLOBALPTR 147 }; 148 149 enum ValAlign { 150 ALIGN_QWORD, 151 ALIGN_DWORD, 152 ALIGN_GRF, 153 ALIGN_PTR 154 }; 155 156 ImplicitArg( 157 const ArgType& argType, 158 const std::string& name, 159 const ValType valType, 160 WIAnalysis::WIDependancy dependency, 161 unsigned int nbElement, 162 ValAlign align, 163 bool isConstantBuf); 164 165 ImplicitArg( 166 const ArgType& argType, 167 const std::string& name, 168 const ValType valType, 169 WIAnalysis::WIDependancy dependency, 170 unsigned int nbElement, 171 ValAlign align, 172 bool isConstantBuf, 173 llvm::GenISAIntrinsic::ID GenIntrinsicID); 174 175 /// @brief Getter functions 176 ArgType getArgType() const; 177 const std::string& getName() const; 178 llvm::Type* getLLVMType(llvm::LLVMContext& context) const; 179 WIAnalysis::WIDependancy getDependency() const; 180 unsigned int getAllocateSize(const llvm::DataLayout& DL) const; 181 unsigned int getNumberElements() const; 182 VISA_Type getVISAType(const llvm::DataLayout& DL) const; 183 IGC::e_alignment getAlignType(const llvm::DataLayout& DL) const; 184 size_t getAlignment(const llvm::DataLayout& DL) const; 185 unsigned int getPointerSize(const llvm::DataLayout& DL) const; 186 bool isConstantBuf() const; 187 bool isLocalIDs() const; 188 llvm::GenISAIntrinsic::ID getGenIntrinsicID() const; 189 190 private: 191 const ArgType m_argType; 192 const std::string m_name; 193 const ValType m_valType; 194 const WIAnalysis::WIDependancy m_dependency; 195 const unsigned int m_nbElement; 196 const ValAlign m_align; 197 const bool m_isConstantBuf; 198 const llvm::GenISAIntrinsic::ID m_GenIntrinsicID; 199 }; 200 201 /// @brief ImplicitArgs is used for accessing the actual implict information that is passed from 202 /// the OpenCL runtime to IGC. 203 /// @Author Marina Yatsina 204 class ImplicitArgs { 205 public: 206 // Constructors ImplicitArgs()207 ImplicitArgs() {} 208 209 /// @brief Constructor. 210 /// Constructs the function's implicit arguments based on the given function's metadata 211 /// It actually constructs a mapping to a subset of IMPLICIT_ARGS 212 /// @param func the function to get impilcit args for. 213 /// @param the metadata utils object 214 ImplicitArgs(const llvm::Function& func, const IGCMD::MetaDataUtils* pMdUtils); 215 216 /// @brief Returns the number of implicit arguments that are passed from the runtime 217 /// @return The number of implicit arguments 218 unsigned int size() const; 219 220 /// @brief Returns the i-th implicit argument 221 /// @param i The implicit argument index 222 /// @return The i-th implicit argument 223 const ImplicitArg& operator[](unsigned int i) const; 224 225 /// @brief Returns the index of the appropriate implicit argument based on the given argument type 226 /// @param argType The implicit argument type 227 /// @return The implicit argument's index for a given argument type 228 unsigned int getArgIndex(ImplicitArg::ArgType argType) const; 229 230 /// @brief Returns the index of the appropriate implicit image or sampler argument 231 /// based on the given argument type and the associated image argument 232 /// @param argType The implicit argument type 233 /// (height/width/depth for images, normalized/address/snapwa for samplers) 234 /// @param image The associated image/sampler argument 235 /// @return The implicit argument's index for a given argument type 236 unsigned int getImageArgIndex(ImplicitArg::ArgType argType, const llvm::Argument* image) const; 237 238 /// @brief Returns the index of the appropriate implicit argument 239 /// based on the given argument type and the argument number 240 /// @param argType The implicit argument type 241 /// (height/width/depth for images, normalized/address/snapwa for samplers) 242 /// @param argNum The explicit argument number of the type 243 /// @return The implicit argument's index for a given argument type 244 unsigned int getNumberedArgIndex(ImplicitArg::ArgType argType, int argNum) const; 245 246 /// @brief Returns the argument type of the argument at the given index 247 /// @param i The implicit argument index 248 /// @return The argument type of the argument at the given index 249 ImplicitArg::ArgType getArgType(unsigned int i) const; 250 251 /// @brief Returns the argument type of the given matching intrinsic ID 252 /// @param i The GenISAIntrinsic ID 253 /// @return The argument type 254 static ImplicitArg::ArgType getArgType(llvm::GenISAIntrinsic::ID id); 255 256 /// @brief Returns the argument dependency of the given matching intrinsic ID 257 /// @param i The GenISAIntrinsic ID 258 /// @return The argument dependency 259 static IGC::WIAnalysis::WIDependancy getArgDep(llvm::GenISAIntrinsic::ID id); 260 261 /// @brief Returns if the given arg type supports the GenISAIntrinsic instruction 262 /// @param i The ImplicitArg type 263 /// @return If intrinsic supported 264 static bool hasIntrinsicSupport(ImplicitArg::ArgType i); 265 266 /// @brief Returns the explicit argument number of the given implicit argument index 267 /// @param i The implicit argument index 268 /// @return The explicit argument number of the given implicit argument index 269 int32_t getExplicitArgNum(uint index) const; 270 271 /// @brief Returns the structure offset of the given implicit argument index 272 /// @param i The implicit argument index 273 /// @return The structure offset of the given implicit argument index 274 int32_t getStructArgOffset(uint index) const; 275 276 /// @brief Creates implict arguments metadata for the given function based on the given implicit arguments 277 /// it should receive. If implicit metadata exists, it adds to it. 278 /// @param F The function for which to create the implicit argument's metadata 279 /// @param implicitArgs The implicit argument that are required by the given function 280 /// @param pMdUtils The Metadata API object 281 static void addImplicitArgs(llvm::Function& F, const llvm::SmallVectorImpl<ImplicitArg::ArgType>& implicitArgs, const IGCMD::MetaDataUtils* pMdUtils); 282 //TODO doc 283 284 /// @brief Creates implict image arguments metadata for the given function based on the given implicit image 285 /// arguments it should receive. If implicit image metadata exists, it adds to it. 286 /// @param F The function for which to create the implicit argument's metadata 287 /// @param argMap A map of implict argument types to the Value pointers to the arguments 288 /// @param pMdUtils The Metadata API object 289 static void addImageArgs(llvm::Function& F, const ImplicitArg::ArgMap& argMap, const IGCMD::MetaDataUtils* pMdUtils); 290 // TODO doc 291 292 static void addStructArgs(llvm::Function& F, const llvm::Argument* A, const ImplicitArg::StructArgList& S, const IGCMD::MetaDataUtils* pMdUtils); 293 294 /// @brief Creates implict arguments metadata for the given function based on the given implicit arguments 295 /// it should receive. If implicit metadata exists, it adds to it. 296 /// @param F The function for which to create the implicit argument's metadata 297 /// @param argMap A map of implict argument types to the set of numbers of arguments 298 /// @param pMdUtils The Metadata API object 299 static void addNumberedArgs(llvm::Function& F, const ImplicitArg::ArgMap& argMap, const IGCMD::MetaDataUtils* pMdUtils); 300 301 /// @brief Create implicit arguments metadata for the given function. It adds one 302 /// implicit argument for each explicit pointer argument to global or constant buffer. 303 /// @param F The function for which to create the implicit argument's metadata 304 /// @param pMdUtils The Metadata API object 305 static void addBufferOffsetArgs(llvm::Function& F, const IGCMD::MetaDataUtils* pMdUtils, IGC::ModuleMetaData* modMD); 306 307 /// @brief Create implicit arguments metadata for the given function. It adds one 308 /// implicit argument for each explicit pointer argument to global or constant buffer. 309 /// @param F The function for which to create the implicit argument's metadata 310 /// @param pMdUtils The Metadata API object 311 static void addBindlessOffsetArgs(llvm::Function& F, const IGCMD::MetaDataUtils* pMdUtils, IGC::ModuleMetaData* modMD); 312 313 /// @brief Check if the given implicit argument type exist in the(implicit) function argument associated 314 /// @param argType The type of the implict argument that should be checked 315 /// @return true if the argument exist, false otherwise. 316 bool isImplicitArgExist(ImplicitArg::ArgType argType) const; 317 static bool isImplicitArgExist(llvm::Function& F, ImplicitArg::ArgType argType, const IGCMD::MetaDataUtils* pMdUtils); 318 319 /// @brief Returns the (implicit) function argument associated with the given implicit argument type 320 /// @param F The Function for which the implict argument should be returned 321 /// @param argType The type of the implict argument that should be returned 322 /// @return The (implicit) function argument associated with the given argument type 323 /// In case the argument doesn't exist, return nullptr 324 llvm::Argument* getImplicitArg(llvm::Function &F, ImplicitArg::ArgType argType) const; 325 326 /// @brief Returns the (implicit) function argument associated with the given implicit argument type 327 /// and argument number 328 /// @param F The Function for which the implict argument should be returned 329 /// @param argType The type of the implict argument that should be returned 330 /// @param argNum The explicit argument number of the type 331 /// @return The (implicit) function argument associated with the given argument type and number 332 /// In case the argument doesn't exist, return nullptr 333 llvm::Argument* getNumberedImplicitArg(llvm::Function &F, ImplicitArg::ArgType argType, int argNum) const; 334 335 /// @brief Returns true if the given argument type is an image or sampler. 336 /// @param argType The argument type to check. 337 static bool isImplicitImage(ImplicitArg::ArgType argType); 338 339 /// @brief Returns true if the given argument type is a struct 340 /// @param argType The argument type to check. 341 static bool isImplicitStruct(ImplicitArg::ArgType argType); 342 343 llvm::Value* getImplicitArgValue(llvm::Function& F, ImplicitArg::ArgType argType, const IGCMD::MetaDataUtils* pMdUtils); 344 345 private: 346 /// @brief The function's metadata information. 347 IGCMD::FunctionInfoMetaDataHandle m_funcInfoMD; 348 349 static bool isImplicitArgExist( 350 const IGCMD::FunctionInfoMetaDataHandle& funcInfo, 351 ImplicitArg::ArgType argType); 352 }; 353 354 } // namespace IGC 355