Skip to content

Commit 050bb26

Browse files
authored
[llvm] Implement S_INLINEES debug symbol (#67490)
The `S_INLINEES` debug symbol is used to record all the functions that are directly inlined within the current function (nested inlining is ignored). This change implements support for emitting the `S_INLINEES` debug symbol in LLVM, and cleans up how the `S_INLINEES` and `S_CALLEES` debug symbols are dumped.
1 parent a82368c commit 050bb26

File tree

13 files changed

+138
-4
lines changed

13 files changed

+138
-4
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,7 @@ class LVSymbolVisitor final : public SymbolVisitorCallbacks {
226226
Error visitKnownRecord(CVSymbol &Record, UDTSym &UDT) override;
227227
Error visitKnownRecord(CVSymbol &Record, UsingNamespaceSym &UN) override;
228228
Error visitKnownRecord(CVSymbol &Record, JumpTableSym &JumpTable) override;
229+
Error visitKnownRecord(CVSymbol &Record, CallerSym &Caller) override;
229230
};
230231

231232
// Visitor for CodeView types and symbols to populate elements.

llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,10 @@ CodeViewDebug::getInlineSite(const DILocation *InlinedAt,
250250
InlinedAt->getLine(), InlinedAt->getColumn(), SMLoc());
251251
Site->Inlinee = Inlinee;
252252
InlinedSubprograms.insert(Inlinee);
253-
getFuncIdForSubprogram(Inlinee);
253+
auto InlineeIdx = getFuncIdForSubprogram(Inlinee);
254+
255+
if (InlinedAt->getInlinedAt() == nullptr)
256+
CurFn->Inlinees.insert(InlineeIdx);
254257
}
255258
return *Site;
256259
}
@@ -1194,6 +1197,7 @@ void CodeViewDebug::emitDebugInfoForFunction(const Function *GV,
11941197
OS.emitInt32(uint32_t(FI.FrameProcOpts));
11951198
endSymbolRecord(FrameProcEnd);
11961199

1200+
emitInlinees(FI.Inlinees);
11971201
emitLocalVariableList(FI, FI.Locals);
11981202
emitGlobalVariableList(FI.Globals);
11991203
emitLexicalBlockList(FI.ChildBlocks, FI);
@@ -3588,3 +3592,31 @@ void CodeViewDebug::emitDebugInfoForJumpTables(const FunctionInfo &FI) {
35883592
endSymbolRecord(JumpTableEnd);
35893593
}
35903594
}
3595+
3596+
void CodeViewDebug::emitInlinees(
3597+
const SmallSet<codeview::TypeIndex, 1> &Inlinees) {
3598+
// Divide the list of inlinees into chunks such that each chunk fits within
3599+
// one record.
3600+
constexpr auto ChunkSize =
3601+
(MaxRecordLength - sizeof(SymbolKind) - sizeof(uint32_t)) /
3602+
sizeof(uint32_t);
3603+
3604+
SmallVector<TypeIndex> SortedInlinees{Inlinees.begin(), Inlinees.end()};
3605+
llvm::sort(SortedInlinees);
3606+
3607+
uint64_t CurrentIndex = 0;
3608+
while (CurrentIndex < SortedInlinees.size()) {
3609+
auto Symbol = beginSymbolRecord(SymbolKind::S_INLINEES);
3610+
auto CurrentChunkSize =
3611+
std::min(ChunkSize, SortedInlinees.size() - CurrentIndex);
3612+
OS.AddComment("Count");
3613+
OS.emitInt32(CurrentChunkSize);
3614+
3615+
const uint64_t CurrentChunkEnd = CurrentIndex + CurrentChunkSize;
3616+
for (; CurrentIndex < CurrentChunkEnd; ++CurrentIndex) {
3617+
OS.AddComment("Inlinee");
3618+
OS.emitInt32(SortedInlinees[CurrentIndex].getIndex());
3619+
}
3620+
endSymbolRecord(Symbol);
3621+
}
3622+
}

llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "llvm/ADT/MapVector.h"
2121
#include "llvm/ADT/PointerUnion.h"
2222
#include "llvm/ADT/SetVector.h"
23+
#include "llvm/ADT/SmallSet.h"
2324
#include "llvm/ADT/SmallVector.h"
2425
#include "llvm/CodeGen/DbgEntityHistoryCalculator.h"
2526
#include "llvm/CodeGen/DebugHandlerBase.h"
@@ -158,6 +159,9 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase {
158159
/// Ordered list of top-level inlined call sites.
159160
SmallVector<const DILocation *, 1> ChildSites;
160161

162+
/// Set of all functions directly inlined into this one.
163+
SmallSet<codeview::TypeIndex, 1> Inlinees;
164+
161165
SmallVector<LocalVariable, 1> Locals;
162166
SmallVector<CVGlobalVariable, 1> Globals;
163167

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

378+
void emitInlinees(const SmallSet<codeview::TypeIndex, 1> &Inlinees);
379+
374380
using InlinedEntity = DbgValueHistoryMap::InlinedEntity;
375381

376382
void collectGlobalVariableInfo();

llvm/lib/DebugInfo/CodeView/SymbolDumper.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -589,7 +589,22 @@ Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
589589
}
590590

591591
Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, CallerSym &Caller) {
592-
ListScope S(W, CVR.kind() == S_CALLEES ? "Callees" : "Callers");
592+
llvm::StringRef ScopeName;
593+
switch (CVR.kind()) {
594+
case S_CALLEES:
595+
ScopeName = "Callees";
596+
break;
597+
case S_CALLERS:
598+
ScopeName = "Callers";
599+
break;
600+
case S_INLINEES:
601+
ScopeName = "Inlinees";
602+
break;
603+
default:
604+
return llvm::make_error<CodeViewError>(
605+
"Unknown CV Record type for a CallerSym object!");
606+
}
607+
ListScope S(W, ScopeName);
593608
for (auto FuncID : Caller.Indices)
594609
printTypeIndex("FuncID", FuncID);
595610
return Error::success();

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

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1705,6 +1705,31 @@ Error LVSymbolVisitor::visitKnownRecord(CVSymbol &CVR,
17051705
return Error::success();
17061706
}
17071707

1708+
// S_CALLERS, S_CALLEES, S_INLINEES
1709+
Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record, CallerSym &Caller) {
1710+
LLVM_DEBUG({
1711+
llvm::StringRef FieldName;
1712+
switch (Caller.getKind()) {
1713+
case SymbolRecordKind::CallerSym:
1714+
FieldName = "Callee";
1715+
break;
1716+
case SymbolRecordKind::CalleeSym:
1717+
FieldName = "Caller";
1718+
break;
1719+
case SymbolRecordKind::InlineesSym:
1720+
FieldName = "Inlinee";
1721+
break;
1722+
default:
1723+
return llvm::make_error<CodeViewError>(
1724+
"Unknown CV Record type for a CallerSym object!");
1725+
}
1726+
for (auto FuncID : Caller.Indices) {
1727+
printTypeIndex(FieldName, FuncID);
1728+
}
1729+
});
1730+
return Error::success();
1731+
}
1732+
17081733
#undef DEBUG_TYPE
17091734
#define DEBUG_TYPE "CodeViewLogicalVisitor"
17101735

llvm/test/DebugInfo/COFF/inlining-files.ll

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,12 @@
2121
; OBJ: {{.*}}Proc{{.*}}Sym {
2222
; OBJ: DisplayName: f
2323
; OBJ: }
24+
; OBJ: InlineesSym {
25+
; OBJ-NEXT: Kind: S_INLINEES (0x1168)
26+
; OBJ-NEXT: Inlinees [
27+
; OBJ-NEXT: FuncID: file_change (0x1002)
28+
; OBJ-NEXT: ]
29+
; OBJ-NEXT:}
2430
; OBJ: InlineSiteSym {
2531
; OBJ: PtrParent: 0x0
2632
; OBJ: PtrEnd: 0x0

llvm/test/DebugInfo/COFF/inlining-header.ll

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,13 @@
7575
; OBJ: LinkageName: _main
7676
; OBJ: }
7777

78+
; OBJ: InlineesSym {
79+
; OBJ-NEXT: Kind: S_INLINEES (0x1168)
80+
; OBJ-NEXT: Inlinees [
81+
; OBJ-NEXT: FuncID: g (0x1002)
82+
; OBJ-NEXT: ]
83+
; OBJ-NEXT: }
84+
7885
; Previously, g's InlineSiteSym referenced t.h, which was wasteful.
7986
; OBJ: InlineSiteSym {
8087
; OBJ: Inlinee: g (0x1002)

llvm/test/DebugInfo/COFF/inlining-levels.ll

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@
1919
; OBJ: Subsection [
2020
; OBJ: SubSectionType: Symbols (0xF1)
2121
; OBJ: {{.*}}Proc{{.*}}Sym {
22+
; OBJ: InlineesSym {
23+
; OBJ-NEXT: Kind: S_INLINEES (0x1168)
24+
; OBJ-NEXT: Inlinees [
25+
; OBJ-NEXT: FuncID: h (0x1002)
26+
; OBJ-NEXT: ]
27+
; OBJ-NEXT:}
2228
; OBJ: InlineSiteSym {
2329
; OBJ: Inlinee: h (0x1002)
2430
; OBJ: }

llvm/test/DebugInfo/COFF/inlining-padding.ll

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,15 @@
3333
; CHECK: )
3434
; CHECK: }
3535

36+
; CHECK: InlineesSym {
37+
; CHECK-NEXT: Kind: S_INLINEES (0x1168)
38+
; CHECK-NEXT: Inlinees [
39+
; CHECK-NEXT: FuncID: a (0x1002)
40+
; CHECK-NEXT: FuncID: ab (0x1003)
41+
; CHECK-NEXT: FuncID: abc (0x1004)
42+
; CHECK-NEXT: FuncID: abcd (0x1005)
43+
; CHECK-NEXT: ]
44+
3645
; C++ source used to generate the IR:
3746
;
3847
; extern volatile int x;

llvm/test/DebugInfo/COFF/inlining-same-name.ll

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@
1818
; CHECK: {{.*}}Proc{{.*}}Sym {
1919
; CHECK: DisplayName: main
2020
; CHECK: }
21+
; CHECK: InlineesSym {
22+
; CHECK-NEXT: Kind: S_INLINEES (0x1168)
23+
; CHECK-NEXT: Inlinees [
24+
; CHECK-NEXT: FuncID: same_name (0x1002)
25+
; CHECK-NEXT: ]
26+
; CHECK-NEXT:}
2127
; CHECK: InlineSiteSym {
2228
; CHECK: Inlinee: same_name (0x1002)
2329
; CHECK: }

llvm/test/DebugInfo/COFF/inlining.ll

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,12 @@
166166
; OBJ: DisplayName: baz
167167
; OBJ: LinkageName: ?baz@@YAXXZ
168168
; OBJ: }
169+
; OBJ: InlineesSym {
170+
; OBJ-NEXT: Kind: S_INLINEES (0x1168)
171+
; OBJ-NEXT: Inlinees [
172+
; OBJ-NEXT: FuncID: bar (0x1002)
173+
; OBJ-NEXT: ]
174+
; OBJ-NEXT:}
169175
; OBJ: InlineSiteSym {
170176
; OBJ: PtrParent: 0x0
171177
; OBJ: PtrEnd: 0x0

llvm/test/tools/llvm-readobj/COFF/codeview-inlinees.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ CHECK: Kind: S_INLINESITE (0x114D)
2828
CHECK: Inlinee: f (0x1003)
2929
CHECK: InlineesSym {
3030
CHECK-NEXT: Kind: S_INLINEES (0x1168)
31-
CHECK-NEXT: Callers [
31+
CHECK-NEXT: Inlinees [
3232
CHECK-NEXT: FuncID: f (0x1003)
3333
CHECK-NEXT: FuncID: h (0x1004)
3434
CHECK-NEXT: ]

llvm/tools/llvm-pdbutil/MinimalSymbolDumper.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -875,9 +875,24 @@ Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
875875
}
876876

877877
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, CallerSym &Caller) {
878+
const char *Format;
879+
switch (CVR.kind()) {
880+
case S_CALLEES:
881+
Format = "callee: {0}";
882+
break;
883+
case S_CALLERS:
884+
Format = "caller: {0}";
885+
break;
886+
case S_INLINEES:
887+
Format = "inlinee: {0}";
888+
break;
889+
default:
890+
return llvm::make_error<CodeViewError>(
891+
"Unknown CV Record type for a CallerSym object!");
892+
}
878893
AutoIndent Indent(P, 7);
879894
for (const auto &I : Caller.Indices) {
880-
P.formatLine("callee: {0}", idIndex(I));
895+
P.formatLine(Format, idIndex(I));
881896
}
882897
return Error::success();
883898
}

0 commit comments

Comments
 (0)