Use IRMover directly.

This has a few advantages:
* If lld selected a non bitcode symbol, be the bitcode GV is not merged
* lib/Linker is not redoing symbol resolution.

llvm-svn: 262773
This commit is contained in:
Rafael Espindola
2016-03-05 14:51:51 +00:00
parent 4aa36fd4e3
commit 7f6d50b229
3 changed files with 56 additions and 10 deletions

View File

@@ -20,7 +20,7 @@
#include "Symbols.h"
#include "llvm/Bitcode/ReaderWriter.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/Linker/Linker.h"
#include "llvm/Linker/IRMover.h"
#include "llvm/Support/StringSaver.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Target/TargetMachine.h"
@@ -126,21 +126,36 @@ std::unique_ptr<InputFile> SymbolTable<ELFT>::codegen(Module &M) {
return createObjectFile(*LtoBuffer);
}
static void addBitcodeFile(IRMover &Mover, BitcodeFile &F,
LLVMContext &Context) {
std::unique_ptr<MemoryBuffer> Buffer =
MemoryBuffer::getMemBuffer(F.MB, false);
std::unique_ptr<Module> M =
check(getLazyBitcodeModule(std::move(Buffer), Context,
/*ShouldLazyLoadMetadata*/ true));
std::vector<GlobalValue *> Keep;
for (SymbolBody *B : F.getSymbols()) {
if (B->repl() != B)
continue;
auto *DB = dyn_cast<DefinedBitcode>(B);
if (!DB)
continue;
GlobalValue *GV = M->getNamedValue(B->getName());
assert(GV);
Keep.push_back(GV);
}
Mover.move(std::move(M), Keep, [](GlobalValue &, IRMover::ValueAdder) {});
}
// Merge all the bitcode files we have seen, codegen the result and return
// the resulting ObjectFile.
template <class ELFT>
ObjectFile<ELFT> *SymbolTable<ELFT>::createCombinedLtoObject() {
LLVMContext Context;
Module Combined("ld-temp.o", Context);
Linker L(Combined);
for (const std::unique_ptr<BitcodeFile> &F : BitcodeFiles) {
std::unique_ptr<MemoryBuffer> Buffer =
MemoryBuffer::getMemBuffer(F->MB, false);
std::unique_ptr<Module> M =
check(getLazyBitcodeModule(std::move(Buffer), Context,
/*ShouldLazyLoadMetadata*/ true));
L.linkInModule(std::move(M));
}
IRMover Mover(Combined);
for (const std::unique_ptr<BitcodeFile> &F : BitcodeFiles)
addBitcodeFile(Mover, *F, Context);
std::unique_ptr<InputFile> F = codegen(Combined);
ObjectFiles.emplace_back(cast<ObjectFile<ELFT>>(F.release()));
return &*ObjectFiles.back();

View File

@@ -0,0 +1,4 @@
.data
.global a
a:
.long 9

View File

@@ -0,0 +1,27 @@
; REQUIRES: x86
; RUN: llvm-as %s -o %t1.o
; RUN: llvm-mc -triple=x86_64-pc-linux %p/Inputs/resolution.s -o %t2.o -filetype=obj
; RUN: ld.lld %t1.o %t2.o -o %t.so -shared
; RUN: llvm-readobj -s --section-data %t.so | FileCheck %s
; CHECK: Name: .data
; CHECK-NEXT: Type: SHT_PROGBITS
; CHECK-NEXT: Flags [
; CHECK-NEXT: SHF_ALLOC
; CHECK-NEXT: SHF_WRITE
; CHECK-NEXT: ]
; CHECK-NEXT: Address:
; CHECK-NEXT: Offset:
; CHECK-NEXT: Size: 4
; CHECK-NEXT: Link: 0
; CHECK-NEXT: Info: 0
; CHECK-NEXT: AddressAlignment: 1
; CHECK-NEXT: EntrySize: 0
; CHECK-NEXT: SectionData (
; CHECK-NEXT: 0000: 09000000 |{{.*}}|
; CHECK-NEXT: )
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
@a = weak global i32 8