Skip to content

Commit

Permalink
Create Patches for Function Pointer Symbol and Relocation Tables
Browse files Browse the repository at this point in the history
Change-Id: I29ce6ed33d8f74caef9b818e452ff770419e9647
  • Loading branch information
dlei6g authored and gfxbot committed Mar 21, 2019
1 parent 6a6a81d commit 81d4678
Show file tree
Hide file tree
Showing 9 changed files with 252 additions and 28 deletions.
73 changes: 53 additions & 20 deletions IGC/AdaptorOCL/OCL/Patch/patch_parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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:
{
Expand Down
92 changes: 92 additions & 0 deletions IGC/AdaptorOCL/OCL/sp/sp_g8.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
8 changes: 5 additions & 3 deletions IGC/AdaptorOCL/ocl_igc_shared/executable_format/patch_list.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down
12 changes: 12 additions & 0 deletions IGC/AdaptorOCL/ocl_igc_shared/executable_format/patch_shared.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 )
77 changes: 77 additions & 0 deletions IGC/Compiler/CISACodeGen/CISABuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down
3 changes: 3 additions & 0 deletions IGC/Compiler/CISACodeGen/CISABuilder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,9 @@ class CEncoder
// 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;
Expand Down
7 changes: 3 additions & 4 deletions IGC/Compiler/CISACodeGen/CShader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
Expand Down Expand Up @@ -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())
{
Expand Down
2 changes: 1 addition & 1 deletion IGC/Compiler/CISACodeGen/EmitVISAPass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
6 changes: 6 additions & 0 deletions IGC/Compiler/CodeGenPublic.h
Original file line number Diff line number Diff line change
Expand Up @@ -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()
{
Expand Down

0 comments on commit 81d4678

Please sign in to comment.