@@ -339,6 +339,10 @@ void GenXOCLRuntimeInfo::KernelInfo::setPrintStrings(
339339 });
340340}
341341
342+ GenXOCLRuntimeInfo::KernelInfo::KernelInfo (const GenXSubtarget &ST)
343+ : Name{" Intel_Symbol_Table_Void_Program" }, GRFSizeInBytes{
344+ ST.getGRFByteSize ()} {}
345+
342346GenXOCLRuntimeInfo::KernelInfo::KernelInfo (const FunctionGroup &FG,
343347 const GenXSubtarget &ST,
344348 const GenXBackendConfig &BC) {
@@ -413,18 +417,20 @@ void constructSymbols(InputIter First, InputIter Last, OutputIter Out) {
413417}
414418
415419static GenXOCLRuntimeInfo::SymbolSeq constructFunctionSymbols (
416- genx::BinaryDataAccumulator<const Function *> &GenBinary) {
420+ genx::BinaryDataAccumulator<const Function *> &GenBinary, bool HasKernel ) {
417421 GenXOCLRuntimeInfo::SymbolSeq Symbols;
418422 Symbols.reserve (GenBinary.getNumSections ());
419- auto &KernelSection = GenBinary.front ();
420- Symbols.emplace_back (vISA::GenSymType::S_KERNEL, KernelSection.Info .Offset ,
421- KernelSection.Info .getSize (),
422- KernelSection.Key ->getName ().str ());
423+ if (HasKernel) {
424+ auto &KernelSection = GenBinary.front ();
425+ Symbols.emplace_back (vISA::GenSymType::S_KERNEL, KernelSection.Info .Offset ,
426+ KernelSection.Info .getSize (),
427+ KernelSection.Key ->getName ().str ());
428+ }
423429
424- // Skipping first section with the kernel.
425- constructSymbols<vISA::GenSymType::S_FUNC>(std::next (GenBinary. begin ()),
426- GenBinary.end (),
427- std::back_inserter (Symbols));
430+ // Skipping first section if binary has a kernel.
431+ constructSymbols<vISA::GenSymType::S_FUNC>(
432+ HasKernel ? std::next (GenBinary. begin ()) : GenBinary.begin (),
433+ GenBinary. end (), std::back_inserter (Symbols));
428434
429435 return Symbols;
430436}
@@ -452,13 +458,12 @@ appendFuncBinary(genx::BinaryDataAccumulator<const Function *> &GenBinary,
452458// Returns the success status of the loading.
453459static bool
454460loadGenBinaryFromFile (genx::BinaryDataAccumulator<const Function *> &GenBinary,
455- const Function &Kernel, const Function &F,
456- vc::ShaderOverrider const &Loader,
461+ const Function &F, vc::ShaderOverrider const &Loader,
457462 vc::ShaderOverrider::Extensions Ext) {
458463 void *GenBin = nullptr ;
459464 int GenBinSize = 0 ;
460465
461- if (!Loader.override (GenBin, GenBinSize, Kernel. getName (), F.getName (), Ext))
466+ if (!Loader.override (GenBin, GenBinSize, F.getName (), Ext))
462467 return false ;
463468
464469 if (!GenBin || !GenBinSize) {
@@ -477,29 +482,24 @@ loadGenBinaryFromFile(genx::BinaryDataAccumulator<const Function *> &GenBinary,
477482// Returns the success status of the overriding.
478483static bool
479484tryOverrideBinary (genx::BinaryDataAccumulator<const Function *> &GenBinary,
480- const Function &Kernel, const Function &F,
481- vc::ShaderOverrider const &Loader) {
485+ const Function &F, vc::ShaderOverrider const &Loader) {
482486 using Extensions = vc::ShaderOverrider::Extensions;
483487
484488 // Attempts to override .asm
485- if (loadGenBinaryFromFile (GenBinary, Kernel, F, Loader, Extensions::ASM))
489+ if (loadGenBinaryFromFile (GenBinary, F, Loader, Extensions::ASM))
486490 return true ;
487491
488492 // If it has failed then attempts to override .dat file
489- return loadGenBinaryFromFile (GenBinary, Kernel, F, Loader, Extensions::DAT);
493+ return loadGenBinaryFromFile (GenBinary, F, Loader, Extensions::DAT);
490494}
491495
492- // Either loads binaries from VISABuilder or overrides from files.
493- // \p Kernel should always be kernel function, meanwhile if \p F is actually a
494- // kernel means we are loading kernel, and if \p F is a function means we are
495- // loading function.
496- static void
497- loadBinaries (genx::BinaryDataAccumulator<const Function *> &GenBinary,
498- VISABuilder &VB, const Function &Kernel, const Function &F,
499- GenXBackendConfig const &BC) {
496+ // Either loads binary from VISABuilder or overrides from file.
497+ static void loadBinary (genx::BinaryDataAccumulator<const Function *> &GenBinary,
498+ VISABuilder &VB, const Function &F,
499+ GenXBackendConfig const &BC) {
500500 // Attempt to override
501501 if (BC.hasShaderOverrider () &&
502- tryOverrideBinary (GenBinary, Kernel, F, BC.getShaderOverrider ()))
502+ tryOverrideBinary (GenBinary, F, BC.getShaderOverrider ()))
503503 return ;
504504
505505 // If there is no overriding or attemp fails, then gets binary from compilation
@@ -537,23 +537,11 @@ std::vector<const Function *> collectCalledFunctions(const FunctionGroup &FG,
537537// Constructs gen binary for provided function group \p FG.
538538static genx::BinaryDataAccumulator<const Function *>
539539getGenBinary (const FunctionGroup &FG, VISABuilder &VB,
540- GenXBackendConfig const &BC,
541- std::set<const Function *> &ProcessedCalls) {
540+ GenXBackendConfig const &BC) {
542541 Function const *Kernel = FG.getHead ();
543542 genx::BinaryDataAccumulator<const Function *> GenBinary;
544543 // load kernel
545- loadBinaries (GenBinary, VB, *Kernel, *Kernel, BC);
546-
547- const auto IndirectFunctions = collectCalledFunctions (
548- FG, [](const Function *F) { return genx::isReferencedIndirectly (F); });
549- for (const Function *F : IndirectFunctions) {
550- if (ProcessedCalls.count (F) != 0 )
551- continue ;
552- ProcessedCalls.insert (F);
553- // load functions
554- loadBinaries (GenBinary, VB, *Kernel, *F, BC);
555- }
556-
544+ loadBinary (GenBinary, VB, *Kernel, BC);
557545 return std::move (GenBinary);
558546}
559547
@@ -656,7 +644,6 @@ class RuntimeInfoCollector final {
656644 const GenXSubtarget &ST;
657645 const Module &M;
658646 const GenXDebugInfo &DBG;
659- std::set<const llvm::Function *> ProcessedCalls;
660647
661648public:
662649 using KernelStorageTy = GenXOCLRuntimeInfo::KernelStorageTy;
@@ -673,7 +660,9 @@ class RuntimeInfoCollector final {
673660 CompiledModuleT run ();
674661
675662private:
676- CompiledKernel collectFunctionGroupInfo (const FunctionGroup &FG);
663+ CompiledKernel collectFunctionGroupInfo (const FunctionGroup &FG) const ;
664+ CompiledKernel collectFunctionSubgroupsInfo (
665+ const std::vector<FunctionGroup *> &Subgroups) const ;
677666};
678667
679668} // namespace
@@ -684,12 +673,20 @@ RuntimeInfoCollector::CompiledModuleT RuntimeInfoCollector::run() {
684673 [this ](const FunctionGroup *FG) {
685674 return collectFunctionGroupInfo (*FG);
686675 });
676+ std::vector<FunctionGroup *> IndirectlyReferencedFuncs;
677+ std::copy_if (FGA.subgroup_begin (), FGA.subgroup_end (),
678+ std::back_inserter (IndirectlyReferencedFuncs),
679+ [](const FunctionGroup *FG) {
680+ return genx::isReferencedIndirectly (FG->getHead ());
681+ });
682+ if (!IndirectlyReferencedFuncs.empty ())
683+ Kernels.push_back (collectFunctionSubgroupsInfo (IndirectlyReferencedFuncs));
687684 return {getModuleInfo (M), std::move (Kernels),
688685 M.getDataLayout ().getPointerSize ()};
689686}
690687
691688RuntimeInfoCollector::CompiledKernel
692- RuntimeInfoCollector::collectFunctionGroupInfo (const FunctionGroup &FG) {
689+ RuntimeInfoCollector::collectFunctionGroupInfo (const FunctionGroup &FG) const {
693690 using KernelInfo = GenXOCLRuntimeInfo::KernelInfo;
694691 using GTPinInfo = GenXOCLRuntimeInfo::GTPinInfo;
695692 using CompiledKernel = GenXOCLRuntimeInfo::CompiledKernel;
@@ -722,7 +719,7 @@ RuntimeInfoCollector::collectFunctionGroupInfo(const FunctionGroup &FG) {
722719 }
723720
724721 genx::BinaryDataAccumulator<const Function *> GenBinary =
725- getGenBinary (FG, VB, BC, ProcessedCalls );
722+ getGenBinary (FG, VB, BC);
726723
727724 const auto & Dbg = DBG.getModuleDebug ();
728725 auto DbgIt = Dbg.find (KernelFunction);
@@ -737,20 +734,42 @@ RuntimeInfoCollector::collectFunctionGroupInfo(const FunctionGroup &FG) {
737734 CISA_CALL (VK->GetGenRelocEntryBuffer (Info.LegacyFuncRelocations .Buffer ,
738735 Info.LegacyFuncRelocations .Size ,
739736 Info.LegacyFuncRelocations .Entries ));
740- Info.Func .Symbols = constructFunctionSymbols (GenBinary);
737+ Info.Func .Symbols = constructFunctionSymbols (GenBinary, /* HasKernel= */ true );
741738
742739 void *GTPinBuffer = nullptr ;
743740 unsigned GTPinBufferSize = 0 ;
744741 CISA_CALL (VK->GetGTPinBuffer (GTPinBuffer, GTPinBufferSize));
745742
746743 auto *GTPinBytes = static_cast <char *>(GTPinBuffer);
747- GTPinInfo gtpin{{ GTPinBytes, GTPinBytes + GTPinBufferSize} };
744+ GTPinInfo gtpin{GTPinBytes, GTPinBytes + GTPinBufferSize};
748745
749746 Info.Func .Data .Buffer = std::move (GenBinary).emitConsolidatedData ();
750747 return CompiledKernel{std::move (Info), *JitInfo, std::move (gtpin),
751748 std::move (DebugData)};
752749}
753750
751+ RuntimeInfoCollector::CompiledKernel
752+ RuntimeInfoCollector::collectFunctionSubgroupsInfo (
753+ const std::vector<FunctionGroup *> &Subgroups) const {
754+ using KernelInfo = GenXOCLRuntimeInfo::KernelInfo;
755+ using CompiledKernel = GenXOCLRuntimeInfo::CompiledKernel;
756+
757+ IGC_ASSERT (!Subgroups.empty ());
758+ KernelInfo Info{ST};
759+
760+ genx::BinaryDataAccumulator<const Function *> GenBinary;
761+ for (auto *FG : Subgroups) {
762+ auto *Func = FG->getHead ();
763+ IGC_ASSERT (genx::fg::isSubGroupHead (*Func));
764+ loadBinary (GenBinary, VB, *Func, BC);
765+ }
766+ Info.Func .Symbols = constructFunctionSymbols (GenBinary, /* HasKernel*/ false );
767+ Info.Func .Data .Buffer = GenBinary.emitConsolidatedData ();
768+
769+ return CompiledKernel{std::move (Info), FINALIZER_INFO{}, /* GtpinInfo*/ {},
770+ /* DebugInfo*/ {}};
771+ }
772+
754773void GenXOCLRuntimeInfo::getAnalysisUsage (AnalysisUsage &AU) const {
755774 AU.addRequired <FunctionGroupAnalysis>();
756775 AU.addRequired <GenXBackendConfig>();
0 commit comments