[llvm] 050bb26 - [llvm] Implement S_INLINEES debug symbol (#67490)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 27 14:06:29 PDT 2023
Author: Daniel Paoliello
Date: 2023-09-27T14:06:22-07:00
New Revision: 050bb26174cd9eb60c3c192476091494604f9a5d
URL: https://github.com/llvm/llvm-project/commit/050bb26174cd9eb60c3c192476091494604f9a5d
DIFF: https://github.com/llvm/llvm-project/commit/050bb26174cd9eb60c3c192476091494604f9a5d.diff
LOG: [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.
Added:
Modified:
llvm/include/llvm/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.h
llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h
llvm/lib/DebugInfo/CodeView/SymbolDumper.cpp
llvm/lib/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.cpp
llvm/test/DebugInfo/COFF/inlining-files.ll
llvm/test/DebugInfo/COFF/inlining-header.ll
llvm/test/DebugInfo/COFF/inlining-levels.ll
llvm/test/DebugInfo/COFF/inlining-padding.ll
llvm/test/DebugInfo/COFF/inlining-same-name.ll
llvm/test/DebugInfo/COFF/inlining.ll
llvm/test/tools/llvm-readobj/COFF/codeview-inlinees.test
llvm/tools/llvm-pdbutil/MinimalSymbolDumper.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.h b/llvm/include/llvm/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.h
index e371fecff1234e2..6271c7b8b2c5bd6 100644
--- a/llvm/include/llvm/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.h
+++ b/llvm/include/llvm/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.h
@@ -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.
diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
index b25a38b26344138..335eccb106519ca 100644
--- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
@@ -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;
}
@@ -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);
@@ -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);
+ }
+}
diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h
index eb274d25de9197a..4c03bf79d04da75 100644
--- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h
+++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h
@@ -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"
@@ -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;
@@ -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();
diff --git a/llvm/lib/DebugInfo/CodeView/SymbolDumper.cpp b/llvm/lib/DebugInfo/CodeView/SymbolDumper.cpp
index c86fb244f6887b9..f56739db7c75f61 100644
--- a/llvm/lib/DebugInfo/CodeView/SymbolDumper.cpp
+++ b/llvm/lib/DebugInfo/CodeView/SymbolDumper.cpp
@@ -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();
diff --git a/llvm/lib/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.cpp b/llvm/lib/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.cpp
index fdb089c1a5f7160..5a6414f5564f8e6 100644
--- a/llvm/lib/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.cpp
+++ b/llvm/lib/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.cpp
@@ -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"
diff --git a/llvm/test/DebugInfo/COFF/inlining-files.ll b/llvm/test/DebugInfo/COFF/inlining-files.ll
index 9678219eca380ee..37edc6b8878a519 100644
--- a/llvm/test/DebugInfo/COFF/inlining-files.ll
+++ b/llvm/test/DebugInfo/COFF/inlining-files.ll
@@ -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
diff --git a/llvm/test/DebugInfo/COFF/inlining-header.ll b/llvm/test/DebugInfo/COFF/inlining-header.ll
index 0e990cbb0fccac6..9a8200ca9fc56d1 100644
--- a/llvm/test/DebugInfo/COFF/inlining-header.ll
+++ b/llvm/test/DebugInfo/COFF/inlining-header.ll
@@ -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)
diff --git a/llvm/test/DebugInfo/COFF/inlining-levels.ll b/llvm/test/DebugInfo/COFF/inlining-levels.ll
index 70195e5371f5f43..8af12512d2ab30d 100644
--- a/llvm/test/DebugInfo/COFF/inlining-levels.ll
+++ b/llvm/test/DebugInfo/COFF/inlining-levels.ll
@@ -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: }
diff --git a/llvm/test/DebugInfo/COFF/inlining-padding.ll b/llvm/test/DebugInfo/COFF/inlining-padding.ll
index afe899db310ccec..75254b3e9a7c604 100644
--- a/llvm/test/DebugInfo/COFF/inlining-padding.ll
+++ b/llvm/test/DebugInfo/COFF/inlining-padding.ll
@@ -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;
diff --git a/llvm/test/DebugInfo/COFF/inlining-same-name.ll b/llvm/test/DebugInfo/COFF/inlining-same-name.ll
index da3cabcb2bf8d82..374630b94ba4b61 100644
--- a/llvm/test/DebugInfo/COFF/inlining-same-name.ll
+++ b/llvm/test/DebugInfo/COFF/inlining-same-name.ll
@@ -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: }
diff --git a/llvm/test/DebugInfo/COFF/inlining.ll b/llvm/test/DebugInfo/COFF/inlining.ll
index d0b03cc5b21e3d3..6953abc87813a60 100644
--- a/llvm/test/DebugInfo/COFF/inlining.ll
+++ b/llvm/test/DebugInfo/COFF/inlining.ll
@@ -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
diff --git a/llvm/test/tools/llvm-readobj/COFF/codeview-inlinees.test b/llvm/test/tools/llvm-readobj/COFF/codeview-inlinees.test
index 9f818dfc289908a..f8720e35641a778 100644
--- a/llvm/test/tools/llvm-readobj/COFF/codeview-inlinees.test
+++ b/llvm/test/tools/llvm-readobj/COFF/codeview-inlinees.test
@@ -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: ]
diff --git a/llvm/tools/llvm-pdbutil/MinimalSymbolDumper.cpp b/llvm/tools/llvm-pdbutil/MinimalSymbolDumper.cpp
index 6b6ba48f9214d85..1beb2d2827441ea 100644
--- a/llvm/tools/llvm-pdbutil/MinimalSymbolDumper.cpp
+++ b/llvm/tools/llvm-pdbutil/MinimalSymbolDumper.cpp
@@ -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();
}
More information about the llvm-commits
mailing list