forked from OSchip/llvm-project
Avoid calling getNamedValue.
In lld we usually avoid hash lookups. In addition to that, IR names are not fully mangled, so it is best to avoid using them whenever possible. llvm-svn: 263248
This commit is contained in:
parent
7423f40674
commit
9b3acf9098
|
@ -436,6 +436,50 @@ static uint8_t getGvVisibility(const GlobalValue *GV) {
|
||||||
llvm_unreachable("Unknown visibility");
|
llvm_unreachable("Unknown visibility");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SymbolBody *
|
||||||
|
BitcodeFile::createSymbolBody(const DenseSet<const Comdat *> &KeptComdats,
|
||||||
|
const IRObjectFile &Obj,
|
||||||
|
const BasicSymbolRef &Sym) {
|
||||||
|
const GlobalValue *GV = Obj.getSymbolGV(Sym.getRawDataRefImpl());
|
||||||
|
assert(GV);
|
||||||
|
if (const Comdat *C = GV->getComdat())
|
||||||
|
if (!KeptComdats.count(C))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
uint8_t Visibility = getGvVisibility(GV);
|
||||||
|
|
||||||
|
SmallString<64> Name;
|
||||||
|
raw_svector_ostream OS(Name);
|
||||||
|
Sym.printName(OS);
|
||||||
|
StringRef NameRef = Saver.save(StringRef(Name));
|
||||||
|
|
||||||
|
const Module &M = Obj.getModule();
|
||||||
|
SymbolBody *Body;
|
||||||
|
uint32_t Flags = Sym.getFlags();
|
||||||
|
bool IsWeak = Flags & BasicSymbolRef::SF_Weak;
|
||||||
|
if (Flags & BasicSymbolRef::SF_Undefined) {
|
||||||
|
Body = new (Alloc) Undefined(NameRef, IsWeak, Visibility, false);
|
||||||
|
} else if (Flags & BasicSymbolRef::SF_Common) {
|
||||||
|
const DataLayout &DL = M.getDataLayout();
|
||||||
|
uint64_t Size = DL.getTypeAllocSize(GV->getValueType());
|
||||||
|
Body = new (Alloc)
|
||||||
|
DefinedCommon(NameRef, Size, GV->getAlignment(), IsWeak, Visibility);
|
||||||
|
} else {
|
||||||
|
Body = new (Alloc) DefinedBitcode(NameRef, IsWeak, Visibility);
|
||||||
|
}
|
||||||
|
Body->IsTls = GV->isThreadLocal();
|
||||||
|
return Body;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BitcodeFile::shouldSkip(const BasicSymbolRef &Sym) {
|
||||||
|
uint32_t Flags = Sym.getFlags();
|
||||||
|
if (!(Flags & BasicSymbolRef::SF_Global))
|
||||||
|
return true;
|
||||||
|
if (Flags & BasicSymbolRef::SF_FormatSpecific)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void BitcodeFile::parse(DenseSet<StringRef> &ComdatGroups) {
|
void BitcodeFile::parse(DenseSet<StringRef> &ComdatGroups) {
|
||||||
LLVMContext Context;
|
LLVMContext Context;
|
||||||
std::unique_ptr<IRObjectFile> Obj = check(IRObjectFile::create(MB, Context));
|
std::unique_ptr<IRObjectFile> Obj = check(IRObjectFile::create(MB, Context));
|
||||||
|
@ -448,43 +492,9 @@ void BitcodeFile::parse(DenseSet<StringRef> &ComdatGroups) {
|
||||||
KeptComdats.insert(&P.second);
|
KeptComdats.insert(&P.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const BasicSymbolRef &Sym : Obj->symbols()) {
|
for (const BasicSymbolRef &Sym : Obj->symbols())
|
||||||
const GlobalValue *GV = Obj->getSymbolGV(Sym.getRawDataRefImpl());
|
if (!shouldSkip(Sym))
|
||||||
assert(GV);
|
SymbolBodies.push_back(createSymbolBody(KeptComdats, *Obj, Sym));
|
||||||
uint32_t Flags = Sym.getFlags();
|
|
||||||
if (const Comdat *C = GV->getComdat())
|
|
||||||
if (!KeptComdats.count(C))
|
|
||||||
continue;
|
|
||||||
if (!(Flags & BasicSymbolRef::SF_Global))
|
|
||||||
continue;
|
|
||||||
if (GV->hasAppendingLinkage()) {
|
|
||||||
ExtraKeeps.push_back(GV->getName().copy(Alloc));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (Flags & BasicSymbolRef::SF_FormatSpecific)
|
|
||||||
continue;
|
|
||||||
uint8_t Visibility = getGvVisibility(GV);
|
|
||||||
|
|
||||||
SmallString<64> Name;
|
|
||||||
raw_svector_ostream OS(Name);
|
|
||||||
Sym.printName(OS);
|
|
||||||
StringRef NameRef = Saver.save(StringRef(Name));
|
|
||||||
|
|
||||||
SymbolBody *Body;
|
|
||||||
bool IsWeak = Flags & BasicSymbolRef::SF_Weak;
|
|
||||||
if (Flags & BasicSymbolRef::SF_Undefined) {
|
|
||||||
Body = new (Alloc) Undefined(NameRef, IsWeak, Visibility, false);
|
|
||||||
} else if (Flags & BasicSymbolRef::SF_Common) {
|
|
||||||
const DataLayout &DL = M.getDataLayout();
|
|
||||||
uint64_t Size = DL.getTypeAllocSize(GV->getValueType());
|
|
||||||
Body = new (Alloc)
|
|
||||||
DefinedCommon(NameRef, Size, GV->getAlignment(), IsWeak, Visibility);
|
|
||||||
} else {
|
|
||||||
Body = new (Alloc) DefinedBitcode(NameRef, IsWeak, Visibility);
|
|
||||||
}
|
|
||||||
Body->IsTls = GV->isThreadLocal();
|
|
||||||
SymbolBodies.push_back(Body);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
|
|
@ -18,8 +18,10 @@
|
||||||
#include "lld/Core/LLVM.h"
|
#include "lld/Core/LLVM.h"
|
||||||
#include "llvm/ADT/DenseSet.h"
|
#include "llvm/ADT/DenseSet.h"
|
||||||
#include "llvm/ADT/STLExtras.h"
|
#include "llvm/ADT/STLExtras.h"
|
||||||
|
#include "llvm/IR/Comdat.h"
|
||||||
#include "llvm/Object/Archive.h"
|
#include "llvm/Object/Archive.h"
|
||||||
#include "llvm/Object/ELF.h"
|
#include "llvm/Object/ELF.h"
|
||||||
|
#include "llvm/Object/IRObjectFile.h"
|
||||||
#include "llvm/Support/StringSaver.h"
|
#include "llvm/Support/StringSaver.h"
|
||||||
|
|
||||||
namespace lld {
|
namespace lld {
|
||||||
|
@ -180,19 +182,16 @@ public:
|
||||||
static bool classof(const InputFile *F);
|
static bool classof(const InputFile *F);
|
||||||
void parse(llvm::DenseSet<StringRef> &ComdatGroups);
|
void parse(llvm::DenseSet<StringRef> &ComdatGroups);
|
||||||
ArrayRef<SymbolBody *> getSymbols() { return SymbolBodies; }
|
ArrayRef<SymbolBody *> getSymbols() { return SymbolBodies; }
|
||||||
ArrayRef<StringRef> getExtraKeeps() { return ExtraKeeps; }
|
static bool shouldSkip(const llvm::object::BasicSymbolRef &Sym);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<SymbolBody *> SymbolBodies;
|
std::vector<SymbolBody *> SymbolBodies;
|
||||||
// Some symbols like llvm.global_ctors are internal to the IR and so
|
|
||||||
// don't show up in SymbolBodies, but must be kept when creating the
|
|
||||||
// combined LTO module. We track them here.
|
|
||||||
// We currently use a different Module for creating SymbolBody's vs when
|
|
||||||
// we are creating the combined LTO module, and so we can't store IR
|
|
||||||
// pointers directly and must rely on the IR names.
|
|
||||||
std::vector<StringRef> ExtraKeeps;
|
|
||||||
llvm::BumpPtrAllocator Alloc;
|
llvm::BumpPtrAllocator Alloc;
|
||||||
llvm::StringSaver Saver{Alloc};
|
llvm::StringSaver Saver{Alloc};
|
||||||
|
SymbolBody *
|
||||||
|
createSymbolBody(const llvm::DenseSet<const llvm::Comdat *> &KeptComdats,
|
||||||
|
const llvm::object::IRObjectFile &Obj,
|
||||||
|
const llvm::object::BasicSymbolRef &Sym);
|
||||||
};
|
};
|
||||||
|
|
||||||
// .so file.
|
// .so file.
|
||||||
|
|
|
@ -84,7 +84,8 @@ void SymbolTable<ELFT>::addFile(std::unique_ptr<InputFile> File) {
|
||||||
BitcodeFiles.emplace_back(cast<BitcodeFile>(File.release()));
|
BitcodeFiles.emplace_back(cast<BitcodeFile>(File.release()));
|
||||||
F->parse(ComdatGroups);
|
F->parse(ComdatGroups);
|
||||||
for (SymbolBody *B : F->getSymbols())
|
for (SymbolBody *B : F->getSymbols())
|
||||||
resolve(B);
|
if (B)
|
||||||
|
resolve(B);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,28 +140,33 @@ std::unique_ptr<InputFile> SymbolTable<ELFT>::codegen(Module &M) {
|
||||||
|
|
||||||
static void addBitcodeFile(IRMover &Mover, BitcodeFile &F,
|
static void addBitcodeFile(IRMover &Mover, BitcodeFile &F,
|
||||||
LLVMContext &Context) {
|
LLVMContext &Context) {
|
||||||
std::unique_ptr<MemoryBuffer> Buffer =
|
|
||||||
MemoryBuffer::getMemBuffer(F.MB, false);
|
std::unique_ptr<IRObjectFile> Obj =
|
||||||
std::unique_ptr<Module> M =
|
check(IRObjectFile::create(F.MB, Context));
|
||||||
check(getLazyBitcodeModule(std::move(Buffer), Context,
|
|
||||||
/*ShouldLazyLoadMetadata*/ false));
|
|
||||||
std::vector<GlobalValue *> Keep;
|
std::vector<GlobalValue *> Keep;
|
||||||
for (SymbolBody *B : F.getSymbols()) {
|
unsigned BodyIndex = 0;
|
||||||
if (&B->repl() != B)
|
ArrayRef<SymbolBody *> Bodies = F.getSymbols();
|
||||||
|
|
||||||
|
for (const BasicSymbolRef &Sym : Obj->symbols()) {
|
||||||
|
GlobalValue *GV = Obj->getSymbolGV(Sym.getRawDataRefImpl());
|
||||||
|
assert(GV);
|
||||||
|
if (GV->hasAppendingLinkage()) {
|
||||||
|
Keep.push_back(GV);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (BitcodeFile::shouldSkip(Sym))
|
||||||
|
continue;
|
||||||
|
SymbolBody *B = Bodies[BodyIndex++];
|
||||||
|
if (!B || &B->repl() != B)
|
||||||
continue;
|
continue;
|
||||||
auto *DB = dyn_cast<DefinedBitcode>(B);
|
auto *DB = dyn_cast<DefinedBitcode>(B);
|
||||||
if (!DB)
|
if (!DB)
|
||||||
continue;
|
continue;
|
||||||
GlobalValue *GV = M->getNamedValue(B->getName());
|
|
||||||
assert(GV);
|
|
||||||
Keep.push_back(GV);
|
Keep.push_back(GV);
|
||||||
}
|
}
|
||||||
for (StringRef S : F.getExtraKeeps()) {
|
|
||||||
GlobalValue *GV = M->getNamedValue(S);
|
Mover.move(Obj->takeModule(), Keep,
|
||||||
assert(GV);
|
[](GlobalValue &, IRMover::ValueAdder) {});
|
||||||
Keep.push_back(GV);
|
|
||||||
}
|
|
||||||
Mover.move(std::move(M), Keep, [](GlobalValue &, IRMover::ValueAdder) {});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is for use when debugging LTO.
|
// This is for use when debugging LTO.
|
||||||
|
|
Loading…
Reference in New Issue