Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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) : live(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 live;

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->live = 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->live)
continue;
}
StringRef name = c->getSectionName();
if (shouldStripSectionSuffix(sc, name, ctx.config.mingw))
name = name.split('$').first;
Expand Down
39 changes: 39 additions & 0 deletions lld/test/COFF/common-dedup.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
; REQUIRES: x86
; RUN: rm -rf %t.dir
; RUN: split-file %s %t.dir
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does split-file automatically make the output directory if it is missing? Wasn't aware of that.

Still, it may be good style to do a preemptive rm -rf %t.dir before this, in case there's incompatible leftover files from an earlier round.

; RUN: llc %t.dir/t1.ll -o %t.dir/t1.obj --filetype=obj
; RUN: llc %t.dir/t2.ll -o %t.dir/t2.obj --filetype=obj
; RUN: lld-link %t.dir/t1.obj %t.dir/t2.obj -entry:main -out:%t.dir/out.exe
; RUN: llvm-readobj --section-headers %t.dir/out.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
}