Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lld/COFF/Chunks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -777,7 +777,7 @@ uint32_t SectionChunk::getSectionNumber() const {
return s.getIndex() + 1;
}

CommonChunk::CommonChunk(const COFFSymbolRef s) : sym(s) {
CommonChunk::CommonChunk(const COFFSymbolRef s) : active(false), sym(s) {
// The value of a common symbol is its size. Align all common symbols smaller
// than 32 bytes naturally, i.e. round the size up to the next power of two.
// This is what MSVC link.exe does.
Expand Down
2 changes: 2 additions & 0 deletions lld/COFF/Chunks.h
Original file line number Diff line number Diff line change
Expand Up @@ -522,6 +522,8 @@ class CommonChunk : public NonSectionChunk {
uint32_t getOutputCharacteristics() const override;
StringRef getSectionName() const override { return ".bss"; }

bool active;

private:
const COFFSymbolRef sym;
};
Expand Down
2 changes: 2 additions & 0 deletions lld/COFF/Symbols.h
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,8 @@ class DefinedCommon : public DefinedCOFF {
CommonChunk *c = nullptr)
: DefinedCOFF(DefinedCommonKind, f, n, s), data(c), size(size) {
this->isExternal = true;
if (c)
c->active = true;
}

static bool classof(const Symbol *s) {
Expand Down
4 changes: 4 additions & 0 deletions lld/COFF/Writer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1114,6 +1114,10 @@ void Writer::createSections() {
sc->printDiscardedMessage();
continue;
}
if (auto *cc = dyn_cast<CommonChunk>(c)) {
if (!cc->active)
continue;
}
StringRef name = c->getSectionName();
if (shouldStripSectionSuffix(sc, name, ctx.config.mingw))
name = name.split('$').first;
Expand Down
38 changes: 38 additions & 0 deletions lld/test/COFF/common-dedup.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
; REQUIRES: x86
; RUN: split-file %s %t.dir
; RUN: llc %t.dir/t1.ll -o %t.t1.obj --filetype=obj
; RUN: llc %t.dir/t2.ll -o %t.t2.obj --filetype=obj
; RUN: lld-link %t.t1.obj %t.t2.obj -entry:main -out:%t.exe
; RUN: llvm-readobj --section-headers %t.exe | FileCheck %s

; Make sure that the data section contains just one copy of @a, not two.
; CHECK: Name: .data
; CHECK-NEXT: VirtualSize: 0x1000

;--- t1.ll
target triple = "x86_64-pc-windows-msvc"
@a = common global [4096 x i8] zeroinitializer

define i32 @usea() {
%ref_common = load i32, ptr @a
ret i32 %ref_common
}

;--- t2.ll
target triple = "x86_64-pc-windows-msvc"
@a = common global [4096 x i8] zeroinitializer

define i32 @useb() {
%ref_common = load i32, ptr @a
ret i32 %ref_common
}

declare i32 @usea()

define dso_local i32 @main() local_unnamed_addr {
entry:
%a = tail call i32 @usea()
%b = tail call i32 @useb()
%add = add nsw i32 %a, %b
ret i32 %add
}