llvm.org GIT mirror llvm / b8b70e1
Debug Info: remove duplication of DIEs when a DIE can be shared across CUs. We add a map in DwarfDebug to map MDNodes that are shareable across CUs to the corresponding DIEs: MDTypeNodeToDieMap. These DIEs can be shared across CUs, that is why we keep the maps in DwarfDebug instead of CompileUnit. We make the assumption that if a DIE is not added to an owner yet, we assume it belongs to the current CU. Since DIEs for the type system are added to their owners immediately after creation, and other DIEs belong to the current CU, the assumption should be true. A testing case is added to show that we only create a single DIE for a type MDNode and we use ref_addr to refer to the type DIE. We also add a testing case to show ref_addr relocations for non-darwin platforms. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@193779 91177308-0d34-0410-b5e6-96231b3b80d8 Manman Ren 6 years ago
10 changed file(s) with 188 addition(s) and 16 deletion(s). Raw diff Collapse all Expand all
114114 /// Climb up the parent chain to get the compile unit DIE to which this DIE
115115 /// belongs.
116116 const DIE *DIE::getCompileUnit() const {
117 const DIE *Cu = getCompileUnitOrNull();
118 assert(Cu && "We should not have orphaned DIEs.");
119 return Cu;
120 }
121
122 /// Climb up the parent chain to get the compile unit DIE this DIE belongs
123 /// to. Return NULL if DIE is not added to an owner yet.
124 const DIE *DIE::getCompileUnitOrNull() const {
117125 const DIE *p = this;
118126 while (p) {
119127 if (p->getTag() == dwarf::DW_TAG_compile_unit)
120128 return p;
121129 p = p->getParent();
122130 }
123 llvm_unreachable("We should not have orphaned DIEs.");
131 return NULL;
124132 }
125133
126134 DIEValue *DIE::findAttribute(uint16_t Attribute) {
148148 /// Climb up the parent chain to get the compile unit DIE this DIE belongs
149149 /// to.
150150 const DIE *getCompileUnit() const;
151 /// Similar to getCompileUnit, returns null when DIE is not added to an
152 /// owner yet.
153 const DIE *getCompileUnitOrNull() const;
151154 void setOffset(unsigned O) { Offset = O; }
152155 void setSize(unsigned S) { Size = S; }
153156
9595 }
9696
9797 return -1;
98 }
99
100 /// Check whether the DIE for this MDNode can be shared across CUs.
101 static bool isShareableAcrossCUs(const MDNode *N) {
102 // When the MDNode can be part of the type system, the DIE can be
103 // shared across CUs.
104 return DIDescriptor(N).isType() ||
105 (DIDescriptor(N).isSubprogram() && !DISubprogram(N).isDefinition());
106 }
107
108 /// getDIE - Returns the debug information entry map slot for the
109 /// specified debug variable. We delegate the request to DwarfDebug
110 /// when the DIE for this MDNode can be shared across CUs. The mappings
111 /// will be kept in DwarfDebug for shareable DIEs.
112 DIE *CompileUnit::getDIE(const MDNode *N) const {
113 if (isShareableAcrossCUs(N))
114 return DD->getDIE(N);
115 return MDNodeToDieMap.lookup(N);
116 }
117
118 /// insertDIE - Insert DIE into the map. We delegate the request to DwarfDebug
119 /// when the DIE for this MDNode can be shared across CUs. The mappings
120 /// will be kept in DwarfDebug for shareable DIEs.
121 void CompileUnit::insertDIE(const MDNode *N, DIE *D) {
122 if (isShareableAcrossCUs(N)) {
123 DD->insertDIE(N, D);
124 return;
125 }
126 MDNodeToDieMap.insert(std::make_pair(N, D));
98127 }
99128
100129 /// addFlag - Add a flag that is true.
244273 /// addDIEEntry - Add a DIE attribute data and value.
245274 ///
246275 void CompileUnit::addDIEEntry(DIE *Die, dwarf::Attribute Attribute, DIE *Entry) {
247 // We currently only use ref4.
248 Die->addValue(Attribute, dwarf::DW_FORM_ref4, createDIEEntry(Entry));
276 addDIEEntry(Die, Attribute, createDIEEntry(Entry));
277 }
278
279 void CompileUnit::addDIEEntry(DIE *Die, dwarf::Attribute Attribute,
280 DIEEntry *Entry) {
281 const DIE *DieCU = Die->getCompileUnitOrNull();
282 const DIE *EntryCU = Entry->getEntry()->getCompileUnitOrNull();
283 if (!DieCU)
284 // We assume that Die belongs to this CU, if it is not linked to any CU yet.
285 DieCU = getCUDie();
286 if (!EntryCU)
287 EntryCU = getCUDie();
288 Die->addValue(Attribute, EntryCU == DieCU ? dwarf::DW_FORM_ref4
289 : dwarf::DW_FORM_ref_addr,
290 Entry);
249291 }
250292
251293 /// Create a DIE with the given Tag, add the DIE to its parent, and
881923 DIEEntry *Entry = getDIEEntry(Ty);
882924 // If it exists then use the existing value.
883925 if (Entry) {
884 Entity->addValue(Attribute, dwarf::DW_FORM_ref4, Entry);
926 addDIEEntry(Entity, Attribute, Entry);
885927 return;
886928 }
887929
891933 // Set up proxy.
892934 Entry = createDIEEntry(Buffer);
893935 insertDIEEntry(Ty, Entry);
894 Entity->addValue(Attribute, dwarf::DW_FORM_ref4, Entry);
936 addDIEEntry(Entity, Attribute, Entry);
895937
896938 // If this is a complete composite type then include it in the
897939 // list of global types.
154154 void addAccelType(StringRef Name, std::pair Die);
155155
156156 /// getDIE - Returns the debug information entry map slot for the
157 /// specified debug variable.
158 DIE *getDIE(const MDNode *N) const { return MDNodeToDieMap.lookup(N); }
157 /// specified debug variable. We delegate the request to DwarfDebug
158 /// when the MDNode can be part of the type system, since DIEs for
159 /// the type system can be shared across CUs and the mappings are
160 /// kept in DwarfDebug.
161 DIE *getDIE(const MDNode *N) const;
159162
160163 DIEBlock *getDIEBlock() { return new (DIEValueAllocator) DIEBlock(); }
161164
162 /// insertDIE - Insert DIE into the map.
163 void insertDIE(const MDNode *N, DIE *D) {
164 MDNodeToDieMap.insert(std::make_pair(N, D));
165 }
165 /// insertDIE - Insert DIE into the map. We delegate the request to DwarfDebug
166 /// when the MDNode can be part of the type system, since DIEs for
167 /// the type system can be shared across CUs and the mappings are
168 /// kept in DwarfDebug.
169 void insertDIE(const MDNode *N, DIE *D);
166170
167171 /// addDie - Adds or interns the DIE to the compile unit.
168172 ///
222226 /// addDIEEntry - Add a DIE attribute data and value.
223227 ///
224228 void addDIEEntry(DIE *Die, dwarf::Attribute Attribute, DIE *Entry);
229
230 /// addDIEEntry - Add a DIE attribute data and value.
231 ///
232 void addDIEEntry(DIE *Die, dwarf::Attribute Attribute, DIEEntry *Entry);
225233
226234 /// addBlock - Add block data.
227235 ///
20822082 DwarfInfoSectionSym,
20832083 DIEEntry::getRefAddrSize(Asm));
20842084 } else {
2085 // Make sure Origin belong to the same CU.
2086 assert(Die->getCompileUnit() == Origin->getCompileUnit() &&
2087 "The referenced DIE should belong to the same CU in ref4");
20852088 Asm->EmitInt32(Addr);
20862089 }
20872090 break;
331331 // Maps a CU DIE with its corresponding CompileUnit.
332332 DenseMap CUDieMap;
333333
334 /// Maps MDNodes for type sysstem with the corresponding DIEs. These DIEs can
335 /// be shared across CUs, that is why we keep the map here instead
336 /// of in CompileUnit.
337 DenseMap MDTypeNodeToDieMap;
338
334339 // Used to uniquely define abbreviations.
335340 FoldingSet AbbreviationsSet;
336341
661666 //
662667 DwarfDebug(AsmPrinter *A, Module *M);
663668
669 void insertDIE(const MDNode *TypeMD, DIE *Die) {
670 MDTypeNodeToDieMap.insert(std::make_pair(TypeMD, Die));
671 }
672 DIE *getDIE(const MDNode *TypeMD) {
673 return MDTypeNodeToDieMap.lookup(TypeMD);
674 }
675
664676 /// \brief Emit all Dwarf sections that should come prior to the
665677 /// content.
666678 void beginModule();
0 ; RUN: llc -filetype=asm -O0 -mtriple=x86_64-linux-gnu < %s | FileCheck %s
1 ; RUN: llc -filetype=obj -O0 %s -mtriple=x86_64-linux-gnu -o %t
2 ; RUN: llvm-dwarfdump %t | FileCheck %s -check-prefix=CHECK-DWARF
3
4 ; RUN: llc -filetype=obj %s -mtriple=x86_64-apple-darwin -o %t2
5 ; RUN: llvm-dwarfdump %t2 | FileCheck %s -check-prefix=DARWIN-DWARF
6
7 ; Testing case generated from:
8 ; clang++ tu1.cpp tu2.cpp -g -emit-llvm -c
9 ; llvm-link tu1.bc tu2.bc -o tu12.ll -S
10 ; cat hdr.h
11 ; struct foo {
12 ; };
13 ; cat tu1.cpp
14 ; #include "hdr.h"
15 ; foo f;
16 ; cat tu2.cpp
17 ; #include "hdr.h"
18 ; foo g;
19
20 ; Make sure we use relocation for ref_addr on non-darwin platforms.
21 ; CHECK: DW_TAG_compile_unit
22 ; CHECK: DW_TAG_variable
23 ; CHECK: .long [[TYPE:.*]] # DW_AT_type
24 ; CHECK: DW_TAG_structure_type
25 ; CHECK: debug_info_end0
26 ; CHECK: DW_TAG_compile_unit
27 ; CHECK-NOT: DW_TAG_structure_type
28 ; This variable's type is in the 1st CU.
29 ; CHECK: DW_TAG_variable
30 ; Make sure this is relocatable.
31 ; CHECK: .quad .Lsection_info+[[TYPE]] # DW_AT_type
32 ; CHECK-NOT: DW_TAG_structure_type
33 ; CHECK: debug_info_end1
34
35 ; CHECK-DWARF: DW_TAG_compile_unit
36 ; CHECK-DWARF: 0x[[ADDR:.*]]: DW_TAG_structure_type
37 ; CHECK-DWARF: DW_TAG_compile_unit
38 ; CHECK-DWARF: DW_TAG_variable
39 ; CHECK-DWARF: DW_AT_type [DW_FORM_ref_addr] {{.*}}[[ADDR]])
40
41 ; DARWIN-DWARF: DW_TAG_compile_unit
42 ; DARWIN-DWARF: 0x[[ADDR:.*]]: DW_TAG_structure_type
43 ; DARWIN-DWARF: DW_TAG_compile_unit
44 ; DARWIN-DWARF: DW_TAG_variable
45 ; DARWIN-DWARF: DW_AT_type [DW_FORM_ref_addr] {{.*}}[[ADDR]])
46
47 %struct.foo = type { i8 }
48
49 @f = global %struct.foo zeroinitializer, align 1
50 @g = global %struct.foo zeroinitializer, align 1
51
52 !llvm.dbg.cu = !{!0, !9}
53 !llvm.module.flags = !{!14}
54
55 !0 = metadata !{i32 786449, metadata !1, i32 4, metadata !"clang version 3.4 (trunk 191799)", i1 false, metadata !"", i32 0, metadata !2, metadata !3, metadata !2, metadata !6, metadata !2, metadata !""} ; [ DW_TAG_compile_unit ] [/Users/manmanren/test-Nov/type_unique_air/ref_addr/tu1.cpp] [DW_LANG_C_plus_plus]
56 !1 = metadata !{metadata !"tu1.cpp", metadata !"/Users/manmanren/test-Nov/type_unique_air/ref_addr"}
57 !2 = metadata !{i32 0}
58 !3 = metadata !{metadata !4}
59 !4 = metadata !{i32 786451, metadata !5, null, metadata !"foo", i32 1, i64 8, i64 8, i32 0, i32 0, null, metadata !2, i32 0, null, null, metadata !"_ZTS3foo"} ; [ DW_TAG_structure_type ] [foo] [line 1, size 8, align 8, offset 0] [def] [from ]
60 !5 = metadata !{metadata !"./hdr.h", metadata !"/Users/manmanren/test-Nov/type_unique_air/ref_addr"}
61 !6 = metadata !{metadata !7}
62 !7 = metadata !{i32 786484, i32 0, null, metadata !"f", metadata !"f", metadata !"", metadata !8, i32 2, metadata !4, i32 0, i32 1, %struct.foo* @f, null} ; [ DW_TAG_variable ] [f] [line 2] [def]
63 !8 = metadata !{i32 786473, metadata !1} ; [ DW_TAG_file_type ] [/Users/manmanren/test-Nov/type_unique_air/ref_addr/tu1.cpp]
64 !9 = metadata !{i32 786449, metadata !10, i32 4, metadata !"clang version 3.4 (trunk 191799)", i1 false, metadata !"", i32 0, metadata !2, metadata !3, metadata !2, metadata !11, metadata !2, metadata !""} ; [ DW_TAG_compile_unit ] [/Users/manmanren/test-Nov/type_unique_air/ref_addr/tu2.cpp] [DW_LANG_C_plus_plus]
65 !10 = metadata !{metadata !"tu2.cpp", metadata !"/Users/manmanren/test-Nov/type_unique_air/ref_addr"}
66 !11 = metadata !{metadata !12}
67 !12 = metadata !{i32 786484, i32 0, null, metadata !"g", metadata !"g", metadata !"", metadata !13, i32 2, metadata !4, i32 0, i32 1, %struct.foo* @g, null} ; [ DW_TAG_variable ] [g] [line 2] [def]
68 !13 = metadata !{i32 786473, metadata !10} ; [ DW_TAG_file_type ] [/Users/manmanren/test-Nov/type_unique_air/ref_addr/tu2.cpp]
69 !14 = metadata !{i32 2, metadata !"Dwarf Version", i32 2}
0 ; Make sure the backend generates a single DIE and uses ref_addr.
1 ; CHECK: 0x[[BASE:.*]]: DW_TAG_structure_type
2 ; CHECK-NEXT: DW_AT_name {{.*}} = "Base"
3 ; CHECK-NOT: DW_TAG_structure_type
4 ; CHECK: 0x[[INT:.*]]: DW_TAG_base_type
15 ; CHECK-NEXT: DW_AT_name {{.*}} = "int"
26 ; CHECK-NOT: DW_TAG_base_type
3 ; CHECK: 0x[[BASE:.*]]: DW_TAG_structure_type
4 ; CHECK-NEXT: DW_AT_name {{.*}} = "Base"
5 ; CHECK-NOT: DW_TAG_structure_type
7
8 ; CHECK: DW_TAG_compile_unit
69 ; CHECK: DW_TAG_formal_parameter
710 ; CHECK: DW_AT_type [DW_FORM_ref_addr] {{.*}}[[INT]])
811 ; CHECK: DW_TAG_variable
912 ; CHECK: DW_AT_type [DW_FORM_ref_addr] {{.*}}[[BASE]])
1013
14 ; Make sure llvm-link only generates a single copy of the struct.
1115 ; LINK: DW_TAG_structure_type
1216 ; LINK-NOT: DW_TAG_structure_type
1317
None ; RUN: llvm-link %s %p/type-unique-simple-b.ll -S -o - | FileCheck %s
0 ; REQUIRES: object-emission
11
2 ; CHECK: DW_TAG_structure_type
2 ; RUN: llvm-link %s %p/type-unique-simple-b.ll -S -o %t
3 ; RUN: cat %t | FileCheck %s -check-prefix=LINK
4 ; RUN: llc -filetype=obj -O0 < %t > %t2
5 ; RUN: llvm-dwarfdump -debug-dump=info %t2 | FileCheck %s
6
7 ; Make sure the backend generates a single DIE and uses ref_addr.
8 ; CHECK: 0x[[BASE:.*]]: DW_TAG_structure_type
9 ; CHECK-NEXT: DW_AT_name {{.*}} = "Base"
310 ; CHECK-NOT: DW_TAG_structure_type
11 ; CHECK: 0x[[INT:.*]]: DW_TAG_base_type
12 ; CHECK-NEXT: DW_AT_name {{.*}} = "int"
13 ; CHECK-NOT: DW_TAG_base_type
14
15 ; CHECK: DW_TAG_compile_unit
16 ; CHECK: DW_TAG_formal_parameter
17 ; CHECK: DW_AT_type [DW_FORM_ref_addr] {{.*}}[[INT]])
18 ; CHECK: DW_TAG_variable
19 ; CHECK: DW_AT_type [DW_FORM_ref_addr] {{.*}}[[BASE]])
20
21 ; Make sure llvm-link only generates a single copy of the struct.
22 ; LINK: DW_TAG_structure_type
23 ; LINK-NOT: DW_TAG_structure_type
424 ; Content of header files:
525 ; struct Base {
626 ; int a;
11
22 ; RUN: llvm-link %S/Inputs/type-unique-simple2-a.ll %S/Inputs/type-unique-simple2-b.ll -S -o %t
33 ; RUN: cat %t | FileCheck %S/Inputs/type-unique-simple2-a.ll -check-prefix=LINK
4 ; RUN: llc -filetype=obj -O0 < %t > %t2
5 ; RUN: llvm-dwarfdump -debug-dump=info %t2 | FileCheck %S/Inputs/type-unique-simple2-a.ll