Skip to content

Commit 104f49f

Browse files
Kotynia, Piotrigcbot
authored andcommitted
Sorting VISA modules simplified
Refactor, simplify and improve data structures for VISA module sorting in DebugInfo pass.
1 parent 609ff1f commit 104f49f

File tree

2 files changed

+82
-66
lines changed

2 files changed

+82
-66
lines changed

IGC/Compiler/CISACodeGen/DebugInfo.cpp

Lines changed: 78 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ SPDX-License-Identifier: MIT
1616
#include "DebugInfo/VISADebugInfo.hpp"
1717
#include "Compiler/ScalarDebugInfo/VISAScalarModule.hpp"
1818
#include "llvm/IR/IntrinsicInst.h"
19+
#include "llvm/ADT/SmallVector.h"
1920

2021
using namespace llvm;
2122
using namespace IGC;
@@ -27,8 +28,6 @@ using namespace CLElfLib;
2728
char DebugInfoPass::ID = 0;
2829
char CatchAllLineNumber::ID = 0;
2930

30-
using VISAIndexToModule = std::pair<unsigned int, std::pair<llvm::Function *, IGC::VISAModule *>>;
31-
3231
// Register pass to igc-opt
3332
#define PASS_FLAG1 "igc-debug-finalize"
3433
#define PASS_DESCRIPTION1 "DebugInfo pass, llvmIR part(WAs)"
@@ -112,9 +111,10 @@ void setVISAModuleType(VISAModule *v, const DbgDecoder &decodedDbg) {
112111
}
113112
}
114113

115-
unsigned int getGenISAIndex(
114+
unsigned int getGenOffset(
116115
const std::vector<std::pair<unsigned int, unsigned int>> &indexMap,
117116
unsigned int VISAIndex) {
117+
// indexMap is VISA index <-> gen offset mapping.
118118
unsigned retval = 0;
119119
for (auto &item : indexMap) {
120120
if (item.first == VISAIndex) {
@@ -124,51 +124,86 @@ unsigned int getGenISAIndex(
124124
return retval;
125125
}
126126

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();
131141

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;
134174

135175
for (auto &item : decodedDbg.compiledObjs) {
136-
firstSubroutineVISAIndex[item.relocOffset] = item.CISAIndexMap.back().first;
176+
genOffsetToLastVISAindex[item.relocOffset] = item.CISAIndexMap.back().first;
137177
for (auto &subroutine : item.subs) {
138178
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;
141181
}
142182
}
143183

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.
166194

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));
169200
}
170201

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+
});
172207
}
173208

174209
bool DebugInfoPass::runOnModule(llvm::Module &M) {
@@ -209,45 +244,22 @@ bool DebugInfoPass::runOnModule(llvm::Module &M) {
209244
m_currShader->ProgramOutput()->m_debugDataGenISA);
210245
const DbgDecoder &decodedDbg = VisaDbgInfo.getRawDecodedData();
211246

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);
239251

240252
m_pDebugEmitter->SetDISPCache(&DISPCache);
241253
for (auto &m : sortedVISAModules) {
242-
m_pDebugEmitter->registerVISA(m.second.second);
254+
m_pDebugEmitter->registerVISA(m.second);
243255
}
244256

245257
unsigned int size = sortedVISAModules.size();
246258
bool finalize = false;
247259
for (auto &m : sortedVISAModules) {
248260
if (--size == 0)
249261
finalize = true;
250-
m_pDebugEmitter->setCurrentVISA(m.second.second);
262+
m_pDebugEmitter->setCurrentVISA(m.second);
251263
emitDebugInfo(finalize, VisaDbgInfo);
252264
}
253265

IGC/Compiler/CISACodeGen/DebugInfo.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ using namespace IGC;
2424
using namespace IGC::IGCMD;
2525
using namespace std;
2626

27+
// This type matches VISA index with its associated Function-VISAModule pair.
28+
using VISAIndexToModule = std::pair<unsigned int, IGC::VISAModule *>;
29+
2730
namespace IGC
2831
{
2932
class CVariable;
@@ -52,6 +55,7 @@ namespace IGC
5255

5356
std::vector<CShader *> findShaderCandidates();
5457
void emitDebugInfo(bool, const IGC::VISADebugInfo &VDI);
58+
void getSortedVISAModules(llvm::SmallVector<VISAIndexToModule, 8> &, const DbgDecoder &);
5559
};
5660

5761
class CatchAllLineNumber : public llvm::FunctionPass

0 commit comments

Comments
 (0)