1 /*========================== begin_copyright_notice ============================ 2 3 Copyright (C) 2020-2021 Intel Corporation 4 5 SPDX-License-Identifier: MIT 6 7 ============================= end_copyright_notice ===========================*/ 8 9 #pragma once 10 11 #include <vector> 12 #include <ZEELFObjectBuilder.hpp> 13 #include "sp_g8.h" 14 #include "llvm/BinaryFormat/ELF.h" 15 #include "CLElfLib/ElfReader.h" 16 17 namespace IGC 18 { 19 struct SOpenCLKernelInfo; 20 struct SOpenCLProgramInfo; 21 class CBTILayout; 22 class OpenCLProgramContext; 23 } 24 25 namespace vISA 26 { 27 struct ZESymEntry; 28 } 29 30 namespace iOpenCL 31 { 32 33 /// ZEBinaryBuilder - Provides services to create a ZE Binary from given 34 /// SProgramOutput information 35 class ZEBinaryBuilder : DisallowCopy 36 { 37 public: 38 // Setup ZEBin platform, and ELF header information. The program scope information 39 // is also be parsed from SOpenCLProgramInfo in the constructor 40 ZEBinaryBuilder(const PLATFORM plat, bool is64BitPointer, 41 const IGC::SOpenCLProgramInfo& programInfo, const uint8_t* spvData, uint32_t spvSize); 42 43 // Set the ProductFamily as the specified value. 44 void setProductFamily(PRODUCT_FAMILY value); 45 46 // Set the GfxCoreFamily as the specified value. 47 void setGfxCoreFamily(GFXCORE_FAMILY value); 48 49 /// add kernel information. Also create kernel metadata information for .ze_info 50 /// This function can be called several times for adding different kernel information 51 /// into this ZEObject 52 /// The given rawIsaBinary must be lived through the entire ZEBinaryBuilder life 53 void createKernel( 54 const char* rawIsaBinary, 55 unsigned int rawIsaBinarySize, 56 const IGC::SOpenCLKernelInfo& annotations, 57 const uint32_t grfSize, 58 const IGC::CBTILayout& layout, 59 const std::string& visaasm, 60 bool isProgramDebuggable); 61 62 // getElfSymbol - find a symbol name in ELF binary and return a symbol entry 63 // that will later be transformed to ZE binary format 64 void getElfSymbol(CLElfLib::CElfReader* elfReader, const unsigned int symtabIdx, llvm::ELF::Elf64_Sym& symtabEntry, 65 char*& symName); 66 67 /// addElfSections - copy every section of ELF file (a buffer in memory) to zeBinary 68 void addElfSections(void* elfBin, size_t elfSize); 69 70 /// getBinaryObject - get the final ze object 71 void getBinaryObject(llvm::raw_pwrite_stream& os); 72 73 // getBinaryObject - write the final object into given Util::BinaryStream 74 // Avoid using this function, which has extra buffer copy 75 void getBinaryObject(Util::BinaryStream& outputStream); 76 77 void printBinaryObject(const std::string& filename); 78 79 private: 80 /// ------------ program scope helper functions ------------ 81 /// add program scope information. This function will be called in the ctor. 82 /// The program scope information include global buffers (data sections for 83 /// globals and global constants) 84 /// ProgramScopeInfo must be prepared before kernel information. For example, 85 /// Symbols are per-kernel information but they could possible refering to 86 /// program-scope sections such as global buffer. 87 void addProgramScopeInfo(const IGC::SOpenCLProgramInfo& programInfo); 88 89 /// add data section for global constants 90 void addGlobalConstants(const IGC::SOpenCLProgramInfo& annotations); 91 92 /// add data section for globals 93 void addGlobals(const IGC::SOpenCLProgramInfo& annotations); 94 95 /// add spir-v section 96 void addSPIRV(const uint8_t* data, uint32_t size); 97 98 /// add program scope symbols (e.g. symbols defined in global/const buffer) 99 void addProgramSymbols(const IGC::SOpenCLProgramInfo& annotations); 100 101 /// add program scope relocations (e.g. relocations for global/const buffer) 102 void addProgramRelocations(const IGC::SOpenCLProgramInfo& annotations); 103 104 /// ------------ kernel scope helper functions ------------ 105 /// add gen binary 106 zebin::ZEELFObjectBuilder::SectionID addKernelBinary( 107 const std::string& kernelName, const char* kernelBinary, 108 unsigned int kernelBinarySize); 109 110 /// add execution environment 111 void addKernelExecEnv(const IGC::SOpenCLKernelInfo& annotations, 112 zebin::zeInfoKernel& zeinfoKernel); 113 114 /// add experimental properties 115 void addKernelExperimentalProperties(const IGC::SOpenCLKernelInfo& annotations, 116 zebin::zeInfoKernel& zeinfoKernel); 117 118 /// add symbols of this kernel corresponding to kernel binary 119 /// added by addKernelBinary 120 void addKernelSymbols( 121 zebin::ZEELFObjectBuilder::SectionID kernelSectId, 122 const IGC::SOpenCLKernelInfo& annotations); 123 124 /// get symbol type and binding 125 /// FIXME: this should be decided when symbol being created 126 uint8_t getSymbolElfType(const vISA::ZESymEntry& sym); 127 uint8_t getSymbolElfBinding(const vISA::ZESymEntry& sym); 128 129 /// addSymbol - a helper function to add a symbol which is defined in targetSect 130 void addSymbol(const vISA::ZESymEntry& sym, zebin::ZEELFObjectBuilder::SectionID targetSect); 131 132 /// add relocations of this kernel corresponding to binary added by 133 /// addKernelBinary. 134 void addKernelRelocations( 135 zebin::ZEELFObjectBuilder::SectionID targetId, 136 const IGC::SOpenCLKernelInfo& annotations); 137 138 /// add local ids as per-thread payload argument 139 void addLocalIds(uint32_t simdSize, uint32_t grfSize, 140 bool has_local_id_x, bool has_local_id_y, bool has_local_id_z, 141 zebin::zeInfoKernel& zeinfoKernel); 142 143 /// add payload arguments and BTI info from IGC::SOpenCLKernelInfo 144 /// payload arguments and BTI info have been added at 145 /// COpenCLKernel::CreateZEPayloadArguments 146 void addPayloadArgsAndBTI( 147 const IGC::SOpenCLKernelInfo& annotations, 148 zebin::zeInfoKernel& zeinfoKernel); 149 150 /// add Memory buffer information 151 void addMemoryBuffer( 152 const IGC::SOpenCLKernelInfo& annotations, 153 zebin::zeInfoKernel& zeinfoKernel); 154 155 /// add gtpin_info section 156 /// Add everything used to be in patch token iOpenCL::PATCH_TOKEN_GTPIN_INFO 157 /// into gtpin_info section 158 void addGTPinInfo(const IGC::SOpenCLKernelInfo& annotations); 159 160 /// ------------ Verifier sub-functions ------------ 161 bool hasSystemKernel( 162 const IGC::OpenCLProgramContext* clContext, 163 const USC::SSystemThreadKernelOutput* pSystemThreadKernelOutput); 164 165 bool hasSystemThreadSurface(const IGC::OpenCLProgramContext* clContext); 166 167 /// Calculate correct (pure) size of ELF binary, because m_debugDataSize in kernel output 168 /// contains something else. 169 size_t calcElfSize(void* elfBin, size_t elfSize); 170 171 /// add debug environment 172 void addKernelDebugEnv(const IGC::SOpenCLKernelInfo& annotations, 173 const IGC::CBTILayout& layout, 174 zebin::zeInfoKernel& zeinfoKernel); 175 176 /// add visasm of the kernel 177 void addKernelVISAAsm(const std::string& kernel, const std::string& visaasm); 178 private: 179 // mBuilder - Builder of a ZE ELF object 180 zebin::ZEELFObjectBuilder mBuilder; 181 182 // mZEInfoBuilder - Builder and holder of a zeInfoContainer, which will 183 // be added into ZEELFObjectBuilder as .ze_info section 184 zebin::ZEInfoBuilder mZEInfoBuilder; 185 186 const PLATFORM mPlatform; 187 G6HWC::SMediaHardwareCapabilities mHWCaps; 188 189 /// sectionID holder for program scope sections 190 /// There should be only one global, global constant buffer per program 191 zebin::ZEELFObjectBuilder::SectionID mGlobalConstSectID = -1; 192 zebin::ZEELFObjectBuilder::SectionID mConstStringSectID = -1; 193 zebin::ZEELFObjectBuilder::SectionID mGlobalSectID = -1; 194 }; 195 196 } //namespace iOpenCL 197