@@ -16,6 +16,7 @@ SPDX-License-Identifier: MIT
16
16
#include " DebugInfo/VISADebugInfo.hpp"
17
17
#include " Compiler/ScalarDebugInfo/VISAScalarModule.hpp"
18
18
#include " llvm/IR/IntrinsicInst.h"
19
+ #include " llvm/ADT/SmallVector.h"
19
20
20
21
using namespace llvm ;
21
22
using namespace IGC ;
@@ -27,8 +28,6 @@ using namespace CLElfLib;
27
28
char DebugInfoPass::ID = 0 ;
28
29
char CatchAllLineNumber::ID = 0 ;
29
30
30
- using VISAIndexToModule = std::pair<unsigned int , std::pair<llvm::Function *, IGC::VISAModule *>>;
31
-
32
31
// Register pass to igc-opt
33
32
#define PASS_FLAG1 " igc-debug-finalize"
34
33
#define PASS_DESCRIPTION1 " DebugInfo pass, llvmIR part(WAs)"
@@ -112,9 +111,10 @@ void setVISAModuleType(VISAModule *v, const DbgDecoder &decodedDbg) {
112
111
}
113
112
}
114
113
115
- unsigned int getGenISAIndex (
114
+ unsigned int getGenOffset (
116
115
const std::vector<std::pair<unsigned int , unsigned int >> &indexMap,
117
116
unsigned int VISAIndex) {
117
+ // indexMap is VISA index <-> gen offset mapping.
118
118
unsigned retval = 0 ;
119
119
for (auto &item : indexMap) {
120
120
if (item.first == VISAIndex) {
@@ -124,51 +124,86 @@ unsigned int getGenISAIndex(
124
124
return retval;
125
125
}
126
126
127
- unsigned int getLastVISAIndex (IGC::VISAModule *v,
128
- const DbgDecoder &decodedDbg) {
129
- // Detect last instructions of kernel. This information is absent in
130
- // dbg info. So detect is as first instruction of first subroutine - 1.
127
+ unsigned int getLastGenOffset (IGC::VISAModule *v,
128
+ const DbgDecoder &decodedDbg,
129
+ const DenseMap<uint32_t , unsigned int > &genOffsetToLastVISAindex) {
130
+
131
+ // Iterate through dbg info objects to find the one which matches the given VISAModule.
132
+ for (auto &item : decodedDbg.compiledObjs ) {
133
+ // Name of the kernel or stack call function.
134
+ auto &objectName = item.kernelName ;
135
+
136
+ // First instruction that went through the LLVM IR -> VISA translation.
137
+ auto firstInst = (v->GetInstInfoMap ()->begin ())->first ;
138
+
139
+ // Parent function of firstInst. It can be kernel, stackcall or subroutine.
140
+ auto funcName = firstInst->getParent ()->getParent ()->getName ();
131
141
132
- // reloc_index <-> first subroutine inst's VISA id
133
- std::unordered_map<uint32_t , unsigned int > firstSubroutineVISAIndex;
142
+ if (funcName.compare (objectName) == 0 ) {
143
+ // firstInst is inside a function having no subroutines -> last VISA is trivial.
144
+ if (item.subs .size () == 0 )
145
+ return item.CISAIndexMap .back ().second ;
146
+ // firstInst is inside a function having subroutines. Use created mapping.
147
+ return getGenOffset (item.CISAIndexMap , genOffsetToLastVISAindex.lookup (item.relocOffset ));
148
+ }
149
+
150
+ // Check if firstInst is inside a subroutine.
151
+ for (auto &sub : item.subs ) {
152
+ auto &subName = sub.name ;
153
+ if (funcName.compare (subName) == 0 )
154
+ return getGenOffset (item.CISAIndexMap , sub.endVISAIndex );
155
+ }
156
+ }
157
+
158
+ return 0 ;
159
+ }
160
+
161
+ void DebugInfoPass::getSortedVISAModules (
162
+ llvm::SmallVector<VISAIndexToModule, 8 > &sortedModules,
163
+ const DbgDecoder &decodedDbg) {
164
+
165
+ // This structure contains mapping:
166
+ // gen offset <-> VISA index of the last instruction
167
+ // for every compile object (kernel or stack call function) in the shader.
168
+ //
169
+ // Last VISA id is the smallest from: last VISA id from object's index map
170
+ // and start VISA indexes of object's subroutines - 1.
171
+ // We use the fact that subroutines are always placed after kernel / stack
172
+ // call function.
173
+ llvm::DenseMap<uint32_t , unsigned int > genOffsetToLastVISAindex;
134
174
135
175
for (auto &item : decodedDbg.compiledObjs ) {
136
- firstSubroutineVISAIndex [item.relocOffset ] = item.CISAIndexMap .back ().first ;
176
+ genOffsetToLastVISAindex [item.relocOffset ] = item.CISAIndexMap .back ().first ;
137
177
for (auto &subroutine : item.subs ) {
138
178
auto subStartVISAIndex = subroutine.startVISAIndex ;
139
- if (firstSubroutineVISAIndex [item.relocOffset ] > subStartVISAIndex)
140
- firstSubroutineVISAIndex [item.relocOffset ] = subStartVISAIndex - 1 ;
179
+ if (genOffsetToLastVISAindex [item.relocOffset ] > subStartVISAIndex)
180
+ genOffsetToLastVISAindex [item.relocOffset ] = subStartVISAIndex - 1 ;
141
181
}
142
182
}
143
183
144
- unsigned int genOffset = 0 ;
145
- for (auto &item : decodedDbg.compiledObjs ) {
146
- auto &name = item.kernelName ;
147
- auto firstInst = (v->GetInstInfoMap ()->begin ())->first ;
148
- auto funcName = firstInst->getParent ()->getParent ()->getName ();
149
- if (item.subs .size () == 0 && funcName.compare (name) == 0 ) {
150
- // No subroutines -> last visa is trivial.
151
- genOffset = item.CISAIndexMap .back ().second ;
152
- } else {
153
- if (funcName.compare (name) == 0 ) {
154
- genOffset = getGenISAIndex (item.CISAIndexMap ,
155
- firstSubroutineVISAIndex[item.relocOffset ]);
156
- break ;
157
- }
158
- for (auto &sub : item.subs ) {
159
- auto &subName = sub.name ;
160
- if (funcName.compare (subName) == 0 ) {
161
- genOffset = getGenISAIndex (item.CISAIndexMap , sub.endVISAIndex );
162
- break ;
163
- }
164
- }
165
- }
184
+ for (auto &m : m_currShader->GetDebugInfoData ().m_VISAModules ) {
185
+ // Deduce and set correct module type: KERNEL, STACKCALL_FUNC or
186
+ // SUBROUTINE.
187
+ setVISAModuleType (m.second , decodedDbg);
188
+
189
+ // getLastGenOffset returns zero if debug info for given function
190
+ // was not found, skip the function in such case. This can happen,
191
+ // when the function was optimized away but the definition is still
192
+ // present inside the module.
193
+ // Otherwise, it returns offset of the last instruction of the function.
166
194
167
- if (genOffset)
168
- break ;
195
+ unsigned int lastGenOffset =
196
+ getLastGenOffset (m.second , decodedDbg, genOffsetToLastVISAindex);
197
+ if (lastGenOffset == 0 )
198
+ continue ;
199
+ sortedModules.push_back (std::make_pair (lastGenOffset, m.second ));
169
200
}
170
201
171
- return genOffset;
202
+ // We sort VISA modules by their gen offset.
203
+ std::sort (sortedModules.begin (), sortedModules.end (),
204
+ [](VISAIndexToModule &p1, VISAIndexToModule &p2) {
205
+ return p1.first < p2.first ;
206
+ });
172
207
}
173
208
174
209
bool DebugInfoPass::runOnModule (llvm::Module &M) {
@@ -209,45 +244,22 @@ bool DebugInfoPass::runOnModule(llvm::Module &M) {
209
244
m_currShader->ProgramOutput ()->m_debugDataGenISA );
210
245
const DbgDecoder &decodedDbg = VisaDbgInfo.getRawDecodedData ();
211
246
212
- // This vector binds Function-VISAModule pairs with Function's last
213
- // VISA index. We sort functions in order of their placement in binary.
214
- std::vector<VISAIndexToModule> sortedVISAModules;
215
-
216
- for (auto &m : m_currShader->GetDebugInfoData ().m_VISAModules ) {
217
- // Deduce and set correct module type: KERNEL, STACKCALL_FUNC or
218
- // SUBROUTINE
219
- setVISAModuleType (m.second , decodedDbg);
220
-
221
- // getLastVISAIndex returns zero if debug info for given function
222
- // was not found, skip the function in such case. This can happen,
223
- // when the function was optimized away but the definition is still
224
- // present inside the module.
225
- // Otherwise, it returns VISA index of the last instruction in the
226
- // function.
227
-
228
- unsigned int lastVISAId = getLastVISAIndex (m.second , decodedDbg);
229
- if (lastVISAId == 0 )
230
- continue ;
231
- sortedVISAModules.push_back (
232
- std::make_pair (lastVISAId, std::make_pair (m.first , m.second )));
233
- }
234
-
235
- std::sort (sortedVISAModules.begin (), sortedVISAModules.end (),
236
- [](VISAIndexToModule &p1, VISAIndexToModule &p2) {
237
- return p1.first < p2.first ;
238
- });
247
+ // This vector contains VISAModules sorted by their last gen offset.
248
+ // It means they are sorted in order of their placement in binary.
249
+ llvm::SmallVector<VISAIndexToModule, 8 > sortedVISAModules;
250
+ getSortedVISAModules (sortedVISAModules, decodedDbg);
239
251
240
252
m_pDebugEmitter->SetDISPCache (&DISPCache);
241
253
for (auto &m : sortedVISAModules) {
242
- m_pDebugEmitter->registerVISA (m.second . second );
254
+ m_pDebugEmitter->registerVISA (m.second );
243
255
}
244
256
245
257
unsigned int size = sortedVISAModules.size ();
246
258
bool finalize = false ;
247
259
for (auto &m : sortedVISAModules) {
248
260
if (--size == 0 )
249
261
finalize = true ;
250
- m_pDebugEmitter->setCurrentVISA (m.second . second );
262
+ m_pDebugEmitter->setCurrentVISA (m.second );
251
263
emitDebugInfo (finalize, VisaDbgInfo);
252
264
}
253
265
0 commit comments