[LTO] Create Undefined Bitcode symbol when we drop a comdat member.

Differential Revision:  http://reviews.llvm.org/D19389

llvm-svn: 267181
This commit is contained in:
Davide Italiano 2016-04-22 18:26:33 +00:00
parent 9598f10104
commit 9f8efffe29
4 changed files with 81 additions and 19 deletions

View File

@ -458,16 +458,19 @@ static uint8_t getGvVisibility(const GlobalValue *GV) {
}
SymbolBody *
BitcodeFile::createSymbolBody(const DenseSet<const Comdat *> &KeptComdats,
BitcodeFile::createBody(const DenseSet<const Comdat *> &KeptComdats,
const IRObjectFile &Obj,
const BasicSymbolRef &Sym) {
const GlobalValue *GV = Obj.getSymbolGV(Sym.getRawDataRefImpl());
if (GV)
if (const Comdat *C = GV->getComdat())
if (!KeptComdats.count(C))
return nullptr;
const BasicSymbolRef &Sym,
const GlobalValue *GV) {
SmallString<64> Name;
raw_svector_ostream OS(Name);
Sym.printName(OS);
StringRef NameRef = Saver.save(StringRef(Name));
SymbolBody *Body;
uint32_t Flags = Sym.getFlags();
bool IsWeak = Flags & BasicSymbolRef::SF_Weak;
uint8_t Visibility;
if (GV)
Visibility = getGvVisibility(GV);
@ -476,28 +479,37 @@ BitcodeFile::createSymbolBody(const DenseSet<const Comdat *> &KeptComdats,
// protected visibility.
Visibility = STV_DEFAULT;
SmallString<64> Name;
raw_svector_ostream OS(Name);
Sym.printName(OS);
StringRef NameRef = Saver.save(StringRef(Name));
if (GV)
if (const Comdat *C = GV->getComdat())
if (!KeptComdats.count(C)) {
Body = new (Alloc)
UndefinedBitcode(NameRef, IsWeak, Visibility);
return Body;
}
const Module &M = Obj.getModule();
SymbolBody *Body;
bool IsWeak = Flags & BasicSymbolRef::SF_Weak;
if (Flags & BasicSymbolRef::SF_Undefined) {
Body = new (Alloc) UndefinedBitcode(NameRef, IsWeak, Visibility);
} else if (Flags & BasicSymbolRef::SF_Common) {
if (Flags & BasicSymbolRef::SF_Undefined)
return new (Alloc) UndefinedBitcode(NameRef, IsWeak, Visibility);
if (Flags & BasicSymbolRef::SF_Common) {
// FIXME: Set SF_Common flag correctly for module asm symbols, and expose
// size and alignment.
assert(GV);
const DataLayout &DL = M.getDataLayout();
uint64_t Size = DL.getTypeAllocSize(GV->getValueType());
Body = new (Alloc)
return new (Alloc)
DefinedCommon(NameRef, Size, GV->getAlignment(),
IsWeak ? STB_WEAK : STB_GLOBAL, Visibility, /*Type*/ 0);
} else {
Body = new (Alloc) DefinedBitcode(NameRef, IsWeak, Visibility);
}
return new (Alloc) DefinedBitcode(NameRef, IsWeak, Visibility);
}
SymbolBody *
BitcodeFile::createSymbolBody(const DenseSet<const Comdat *> &KeptComdats,
const IRObjectFile &Obj,
const BasicSymbolRef &Sym) {
const GlobalValue *GV = Obj.getSymbolGV(Sym.getRawDataRefImpl());
SymbolBody *Body = createBody(KeptComdats, Obj, Sym, GV);
// FIXME: Expose a thread-local flag for module asm symbols.
if (GV) {
if (GV->isThreadLocal())

View File

@ -226,6 +226,11 @@ private:
createSymbolBody(const llvm::DenseSet<const llvm::Comdat *> &KeptComdats,
const llvm::object::IRObjectFile &Obj,
const llvm::object::BasicSymbolRef &Sym);
SymbolBody *
createBody(const llvm::DenseSet<const llvm::Comdat *> &KeptComdats,
const llvm::object::IRObjectFile &Obj,
const llvm::object::BasicSymbolRef &Sym,
const llvm::GlobalValue *GV);
};
// .so file.

View File

@ -0,0 +1,5 @@
.section .text.f,"axG",@progbits,c,comdat
.globl foo
foo:
retq

View File

@ -0,0 +1,40 @@
; RUN: llvm-as %s -o %t.o
; RUN: llvm-mc -triple=x86_64-pc-linux %p/Inputs/comdat.s -o %t2.o -filetype=obj
; RUN: ld.lld -m elf_x86_64 %t.o %t2.o -o %t.so -shared
; RUN: llvm-readobj -t %t.so | FileCheck %s
; RUN: ld.lld -m elf_x86_64 %t2.o %t.o -o %t2.so -shared
; RUN: llvm-readobj -t %t2.so | FileCheck %s --check-prefix=OTHER
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
$c = comdat any
define protected void @foo() comdat($c) {
ret void
}
; CHECK: Symbol {
; CHECK: Name: foo
; CHECK-NEXT: Value: 0x1000
; CHECK-NEXT: Size: 1
; CHECK-NEXT: Binding: Global
; CHECK-NEXT: Type: Function
; CHECK-NEXT: Other [
; CHECK-NEXT: STV_PROTECTED
; CHECK-NEXT: ]
; CHECK-NEXT: Section: .text
; CHECK-NEXT: }
; OTHER: Symbol {
; OTHER: Name: foo
; OTHER-NEXT: Value: 0x1000
; OTHER-NEXT: Size: 0
; OTHER-NEXT: Binding: Global
; OTHER-NEXT: Type: None
; OTHER-NEXT: Other [
; OTHER-NEXT: STV_PROTECTED
; OTHER-NEXT: ]
; OTHER-NEXT: Section: .text
; OTHER-NEXT: }