[PATCH] D55239: [codeview] Emit typedefs of types derived from incomplete types
Reid Kleckner via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Mon Dec 3 15:39:46 PST 2018
rnk created this revision.
rnk added reviewers: zturner, aganea.
Herald added a subscriber: hiraditya.
The last time we evaluated this behavior was in r311904, which had this
message:
S_UDT symbols are the debugger's "index" for all the structs,
typedefs, classes, and enums in a program. If any of those
structs/classes don't have a complete declaration, or if there is a
typedef to something that doesn't have a complete definition, then
emitting the S_UDT is unhelpful because it doesn't give the debugger
enough information to do anything useful. On the other hand, it
results in a huge size blow-up in the resulting PDB, which is
exacerbated by an order of magnitude when linking with
/DEBUG:FASTLINK.
With this patch, we drop S_UDT records for types that refer either
directly or indirectly (e.g. through a typedef, pointer, etc) to a
class/struct/union/enum without a complete definition. This brings us
about 50% of the way towards parity with /DEBUG:FASTLINK PDBs
generated from cl-compiled object files.
This modifies LLVM so that we only discard S_UDTs pointing directly to
incomplete types, but keep S_UDTs that indirectly use incomplete types,
as in the following C++ fragment:
struct Opaque;
typedef Opaque *OpaqueHandle;
OpaqueHandle gv;
If we don't emit the OpaqueHandle typedef in this TU, it's possible that
no TU will emit the typedef. On the other hand, this could considerably
increase object file size, so we should keep an eye on that.
https://reviews.llvm.org/D55239
Files:
llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
llvm/test/DebugInfo/COFF/udts-fwd.ll
Index: llvm/test/DebugInfo/COFF/udts-fwd.ll
===================================================================
--- /dev/null
+++ llvm/test/DebugInfo/COFF/udts-fwd.ll
@@ -0,0 +1,49 @@
+; RUN: llc -filetype=obj %s -o %t.obj
+; RUN: llvm-pdbutil dump -symbols %t.obj | FileCheck %s
+
+; Foo is forward declared here. Check that we emit the typedef for the pointer,
+; but not for the incomplete type. We adopted this behavior to make
+; /debug:fastlink more efficient, but it's not clear if it's still the right
+; behavior. This test just encodes it.
+
+; C++ source:
+; struct Foo;
+; typedef Foo TypedefFwd;
+; typedef TypedefFwd *TypedefFwdPtr;
+; TypedefFwdPtr global_ptr;
+
+; CHECK: Symbols
+; CHECK-NEXT: ============================================================
+; CHECK-NOT: S_UDT {{.*}} `TypedefFwd`
+; CHECK: S_UDT [size = {{.*}}] `TypedefFwdPtr`
+; CHECK-NOT: S_UDT {{.*}} `TypedefFwd`
+
+
+; ModuleID = 't.cpp'
+source_filename = "t.cpp"
+target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-pc-windows-msvc19.14.26433"
+
+%struct.Foo = type opaque
+
+@"?global_ptr@@3PEAUFoo@@EA" = dso_local global %struct.Foo* null, align 8, !dbg !0
+
+!llvm.dbg.cu = !{!2}
+!llvm.module.flags = !{!10, !11, !12, !13}
+!llvm.ident = !{!14}
+
+!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
+!1 = distinct !DIGlobalVariable(name: "global_ptr", linkageName: "?global_ptr@@3PEAUFoo@@EA", scope: !2, file: !3, line: 4, type: !6, isLocal: false, isDefinition: true)
+!2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !3, producer: "clang version 8.0.0 ", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None)
+!3 = !DIFile(filename: "t.cpp", directory: "C:\5Csrc\5Cllvm-project\5Cbuild", checksumkind: CSK_MD5, checksum: "eda0a32edcbd7e1d7b0220b9ef0192c7")
+!4 = !{}
+!5 = !{!0}
+!6 = !DIDerivedType(tag: DW_TAG_typedef, name: "TypedefFwdPtr", file: !3, line: 3, baseType: !7)
+!7 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !8, size: 64)
+!8 = !DIDerivedType(tag: DW_TAG_typedef, name: "TypedefFwd", file: !3, line: 2, baseType: !9)
+!9 = !DICompositeType(tag: DW_TAG_structure_type, name: "Foo", file: !3, line: 1, flags: DIFlagFwdDecl, identifier: ".?AUFoo@@")
+!10 = !{i32 2, !"CodeView", i32 1}
+!11 = !{i32 2, !"Debug Info Version", i32 3}
+!12 = !{i32 1, !"wchar_size", i32 2}
+!13 = !{i32 7, !"PIC Level", i32 2}
+!14 = !{!"clang version 8.0.0 "}
Index: llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
===================================================================
--- llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
+++ llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
@@ -1439,15 +1439,14 @@
}
}
- while (true) {
- if (!T || T->isForwardDecl())
- return false;
+ // Look through nested typedefs.
+ while (T->getTag() == dwarf::DW_TAG_typedef)
+ T = cast<DIDerivedType>(T)->getBaseType().resolve();
+
+ // Don't emit a UDT if we only have a forward declaration.
+ if (T && T->isForwardDecl())
+ return false;
- const DIDerivedType *DT = dyn_cast<DIDerivedType>(T);
- if (!DT)
- return true;
- T = DT->getBaseType().resolve();
- }
return true;
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D55239.176502.patch
Type: text/x-patch
Size: 3266 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20181203/950ca685/attachment.bin>
More information about the llvm-commits
mailing list