Skip to content

[llvm] Implement S_INLINEES debug symbol #67490

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ class LVSymbolVisitor final : public SymbolVisitorCallbacks {
Error visitKnownRecord(CVSymbol &Record, UDTSym &UDT) override;
Error visitKnownRecord(CVSymbol &Record, UsingNamespaceSym &UN) override;
Error visitKnownRecord(CVSymbol &Record, JumpTableSym &JumpTable) override;
Error visitKnownRecord(CVSymbol &Record, CallerSym &Caller) override;
};

// Visitor for CodeView types and symbols to populate elements.
Expand Down
34 changes: 33 additions & 1 deletion llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,10 @@ CodeViewDebug::getInlineSite(const DILocation *InlinedAt,
InlinedAt->getLine(), InlinedAt->getColumn(), SMLoc());
Site->Inlinee = Inlinee;
InlinedSubprograms.insert(Inlinee);
getFuncIdForSubprogram(Inlinee);
auto InlineeIdx = getFuncIdForSubprogram(Inlinee);

if (InlinedAt->getInlinedAt() == nullptr)
CurFn->Inlinees.insert(InlineeIdx);
}
return *Site;
}
Expand Down Expand Up @@ -1194,6 +1197,7 @@ void CodeViewDebug::emitDebugInfoForFunction(const Function *GV,
OS.emitInt32(uint32_t(FI.FrameProcOpts));
endSymbolRecord(FrameProcEnd);

emitInlinees(FI.Inlinees);
emitLocalVariableList(FI, FI.Locals);
emitGlobalVariableList(FI.Globals);
emitLexicalBlockList(FI.ChildBlocks, FI);
Expand Down Expand Up @@ -3588,3 +3592,31 @@ void CodeViewDebug::emitDebugInfoForJumpTables(const FunctionInfo &FI) {
endSymbolRecord(JumpTableEnd);
}
}

void CodeViewDebug::emitInlinees(
const SmallSet<codeview::TypeIndex, 1> &Inlinees) {
// Divide the list of inlinees into chunks such that each chunk fits within
// one record.
constexpr auto ChunkSize =
(MaxRecordLength - sizeof(SymbolKind) - sizeof(uint32_t)) /
sizeof(uint32_t);

SmallVector<TypeIndex> SortedInlinees{Inlinees.begin(), Inlinees.end()};
llvm::sort(SortedInlinees);

uint64_t CurrentIndex = 0;
while (CurrentIndex < SortedInlinees.size()) {
auto Symbol = beginSymbolRecord(SymbolKind::S_INLINEES);
auto CurrentChunkSize =
std::min(ChunkSize, SortedInlinees.size() - CurrentIndex);
OS.AddComment("Count");
OS.emitInt32(CurrentChunkSize);

const uint64_t CurrentChunkEnd = CurrentIndex + CurrentChunkSize;
for (; CurrentIndex < CurrentChunkEnd; ++CurrentIndex) {
OS.AddComment("Inlinee");
OS.emitInt32(SortedInlinees[CurrentIndex].getIndex());
}
endSymbolRecord(Symbol);
}
}
6 changes: 6 additions & 0 deletions llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/DbgEntityHistoryCalculator.h"
#include "llvm/CodeGen/DebugHandlerBase.h"
Expand Down Expand Up @@ -158,6 +159,9 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase {
/// Ordered list of top-level inlined call sites.
SmallVector<const DILocation *, 1> ChildSites;

/// Set of all functions directly inlined into this one.
SmallSet<codeview::TypeIndex, 1> Inlinees;

SmallVector<LocalVariable, 1> Locals;
SmallVector<CVGlobalVariable, 1> Globals;

Expand Down Expand Up @@ -371,6 +375,8 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase {
void emitInlinedCallSite(const FunctionInfo &FI, const DILocation *InlinedAt,
const InlineSite &Site);

void emitInlinees(const SmallSet<codeview::TypeIndex, 1> &Inlinees);

using InlinedEntity = DbgValueHistoryMap::InlinedEntity;

void collectGlobalVariableInfo();
Expand Down
17 changes: 16 additions & 1 deletion llvm/lib/DebugInfo/CodeView/SymbolDumper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -589,7 +589,22 @@ Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
}

Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, CallerSym &Caller) {
ListScope S(W, CVR.kind() == S_CALLEES ? "Callees" : "Callers");
llvm::StringRef ScopeName;
switch (CVR.kind()) {
case S_CALLEES:
ScopeName = "Callees";
break;
case S_CALLERS:
ScopeName = "Callers";
break;
case S_INLINEES:
ScopeName = "Inlinees";
break;
default:
return llvm::make_error<CodeViewError>(
"Unknown CV Record type for a CallerSym object!");
}
ListScope S(W, ScopeName);
for (auto FuncID : Caller.Indices)
printTypeIndex("FuncID", FuncID);
return Error::success();
Expand Down
25 changes: 25 additions & 0 deletions llvm/lib/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1705,6 +1705,31 @@ Error LVSymbolVisitor::visitKnownRecord(CVSymbol &CVR,
return Error::success();
}

// S_CALLERS, S_CALLEES, S_INLINEES
Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record, CallerSym &Caller) {
LLVM_DEBUG({
llvm::StringRef FieldName;
switch (Caller.getKind()) {
case SymbolRecordKind::CallerSym:
FieldName = "Callee";
break;
case SymbolRecordKind::CalleeSym:
FieldName = "Caller";
break;
case SymbolRecordKind::InlineesSym:
FieldName = "Inlinee";
break;
default:
return llvm::make_error<CodeViewError>(
"Unknown CV Record type for a CallerSym object!");
}
for (auto FuncID : Caller.Indices) {
printTypeIndex(FieldName, FuncID);
}
});
return Error::success();
}

#undef DEBUG_TYPE
#define DEBUG_TYPE "CodeViewLogicalVisitor"

Expand Down
6 changes: 6 additions & 0 deletions llvm/test/DebugInfo/COFF/inlining-files.ll
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@
; OBJ: {{.*}}Proc{{.*}}Sym {
; OBJ: DisplayName: f
; OBJ: }
; OBJ: InlineesSym {
; OBJ-NEXT: Kind: S_INLINEES (0x1168)
; OBJ-NEXT: Inlinees [
; OBJ-NEXT: FuncID: file_change (0x1002)
; OBJ-NEXT: ]
; OBJ-NEXT:}
; OBJ: InlineSiteSym {
; OBJ: PtrParent: 0x0
; OBJ: PtrEnd: 0x0
Expand Down
7 changes: 7 additions & 0 deletions llvm/test/DebugInfo/COFF/inlining-header.ll
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,13 @@
; OBJ: LinkageName: _main
; OBJ: }

; OBJ: InlineesSym {
; OBJ-NEXT: Kind: S_INLINEES (0x1168)
; OBJ-NEXT: Inlinees [
; OBJ-NEXT: FuncID: g (0x1002)
; OBJ-NEXT: ]
; OBJ-NEXT: }

; Previously, g's InlineSiteSym referenced t.h, which was wasteful.
; OBJ: InlineSiteSym {
; OBJ: Inlinee: g (0x1002)
Expand Down
6 changes: 6 additions & 0 deletions llvm/test/DebugInfo/COFF/inlining-levels.ll
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@
; OBJ: Subsection [
; OBJ: SubSectionType: Symbols (0xF1)
; OBJ: {{.*}}Proc{{.*}}Sym {
; OBJ: InlineesSym {
; OBJ-NEXT: Kind: S_INLINEES (0x1168)
; OBJ-NEXT: Inlinees [
; OBJ-NEXT: FuncID: h (0x1002)
; OBJ-NEXT: ]
; OBJ-NEXT:}
; OBJ: InlineSiteSym {
; OBJ: Inlinee: h (0x1002)
; OBJ: }
Expand Down
9 changes: 9 additions & 0 deletions llvm/test/DebugInfo/COFF/inlining-padding.ll
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,15 @@
; CHECK: )
; CHECK: }

; CHECK: InlineesSym {
; CHECK-NEXT: Kind: S_INLINEES (0x1168)
; CHECK-NEXT: Inlinees [
; CHECK-NEXT: FuncID: a (0x1002)
; CHECK-NEXT: FuncID: ab (0x1003)
; CHECK-NEXT: FuncID: abc (0x1004)
; CHECK-NEXT: FuncID: abcd (0x1005)
; CHECK-NEXT: ]

; C++ source used to generate the IR:
;
; extern volatile int x;
Expand Down
6 changes: 6 additions & 0 deletions llvm/test/DebugInfo/COFF/inlining-same-name.ll
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@
; CHECK: {{.*}}Proc{{.*}}Sym {
; CHECK: DisplayName: main
; CHECK: }
; CHECK: InlineesSym {
; CHECK-NEXT: Kind: S_INLINEES (0x1168)
; CHECK-NEXT: Inlinees [
; CHECK-NEXT: FuncID: same_name (0x1002)
; CHECK-NEXT: ]
; CHECK-NEXT:}
; CHECK: InlineSiteSym {
; CHECK: Inlinee: same_name (0x1002)
; CHECK: }
Expand Down
6 changes: 6 additions & 0 deletions llvm/test/DebugInfo/COFF/inlining.ll
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,12 @@
; OBJ: DisplayName: baz
; OBJ: LinkageName: ?baz@@YAXXZ
; OBJ: }
; OBJ: InlineesSym {
; OBJ-NEXT: Kind: S_INLINEES (0x1168)
; OBJ-NEXT: Inlinees [
; OBJ-NEXT: FuncID: bar (0x1002)
; OBJ-NEXT: ]
; OBJ-NEXT:}
; OBJ: InlineSiteSym {
; OBJ: PtrParent: 0x0
; OBJ: PtrEnd: 0x0
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/tools/llvm-readobj/COFF/codeview-inlinees.test
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ CHECK: Kind: S_INLINESITE (0x114D)
CHECK: Inlinee: f (0x1003)
CHECK: InlineesSym {
CHECK-NEXT: Kind: S_INLINEES (0x1168)
CHECK-NEXT: Callers [
CHECK-NEXT: Inlinees [
CHECK-NEXT: FuncID: f (0x1003)
CHECK-NEXT: FuncID: h (0x1004)
CHECK-NEXT: ]
Expand Down
17 changes: 16 additions & 1 deletion llvm/tools/llvm-pdbutil/MinimalSymbolDumper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -875,9 +875,24 @@ Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
}

Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, CallerSym &Caller) {
const char *Format;
switch (CVR.kind()) {
case S_CALLEES:
Format = "callee: {0}";
break;
case S_CALLERS:
Format = "caller: {0}";
break;
case S_INLINEES:
Format = "inlinee: {0}";
break;
default:
return llvm::make_error<CodeViewError>(
"Unknown CV Record type for a CallerSym object!");
}
AutoIndent Indent(P, 7);
for (const auto &I : Caller.Indices) {
P.formatLine("callee: {0}", idIndex(I));
P.formatLine(Format, idIndex(I));
}
return Error::success();
}
Expand Down