Skip to content

Commit 0bd9352

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 #135349 Note: Address reviewers comments.
1 parent 6854229 commit 0bd9352

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
@@ -2261,6 +2261,34 @@ layout and given the number of matches.
22612261
-----------------------------
22622262
Total 33 12
22632263
2264+
The following prints all *symbols* and *types* that contain the exact **'INTPTR'**
2265+
in their names or types, using a tab layout and given the number of matches.
2266+
2267+
.. code-block:: none
2268+
2269+
llvm-debuginfo-analyzer --attribute=level
2270+
--select=INTPTR
2271+
--report=list
2272+
--print=symbols,types,summary
2273+
test-clang.ll
2274+
2275+
Logical View:
2276+
[000] {File} 'test-clang.ll'
2277+
2278+
[001] {CompileUnit} 'test.cpp'
2279+
[002] 1 {TypeAlias} 'INTPTR' -> '* const int'
2280+
[003] 2 {Parameter} 'ParamPtr' -> 'INTPTR'
2281+
2282+
-----------------------------
2283+
Element Total Printed
2284+
-----------------------------
2285+
Scopes 5 0
2286+
Symbols 4 1
2287+
Types 2 1
2288+
Lines 23 0
2289+
-----------------------------
2290+
Total 34 2
2291+
22642292
COMPARISON MODE
22652293
^^^^^^^^^^^^^^^
22662294
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
@@ -30,7 +30,7 @@ namespace logicalview {
3030

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

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

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

7372
public:
7473
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
@@ -517,16 +517,14 @@ void LVDWARFReader::createLineAndFileRecords(
517517
for (const DWARFDebugLine::FileNameEntry &Entry :
518518
Lines->Prologue.FileNames) {
519519
std::string Directory;
520-
Lines->getDirectoryForEntry(Entry, Directory);
520+
if (Lines->getDirectoryForEntry(Entry, Directory))
521+
Directory = transformPath(Directory);
521522
if (Directory.empty())
522523
Directory = std::string(CompileUnit->getCompilationDirectory());
523-
// Take just the filename component, as it may be contain the full
524-
// path that would be added to the already existing path in Directory.
525-
StringRef File =
526-
llvm::sys::path::filename(dwarf::toStringRef(Entry.Name));
524+
std::string File = transformPath(dwarf::toStringRef(Entry.Name));
527525
std::string String;
528526
raw_string_ostream(String) << Directory << "/" << File;
529-
CompileUnit->addFilename(transformPath(String));
527+
CompileUnit->addFilename(String);
530528
}
531529

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

0 commit comments

Comments
 (0)