From 9b3acf9098607047211559b7e2771b18b5e3dce7 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Fri, 11 Mar 2016 16:11:47 +0000 Subject: [PATCH] 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 --- lld/ELF/InputFiles.cpp | 84 +++++++++++++++++++++++++++---------------------- lld/ELF/InputFiles.h | 15 +++++---- lld/ELF/SymbolTable.cpp | 38 ++++++++++++---------- 3 files changed, 76 insertions(+), 61 deletions(-) diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index 4f3b812..fcc05c2 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -436,6 +436,50 @@ static uint8_t getGvVisibility(const GlobalValue *GV) { llvm_unreachable("Unknown visibility"); } +SymbolBody * +BitcodeFile::createSymbolBody(const DenseSet &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 &ComdatGroups) { LLVMContext Context; std::unique_ptr Obj = check(IRObjectFile::create(MB, Context)); @@ -448,43 +492,9 @@ void BitcodeFile::parse(DenseSet &ComdatGroups) { KeptComdats.insert(&P.second); } - for (const BasicSymbolRef &Sym : Obj->symbols()) { - const GlobalValue *GV = Obj->getSymbolGV(Sym.getRawDataRefImpl()); - assert(GV); - 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); - } + for (const BasicSymbolRef &Sym : Obj->symbols()) + if (!shouldSkip(Sym)) + SymbolBodies.push_back(createSymbolBody(KeptComdats, *Obj, Sym)); } template diff --git a/lld/ELF/InputFiles.h b/lld/ELF/InputFiles.h index 9019241..5cd9df1 100644 --- a/lld/ELF/InputFiles.h +++ b/lld/ELF/InputFiles.h @@ -18,8 +18,10 @@ #include "lld/Core/LLVM.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/IR/Comdat.h" #include "llvm/Object/Archive.h" #include "llvm/Object/ELF.h" +#include "llvm/Object/IRObjectFile.h" #include "llvm/Support/StringSaver.h" namespace lld { @@ -180,19 +182,16 @@ public: static bool classof(const InputFile *F); void parse(llvm::DenseSet &ComdatGroups); ArrayRef getSymbols() { return SymbolBodies; } - ArrayRef getExtraKeeps() { return ExtraKeeps; } + static bool shouldSkip(const llvm::object::BasicSymbolRef &Sym); private: std::vector 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 ExtraKeeps; llvm::BumpPtrAllocator Alloc; llvm::StringSaver Saver{Alloc}; + SymbolBody * + createSymbolBody(const llvm::DenseSet &KeptComdats, + const llvm::object::IRObjectFile &Obj, + const llvm::object::BasicSymbolRef &Sym); }; // .so file. diff --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp index 1c98046..1cb9d7d 100644 --- a/lld/ELF/SymbolTable.cpp +++ b/lld/ELF/SymbolTable.cpp @@ -84,7 +84,8 @@ void SymbolTable::addFile(std::unique_ptr File) { BitcodeFiles.emplace_back(cast(File.release())); F->parse(ComdatGroups); for (SymbolBody *B : F->getSymbols()) - resolve(B); + if (B) + resolve(B); return; } @@ -139,28 +140,33 @@ std::unique_ptr SymbolTable::codegen(Module &M) { static void addBitcodeFile(IRMover &Mover, BitcodeFile &F, LLVMContext &Context) { - std::unique_ptr Buffer = - MemoryBuffer::getMemBuffer(F.MB, false); - std::unique_ptr M = - check(getLazyBitcodeModule(std::move(Buffer), Context, - /*ShouldLazyLoadMetadata*/ false)); + + std::unique_ptr Obj = + check(IRObjectFile::create(F.MB, Context)); std::vector Keep; - for (SymbolBody *B : F.getSymbols()) { - if (&B->repl() != B) + unsigned BodyIndex = 0; + ArrayRef 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; auto *DB = dyn_cast(B); if (!DB) continue; - GlobalValue *GV = M->getNamedValue(B->getName()); - assert(GV); Keep.push_back(GV); } - for (StringRef S : F.getExtraKeeps()) { - GlobalValue *GV = M->getNamedValue(S); - assert(GV); - Keep.push_back(GV); - } - Mover.move(std::move(M), Keep, [](GlobalValue &, IRMover::ValueAdder) {}); + + Mover.move(Obj->takeModule(), Keep, + [](GlobalValue &, IRMover::ValueAdder) {}); } // This is for use when debugging LTO. -- 2.7.4