Skip to content

Commit 7d19274

Browse files
[llvm-debuginfo-analyzer] Add support for LLVM IR format.
Add support for the LLVM IR format and be able to generate logical views. Both textual representation (.ll) and bitcode (.bc) format are supported. Note: This patch requires: Add DebugSSAUpdater class to track debug value liveness llvm#135349 Note: Address reviewers comments.
1 parent 66187f5 commit 7d19274

File tree

10 files changed

+302
-274
lines changed

10 files changed

+302
-274
lines changed

llvm/docs/CommandGuide/llvm-debuginfo-analyzer.rst

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2264,6 +2264,34 @@ layout and given the number of matches.
22642264
-----------------------------
22652265
Total 33 12
22662266
2267+
The following prints all *symbols* and *types* that contain the exact **'INTPTR'**
2268+
in their names or types, using a tab layout and given the number of matches.
2269+
2270+
.. code-block:: none
2271+
2272+
llvm-debuginfo-analyzer --attribute=level
2273+
--select=INTPTR
2274+
--report=list
2275+
--print=symbols,types,summary
2276+
test-clang.ll
2277+
2278+
Logical View:
2279+
[000] {File} 'test-clang.ll'
2280+
2281+
[001] {CompileUnit} 'test.cpp'
2282+
[002] 1 {TypeAlias} 'INTPTR' -> '* const int'
2283+
[003] 2 {Parameter} 'ParamPtr' -> 'INTPTR'
2284+
2285+
-----------------------------
2286+
Element Total Printed
2287+
-----------------------------
2288+
Scopes 5 0
2289+
Symbols 4 1
2290+
Types 2 1
2291+
Lines 23 0
2292+
-----------------------------
2293+
Total 34 2
2294+
22672295
COMPARISON MODE
22682296
^^^^^^^^^^^^^^^
22692297
Given the previous example we found the above debug information issue

llvm/include/llvm/DebugInfo/LogicalView/LVReaderHandler.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ namespace logicalview {
3131

3232
using LVReaders = std::vector<std::unique_ptr<LVReader>>;
3333
using ArgVector = std::vector<std::string>;
34-
using PdbOrObjOrIr =
34+
using InputHandle =
3535
PointerUnion<object::ObjectFile *, pdb::PDBFile *, object::IRObjectFile *,
3636
MemoryBufferRef *, StringRef *>;
3737

@@ -67,9 +67,8 @@ class LVReaderHandler {
6767
Error handleObject(LVReaders &Readers, StringRef Filename,
6868
MemoryBufferRef Buffer);
6969

70-
Error createReader(StringRef Filename, LVReaders &Readers,
71-
PdbOrObjOrIr &Input, StringRef FileFormatName,
72-
StringRef ExePath = {});
70+
Error createReader(StringRef Filename, LVReaders &Readers, InputHandle &Input,
71+
StringRef FileFormatName, StringRef ExePath = {});
7372

7473
public:
7574
LVReaderHandler() = delete;

llvm/include/llvm/DebugInfo/LogicalView/Readers/LVIRReader.h

Lines changed: 29 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -58,18 +58,17 @@ class LVIRReader final : public LVReader {
5858
// Whether to emit all linkage names, or just abstract subprograms.
5959
bool UseAllLinkageNames = true;
6060

61-
// Dependencies on external options (llc, etc).
61+
// Looking at IR generated with the '-gdwarf -gsplit-dwarf=split' the only
62+
// difference is setting the 'DICompileUnit::splitDebugFilename' to the
63+
// name of the split filename: "xxx.dwo".
6264
bool includeMinimalInlineScopes() const;
6365
bool useAllLinkageNames() const { return UseAllLinkageNames; }
6466

6567
bool LanguageIsFortran = false;
6668
void mapFortranLanguage(unsigned DWLang);
6769
bool moduleIsInFortran() const { return LanguageIsFortran; }
6870

69-
// Generate logical debug line before prologue.
70-
bool GenerateLineBeforePrologue = true;
71-
72-
// We assume a constante increase between instructions.
71+
// We assume a constant instruction-size increase between instructions.
7372
const unsigned OffsetIncrease = 4;
7473
void updateLineOffset() { CurrentOffset += OffsetIncrease; }
7574

@@ -79,6 +78,7 @@ class LVIRReader final : public LVReader {
7978
std::unique_ptr<DbgValueRangeTable> DbgValueRanges;
8079

8180
// Record the last assigned file index for each compile unit.
81+
// This data structure is to aid mapping DIFiles onto a DWARF-like file table.
8282
using LVIndexFiles = std::map<LVScopeCompileUnit *, size_t>;
8383
LVIndexFiles IndexFiles;
8484

@@ -99,13 +99,13 @@ class LVIRReader final : public LVReader {
9999
return FileIndex;
100100
}
101101

102-
// Collect the compile unit metadata files.
102+
// Store a FileID number for each DIFile seen.
103103
using LVCompileUnitFiles = std::map<const DIFile *, size_t>;
104104
LVCompileUnitFiles CompileUnitFiles;
105105

106106
size_t getOrCreateSourceID(const DIFile *File);
107107

108-
// Associate the logical elements to metadata objects.
108+
// Associate the metadata objects to logical elements.
109109
using LVMDObjects = std::map<const MDNode *, LVElement *>;
110110
LVMDObjects MDObjects;
111111

@@ -130,18 +130,23 @@ class LVIRReader final : public LVReader {
130130
return static_cast<LVType *>(getElementForSeenMD(MD));
131131
}
132132

133-
// Inlined concrete scopes with its associated inlined abstract scopes.
134-
// When creating abstract scopes, there is no direct information to find
133+
// Abstract scopes mapped to the associated inlined scopes.
134+
// When creating inlined scopes, there is no direct information to find
135135
// the correct lexical scope.
136-
using LVInlinedScopes = std::map<LVScope *, LVScope *>;
136+
using LVScopeEntry = std::pair<LVScope *, const DILocation *>;
137+
using LVInlinedScopes = std::map<LVScopeEntry, LVScope *>;
137138
LVInlinedScopes InlinedScopes;
138139

139-
void addInlinedScope(LVScope *ConcreteScope, LVScope *AbstractScope) {
140-
if (InlinedScopes.find(ConcreteScope) == InlinedScopes.end())
141-
InlinedScopes.emplace(ConcreteScope, AbstractScope);
140+
void addInlinedScope(LVScope *AbstractScope, const DILocation *InlinedAt,
141+
LVScope *InlinedScope) {
142+
auto Entry = LVScopeEntry(AbstractScope, InlinedAt);
143+
if (InlinedScopes.find(Entry) == InlinedScopes.end())
144+
InlinedScopes.emplace(Entry, InlinedScope);
142145
}
143-
LVScope *getInlinedScope(LVScope *ConcreteScope) const {
144-
LVInlinedScopes::const_iterator Iter = InlinedScopes.find(ConcreteScope);
146+
LVScope *getInlinedScope(LVScope *AbstractScope,
147+
const DILocation *InlinedAt) const {
148+
auto Entry = LVScopeEntry(AbstractScope, InlinedAt);
149+
LVInlinedScopes::const_iterator Iter = InlinedScopes.find(Entry);
145150
return Iter != InlinedScopes.end() ? Iter->second : nullptr;
146151
}
147152

@@ -163,9 +168,6 @@ class LVIRReader final : public LVReader {
163168

164169
void processBasicBlocks(Function &F, const DISubprogram *SP);
165170

166-
void addGlobalName(StringRef Name, LVElement *Element,
167-
const DIScope *Context);
168-
169171
void addAccess(LVElement *Element, DINode::DIFlags Flags);
170172

171173
void addConstantValue(LVElement *Element, const DIExpression *DIExpr);
@@ -175,7 +177,7 @@ class LVIRReader final : public LVReader {
175177
const DIType *Ty);
176178
void addConstantValue(LVElement *Element, const APInt &Value, bool Unsigned);
177179
void addConstantValue(LVElement *Element, uint64_t Value, const DIType *Ty);
178-
void addConstantValue(LVElement *Element, bool Unsigned, uint64_t Value);
180+
void addConstantValue(LVElement *Element, uint64_t Value, bool Unsigned);
179181

180182
void addString(LVElement *Element, StringRef Str);
181183

@@ -197,8 +199,6 @@ class LVIRReader final : public LVReader {
197199
bool applySubprogramDefinitionAttributes(LVScope *Function,
198200
const DISubprogram *SP,
199201
bool Minimal = false);
200-
void applySubprogramAttributesToDefinition(LVScope *Function,
201-
const DISubprogram *SP);
202202

203203
void constructAggregate(LVScopeAggregate *Aggregate,
204204
const DICompositeType *CTy);
@@ -210,7 +210,8 @@ class LVIRReader final : public LVReader {
210210
LVType *IndexType);
211211
void constructImportedEntity(LVElement *Element, const DIImportedEntity *IE);
212212

213-
void constructLine(LVScope *Scope, const DISubprogram *SP, Instruction &I);
213+
void constructLine(LVScope *Scope, const DISubprogram *SP, Instruction &I,
214+
bool &GenerateLineBeforePrologue);
214215

215216
LVSymbol *getOrCreateMember(LVScope *Aggregate, const DIDerivedType *DT);
216217
LVSymbol *getOrCreateStaticMember(LVScope *Aggregate,
@@ -220,14 +221,15 @@ class LVIRReader final : public LVReader {
220221
LVScope *getOrCreateScope(const DIScope *Context);
221222
void constructScope(LVElement *Element, const DIScope *Context);
222223

223-
LVScope *getOrCreateSubprogram(const DISubprogram *SP, bool Minimal = false);
224+
LVScope *getOrCreateSubprogram(const DISubprogram *SP);
224225
LVScope *getOrCreateSubprogram(LVScope *Function, const DISubprogram *SP,
225226
bool Minimal = false);
226227
void constructSubprogramArguments(LVScope *Function,
227228
const DITypeRefArray Args);
228229

229-
LVScope *getOrCreateInlinedScope(LVScope *Parent, const DILocation *DL);
230-
LVScope *getOrCreateAbstractScope(LVScope *OriginScope, const DILocation *DL);
230+
LVScope *getOrCreateAbstractScope(LVScope *Parent, const DILocation *DL);
231+
LVScope *getOrCreateInlinedScope(LVScope *AbstractScope,
232+
const DILocation *DL);
231233

232234
void constructSubrange(LVScopeArray *Array, const DISubrange *GSR,
233235
LVType *IndexType);
@@ -245,8 +247,8 @@ class LVIRReader final : public LVReader {
245247
LVSymbol *getOrCreateVariable(const DIGlobalVariableExpression *GVE);
246248
LVSymbol *getOrCreateVariable(const DIVariable *Var,
247249
const DILocation *DL = nullptr);
248-
LVSymbol *getOrCreateAbstractVariable(LVSymbol *OriginSymbol,
249-
const DILocation *DL);
250+
LVSymbol *getOrCreateInlinedVariable(LVSymbol *OriginSymbol,
251+
const DILocation *DL);
250252

251253
LVElement *constructElement(const DINode *DN);
252254

llvm/lib/DebugInfo/LogicalView/LVReaderHandler.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ Error LVReaderHandler::process() {
4141
}
4242

4343
Error LVReaderHandler::createReader(StringRef Filename, LVReaders &Readers,
44-
PdbOrObjOrIr &Input,
44+
InputHandle &Input,
4545
StringRef FileFormatName,
4646
StringRef ExePath) {
4747
auto CreateOneReader = [&]() -> std::unique_ptr<LVReader> {
@@ -66,7 +66,7 @@ Error LVReaderHandler::createReader(StringRef Filename, LVReaders &Readers,
6666
return std::make_unique<LVIRReader>(Filename, FileFormatName, Ir, W);
6767
}
6868
if (isa<MemoryBufferRef *>(Input)) {
69-
// If the filename extension is '.ll' create a IR reader.
69+
// If the filename extension is '.ll' create an IR reader.
7070
const StringRef IRFileExt = ".ll";
7171
MemoryBufferRef *MemBuf = cast<MemoryBufferRef *>(Input);
7272
if (llvm::sys::path::extension(Filename) == IRFileExt)
@@ -240,7 +240,7 @@ Error LVReaderHandler::handleMach(LVReaders &Readers, StringRef Filename,
240240
if (Expected<std::unique_ptr<MachOObjectFile>> MachOOrErr =
241241
ObjForArch.getAsObjectFile()) {
242242
MachOObjectFile &Obj = **MachOOrErr;
243-
PdbOrObjOrIr Input = &Obj;
243+
InputHandle Input = &Obj;
244244
if (Error Err =
245245
createReader(Filename, Readers, Input, Obj.getFileFormatName()))
246246
return Err;
@@ -260,7 +260,7 @@ Error LVReaderHandler::handleMach(LVReaders &Readers, StringRef Filename,
260260

261261
Error LVReaderHandler::handleObject(LVReaders &Readers, StringRef Filename,
262262
Binary &Binary) {
263-
if (PdbOrObjOrIr Input = dyn_cast<ObjectFile>(&Binary))
263+
if (InputHandle Input = dyn_cast<ObjectFile>(&Binary))
264264
return createReader(Filename, Readers, Input,
265265
cast<ObjectFile *>(Input)->getFileFormatName());
266266

@@ -270,7 +270,7 @@ Error LVReaderHandler::handleObject(LVReaders &Readers, StringRef Filename,
270270
if (Archive *Arch = dyn_cast<Archive>(&Binary))
271271
return handleArchive(Readers, Filename, *Arch);
272272

273-
if (PdbOrObjOrIr Input = dyn_cast<IRObjectFile>(&Binary))
273+
if (InputHandle Input = dyn_cast<IRObjectFile>(&Binary))
274274
return createReader(Filename, Readers, Input, "Bitcode IR");
275275

276276
return createStringError(errc::not_supported,
@@ -287,7 +287,7 @@ Error LVReaderHandler::handleObject(LVReaders &Readers, StringRef Filename,
287287

288288
std::unique_ptr<NativeSession> PdbSession;
289289
PdbSession.reset(static_cast<NativeSession *>(Session.release()));
290-
PdbOrObjOrIr Input = &PdbSession->getPDBFile();
290+
InputHandle Input = &PdbSession->getPDBFile();
291291
StringRef FileFormatName;
292292
size_t Pos = Buffer.find_first_of("\r\n");
293293
if (Pos)
@@ -297,7 +297,7 @@ Error LVReaderHandler::handleObject(LVReaders &Readers, StringRef Filename,
297297

298298
Error LVReaderHandler::handleObject(LVReaders &Readers, StringRef Filename,
299299
MemoryBufferRef Buffer) {
300-
if (PdbOrObjOrIr Input = dyn_cast<MemoryBufferRef>(&Buffer))
300+
if (InputHandle Input = dyn_cast<MemoryBufferRef>(&Buffer))
301301
return createReader(Filename, Readers, Input, IRFileFormat);
302302

303303
return createStringError(errc::not_supported,

llvm/lib/DebugInfo/LogicalView/Readers/LVDWARFReader.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -529,16 +529,14 @@ void LVDWARFReader::createLineAndFileRecords(
529529
for (const DWARFDebugLine::FileNameEntry &Entry :
530530
Lines->Prologue.FileNames) {
531531
std::string Directory;
532-
Lines->getDirectoryForEntry(Entry, Directory);
532+
if (Lines->getDirectoryForEntry(Entry, Directory))
533+
Directory = transformPath(Directory);
533534
if (Directory.empty())
534535
Directory = std::string(CompileUnit->getCompilationDirectory());
535-
// Take just the filename component, as it may be contain the full
536-
// path that would be added to the already existing path in Directory.
537-
StringRef File =
538-
llvm::sys::path::filename(dwarf::toStringRef(Entry.Name));
536+
std::string File = transformPath(dwarf::toStringRef(Entry.Name));
539537
std::string String;
540538
raw_string_ostream(String) << Directory << "/" << File;
541-
CompileUnit->addFilename(transformPath(String));
539+
CompileUnit->addFilename(String);
542540
}
543541

544542
// In DWARF5 the file indexes start at 0;

0 commit comments

Comments
 (0)