@@ -36,7 +36,7 @@ using namespace std;
3636// ElfReader related typedefs
3737using namespace CLElfLib ;
3838
39- std::vector <llvm::DISubprogram*> gatherDISubprogramNodes ( llvm::Module& M );
39+ void gatherDISubprogramNodes (llvm::Module& M, std::unordered_map <llvm::Function*, std::vector< llvm::DISubprogram*>>& DISubprogramNodes );
4040
4141char DebugInfoPass::ID = 0 ;
4242char CatchAllLineNumber::ID = 0 ;
@@ -92,7 +92,43 @@ bool DebugInfoPass::runOnModule(llvm::Module& M)
9292 if (simd32) units.push_back (simd32);
9393 }
9494
95- std::vector<llvm::DISubprogram*> DISubprogramNodes = gatherDISubprogramNodes (M);
95+ std::unordered_map<llvm::Function*, std::vector<llvm::DISubprogram*>> DISubprogramNodes;
96+ gatherDISubprogramNodes (M, DISubprogramNodes);
97+
98+ auto getSPDiesCollection = [&DISubprogramNodes](std::vector<llvm::Function*>& functions)
99+ {
100+ // Function argument is list of all functions for elf.
101+ // Each function may require emission of one or more DISubprogram nodes.
102+ // Return value should be a stable vector of collection of all DISubprogram nodes
103+ // but without duplicates.
104+ std::vector<llvm::DISubprogram*> retUniqueFuncVec;
105+ std::unordered_set<llvm::DISubprogram*> uniqueDISP;
106+ for (auto & f : functions)
107+ {
108+ // iterate over all DISubprogram nodes references by llvm::Function f
109+ auto & DISPNodesForF = DISubprogramNodes[f];
110+ for (auto & SP : DISPNodesForF)
111+ {
112+ if (uniqueDISP.find (SP) == uniqueDISP.end ())
113+ {
114+ retUniqueFuncVec.push_back (SP);
115+ uniqueDISP.insert (SP);
116+ }
117+ }
118+ }
119+ // This vector contains DISubprogram node pointers for which DIEs will be emitted elf
120+ // for current kernel.
121+ //
122+ // Input to IGC may have 100s of kernels. When emitting to dwarf, we can emit subprogram
123+ // DIEs defined in current kernel (+ it's recursive callees) as well as declarations of
124+ // other kernels and functions in input. These declarations quickly add up and cause
125+ // bloat of elf size without adding much benefit. This function is responsible to filter
126+ // and return only those DISubprogram nodes for which we want DIE emitted to elf. This
127+ // only includes DIEs for subprograms ever referenced in this kernel (+ it's recursive
128+ // callees). We skip emitting declaration DIEs for which no code is emitted in current
129+ // kernel.
130+ return retUniqueFuncVec;
131+ };
96132
97133 for (auto & currShader : units)
98134 {
@@ -234,6 +270,10 @@ bool DebugInfoPass::runOnModule(llvm::Module& M)
234270 m_pDebugEmitter->registerVISA (m.second .second );
235271 }
236272
273+ std::vector<llvm::Function*> functions;
274+ std::for_each (sortedVISAModules.begin (), sortedVISAModules.end (),
275+ [&functions](auto & item) { functions.push_back (item.second .first ); });
276+ auto SPDiesToBuild = getSPDiesCollection (functions);
237277 for (auto & m : sortedVISAModules)
238278 {
239279 isOneStepElf |= m.second .second ->isDirectElfInput ;
@@ -242,7 +282,7 @@ bool DebugInfoPass::runOnModule(llvm::Module& M)
242282 if (--size == 0 )
243283 finalize = true ;
244284
245- EmitDebugInfo (finalize, &decodedDbg, DISubprogramNodes );
285+ EmitDebugInfo (finalize, &decodedDbg, SPDiesToBuild );
246286 }
247287
248288 // set VISA dbg info to nullptr to indicate 1-step debug is enabled
0 commit comments