[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