Avoid calling getNamedValue.
authorRafael Espindola <rafael.espindola@gmail.com>
Fri, 11 Mar 2016 16:11:47 +0000 (16:11 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Fri, 11 Mar 2016 16:11:47 +0000 (16:11 +0000)
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
lld/ELF/InputFiles.h
lld/ELF/SymbolTable.cpp

index 4f3b812..fcc05c2 100644 (file)
@@ -436,6 +436,50 @@ static uint8_t getGvVisibility(const GlobalValue *GV) {
   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));
@@ -448,43 +492,9 @@ void BitcodeFile::parse(DenseSet<StringRef> &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 <typename T>
index 9019241..5cd9df1 100644 (file)
 #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<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.
index 1c98046..1cb9d7d 100644 (file)
@@ -84,7 +84,8 @@ void SymbolTable<ELFT>::addFile(std::unique_ptr<InputFile> File) {
     BitcodeFiles.emplace_back(cast<BitcodeFile>(File.release()));
     F->parse(ComdatGroups);
     for (SymbolBody *B : F->getSymbols())
-      resolve(B);
+      if (B)
+        resolve(B);
     return;
   }
 
@@ -139,28 +140,33 @@ std::unique_ptr<InputFile> SymbolTable<ELFT>::codegen(Module &M) {
 
 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.