@@ -39,6 +39,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
3939#include " common/shaderOverride.hpp"
4040#include " common/CompilerStatsUtils.hpp"
4141#include " inc/common/sku_wa.h"
42+ #include " inc/common/RelocationInfo.h"
4243#include < iStdLib/utility.h>
4344
4445#if !defined(_WIN32)
@@ -4214,6 +4215,75 @@ bool CEncoder::AvoidRetryOnSmallSpill() const
42144215 context->m_retryManager .IsFirstTry ();
42154216}
42164217
4218+ void CEncoder::CreateFunctionSymbolTable (void *& buffer, unsigned & bufferSize, unsigned & tableEntries)
4219+ {
4220+ buffer = nullptr ;
4221+ bufferSize = 0 ;
4222+ tableEntries = 0 ;
4223+
4224+ if (IGC_IS_FLAG_ENABLED (EnableFunctionPointer))
4225+ {
4226+ Module* pModule = m_program->GetContext ()->getModule ();
4227+ std::vector<Function*> funcsToExport;
4228+ for (auto &F : pModule->getFunctionList ())
4229+ {
4230+ // Find all functions in the module we need to export as symbols
4231+ if (F.hasFnAttribute (" AsFunctionPointer" ))
4232+ {
4233+ if (!F.isDeclaration () || F.getNumUses () > 0 )
4234+ funcsToExport.push_back (&F);
4235+ }
4236+ }
4237+
4238+ if (funcsToExport.empty ())
4239+ return ;
4240+
4241+ // Allocate buffer to store symbol table entries
4242+ tableEntries = funcsToExport.size ();
4243+ bufferSize = sizeof (IGC::GenSymEntry) * tableEntries;
4244+ buffer = (void *) malloc (bufferSize);
4245+ assert (buffer && " Function Symbol Table not allocated" );
4246+ IGC::GenSymEntry* entry_ptr = (IGC::GenSymEntry*) buffer;
4247+
4248+ for (auto pFunc : funcsToExport)
4249+ {
4250+ assert (pFunc->getName ().size () <= IGC::MAX_SYMBOL_NAME_LENGTH);
4251+ strcpy (entry_ptr->s_name , pFunc->getName ().str ().c_str ());
4252+
4253+ if (pFunc->isDeclaration ())
4254+ {
4255+ // If the function is only declared, set as undefined type
4256+ entry_ptr->s_type = IGC::GenSymType::S_UNDEF;
4257+ entry_ptr->s_offset = 0 ;
4258+ }
4259+ else
4260+ {
4261+ auto Iter = stackFuncMap.find (pFunc);
4262+ assert (Iter != stackFuncMap.end () && " vISA function not found" );
4263+
4264+ // Query vISA for the function's byte offset within the compiled module
4265+ VISAFunction* visaFunc = Iter->second ;
4266+ entry_ptr->s_type = IGC::GenSymType::S_FUNC;
4267+ entry_ptr->s_offset = (uint32_t ) visaFunc->getGenOffset ();
4268+ }
4269+ entry_ptr++;
4270+ }
4271+ }
4272+ }
4273+ void CEncoder::CreateFunctionRelocationTable (void *& buffer, unsigned & bufferSize, unsigned & tableEntries)
4274+ {
4275+ buffer = nullptr ;
4276+ bufferSize = 0 ;
4277+ tableEntries = 0 ;
4278+
4279+ if (IGC_IS_FLAG_ENABLED (EnableFunctionPointer))
4280+ {
4281+ // vISA will directly return the buffer with GenRelocEntry layout
4282+ V (vMainKernel->GetGenRelocEntryBuffer (buffer, bufferSize, tableEntries));
4283+ assert (sizeof (IGC::GenRelocEntry) * tableEntries == bufferSize);
4284+ }
4285+ }
4286+
42174287void CEncoder::Compile ()
42184288{
42194289 COMPILER_TIME_START (m_program->GetContext (), TIME_CG_vISAEmitPass);
@@ -4450,6 +4520,13 @@ void CEncoder::Compile()
44504520
44514521 vMainKernel->GetGTPinBuffer (pOutput->m_gtpinBuffer , pOutput->m_gtpinBufferSize );
44524522
4523+ CreateFunctionSymbolTable (pOutput->m_funcSymbolTable ,
4524+ pOutput->m_funcSymbolTableSize ,
4525+ pOutput->m_funcSymbolTableEntries );
4526+ CreateFunctionRelocationTable (pOutput->m_funcRelocationTable ,
4527+ pOutput->m_funcRelocationTableSize ,
4528+ pOutput->m_funcRelocationTableEntries );
4529+
44534530 if (jitInfo->isSpill == true )
44544531 {
44554532 pOutput->m_scratchSpaceUsedBySpills = jitInfo->spillMemUsed ;
0 commit comments