@@ -36,7 +36,7 @@ using namespace std;
36
36
// ElfReader related typedefs
37
37
using namespace CLElfLib ;
38
38
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 );
40
40
41
41
char DebugInfoPass::ID = 0 ;
42
42
char CatchAllLineNumber::ID = 0 ;
@@ -92,7 +92,43 @@ bool DebugInfoPass::runOnModule(llvm::Module& M)
92
92
if (simd32) units.push_back (simd32);
93
93
}
94
94
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
+ };
96
132
97
133
for (auto & currShader : units)
98
134
{
@@ -234,6 +270,10 @@ bool DebugInfoPass::runOnModule(llvm::Module& M)
234
270
m_pDebugEmitter->registerVISA (m.second .second );
235
271
}
236
272
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);
237
277
for (auto & m : sortedVISAModules)
238
278
{
239
279
isOneStepElf |= m.second .second ->isDirectElfInput ;
@@ -242,7 +282,7 @@ bool DebugInfoPass::runOnModule(llvm::Module& M)
242
282
if (--size == 0 )
243
283
finalize = true ;
244
284
245
- EmitDebugInfo (finalize, &decodedDbg, DISubprogramNodes );
285
+ EmitDebugInfo (finalize, &decodedDbg, SPDiesToBuild );
246
286
}
247
287
248
288
// set VISA dbg info to nullptr to indicate 1-step debug is enabled
0 commit comments