Skip to content

Commit 403072b

Browse files
mtargowsigcbot
authored andcommitted
DIModule SPIRV extension (part 3)
DIModule SPIRV extension (part 3), added debug info emission of Imported Entity
1 parent 5d9d787 commit 403072b

File tree

5 files changed

+246
-25
lines changed

5 files changed

+246
-25
lines changed

IGC/AdaptorOCL/SPIRV/SPIRVReader.cpp

Lines changed: 50 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1089,6 +1089,24 @@ class SPIRVToLLVMDbgTran {
10891089
return addMDNode(inst, createLocation(line, 0, scope, iat));
10901090
}
10911091

1092+
// Encode a line number, a file name and a directory to a string, where a line no., file name
1093+
// and directory are separated by '?' character: lineNumber?fileName?directory
1094+
// There is a workaround for DIModule creation in earlier LLVM versions, where a line and a file
1095+
// parameters are not supported in DIBuilder.
1096+
void encodeLineAndFileForISysRoot(unsigned int line, llvm::DIFile* file, std::string& lineAndFile)
1097+
{
1098+
#if LLVM_VERSION_MAJOR < 11
1099+
lineAndFile.append(std::to_string(line));
1100+
lineAndFile.append("?");
1101+
if (file)
1102+
{
1103+
lineAndFile.append(file->getDirectory().str());
1104+
lineAndFile.append("?");
1105+
lineAndFile.append(file->getFilename().str());
1106+
}
1107+
#endif // LLVM_VERSION_MAJOR < 11.
1108+
}
1109+
10921110
DIModule* createModuleINTEL(SPIRVExtInst* inst)
10931111
{
10941112
if (auto n = getExistingNode<DIModule*>(inst))
@@ -1100,28 +1118,21 @@ class SPIRVToLLVMDbgTran {
11001118
auto& name = BM->get<SPIRVString>(moduleINTEL.getName())->getStr();
11011119
auto cfgMacros = BM->get<SPIRVString>(moduleINTEL.getConfigurationMacros())->getStr();
11021120
auto inclPath = BM->get<SPIRVString>(moduleINTEL.getIncludePath())->getStr();
1103-
1104-
DIModule* diModule;
1105-
1106-
#if LLVM_VERSION_MAJOR <= 10
1107-
llvm::StringRef iSysRoot = StringRef(); // Empty string
1108-
diModule = addMDNode(inst, Builder.createModule(scope, name, cfgMacros, inclPath, iSysRoot));
1109-
#else // LLVM_VERSION_MAJOR >= 11
11101121
auto file = getDIFile(BM->get<SPIRVExtInst>(moduleINTEL.getSource()));
11111122
auto line = moduleINTEL.getLine();
11121123
auto apiNotesFile = BM->get<SPIRVString>(moduleINTEL.getAPINotesFile())->getStr();
1113-
#if LLVM_VERSION_MAJOR == 11
1114-
diModule = addMDNode(inst, Builder.createModule(scope, name, cfgMacros, inclPath, apiNotesFile, file, line));
1115-
#elif LLVM_VERSION_MAJOR >= 12
11161124
bool isDecl = moduleINTEL.getIsDecl() ? true : false;
1117-
diModule = addMDNode(inst, Builder.createModule(scope, name, cfgMacros, inclPath, apiNotesFile, file, line, isDecl));
1118-
#endif
1119-
#endif // LLVM_VERSION_MAJOR >= 11.
1125+
1126+
std::string encodedLineAndFile = "";
1127+
encodeLineAndFileForISysRoot(line, file, encodedLineAndFile);
1128+
llvm::StringRef iSysRoot = StringRef(encodedLineAndFile);
1129+
1130+
DIModule* diModule = addMDNode(inst, Builder.createModule(scope, name, cfgMacros, inclPath, apiNotesFile, file, line, isDecl, iSysRoot));
11201131

11211132
return diModule;
11221133
}
11231134

1124-
DINode* createImportedEntity(SPIRVExtInst* inst)
1135+
DINode* createImportedEntity(SPIRVExtInst* inst, SmallVector<TrackingMDNodeRef, 4>& allImportedModules)
11251136
{
11261137
if (auto n = getExistingNode<DINode*>(inst))
11271138
return n;
@@ -1137,8 +1148,20 @@ class SPIRVToLLVMDbgTran {
11371148

11381149
if (BM->get<SPIRVExtInst>(entity)->getExtOp() == OCLExtOpDbgKind::ModuleINTEL)
11391150
{
1140-
auto diModule = createModuleINTEL(BM->get<SPIRVExtInst>(entity));
1141-
diNode = addMDNode(inst, Builder.createImportedModule(scope, diModule, file, line));
1151+
auto* diModule = createModuleINTEL(BM->get<SPIRVExtInst>(entity));
1152+
IGC_ASSERT(diModule);
1153+
DIImportedEntity* IE = Builder.createImportedModule(scope, diModule, file, line);
1154+
diNode = addMDNode(inst, IE);
1155+
1156+
IGC_ASSERT_MESSAGE(scope, "Invalid Scope encoding!");
1157+
if (isa<DILocalScope>(scope))
1158+
{
1159+
allImportedModules.emplace_back(IE);
1160+
}
1161+
else
1162+
{
1163+
// TODO? ReplaceImportedEntities = true;
1164+
}
11421165
}
11431166

11441167
return diNode;
@@ -1311,12 +1334,20 @@ class SPIRVToLLVMDbgTran {
13111334
if (!Enable)
13121335
return;
13131336

1337+
DICompileUnit* CU = getCompileUnit();
1338+
13141339
auto importedEntities = BM->getImportedEntities();
13151340

1341+
SmallVector<TrackingMDNodeRef, 4> AllImportedModules;
13161342
for (auto& importedEntity : importedEntities)
1317-
{
1318-
(void)createImportedEntity(importedEntity);
1319-
}
1343+
(void)createImportedEntity(importedEntity, AllImportedModules);
1344+
1345+
1346+
if (!AllImportedModules.empty())
1347+
CU->replaceImportedEntities(
1348+
MDTuple::get(CU->getContext(), SmallVector<Metadata*, 16>(AllImportedModules.begin(), AllImportedModules.end())));
1349+
else
1350+
CU->replaceImportedEntities(nullptr); // If there were no local scope imported entities, we can map the whole list to nullptr.
13201351
}
13211352

13221353
void transDbgInfo(SPIRVValue *SV, Value *V);

IGC/DebugInfo/DwarfCompileUnit.cpp

Lines changed: 124 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ int64_t CompileUnit::getDefaultLowerBound() const
203203
}
204204

205205
/// Check whether the DIE for this MDNode can be shared across CUs.
206-
static bool isShareableAcrossCUs(llvm::MDNode* D)
206+
static bool isShareableAcrossCUs(const llvm::MDNode* D)
207207
{
208208
// When the MDNode can be part of the type system, the DIE can be
209209
// shared across CUs.
@@ -440,6 +440,20 @@ void CompileUnit::addSourceLine(DIE* Die, DIScope* S, unsigned Line)
440440
addUInt(Die, dwarf::DW_AT_decl_line, None, Line);
441441
}
442442

443+
/// addSourceLine - Add location information to specified debug information
444+
/// entry.
445+
void CompileUnit::addSourceLine(DIE* Die, DIImportedEntity* IE, unsigned Line)
446+
{
447+
// If the line number is 0, don't add it.
448+
if (Line == 0)
449+
return;
450+
451+
unsigned FileID = DD->getOrCreateSourceID(IE->getFile()->getFilename(), IE->getFile()->getDirectory(), getUniqueID());
452+
IGC_ASSERT_MESSAGE(FileID, "Invalid file id");
453+
addUInt(Die, dwarf::DW_AT_decl_file, None, FileID);
454+
addUInt(Die, dwarf::DW_AT_decl_line, None, Line);
455+
}
456+
443457
/// addSourceLine - Add location information to specified debug information
444458
/// entry.
445459
void CompileUnit::addSourceLine(DIE* Die, DIVariable* V)
@@ -736,7 +750,6 @@ IGC::DIE* CompileUnit::getOrCreateContextDIE(DIScope* Context)
736750
return getOrCreateModuleDIE(MD);
737751

738752
return getDIE(Context);
739-
740753
}
741754

742755
/// getOrCreateTypeDIE - Find existing DIE or create new DIE for the
@@ -1658,6 +1671,27 @@ std::string CompileUnit::getParentContextString(DIScope* Context) const
16581671
return CS;
16591672
}
16601673

1674+
// Decode line number, file name and location from a string, where a line no., file name
1675+
// and directory are separated by '?' character: lineNumber?fileName?directory
1676+
// There is a workaround for DIModule creation in earlier LLVM versions, where a line and a file
1677+
// parameters are not supported in DIBuilder.
1678+
void CompileUnit::decodeLineAndFileForISysRoot(StringRef& lineAndFile, unsigned int* line, std::string* file,
1679+
std::string* directory)
1680+
{
1681+
#if LLVM_VERSION_MAJOR < 11
1682+
SmallVector<StringRef, 8> splitStr;
1683+
lineAndFile.split(splitStr, "?");// substr(0, posOfLineAndDirSeparator).str().copy()
1684+
unsigned int posOfFirstQ = lineAndFile.find_first_of('?', 0);
1685+
std::string lineStr = "";
1686+
lineStr.append(splitStr[0].str().c_str(), posOfFirstQ);
1687+
unsigned int posOfSecondQ = lineAndFile.find_first_of('?', posOfFirstQ + 1);
1688+
1689+
directory->append(splitStr[1].str().c_str(), posOfSecondQ - posOfFirstQ);
1690+
file->append(splitStr[2].str().c_str(), splitStr[2].size());
1691+
*line = (unsigned int)std::atoi(splitStr[0].data());
1692+
#endif // LLVM_VERSION_MAJOR < 11
1693+
}
1694+
16611695
/// constructTypeDIE - Construct basic type die from DIBasicType.
16621696
void CompileUnit::constructTypeDIE(DIE& Buffer, DIBasicType* BTy)
16631697
{
@@ -2013,6 +2047,42 @@ void CompileUnit::constructTemplateValueParameterDIE(
20132047
}
20142048

20152049

2050+
/// constructImportedEntityDIE - Create a DIE for DIImportedEntity.
2051+
IGC::DIE* CompileUnit::constructImportedEntityDIE(
2052+
DIImportedEntity* Module)
2053+
{
2054+
DINode* Entity = Module->getEntity();
2055+
if (auto* GV = dyn_cast<DIGlobalVariable>(Entity))
2056+
return nullptr; // Missing support for imported entity linked to a global variable
2057+
2058+
DIE* IMDie = new DIE(Module->getTag());
2059+
insertDIE(Module, IMDie);
2060+
2061+
DIE* EntityDie;
2062+
if (auto* NS = dyn_cast<DINamespace>(Entity))
2063+
EntityDie = getOrCreateNameSpace(NS);
2064+
else if (auto* M = dyn_cast<DIModule>(Entity))
2065+
EntityDie = getOrCreateModuleDIE(M);
2066+
else if (auto* SP = dyn_cast<DISubprogram>(Entity))
2067+
EntityDie = getOrCreateSubprogramDIE(SP);
2068+
else if (auto* T = dyn_cast<DIType>(Entity))
2069+
EntityDie = getOrCreateTypeDIE(T);
2070+
//else if (auto* GV = dyn_cast<DIGlobalVariable>(Entity)) // TODO missing support
2071+
// EntityDie = getOrCreateGlobalVariableDIE(GV, {});
2072+
else
2073+
EntityDie = getDIE(Entity);
2074+
2075+
assert(EntityDie);
2076+
2077+
addSourceLine(IMDie, Module, Module->getLine());
2078+
addDIEEntry(IMDie, dwarf::DW_AT_import, EntityDie);
2079+
StringRef Name = Module->getName();
2080+
if (!Name.empty())
2081+
addString(IMDie, dwarf::DW_AT_name, Name);
2082+
2083+
return IMDie;
2084+
}
2085+
20162086
/// getOrCreateNameSpace - Create a DIE for DINameSpace.
20172087
IGC::DIE* CompileUnit::getOrCreateNameSpace(DINamespace* NS)
20182088
{
@@ -2145,6 +2215,8 @@ IGC::DIE* CompileUnit::getOrCreateSubprogramDIE(DISubprogram* SP)
21452215
{
21462216
DIE* Arg = createAndAddDIE(dwarf::DW_TAG_formal_parameter, *SPDie);
21472217
DIType* ATy = resolve(Args[i]);
2218+
if (!ATy)
2219+
continue;
21482220
addType(Arg, ATy);
21492221
if (ATy->isArtificial())
21502222
{
@@ -2176,10 +2248,58 @@ IGC::DIE* CompileUnit::getOrCreateModuleDIE(DIModule* MD)
21762248
// Construct the context before querying for the existence of the DIE in case
21772249
// such construction creates the DIE (as is the case for member function
21782250
// declarations).
2251+
DIE* ContextDIE = getOrCreateContextDIE(MD->getScope());
2252+
DIE* MDDie = getDIE(MD);
2253+
if (MDDie)
2254+
return MDDie;
2255+
2256+
MDDie = createAndAddDIE(dwarf::DW_TAG_module, *ContextDIE, MD);
2257+
IGC_ASSERT(MDDie);
2258+
2259+
if (!MD->getName().empty())
2260+
{
2261+
addString(MDDie, dwarf::DW_AT_name, MD->getName());
2262+
}
2263+
2264+
#if LLVM_VERSION_MAJOR < 11
2265+
#if LLVM_VERSION_MAJOR < 10
2266+
StringRef iSysRoot = MD->getISysRoot();
2267+
#else // LLVM_VERSION_MAJOR == 10
2268+
StringRef iSysRoot = MD->getSysRoot();
2269+
#endif // LLVM_VERSION_MAJOR == 10
2270+
unsigned int line;
2271+
std::string file = "";
2272+
std::string directory = "";
2273+
2274+
decodeLineAndFileForISysRoot(iSysRoot, &line, &file, &directory);
21792275

2180-
IGC_ASSERT_MESSAGE(false, "Missing implementation for DIModule!");
2276+
// Emit a line number and a file only if line number is significant
2277+
if (line > 0)
2278+
addUInt(MDDie, dwarf::DW_AT_decl_line, None, line);
2279+
// Emit a file if not empty name
2280+
if (!file.empty() || !directory.empty())
2281+
{
2282+
StringRef fileRef(file);
2283+
StringRef dirRef(directory);
2284+
unsigned FileID = DD->getOrCreateSourceID(fileRef, dirRef, getUniqueID());
2285+
addUInt(MDDie, dwarf::DW_AT_decl_file, None, FileID);
2286+
}
2287+
#else // LLVM_VERSION_MAJOR >= 11
2288+
#if LLVM_VERSION_MAJOR == 11
2289+
addSourceLine(MDDie, MD, MD->getLineNo());
2290+
#elif LLVM_VERSION_MAJOR >= 12
2291+
if (!MD->getIsDecl())
2292+
{
2293+
addSourceLine(MDDie, MD, MD->getLineNo());
2294+
}
2295+
else
2296+
{
2297+
addFlag(MDDie, dwarf::DW_AT_declaration);
2298+
}
2299+
#endif // LLVM_VERSION_MAJOR >= 12
2300+
#endif // LLVM_VERSION_MAJOR >= 11.
21812301

2182-
return nullptr;
2302+
return MDDie;
21832303
}
21842304

21852305
/// constructSubrangeDIE - Construct subrange DIE from DISubrange.

IGC/DebugInfo/DwarfCompileUnit.hpp

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,11 @@ See LICENSE.TXT for details.
2222
#include "llvm/Config/llvm-config.h"
2323

2424
#include "common/LLVMWarningsPush.hpp"
25-
#include "llvm/ADT/DenseMap.h"
2625
#include "llvm/ADT/Optional.h"
26+
#include "llvm/ADT/DenseMap.h"
27+
#include "llvm/ADT/SmallVector.h"
2728
#include "llvm/ADT/StringMap.h"
29+
#include "llvm/ADT/StringRef.h"
2830
#include "llvm/IR/DebugInfo.h"
2931
#include "llvm/IR/GlobalValue.h"
3032
#include "common/LLVMWarningsPop.hpp"
@@ -102,6 +104,11 @@ namespace IGC
102104
StreamEmitter* A, IGC::DwarfDebug* DW);
103105
~CompileUnit();
104106

107+
using ImportedEntityList = llvm::SmallVector<const llvm::MDNode*, 8>;
108+
using ImportedEntityMap = llvm::DenseMap<const llvm::MDNode*, ImportedEntityList>;
109+
110+
ImportedEntityMap ImportedEntities;
111+
105112
// Accessors.
106113
unsigned getUniqueID() const { return UniqueID; }
107114
uint16_t getLanguage() const { return (uint16_t)Node->getSourceLanguage(); }
@@ -205,6 +212,7 @@ namespace IGC
205212
/// addSourceLine - Add location information to specified debug information
206213
/// entry.
207214
void addSourceLine(DIE* Die, llvm::DIScope* S, unsigned Line);
215+
void addSourceLine(DIE* Die, llvm::DIImportedEntity* IE, unsigned Line);
208216
void addSourceLine(DIE* Die, llvm::DIVariable* V);
209217
void addSourceLine(DIE* Die, llvm::DISubprogram* SP);
210218
void addSourceLine(DIE* Die, llvm::DIType* Ty);
@@ -298,6 +306,16 @@ namespace IGC
298306
const DbgDecoder::LiveIntervalsVISA& lr,
299307
uint64_t varSizeInBits, uint64_t offsetInBits);
300308

309+
// Decode line number, file name and location from a string, where a line no. and file name
310+
// (including directory) are separated by '-' character: lineNumber-fileNameIncludingDirectory
311+
// There is a workaround for DIModule creation in earlier LLVM versions, where a line and a file
312+
// parameters are not supported in DIBuilder.
313+
void decodeLineAndFileForISysRoot(llvm::StringRef& lineAndFile, unsigned int* line, std::string* file,
314+
std::string* directory);
315+
316+
/// Construct import_module DIE.
317+
IGC::DIE* constructImportedEntityDIE(llvm::DIImportedEntity* Module);
318+
301319
/// getOrCreateNameSpace - Create a DIE for DINameSpace.
302320
DIE* getOrCreateNameSpace(llvm::DINamespace* NS);
303321

@@ -325,6 +343,20 @@ namespace IGC
325343
/// call insertDIE if MD is not null.
326344
DIE* createAndAddDIE(unsigned Tag, DIE& Parent, llvm::DINode* N = nullptr);
327345

346+
void addImportedEntity(const llvm::DIImportedEntity* IE)
347+
{
348+
llvm::DIScope* Scope = IE->getScope();
349+
assert(Scope && "Invalid Scope encoding!");
350+
if (!llvm::isa<llvm::DILocalScope>(Scope))
351+
{
352+
// No need to add imported enities that are not local declaration.
353+
return;
354+
}
355+
356+
auto* LocalScope = llvm::cast<llvm::DILocalScope>(Scope)->getNonLexicalBlockFileScope();
357+
ImportedEntities[LocalScope].push_back(IE);
358+
}
359+
328360
/// Compute the size of a header for this unit, not including the initial
329361
/// length field.
330362
unsigned getHeaderSize() const

0 commit comments

Comments
 (0)