From 27a5ba120b35cfb180fb06115921145a8becddc1 Mon Sep 17 00:00:00 2001 From: Alexander Yermolovich Date: Mon, 6 Jan 2025 15:18:47 -0800 Subject: [PATCH 1/5] [LLVM][DWARF] Create debug names entry for non-tu top level DIE LLVM tries to create TU optimistically. If that fails it discards the TU state and creates TU wihin the CU. When this happens the entry in debug names table for top level DIE is not created. This causes llvm-dwarfdumjp --debug-names --verify to fail because an entry is missing. This patch adds a call to updateAcceleratorTables, when TU creation fails. --- llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 9 +- llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h | 3 +- llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp | 3 +- .../dwarf5-debug-names-addr-tu-to-non-tu.ll | 83 +++++++++++++++++++ 4 files changed, 92 insertions(+), 6 deletions(-) create mode 100644 llvm/test/DebugInfo/X86/dwarf5-debug-names-addr-tu-to-non-tu.ll diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index e1291e2a14a66..c88ca8c256bb7 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -3704,19 +3704,19 @@ uint64_t DwarfDebug::makeTypeSignature(StringRef Identifier) { return Result.high(); } -void DwarfDebug::addDwarfTypeUnitType(DwarfCompileUnit &CU, +bool DwarfDebug::addDwarfTypeUnitType(DwarfCompileUnit &CU, StringRef Identifier, DIE &RefDie, const DICompositeType *CTy) { // Fast path if we're building some type units and one has already used the // address pool we know we're going to throw away all this work anyway, so // don't bother building dependent types. if (!TypeUnitsUnderConstruction.empty() && AddrPool.hasBeenUsed()) - return; + return false; auto Ins = TypeSignatures.insert(std::make_pair(CTy, 0)); if (!Ins.second) { CU.addDIETypeSignature(RefDie, Ins.first->second); - return; + return false; } setCurrentDWARF5AccelTable(DWARF5AccelTableKind::TU); @@ -3789,7 +3789,7 @@ void DwarfDebug::addDwarfTypeUnitType(DwarfCompileUnit &CU, // they depend on addresses, throwing them out and rebuilding them. setCurrentDWARF5AccelTable(DWARF5AccelTableKind::CU); CU.constructTypeDIE(RefDie, cast(CTy)); - return; + return true; } // If the type wasn't dependent on fission addresses, finish adding the type @@ -3811,6 +3811,7 @@ void DwarfDebug::addDwarfTypeUnitType(DwarfCompileUnit &CU, setCurrentDWARF5AccelTable(DWARF5AccelTableKind::CU); } CU.addDIETypeSignature(RefDie, Signature); + return false; } // Add the Name along with its companion DIE to the appropriate accelerator diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h index 9662c617d730e..2bbd0805b1c4d 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -744,7 +744,8 @@ class DwarfDebug : public DebugHandlerBase { /// Add a DIE to the set of types that we're going to pull into /// type units. - void addDwarfTypeUnitType(DwarfCompileUnit &CU, StringRef Identifier, + /// Returns true if TU creation fails, and type was emitted in the CU. + bool addDwarfTypeUnitType(DwarfCompileUnit &CU, StringRef Identifier, DIE &Die, const DICompositeType *CTy); /// Add a label so that arange data can be generated for it. diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp index 0a8a1ad38c959..90ee8b21cb87f 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp @@ -589,7 +589,8 @@ DIE *DwarfUnit::createTypeDIE(const DIScope *Context, DIE &ContextDIE, // Skip updating the accelerator tables since this is not the full type. if (MDString *TypeId = CTy->getRawIdentifier()) { addGlobalType(Ty, TyDIE, Context); - DD->addDwarfTypeUnitType(getCU(), TypeId->getString(), TyDIE, CTy); + if (DD->addDwarfTypeUnitType(getCU(), TypeId->getString(), TyDIE, CTy)) + updateAcceleratorTables(Context, Ty, TyDIE); } else { updateAcceleratorTables(Context, Ty, TyDIE); finishNonUnitTypeDIE(TyDIE, CTy); diff --git a/llvm/test/DebugInfo/X86/dwarf5-debug-names-addr-tu-to-non-tu.ll b/llvm/test/DebugInfo/X86/dwarf5-debug-names-addr-tu-to-non-tu.ll new file mode 100644 index 0000000000000..a1a5b073f2a91 --- /dev/null +++ b/llvm/test/DebugInfo/X86/dwarf5-debug-names-addr-tu-to-non-tu.ll @@ -0,0 +1,83 @@ +; RUN: llc -filetype=obj -O0 -generate-type-units -mtriple=x86_64-unknown-linux-gnu < %s \ +; RUN: | llvm-dwarfdump -debug-info -debug-names - \ +; RUN: | FileCheck %s + +;; Test that an entry in the debug names table gets created for a top level DIE when the creation of TU is aborted. + +; CHECK: [[OFFSET:0x[0-9a-f]*]]: DW_TAG_structure_type +; CHECK: [[OFFSET1:0x[0-9a-f]*]]: DW_TAG_structure_type + +; CHECK: Bucket 0 [ +; CHECK-NEXT: Name 1 { +; CHECK-NEXT: Hash: {{.+}} +; CHECK-NEXT: String: {{.+}} "t3" +; CHECK-NEXT: Entry @ {{.+}} { +; CHECK-NEXT: Abbrev: 0x1 +; CHECK-NEXT: Tag: DW_TAG_structure_type +; CHECK-NEXT: DW_IDX_die_offset: [[OFFSET]] +; CHECK-NEXT: DW_IDX_parent: + +; CHECK: Name 5 { +; CHECK-NEXT: Hash: {{.+}} +; CHECK-NEXT: String: {{.+}} "t2<&foo>" +; CHECK-NEXT: Entry @ 0xe1 { +; CHECK-NEXT: Abbrev: 0x1 +; CHECK-NEXT: Tag: DW_TAG_structure_type +; CHECK-NEXT: DW_IDX_die_offset: [[OFFSET1]] +; CHECK-NEXT: DW_IDX_parent: + +;; clang++ -O0 main.cpp -gdwarf-5 -fdebug-types-section -gpubnames -S -emit-llvm -glldb -o main.ll +;; int foo; +;; namespace { +;; struct t1 {}; +;; } // namespace +;; template struct t2 { +;; t1 v1; +;; }; +;; struct t3 { +;; t2<&foo> v1; +;; }; +;; t3 v1; + +; ModuleID = 'main.cpp' +source_filename = "main.cpp" +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +%struct.t3 = type { i8 } + +@foo = dso_local global i32 0, align 4, !dbg !0 +@v1 = dso_local global %struct.t3 zeroinitializer, align 1, !dbg !5 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!20, !21, !22, !23, !24, !25, !26} +!llvm.ident = !{!27} + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "foo", scope: !2, file: !3, line: 1, type: !19, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !3, producer: "clang version 20.0.0git (git@github.com:llvm/llvm-project.git ba373096e8ac83a7136fc44bc4e71a7bc53417a6)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !4, splitDebugInlining: false, sysroot: "/") +!3 = !DIFile(filename: "main.cpp", directory: "/StructuredType", checksumkind: CSK_MD5, checksum: "f91f8d905197b1c0309da9526bc4776e") +!4 = !{!0, !5} +!5 = !DIGlobalVariableExpression(var: !6, expr: !DIExpression()) +!6 = distinct !DIGlobalVariable(name: "v1", scope: !2, file: !3, line: 11, type: !7, isLocal: false, isDefinition: true) +!7 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t3", file: !3, line: 8, size: 8, flags: DIFlagTypePassByValue, elements: !8, identifier: "_ZTS2t3") +!8 = !{!9} +!9 = !DIDerivedType(tag: DW_TAG_member, name: "v1", scope: !7, file: !3, line: 9, baseType: !10, size: 8) +!10 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t2<&foo>", file: !3, line: 5, size: 8, flags: DIFlagTypePassByValue, elements: !11, templateParams: !16, identifier: "_ZTS2t2IXadL_Z3fooEEE") +!11 = !{!12} +!12 = !DIDerivedType(tag: DW_TAG_member, name: "v1", scope: !10, file: !3, line: 6, baseType: !13, size: 8) +!13 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t1", scope: !14, file: !3, line: 3, size: 8, flags: DIFlagTypePassByValue, elements: !15) +!14 = !DINamespace(scope: null) +!15 = !{} +!16 = !{!17} +!17 = !DITemplateValueParameter(type: !18, value: ptr @foo) +!18 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !19, size: 64) +!19 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!20 = !{i32 7, !"Dwarf Version", i32 5} +!21 = !{i32 2, !"Debug Info Version", i32 3} +!22 = !{i32 1, !"wchar_size", i32 4} +!23 = !{i32 8, !"PIC Level", i32 2} +!24 = !{i32 7, !"PIE Level", i32 2} +!25 = !{i32 7, !"uwtable", i32 2} +!26 = !{i32 7, !"frame-pointer", i32 2} +!27 = !{!"clang version 20.0.0git (git@github.com:llvm/llvm-project.git ba373096e8ac83a7136fc44bc4e71a7bc53417a6)"} From b2b8301696892a669926329282424b65c13fc5c6 Mon Sep 17 00:00:00 2001 From: Alexander Yermolovich Date: Tue, 7 Jan 2025 12:31:51 -0800 Subject: [PATCH 2/5] moved call inside addDwarfTypeUnitType --- llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 11 ++++++----- llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h | 3 +-- llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp | 3 +-- llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h | 10 +++++----- 4 files changed, 13 insertions(+), 14 deletions(-) diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index c88ca8c256bb7..df43c0d067308 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -3704,19 +3704,19 @@ uint64_t DwarfDebug::makeTypeSignature(StringRef Identifier) { return Result.high(); } -bool DwarfDebug::addDwarfTypeUnitType(DwarfCompileUnit &CU, +void DwarfDebug::addDwarfTypeUnitType(DwarfCompileUnit &CU, StringRef Identifier, DIE &RefDie, const DICompositeType *CTy) { // Fast path if we're building some type units and one has already used the // address pool we know we're going to throw away all this work anyway, so // don't bother building dependent types. if (!TypeUnitsUnderConstruction.empty() && AddrPool.hasBeenUsed()) - return false; + return; auto Ins = TypeSignatures.insert(std::make_pair(CTy, 0)); if (!Ins.second) { CU.addDIETypeSignature(RefDie, Ins.first->second); - return false; + return; } setCurrentDWARF5AccelTable(DWARF5AccelTableKind::TU); @@ -3789,7 +3789,8 @@ bool DwarfDebug::addDwarfTypeUnitType(DwarfCompileUnit &CU, // they depend on addresses, throwing them out and rebuilding them. setCurrentDWARF5AccelTable(DWARF5AccelTableKind::CU); CU.constructTypeDIE(RefDie, cast(CTy)); - return true; + CU.updateAcceleratorTables(CTy->getScope(), CTy, RefDie); + return; } // If the type wasn't dependent on fission addresses, finish adding the type @@ -3811,7 +3812,7 @@ bool DwarfDebug::addDwarfTypeUnitType(DwarfCompileUnit &CU, setCurrentDWARF5AccelTable(DWARF5AccelTableKind::CU); } CU.addDIETypeSignature(RefDie, Signature); - return false; + return; } // Add the Name along with its companion DIE to the appropriate accelerator diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h index 2bbd0805b1c4d..9662c617d730e 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -744,8 +744,7 @@ class DwarfDebug : public DebugHandlerBase { /// Add a DIE to the set of types that we're going to pull into /// type units. - /// Returns true if TU creation fails, and type was emitted in the CU. - bool addDwarfTypeUnitType(DwarfCompileUnit &CU, StringRef Identifier, + void addDwarfTypeUnitType(DwarfCompileUnit &CU, StringRef Identifier, DIE &Die, const DICompositeType *CTy); /// Add a label so that arange data can be generated for it. diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp index 90ee8b21cb87f..0a8a1ad38c959 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp @@ -589,8 +589,7 @@ DIE *DwarfUnit::createTypeDIE(const DIScope *Context, DIE &ContextDIE, // Skip updating the accelerator tables since this is not the full type. if (MDString *TypeId = CTy->getRawIdentifier()) { addGlobalType(Ty, TyDIE, Context); - if (DD->addDwarfTypeUnitType(getCU(), TypeId->getString(), TyDIE, CTy)) - updateAcceleratorTables(Context, Ty, TyDIE); + DD->addDwarfTypeUnitType(getCU(), TypeId->getString(), TyDIE, CTy); } else { updateAcceleratorTables(Context, Ty, TyDIE); finishNonUnitTypeDIE(TyDIE, CTy); diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h index 02256546b6b80..163205378fb4b 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h @@ -315,6 +315,11 @@ class DwarfUnit : public DIEUnit { /// Get context owner's DIE. DIE *createTypeDIE(const DICompositeType *Ty); + /// If this is a named finished type then include it in the list of types for + /// the accelerator tables. + void updateAcceleratorTables(const DIScope *Context, const DIType *Ty, + const DIE &TyDIE); + protected: ~DwarfUnit(); @@ -357,11 +362,6 @@ class DwarfUnit : public DIEUnit { virtual void finishNonUnitTypeDIE(DIE& D, const DICompositeType *CTy) = 0; - /// If this is a named finished type then include it in the list of types for - /// the accelerator tables. - void updateAcceleratorTables(const DIScope *Context, const DIType *Ty, - const DIE &TyDIE); - virtual bool isDwoUnit() const = 0; const MCSymbol *getCrossSectionRelativeBaseAddress() const override; From a19159567d93a4c991b4c6bfcf67b8b8e4f9c7e7 Mon Sep 17 00:00:00 2001 From: Alexander Yermolovich Date: Tue, 7 Jan 2025 12:35:33 -0800 Subject: [PATCH 3/5] removed return --- llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index df43c0d067308..11de4b61797bd 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -3812,7 +3812,6 @@ void DwarfDebug::addDwarfTypeUnitType(DwarfCompileUnit &CU, setCurrentDWARF5AccelTable(DWARF5AccelTableKind::CU); } CU.addDIETypeSignature(RefDie, Signature); - return; } // Add the Name along with its companion DIE to the appropriate accelerator From e32c5d4747bbc8d1bb19e0047a87f113244fbf59 Mon Sep 17 00:00:00 2001 From: Alexander Yermolovich Date: Tue, 7 Jan 2025 14:48:40 -0800 Subject: [PATCH 4/5] moved repro/source code below test description --- .../dwarf5-debug-names-addr-tu-to-non-tu.ll | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/llvm/test/DebugInfo/X86/dwarf5-debug-names-addr-tu-to-non-tu.ll b/llvm/test/DebugInfo/X86/dwarf5-debug-names-addr-tu-to-non-tu.ll index a1a5b073f2a91..ada9d6dff24c5 100644 --- a/llvm/test/DebugInfo/X86/dwarf5-debug-names-addr-tu-to-non-tu.ll +++ b/llvm/test/DebugInfo/X86/dwarf5-debug-names-addr-tu-to-non-tu.ll @@ -4,6 +4,19 @@ ;; Test that an entry in the debug names table gets created for a top level DIE when the creation of TU is aborted. +;; clang++ -O0 main.cpp -gdwarf-5 -fdebug-types-section -gpubnames -S -emit-llvm -glldb -o main.ll +;; int foo; +;; namespace { +;; struct t1 {}; +;; } // namespace +;; template struct t2 { +;; t1 v1; +;; }; +;; struct t3 { +;; t2<&foo> v1; +;; }; +;; t3 v1; + ; CHECK: [[OFFSET:0x[0-9a-f]*]]: DW_TAG_structure_type ; CHECK: [[OFFSET1:0x[0-9a-f]*]]: DW_TAG_structure_type @@ -26,19 +39,6 @@ ; CHECK-NEXT: DW_IDX_die_offset: [[OFFSET1]] ; CHECK-NEXT: DW_IDX_parent: -;; clang++ -O0 main.cpp -gdwarf-5 -fdebug-types-section -gpubnames -S -emit-llvm -glldb -o main.ll -;; int foo; -;; namespace { -;; struct t1 {}; -;; } // namespace -;; template struct t2 { -;; t1 v1; -;; }; -;; struct t3 { -;; t2<&foo> v1; -;; }; -;; t3 v1; - ; ModuleID = 'main.cpp' source_filename = "main.cpp" target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" From dda7d6d22d9e14ad1869a393155d7b4f47f04e05 Mon Sep 17 00:00:00 2001 From: Alexander Yermolovich Date: Tue, 7 Jan 2025 14:49:35 -0800 Subject: [PATCH 5/5] changed test description --- llvm/test/DebugInfo/X86/dwarf5-debug-names-addr-tu-to-non-tu.ll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/test/DebugInfo/X86/dwarf5-debug-names-addr-tu-to-non-tu.ll b/llvm/test/DebugInfo/X86/dwarf5-debug-names-addr-tu-to-non-tu.ll index ada9d6dff24c5..a836b2a44e844 100644 --- a/llvm/test/DebugInfo/X86/dwarf5-debug-names-addr-tu-to-non-tu.ll +++ b/llvm/test/DebugInfo/X86/dwarf5-debug-names-addr-tu-to-non-tu.ll @@ -2,7 +2,7 @@ ; RUN: | llvm-dwarfdump -debug-info -debug-names - \ ; RUN: | FileCheck %s -;; Test that an entry in the debug names table gets created for a top level DIE when the creation of TU is aborted. +;; Test that an entry in the debug names table gets created for a top level DIE when the creation of TU fails. ;; clang++ -O0 main.cpp -gdwarf-5 -fdebug-types-section -gpubnames -S -emit-llvm -glldb -o main.ll ;; int foo;