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) {
LLVMContext Context;
std::unique_ptr<IRObjectFile> Obj = check(IRObjectFile::create(MB, Context));
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 <typename T>
#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 {
static bool classof(const InputFile *F);
void parse(llvm::DenseSet<StringRef> &ComdatGroups);
ArrayRef<SymbolBody *> getSymbols() { return SymbolBodies; }
- ArrayRef<StringRef> getExtraKeeps() { return ExtraKeeps; }
+ static bool shouldSkip(const llvm::object::BasicSymbolRef &Sym);
private:
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::StringSaver Saver{Alloc};
+ SymbolBody *
+ createSymbolBody(const llvm::DenseSet<const llvm::Comdat *> &KeptComdats,
+ const llvm::object::IRObjectFile &Obj,
+ const llvm::object::BasicSymbolRef &Sym);
};
// .so file.
BitcodeFiles.emplace_back(cast<BitcodeFile>(File.release()));
F->parse(ComdatGroups);
for (SymbolBody *B : F->getSymbols())
- resolve(B);
+ if (B)
+ resolve(B);
return;
}
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*/ false));
+
+ std::unique_ptr<IRObjectFile> Obj =
+ check(IRObjectFile::create(F.MB, Context));
std::vector<GlobalValue *> Keep;
- for (SymbolBody *B : F.getSymbols()) {
- if (&B->repl() != B)
+ unsigned BodyIndex = 0;
+ 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;
auto *DB = dyn_cast<DefinedBitcode>(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.