diff options
| author | Zachary Turner <zturner@google.com> | 2017-08-28 18:49:04 +0000 |
|---|---|---|
| committer | Zachary Turner <zturner@google.com> | 2017-08-28 18:49:04 +0000 |
| commit | a7b041748d97ac0671e1d59233be0f9a7653ecd8 (patch) | |
| tree | e50a75ae75c4be9f0d0a0db62d8034ad4ab93f97 /llvm/test/DebugInfo/COFF | |
| parent | c35e4de38872a56e09b7f652e28d0103fa5eeef8 (diff) | |
| download | bcm5719-llvm-a7b041748d97ac0671e1d59233be0f9a7653ecd8.tar.gz bcm5719-llvm-a7b041748d97ac0671e1d59233be0f9a7653ecd8.zip | |
[CodeView] Don't output S_UDT symbols for forward decls.
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.
Differential Revision: https://reviews.llvm.org/D37162
llvm-svn: 311904
Diffstat (limited to 'llvm/test/DebugInfo/COFF')
| -rw-r--r-- | llvm/test/DebugInfo/COFF/purge-typedef-udts.ll | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/llvm/test/DebugInfo/COFF/purge-typedef-udts.ll b/llvm/test/DebugInfo/COFF/purge-typedef-udts.ll new file mode 100644 index 00000000000..28106d74e90 --- /dev/null +++ b/llvm/test/DebugInfo/COFF/purge-typedef-udts.ll @@ -0,0 +1,120 @@ +; RUN: llc < %s -filetype=obj | llvm-readobj - -codeview | FileCheck %s +source_filename = "test/DebugInfo/COFF/purge-typedef-udts.ll" +target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32" +target triple = "i686-pc-windows-msvc19.11.25506" + +; C++ source to regenerate: +; $ cat t.cpp +; struct Foo; +; struct Bar { +; Bar() {} +; int X; +; }; +; +; typedef Foo FooTypedef; +; typedef Bar BarTypedef; +; +; int func(void *F) { return 7; } +; int func(const FooTypedef *F) { return func((void*)F); } +; int func(const BarTypedef *B) { return func((void*)B->X); } + +; CHECK-NOT: UDTName: FooTypedef +; CHECK: UDTName: BarTypedef + +%struct.Foo = type opaque +%struct.Bar = type { i32 } + +; Function Attrs: noinline nounwind optnone +define i32 @"\01?func@@YAHPAX@Z"(i8* %F) #0 !dbg !10 { +entry: + %F.addr = alloca i8*, align 4 + store i8* %F, i8** %F.addr, align 4 + call void @llvm.dbg.declare(metadata i8** %F.addr, metadata !14, metadata !DIExpression()), !dbg !15 + ret i32 7, !dbg !16 +} + +; Function Attrs: nounwind readnone speculatable +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +; Function Attrs: noinline nounwind optnone +define i32 @"\01?func@@YAHPBUFoo@@@Z"(%struct.Foo* %F) #0 !dbg !17 { +entry: + %F.addr = alloca %struct.Foo*, align 4 + store %struct.Foo* %F, %struct.Foo** %F.addr, align 4 + call void @llvm.dbg.declare(metadata %struct.Foo** %F.addr, metadata !24, metadata !DIExpression()), !dbg !25 + %0 = load %struct.Foo*, %struct.Foo** %F.addr, align 4, !dbg !26 + %1 = bitcast %struct.Foo* %0 to i8*, !dbg !26 + %call = call i32 @"\01?func@@YAHPAX@Z"(i8* %1), !dbg !27 + ret i32 %call, !dbg !28 +} + +; Function Attrs: noinline nounwind optnone +define i32 @"\01?func@@YAHPBUBar@@@Z"(%struct.Bar* %B) #0 !dbg !29 { +entry: + %B.addr = alloca %struct.Bar*, align 4 + store %struct.Bar* %B, %struct.Bar** %B.addr, align 4 + call void @llvm.dbg.declare(metadata %struct.Bar** %B.addr, metadata !42, metadata !DIExpression()), !dbg !43 + %0 = load %struct.Bar*, %struct.Bar** %B.addr, align 4, !dbg !44 + %X = getelementptr inbounds %struct.Bar, %struct.Bar* %0, i32 0, i32 0, !dbg !45 + %1 = load i32, i32* %X, align 4, !dbg !45 + %2 = inttoptr i32 %1 to i8*, !dbg !46 + %call = call i32 @"\01?func@@YAHPAX@Z"(i8* %2), !dbg !47 + ret i32 %call, !dbg !48 +} + +attributes #0 = { noinline nounwind optnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="pentium4" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind readnone speculatable } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!5, !6, !7, !8} +!llvm.ident = !{!9} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 6.0.0 ", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !3) +!1 = !DIFile(filename: "t.cpp", directory: "D:\5Csrc\5Cllvmbuild\5Cninja", checksumkind: CSK_MD5, checksum: "27c44c8a5531845f61f582a24ef5c151") +!2 = !{} +!3 = !{!4} +!4 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 32) +!5 = !{i32 1, !"NumRegisterParameters", i32 0} +!6 = !{i32 2, !"CodeView", i32 1} +!7 = !{i32 2, !"Debug Info Version", i32 3} +!8 = !{i32 1, !"wchar_size", i32 2} +!9 = !{!"clang version 6.0.0 "} +!10 = distinct !DISubprogram(name: "func", linkageName: "\01?func@@YAHPAX@Z", scope: !1, file: !1, line: 10, type: !11, isLocal: false, isDefinition: true, scopeLine: 10, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2) +!11 = !DISubroutineType(types: !12) +!12 = !{!13, !4} +!13 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!14 = !DILocalVariable(name: "F", arg: 1, scope: !10, file: !1, line: 10, type: !4) +!15 = !DILocation(line: 10, column: 16, scope: !10) +!16 = !DILocation(line: 10, column: 21, scope: !10) +!17 = distinct !DISubprogram(name: "func", linkageName: "\01?func@@YAHPBUFoo@@@Z", scope: !1, file: !1, line: 11, type: !18, isLocal: false, isDefinition: true, scopeLine: 11, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2) +!18 = !DISubroutineType(types: !19) +!19 = !{!13, !20} +!20 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !21, size: 32) +!21 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !22) +!22 = !DIDerivedType(tag: DW_TAG_typedef, name: "FooTypedef", file: !1, line: 7, baseType: !23) +!23 = !DICompositeType(tag: DW_TAG_structure_type, name: "Foo", file: !1, line: 1, flags: DIFlagFwdDecl, identifier: ".?AUFoo@@") +!24 = !DILocalVariable(name: "F", arg: 1, scope: !17, file: !1, line: 11, type: !20) +!25 = !DILocation(line: 11, column: 28, scope: !17) +!26 = !DILocation(line: 11, column: 52, scope: !17) +!27 = !DILocation(line: 11, column: 40, scope: !17) +!28 = !DILocation(line: 11, column: 33, scope: !17) +!29 = distinct !DISubprogram(name: "func", linkageName: "\01?func@@YAHPBUBar@@@Z", scope: !1, file: !1, line: 12, type: !30, isLocal: false, isDefinition: true, scopeLine: 12, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2) +!30 = !DISubroutineType(types: !31) +!31 = !{!13, !32} +!32 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !33, size: 32) +!33 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !34) +!34 = !DIDerivedType(tag: DW_TAG_typedef, name: "BarTypedef", file: !1, line: 8, baseType: !35) +!35 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Bar", file: !1, line: 2, size: 32, elements: !36, identifier: ".?AUBar@@") +!36 = !{!37, !38} +!37 = !DIDerivedType(tag: DW_TAG_member, name: "X", scope: !35, file: !1, line: 4, baseType: !13, size: 32) +!38 = !DISubprogram(name: "Bar", scope: !35, file: !1, line: 3, type: !39, isLocal: false, isDefinition: false, scopeLine: 3, flags: DIFlagPrototyped, isOptimized: false) +!39 = !DISubroutineType(cc: DW_CC_BORLAND_thiscall, types: !40) +!40 = !{null, !41} +!41 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !35, size: 32, flags: DIFlagArtificial | DIFlagObjectPointer) +!42 = !DILocalVariable(name: "B", arg: 1, scope: !29, file: !1, line: 12, type: !32) +!43 = !DILocation(line: 12, column: 28, scope: !29) +!44 = !DILocation(line: 12, column: 52, scope: !29) +!45 = !DILocation(line: 12, column: 55, scope: !29) +!46 = !DILocation(line: 12, column: 45, scope: !29) +!47 = !DILocation(line: 12, column: 40, scope: !29) +!48 = !DILocation(line: 12, column: 33, scope: !29) |

