Commit 81d46788 authored by Xiao Lei's avatar Xiao Lei Committed by gbsbuild

Create Patches for Function Pointer Symbol and Relocation Tables

Change-Id: I29ce6ed33d8f74caef9b818e452ff770419e9647
parent 6a6a81d9
......@@ -1414,29 +1414,62 @@ void DebugPatchList(
break;
case iOpenCL::PATCH_TOKEN_GTPIN_FREE_GRF_INFO:
{
const iOpenCL::SPatchGtpinFreeGRFInfo* pPatchItem =
(const iOpenCL::SPatchGtpinFreeGRFInfo*)pHeader;
{
const iOpenCL::SPatchGtpinFreeGRFInfo* pPatchItem =
(const iOpenCL::SPatchGtpinFreeGRFInfo*)pHeader;
ICBE_DPF_STR(output, GFXDBG_HARDWARE,
"PATCH_TOKEN_GTPIN_FREE_GRF_INFO (%08X) (size = %d)\n",
pPatchItem->Token,
pPatchItem->Size);
ICBE_DPF_STR(output, GFXDBG_HARDWARE,
"PATCH_TOKEN_GTPIN_FREE_GRF_INFO (%08X) (size = %d)\n",
pPatchItem->Token,
pPatchItem->Size);
ICBE_DPF_STR(output, GFXDBG_HARDWARE,
"\tBufferSize = %d\n",
pPatchItem->BufferSize);
}
ICBE_DPF_STR(output, GFXDBG_HARDWARE,
"\tBufferSize = %d\n",
pPatchItem->BufferSize);
}
break;
case iOpenCL::PATCH_TOKEN_GTPIN_INFO:
{
const iOpenCL::SPatchItemHeader* pPatchItem = pHeader;
ICBE_DPF_STR(output, GFXDBG_HARDWARE,
"PATCH_TOKEN_GTPIN_INFO (%08X) (size = %d)\n",
pPatchItem->Token,
pPatchItem->Size);
}
break;
{
const iOpenCL::SPatchItemHeader* pPatchItem = pHeader;
ICBE_DPF_STR(output, GFXDBG_HARDWARE,
"PATCH_TOKEN_GTPIN_INFO (%08X) (size = %d)\n",
pPatchItem->Token,
pPatchItem->Size);
}
break;
case iOpenCL::PATCH_TOKEN_FUNCTION_SYMBOL_TABLE:
{
const iOpenCL::SPatchFunctionTableInfo* pPatchItem =
(const iOpenCL::SPatchFunctionTableInfo*)pHeader;
ICBE_DPF_STR(output, GFXDBG_HARDWARE,
"PATCH_TOKEN_FUNCTION_SYMBOL_TABLE (%08X) (size = %d)\n",
pPatchItem->Token,
pPatchItem->Size);
ICBE_DPF_STR(output, GFXDBG_HARDWARE,
"\tNumEntries = %d\n",
pPatchItem->NumEntries);
}
break;
case iOpenCL::PATCH_TOKEN_FUNCTION_RELOCATION_TABLE:
{
const iOpenCL::SPatchFunctionTableInfo* pPatchItem =
(const iOpenCL::SPatchFunctionTableInfo*)pHeader;
ICBE_DPF_STR(output, GFXDBG_HARDWARE,
"PATCH_TOKEN_FUNCTION_RELOCATION_TABLE (%08X) (size = %d)\n",
pPatchItem->Token,
pPatchItem->Size);
ICBE_DPF_STR(output, GFXDBG_HARDWARE,
"\tNumEntries = %d\n",
pPatchItem->NumEntries);
}
break;
default:
{
......
......@@ -2104,6 +2104,98 @@ RETVAL CGen8OpenCLStateProcessor::CreatePatchList(
}
}
// Patch for function symbol table
if (retValue.Success)
{
iOpenCL::SPatchFunctionTableInfo patch;
memset(&patch, 0, sizeof(patch));
patch.Token = PATCH_TOKEN_FUNCTION_SYMBOL_TABLE;
uint32_t size = 0;
uint32_t entries = 0;
void* buffer = nullptr;
const IGC::SKernelProgram* program = &(annotations.m_kernelProgram);
if (annotations.m_executionEnivronment.CompiledSIMDSize == 8)
{
buffer = program->simd8.m_funcSymbolTable;
size = program->simd8.m_funcSymbolTableSize;
entries = program->simd8.m_funcSymbolTableEntries;
}
else if (annotations.m_executionEnivronment.CompiledSIMDSize == 16)
{
buffer = program->simd16.m_funcSymbolTable;
size = program->simd16.m_funcSymbolTableSize;
entries = program->simd16.m_funcSymbolTableEntries;
}
else if (annotations.m_executionEnivronment.CompiledSIMDSize == 32)
{
buffer = program->simd32.m_funcSymbolTable;
size = program->simd32.m_funcSymbolTableSize;
entries = program->simd32.m_funcSymbolTableEntries;
}
if (size > 0)
{
patch.Size = sizeof(patch) + size;
patch.NumEntries = entries;
retValue = AddPatchItem(patch, membuf);
if (!membuf.Write((const char*)buffer, size))
{
retValue.Success = false;
return retValue;
}
free(buffer);
}
}
// Patch for function relocation table
if (retValue.Success)
{
iOpenCL::SPatchFunctionTableInfo patch;
memset(&patch, 0, sizeof(patch));
patch.Token = PATCH_TOKEN_FUNCTION_RELOCATION_TABLE;
uint32_t size = 0;
uint32_t entries = 0;
void* buffer = nullptr;
const IGC::SKernelProgram* program = &(annotations.m_kernelProgram);
if (annotations.m_executionEnivronment.CompiledSIMDSize == 8)
{
buffer = program->simd8.m_funcRelocationTable;
size = program->simd8.m_funcRelocationTableSize;
entries = program->simd8.m_funcRelocationTableEntries;
}
else if (annotations.m_executionEnivronment.CompiledSIMDSize == 16)
{
buffer = program->simd16.m_funcRelocationTable;
size = program->simd16.m_funcRelocationTableSize;
entries = program->simd16.m_funcRelocationTableEntries;
}
else if (annotations.m_executionEnivronment.CompiledSIMDSize == 32)
{
buffer = program->simd32.m_funcRelocationTable;
size = program->simd32.m_funcRelocationTableSize;
entries = program->simd32.m_funcRelocationTableEntries;
}
if (size > 0)
{
patch.Size = sizeof(patch) + size;
patch.NumEntries = entries;
retValue = AddPatchItem(patch, membuf);
if (!membuf.Write((const char*)buffer, size))
{
retValue.Success = false;
return retValue;
}
freeBlock(buffer);
}
}
return retValue;
}
......
......@@ -34,7 +34,7 @@ Abstract: Contains common patch structure definitions
namespace iOpenCL
{
const uint32_t CURRENT_ICBE_VERSION = 1057;
const uint32_t CURRENT_ICBE_VERSION = 1058;
const uint32_t MAGIC_CL = 0x494E5443; // 'I', 'N', 'T', 'C'
const uint32_t INVALID_INDEX = 0xFFFFFFFF;
......@@ -147,13 +147,15 @@ enum PATCH_TOKEN
PATCH_TOKEN_CONSTRUCTOR_DESTRUCTOR_KERNEL_PROGRAM_BINARY_INFO, // 49 - (Unused)
PATCH_TOKEN_INLINE_VME_SAMPLER_INFO, // 50 - (Unused)
PATCH_TOKEN_GTPIN_FREE_GRF_INFO, // 51 @SPatchGtpinFreeGRFInfo@
PATCH_TOKEN_GTPIN_INFO,
PATCH_TOKEN_GTPIN_INFO, // 52 @SPatchItemHeader@
PATCH_TOKEN_FUNCTION_SYMBOL_TABLE, // 53 @SPatchFunctionTableInfo@
PATCH_TOKEN_FUNCTION_RELOCATION_TABLE, // 54 @SPatchFunctionTableInfo@
NUM_PATCH_TOKENS
};
// Update CURRENT_ICBE_VERSION when modifying the patch list
static_assert( NUM_PATCH_TOKENS == 53, "NUM_PATCH_TOKENS has invalid value");
static_assert( NUM_PATCH_TOKENS == 55, "NUM_PATCH_TOKENS has invalid value");
/*****************************************************************************\
ENUM: IMAGE_MEMORY_OBJECT_TYPE
......
......@@ -540,6 +540,18 @@ struct SPatchGtpinFreeGRFInfo :
// Update CURRENT_ICBE_VERSION when modifying the patch list
static_assert(sizeof(SPatchGtpinFreeGRFInfo) == (4 + sizeof(SPatchItemHeader)), "The size of SPatchGtpinFreeGRFInfo is not what is expected");
/*****************************************************************************\
STRUCT: SPatchFunctionTableInfo
\*****************************************************************************/
struct SPatchFunctionTableInfo :
SPatchItemHeader
{
uint32_t NumEntries;
};
// Update CURRENT_ICBE_VERSION when modifying the patch list
static_assert(sizeof(SPatchFunctionTableInfo) == (4 + sizeof(SPatchItemHeader)), "The size of SPatchFunctionTableInfo is not what is expected");
} // namespace
#pragma pack( pop )
......@@ -39,6 +39,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "common/shaderOverride.hpp"
#include "common/CompilerStatsUtils.hpp"
#include "inc/common/sku_wa.h"
#include "inc/common/RelocationInfo.h"
#include <iStdLib/utility.h>
#if !defined(_WIN32)
......@@ -4214,6 +4215,75 @@ bool CEncoder::AvoidRetryOnSmallSpill() const
context->m_retryManager.IsFirstTry();
}
void CEncoder::CreateFunctionSymbolTable(void*& buffer, unsigned& bufferSize, unsigned& tableEntries)
{
buffer = nullptr;
bufferSize = 0;
tableEntries = 0;
if (IGC_IS_FLAG_ENABLED(EnableFunctionPointer))
{
Module* pModule = m_program->GetContext()->getModule();
std::vector<Function*> funcsToExport;
for (auto &F : pModule->getFunctionList())
{
// Find all functions in the module we need to export as symbols
if (F.hasFnAttribute("AsFunctionPointer"))
{
if (!F.isDeclaration() || F.getNumUses() > 0)
funcsToExport.push_back(&F);
}
}
if (funcsToExport.empty())
return;
// Allocate buffer to store symbol table entries
tableEntries = funcsToExport.size();
bufferSize = sizeof(IGC::GenSymEntry) * tableEntries;
buffer = (void*) malloc(bufferSize);
assert(buffer && "Function Symbol Table not allocated");
IGC::GenSymEntry* entry_ptr = (IGC::GenSymEntry*) buffer;
for (auto pFunc : funcsToExport)
{
assert(pFunc->getName().size() <= IGC::MAX_SYMBOL_NAME_LENGTH);
strcpy(entry_ptr->s_name, pFunc->getName().str().c_str());
if (pFunc->isDeclaration())
{
// If the function is only declared, set as undefined type
entry_ptr->s_type = IGC::GenSymType::S_UNDEF;
entry_ptr->s_offset = 0;
}
else
{
auto Iter = stackFuncMap.find(pFunc);
assert(Iter != stackFuncMap.end() && "vISA function not found");
// Query vISA for the function's byte offset within the compiled module
VISAFunction* visaFunc = Iter->second;
entry_ptr->s_type = IGC::GenSymType::S_FUNC;
entry_ptr->s_offset = (uint32_t) visaFunc->getGenOffset();
}
entry_ptr++;
}
}
}
void CEncoder::CreateFunctionRelocationTable(void*& buffer, unsigned& bufferSize, unsigned& tableEntries)
{
buffer = nullptr;
bufferSize = 0;
tableEntries = 0;
if (IGC_IS_FLAG_ENABLED(EnableFunctionPointer))
{
// vISA will directly return the buffer with GenRelocEntry layout
V(vMainKernel->GetGenRelocEntryBuffer(buffer, bufferSize, tableEntries));
assert(sizeof(IGC::GenRelocEntry) * tableEntries == bufferSize);
}
}
void CEncoder::Compile()
{
COMPILER_TIME_START(m_program->GetContext(), TIME_CG_vISAEmitPass);
......@@ -4450,6 +4520,13 @@ void CEncoder::Compile()
vMainKernel->GetGTPinBuffer(pOutput->m_gtpinBuffer, pOutput->m_gtpinBufferSize);
CreateFunctionSymbolTable(pOutput->m_funcSymbolTable,
pOutput->m_funcSymbolTableSize,
pOutput->m_funcSymbolTableEntries);
CreateFunctionRelocationTable(pOutput->m_funcRelocationTable,
pOutput->m_funcRelocationTableSize,
pOutput->m_funcRelocationTableEntries);
if (jitInfo->isSpill == true)
{
pOutput->m_scratchSpaceUsedBySpills = jitInfo->spillMemUsed;
......
......@@ -489,6 +489,9 @@ private:
// save compile time by avoiding retry if the amount of spill is (very) small
bool AvoidRetryOnSmallSpill() const;
void CreateFunctionSymbolTable(void*& buffer, unsigned& bufferSize, unsigned& tableEntries);
void CreateFunctionRelocationTable(void*& buffer, unsigned& bufferSize, unsigned& tableEntries);
protected:
// encoder states
SEncoderState m_encoderState;
......
......@@ -533,10 +533,8 @@ void CShader::CreateConstantBufferOutput(SKernelProgram *pKernelProgram)
void CShader::CreateFuncSymbolToRegisterMap(llvm::Function* pFunc)
{
// Functions with uses in this module requires relocation
CVariable* funcAddr = GetSymbol(pFunc);
//CVariable* funcAddr32bit = GetNewVariable(1, ISA_TYPE_UD, EALIGN_GRF, true);
//encoder.Cast(funcAddr32bit, funcAddr);
//encoder.Push();
encoder.AddFunctionSymbol(pFunc, funcAddr);
encoder.Push();
}
......@@ -2232,7 +2230,8 @@ CVariable* CShader::GetSymbol(llvm::Value *value, bool fromConstantPool)
if (Constant *C = llvm::dyn_cast<llvm::Constant>(value))
{
// Function Pointer
if (isa<GlobalValue>(value) &&
if (IGC_IS_FLAG_ENABLED(EnableFunctionPointer) &&
isa<GlobalValue>(value) &&
value->getType()->isPointerTy() &&
value->getType()->getPointerElementType()->isFunctionTy())
{
......
......@@ -414,7 +414,7 @@ bool EmitPass::runOnFunction(llvm::Function &F)
// Creates a mapping of the function symbol to a register.
// Any user function used by the kernel, including function declarations,
// should have a register allocated to store it's physical address
if (F.getNumUses() > 0 && F.hasFnAttribute("AsFunctionPointer"))
if (F.hasFnAttribute("AsFunctionPointer") && F.getNumUses() > 0)
{
m_currShader->CreateFuncSymbolToRegisterMap(&F);
}
......
......@@ -102,6 +102,12 @@ namespace IGC
unsigned int m_InstructionCount;
void* m_gtpinBuffer; // Will be populated by VISA only when special switch is passed by gtpin
unsigned int m_gtpinBufferSize;
void* m_funcSymbolTable;
unsigned int m_funcSymbolTableSize;
unsigned int m_funcSymbolTableEntries;
void* m_funcRelocationTable;
unsigned int m_funcRelocationTableSize;
unsigned int m_funcRelocationTableEntries;
void Destroy()
{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment