Skip to content

Commit 9970817

Browse files
committedJun 11, 2019
Deduplicate S_CONSTANTs in LLD.
Summary: Deduplicate S_CONSTANTS when linking, if they have the same value. Reviewers: rnk Subscribers: hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D63151 llvm-svn: 363089
1 parent 36bd1c9 commit 9970817

File tree

4 files changed

+450
-4
lines changed

4 files changed

+450
-4
lines changed
 
Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
.text
2+
.def @feat.00;
3+
.scl 3;
4+
.type 0;
5+
.endef
6+
.globl @feat.00
7+
.set @feat.00, 0
8+
.file "t.cpp"
9+
.def main;
10+
.scl 2;
11+
.type 32;
12+
.endef
13+
.globl main # -- Begin function main
14+
.p2align 4, 0x90
15+
main: # @main
16+
.Lfunc_begin0:
17+
.cv_func_id 0
18+
.cv_file 1 "C:\\src\\testing\\t.cpp" "D28AB0CC784E17E5DF9BBB49CB629C81" 1
19+
.cv_loc 0 1 4 0 # t.cpp:4:0
20+
.seh_proc main
21+
# %bb.0: # %entry
22+
pushq %rax
23+
.seh_stackalloc 8
24+
.seh_endprologue
25+
movl $0, 4(%rsp)
26+
.Ltmp0:
27+
movl $83, %eax
28+
popq %rcx
29+
retq
30+
.Ltmp1:
31+
.Lfunc_end0:
32+
.seh_handlerdata
33+
.text
34+
.seh_endproc
35+
# -- End function
36+
.section .debug$S,"dr"
37+
.p2align 2
38+
.long 4 # Debug section magic
39+
.long 241
40+
.long .Ltmp3-.Ltmp2 # Subsection size
41+
.Ltmp2:
42+
.short .Ltmp5-.Ltmp4 # Record length
43+
.Ltmp4:
44+
.short 4412 # Record kind: S_COMPILE3
45+
.long 1 # Flags and language
46+
.short 208 # CPUType
47+
.short 9 # Frontend version
48+
.short 0
49+
.short 0
50+
.short 0
51+
.short 9000 # Backend version
52+
.short 0
53+
.short 0
54+
.short 0
55+
.asciz "clang version 9.0.0 (https://github.com/llvm/llvm-project.git ad522e17b285b1f2667163d52da5abf0968ec650)" # Null-terminated compiler version string
56+
.p2align 2
57+
.Ltmp5:
58+
.Ltmp3:
59+
.p2align 2
60+
.long 241 # Symbol subsection for main
61+
.long .Ltmp7-.Ltmp6 # Subsection size
62+
.Ltmp6:
63+
.short .Ltmp9-.Ltmp8 # Record length
64+
.Ltmp8:
65+
.short 4423 # Record kind: S_GPROC32_ID
66+
.long 0 # PtrParent
67+
.long 0 # PtrEnd
68+
.long 0 # PtrNext
69+
.long .Lfunc_end0-main # Code size
70+
.long 0 # Offset after prologue
71+
.long 0 # Offset before epilogue
72+
.long 4098 # Function type index
73+
.secrel32 main # Function section relative address
74+
.secidx main # Function section index
75+
.byte 0 # Flags
76+
.asciz "main" # Function name
77+
.p2align 2
78+
.Ltmp9:
79+
.short .Ltmp11-.Ltmp10 # Record length
80+
.Ltmp10:
81+
.short 4114 # Record kind: S_FRAMEPROC
82+
.long 8 # FrameSize
83+
.long 0 # Padding
84+
.long 0 # Offset of padding
85+
.long 0 # Bytes of callee saved registers
86+
.long 0 # Exception handler offset
87+
.short 0 # Exception handler section
88+
.long 81920 # Flags (defines frame register)
89+
.p2align 2
90+
.Ltmp11:
91+
.short 2 # Record length
92+
.short 4431 # Record kind: S_PROC_ID_END
93+
.Ltmp7:
94+
.p2align 2
95+
.cv_linetable 0, main, .Lfunc_end0
96+
.long 241 # Symbol subsection for globals
97+
.long .Ltmp13-.Ltmp12 # Subsection size
98+
.Ltmp12:
99+
.short .Ltmp15-.Ltmp14 # Record length
100+
.Ltmp14:
101+
.short 4359 # Record kind: S_CONSTANT
102+
.long 4099 # Type
103+
.byte 0x29, 0x00 # Value
104+
.asciz "Foo" # Name
105+
.p2align 2
106+
.Ltmp15:
107+
.short .Ltmp17-.Ltmp16 # Record length
108+
.Ltmp16:
109+
.short 4359 # Record kind: S_CONSTANT
110+
.long 4099 # Type
111+
.byte 0x2a, 0x00 # Value
112+
.asciz "Bar" # Name
113+
.p2align 2
114+
.Ltmp17:
115+
.Ltmp13:
116+
.p2align 2
117+
.cv_filechecksums # File index to string table offset subsection
118+
.cv_stringtable # String table
119+
.long 241
120+
.long .Ltmp19-.Ltmp18 # Subsection size
121+
.Ltmp18:
122+
.short .Ltmp21-.Ltmp20 # Record length
123+
.Ltmp20:
124+
.short 4428 # Record kind: S_BUILDINFO
125+
.long 4102 # LF_BUILDINFO index
126+
.p2align 2
127+
.Ltmp21:
128+
.Ltmp19:
129+
.p2align 2
130+
.section .debug$T,"dr"
131+
.p2align 2
132+
.long 4 # Debug section magic
133+
# ArgList (0x1000) {
134+
# TypeLeafKind: LF_ARGLIST (0x1201)
135+
# NumArgs: 0
136+
# Arguments [
137+
# ]
138+
# }
139+
.byte 0x06, 0x00, 0x01, 0x12
140+
.byte 0x00, 0x00, 0x00, 0x00
141+
# Procedure (0x1001) {
142+
# TypeLeafKind: LF_PROCEDURE (0x1008)
143+
# ReturnType: int (0x74)
144+
# CallingConvention: NearC (0x0)
145+
# FunctionOptions [ (0x0)
146+
# ]
147+
# NumParameters: 0
148+
# ArgListType: () (0x1000)
149+
# }
150+
.byte 0x0e, 0x00, 0x08, 0x10
151+
.byte 0x74, 0x00, 0x00, 0x00
152+
.byte 0x00, 0x00, 0x00, 0x00
153+
.byte 0x00, 0x10, 0x00, 0x00
154+
# FuncId (0x1002) {
155+
# TypeLeafKind: LF_FUNC_ID (0x1601)
156+
# ParentScope: 0x0
157+
# FunctionType: int () (0x1001)
158+
# Name: main
159+
# }
160+
.byte 0x12, 0x00, 0x01, 0x16
161+
.byte 0x00, 0x00, 0x00, 0x00
162+
.byte 0x01, 0x10, 0x00, 0x00
163+
.byte 0x6d, 0x61, 0x69, 0x6e
164+
.byte 0x00, 0xf3, 0xf2, 0xf1
165+
# Modifier (0x1003) {
166+
# TypeLeafKind: LF_MODIFIER (0x1001)
167+
# ModifiedType: int (0x74)
168+
# Modifiers [ (0x1)
169+
# Const (0x1)
170+
# ]
171+
# }
172+
.byte 0x0a, 0x00, 0x01, 0x10
173+
.byte 0x74, 0x00, 0x00, 0x00
174+
.byte 0x01, 0x00, 0xf2, 0xf1
175+
# StringId (0x1004) {
176+
# TypeLeafKind: LF_STRING_ID (0x1605)
177+
# Id: 0x0
178+
# StringData: C:\src\testing
179+
# }
180+
.byte 0x16, 0x00, 0x05, 0x16
181+
.byte 0x00, 0x00, 0x00, 0x00
182+
.byte 0x43, 0x3a, 0x5c, 0x73
183+
.byte 0x72, 0x63, 0x5c, 0x74
184+
.byte 0x65, 0x73, 0x74, 0x69
185+
.byte 0x6e, 0x67, 0x00, 0xf1
186+
# StringId (0x1005) {
187+
# TypeLeafKind: LF_STRING_ID (0x1605)
188+
# Id: 0x0
189+
# StringData: t.cpp
190+
# }
191+
.byte 0x0e, 0x00, 0x05, 0x16
192+
.byte 0x00, 0x00, 0x00, 0x00
193+
.byte 0x74, 0x2e, 0x63, 0x70
194+
.byte 0x70, 0x00, 0xf2, 0xf1
195+
# BuildInfo (0x1006) {
196+
# TypeLeafKind: LF_BUILDINFO (0x1603)
197+
# NumArgs: 5
198+
# Arguments [
199+
# ArgType: C:\src\testing (0x1004)
200+
# ArgType: 0x0
201+
# ArgType: t.cpp (0x1005)
202+
# ArgType: 0x0
203+
# ArgType: 0x0
204+
# ]
205+
# }
206+
.byte 0x1a, 0x00, 0x03, 0x16
207+
.byte 0x05, 0x00, 0x04, 0x10
208+
.byte 0x00, 0x00, 0x00, 0x00
209+
.byte 0x00, 0x00, 0x05, 0x10
210+
.byte 0x00, 0x00, 0x00, 0x00
211+
.byte 0x00, 0x00, 0x00, 0x00
212+
.byte 0x00, 0x00, 0xf2, 0xf1
213+
214+
.addrsig
Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
.text
2+
.def @feat.00;
3+
.scl 3;
4+
.type 0;
5+
.endef
6+
.globl @feat.00
7+
.set @feat.00, 0
8+
.file "t2.cpp"
9+
.def "?foobar@@YAHXZ";
10+
.scl 2;
11+
.type 32;
12+
.endef
13+
.globl "?foobar@@YAHXZ" # -- Begin function ?foobar@@YAHXZ
14+
.p2align 4, 0x90
15+
"?foobar@@YAHXZ": # @"?foobar@@YAHXZ"
16+
.Lfunc_begin0:
17+
.cv_func_id 0
18+
# %bb.0: # %entry
19+
.cv_file 1 "C:\\src\\testing\\t2.cpp" "C9D7AF07363FDE8EC16D73EC30039C5B" 1
20+
.cv_loc 0 1 5 0 # t2.cpp:5:0
21+
movl $84, %eax
22+
retq
23+
.Ltmp0:
24+
.Lfunc_end0:
25+
# -- End function
26+
.section .debug$S,"dr"
27+
.p2align 2
28+
.long 4 # Debug section magic
29+
.long 241
30+
.long .Ltmp2-.Ltmp1 # Subsection size
31+
.Ltmp1:
32+
.short .Ltmp4-.Ltmp3 # Record length
33+
.Ltmp3:
34+
.short 4412 # Record kind: S_COMPILE3
35+
.long 1 # Flags and language
36+
.short 208 # CPUType
37+
.short 9 # Frontend version
38+
.short 0
39+
.short 0
40+
.short 0
41+
.short 9000 # Backend version
42+
.short 0
43+
.short 0
44+
.short 0
45+
.asciz "clang version 9.0.0 (https://github.com/llvm/llvm-project.git ad522e17b285b1f2667163d52da5abf0968ec650)" # Null-terminated compiler version string
46+
.p2align 2
47+
.Ltmp4:
48+
.Ltmp2:
49+
.p2align 2
50+
.long 241 # Symbol subsection for foobar
51+
.long .Ltmp6-.Ltmp5 # Subsection size
52+
.Ltmp5:
53+
.short .Ltmp8-.Ltmp7 # Record length
54+
.Ltmp7:
55+
.short 4423 # Record kind: S_GPROC32_ID
56+
.long 0 # PtrParent
57+
.long 0 # PtrEnd
58+
.long 0 # PtrNext
59+
.long .Lfunc_end0-"?foobar@@YAHXZ" # Code size
60+
.long 0 # Offset after prologue
61+
.long 0 # Offset before epilogue
62+
.long 4098 # Function type index
63+
.secrel32 "?foobar@@YAHXZ" # Function section relative address
64+
.secidx "?foobar@@YAHXZ" # Function section index
65+
.byte 0 # Flags
66+
.asciz "foobar" # Function name
67+
.p2align 2
68+
.Ltmp8:
69+
.short .Ltmp10-.Ltmp9 # Record length
70+
.Ltmp9:
71+
.short 4114 # Record kind: S_FRAMEPROC
72+
.long 0 # FrameSize
73+
.long 0 # Padding
74+
.long 0 # Offset of padding
75+
.long 0 # Bytes of callee saved registers
76+
.long 0 # Exception handler offset
77+
.short 0 # Exception handler section
78+
.long 0 # Flags (defines frame register)
79+
.p2align 2
80+
.Ltmp10:
81+
.short 2 # Record length
82+
.short 4431 # Record kind: S_PROC_ID_END
83+
.Ltmp6:
84+
.p2align 2
85+
.cv_linetable 0, "?foobar@@YAHXZ", .Lfunc_end0
86+
.long 241 # Symbol subsection for globals
87+
.long .Ltmp12-.Ltmp11 # Subsection size
88+
.Ltmp11:
89+
.short .Ltmp14-.Ltmp13 # Record length
90+
.Ltmp13:
91+
.short 4359 # Record kind: S_CONSTANT
92+
.long 4099 # Type
93+
.byte 0x2a, 0x00 # Value
94+
.asciz "Foo" # Name
95+
.p2align 2
96+
.Ltmp14:
97+
.short .Ltmp16-.Ltmp15 # Record length
98+
.Ltmp15:
99+
.short 4359 # Record kind: S_CONSTANT
100+
.long 4099 # Type
101+
.byte 0x2a, 0x00 # Value
102+
.asciz "Bar" # Name
103+
.p2align 2
104+
.Ltmp16:
105+
.Ltmp12:
106+
.p2align 2
107+
.cv_filechecksums # File index to string table offset subsection
108+
.cv_stringtable # String table
109+
.long 241
110+
.long .Ltmp18-.Ltmp17 # Subsection size
111+
.Ltmp17:
112+
.short .Ltmp20-.Ltmp19 # Record length
113+
.Ltmp19:
114+
.short 4428 # Record kind: S_BUILDINFO
115+
.long 4102 # LF_BUILDINFO index
116+
.p2align 2
117+
.Ltmp20:
118+
.Ltmp18:
119+
.p2align 2
120+
.section .debug$T,"dr"
121+
.p2align 2
122+
.long 4 # Debug section magic
123+
# ArgList (0x1000) {
124+
# TypeLeafKind: LF_ARGLIST (0x1201)
125+
# NumArgs: 0
126+
# Arguments [
127+
# ]
128+
# }
129+
.byte 0x06, 0x00, 0x01, 0x12
130+
.byte 0x00, 0x00, 0x00, 0x00
131+
# Procedure (0x1001) {
132+
# TypeLeafKind: LF_PROCEDURE (0x1008)
133+
# ReturnType: int (0x74)
134+
# CallingConvention: NearC (0x0)
135+
# FunctionOptions [ (0x0)
136+
# ]
137+
# NumParameters: 0
138+
# ArgListType: () (0x1000)
139+
# }
140+
.byte 0x0e, 0x00, 0x08, 0x10
141+
.byte 0x74, 0x00, 0x00, 0x00
142+
.byte 0x00, 0x00, 0x00, 0x00
143+
.byte 0x00, 0x10, 0x00, 0x00
144+
# FuncId (0x1002) {
145+
# TypeLeafKind: LF_FUNC_ID (0x1601)
146+
# ParentScope: 0x0
147+
# FunctionType: int () (0x1001)
148+
# Name: foobar
149+
# }
150+
.byte 0x12, 0x00, 0x01, 0x16
151+
.byte 0x00, 0x00, 0x00, 0x00
152+
.byte 0x01, 0x10, 0x00, 0x00
153+
.byte 0x66, 0x6f, 0x6f, 0x62
154+
.byte 0x61, 0x72, 0x00, 0xf1
155+
# Modifier (0x1003) {
156+
# TypeLeafKind: LF_MODIFIER (0x1001)
157+
# ModifiedType: int (0x74)
158+
# Modifiers [ (0x1)
159+
# Const (0x1)
160+
# ]
161+
# }
162+
.byte 0x0a, 0x00, 0x01, 0x10
163+
.byte 0x74, 0x00, 0x00, 0x00
164+
.byte 0x01, 0x00, 0xf2, 0xf1
165+
# StringId (0x1004) {
166+
# TypeLeafKind: LF_STRING_ID (0x1605)
167+
# Id: 0x0
168+
# StringData: C:\src\testing
169+
# }
170+
.byte 0x16, 0x00, 0x05, 0x16
171+
.byte 0x00, 0x00, 0x00, 0x00
172+
.byte 0x43, 0x3a, 0x5c, 0x73
173+
.byte 0x72, 0x63, 0x5c, 0x74
174+
.byte 0x65, 0x73, 0x74, 0x69
175+
.byte 0x6e, 0x67, 0x00, 0xf1
176+
# StringId (0x1005) {
177+
# TypeLeafKind: LF_STRING_ID (0x1605)
178+
# Id: 0x0
179+
# StringData: t2.cpp
180+
# }
181+
.byte 0x0e, 0x00, 0x05, 0x16
182+
.byte 0x00, 0x00, 0x00, 0x00
183+
.byte 0x74, 0x32, 0x2e, 0x63
184+
.byte 0x70, 0x70, 0x00, 0xf1
185+
# BuildInfo (0x1006) {
186+
# TypeLeafKind: LF_BUILDINFO (0x1603)
187+
# NumArgs: 5
188+
# Arguments [
189+
# ArgType: C:\src\testing (0x1004)
190+
# ArgType: 0x0
191+
# ArgType: t2.cpp (0x1005)
192+
# ArgType: 0x0
193+
# ArgType: 0x0
194+
# ]
195+
# }
196+
.byte 0x1a, 0x00, 0x03, 0x16
197+
.byte 0x05, 0x00, 0x04, 0x10
198+
.byte 0x00, 0x00, 0x00, 0x00
199+
.byte 0x00, 0x00, 0x05, 0x10
200+
.byte 0x00, 0x00, 0x00, 0x00
201+
.byte 0x00, 0x00, 0x00, 0x00
202+
.byte 0x00, 0x00, 0xf2, 0xf1
203+
204+
.addrsig
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# REQUIRES: x86
2+
# RUN: llvm-mc -filetype=obj %S/Inputs/pdb-global-constants-a.s -o %t-a.obj -triple x86_64-windows-msvc
3+
# RUN: llvm-mc -filetype=obj %S/Inputs/pdb-global-constants-b.s -o %t-b.obj -triple x86_64-windows-msvc
4+
# RUN: lld-link -entry:main -nodefaultlib %t-a.obj %t-b.obj -out:%t.exe -pdb:%t.pdb -debug
5+
# RUN: llvm-pdbutil dump -globals %t.pdb | FileCheck %s
6+
7+
# Test that lld deduplicates S_CONSTANT records with the same name and value.
8+
#
9+
# Compiled from this C code, using
10+
# clang t.cpp -g -gcodeview -S
11+
#
12+
# %t-a.cpp:
13+
# const int Foo = 41;
14+
# const int Bar = 42;
15+
# int main() { return Foo + Bar; }
16+
#
17+
# %t-b.cpp:
18+
# const int Foo = 42;
19+
# const int Bar = 42;
20+
# int foobar() { return Foo + Bar; }
21+
22+
CHECK: Global Symbols
23+
CHECK: 88 | S_CONSTANT [size = 16] `Bar`
24+
CHECK-NEXT: type = 0x1002 (const int), value = 42
25+
CHECK-NEXT: 72 | S_CONSTANT [size = 16] `Foo`
26+
CHECK-NEXT: type = 0x1002 (const int), value = 41
27+
CHECK-NEXT: 128 | S_CONSTANT [size = 16] `Foo`
28+
CHECK-NEXT: type = 0x1002 (const int), value = 42

‎llvm/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ using namespace llvm::pdb;
3030
using namespace llvm::codeview;
3131

3232
struct llvm::pdb::GSIHashStreamBuilder {
33-
struct UdtDenseMapInfo {
33+
struct SymbolDenseMapInfo {
3434
static inline CVSymbol getEmptyKey() {
3535
static CVSymbol Empty;
3636
return Empty;
@@ -50,7 +50,7 @@ struct llvm::pdb::GSIHashStreamBuilder {
5050

5151
std::vector<CVSymbol> Records;
5252
uint32_t StreamIndex;
53-
llvm::DenseSet<CVSymbol, UdtDenseMapInfo> UdtHashes;
53+
llvm::DenseSet<CVSymbol, SymbolDenseMapInfo> SymbolHashes;
5454
std::vector<PSHashRecord> HashRecords;
5555
std::array<support::ulittle32_t, (IPHR_HASH + 32) / 32> HashBitmap;
5656
std::vector<support::ulittle32_t> HashBuckets;
@@ -66,8 +66,8 @@ struct llvm::pdb::GSIHashStreamBuilder {
6666
CodeViewContainer::Pdb));
6767
}
6868
void addSymbol(const CVSymbol &Symbol) {
69-
if (Symbol.kind() == S_UDT) {
70-
auto Iter = UdtHashes.insert(Symbol);
69+
if (Symbol.kind() == S_UDT || Symbol.kind() == S_CONSTANT) {
70+
auto Iter = SymbolHashes.insert(Symbol);
7171
if (!Iter.second)
7272
return;
7373
}

0 commit comments

Comments
 (0)
Please sign in to comment.