Use fewer allocators.
authorRafael Espindola <rafael.espindola@gmail.com>
Thu, 27 Oct 2016 13:32:32 +0000 (13:32 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Thu, 27 Oct 2016 13:32:32 +0000 (13:32 +0000)
Instead of having 3 section allocators per file, have 3 for all files.

This is a substantial performance improvement for some cases. Linking
chromium without gc speeds up by 1.065x.

This requires using _exit in fatal since we have to avoid destructing
an InputSection if fatal is called from the constructor.

Thanks to Rui for the suggestion.

llvm-svn: 285290

lld/ELF/Error.cpp
lld/ELF/Error.h
lld/ELF/InputFiles.cpp
lld/ELF/InputFiles.h
lld/ELF/Writer.cpp

index 6c9fb09..bbe9fa1 100644 (file)
 #include "llvm/Support/Error.h"
 #include "llvm/Support/raw_ostream.h"
 
+#if !defined(_MSC_VER) && !defined(__MINGW32__)
+#include <unistd.h>
+#endif
+
 using namespace llvm;
 
 namespace lld {
@@ -43,9 +47,15 @@ void elf::error(std::error_code EC, const Twine &Prefix) {
   error(Prefix + ": " + EC.message());
 }
 
+void elf::exitLld(int Val) {
+  outs().flush();
+  errs().flush();
+  _exit(Val);
+}
+
 void elf::fatal(const Twine &Msg) {
   *ErrorOS << Argv0 << ": error: " << Msg << "\n";
-  exit(1);
+  exitLld(1);
 }
 
 void elf::fatal(std::error_code EC, const Twine &Prefix) {
index 6cb9548..5776d83 100644 (file)
@@ -45,6 +45,7 @@ template <typename T> void error(const ErrorOr<T> &V, const Twine &Prefix) {
   error(V.getError(), Prefix);
 }
 
+LLVM_ATTRIBUTE_NORETURN void exitLld(int Val);
 LLVM_ATTRIBUTE_NORETURN void fatal(const Twine &Msg);
 LLVM_ATTRIBUTE_NORETURN void fatal(std::error_code EC, const Twine &Prefix);
 
index 507090d..b0c177f 100644 (file)
@@ -386,7 +386,8 @@ elf::ObjectFile<ELFT>::createInputSection(const Elf_Shdr &Sec) {
     // If -r is given, we do not interpret or apply relocation
     // but just copy relocation sections to output.
     if (Config->Relocatable)
-      return new (IAlloc.Allocate()) InputSection<ELFT>(this, &Sec, Name);
+      return new (GAlloc<ELFT>::IAlloc.Allocate())
+          InputSection<ELFT>(this, &Sec, Name);
 
     // Find the relocation target section and associate this
     // section with it.
@@ -428,11 +429,14 @@ elf::ObjectFile<ELFT>::createInputSection(const Elf_Shdr &Sec) {
   // .eh_frame_hdr section for runtime. So we handle them with a special
   // class. For relocatable outputs, they are just passed through.
   if (Name == ".eh_frame" && !Config->Relocatable)
-    return new (EHAlloc.Allocate()) EhInputSection<ELFT>(this, &Sec, Name);
+    return new (GAlloc<ELFT>::EHAlloc.Allocate())
+        EhInputSection<ELFT>(this, &Sec, Name);
 
   if (shouldMerge(Sec))
-    return new (MAlloc.Allocate()) MergeInputSection<ELFT>(this, &Sec, Name);
-  return new (IAlloc.Allocate()) InputSection<ELFT>(this, &Sec, Name);
+    return new (GAlloc<ELFT>::MAlloc.Allocate())
+        MergeInputSection<ELFT>(this, &Sec, Name);
+  return new (GAlloc<ELFT>::IAlloc.Allocate())
+      InputSection<ELFT>(this, &Sec, Name);
 }
 
 template <class ELFT> void elf::ObjectFile<ELFT>::initializeSymbols() {
index ca232fc..083e867 100644 (file)
@@ -38,6 +38,21 @@ class InputFile;
 namespace lld {
 namespace elf {
 
+template <class ELFT> struct GAlloc {
+  static llvm::SpecificBumpPtrAllocator<InputSection<ELFT>> IAlloc;
+  static llvm::SpecificBumpPtrAllocator<MergeInputSection<ELFT>> MAlloc;
+  static llvm::SpecificBumpPtrAllocator<EhInputSection<ELFT>> EHAlloc;
+};
+
+template <class ELFT>
+llvm::SpecificBumpPtrAllocator<InputSection<ELFT>> GAlloc<ELFT>::IAlloc;
+
+template <class ELFT>
+llvm::SpecificBumpPtrAllocator<MergeInputSection<ELFT>> GAlloc<ELFT>::MAlloc;
+
+template <class ELFT>
+llvm::SpecificBumpPtrAllocator<EhInputSection<ELFT>> GAlloc<ELFT>::EHAlloc;
+
 using llvm::object::Archive;
 
 class InputFile;
@@ -233,9 +248,6 @@ private:
   // MIPS .MIPS.abiflags section defined by this file.
   std::unique_ptr<MipsAbiFlagsInputSection<ELFT>> MipsAbiFlags;
 
-  llvm::SpecificBumpPtrAllocator<InputSection<ELFT>> IAlloc;
-  llvm::SpecificBumpPtrAllocator<MergeInputSection<ELFT>> MAlloc;
-  llvm::SpecificBumpPtrAllocator<EhInputSection<ELFT>> EHAlloc;
   std::unique_ptr<DIHelper<ELFT>> DIH;
 };
 
index a280194..8a39398 100644 (file)
 #include "llvm/Support/raw_ostream.h"
 #include <climits>
 
-#if !defined(_MSC_VER) && !defined(__MINGW32__)
-#include <unistd.h>
-#endif
-
 using namespace llvm;
 using namespace llvm::ELF;
 using namespace llvm::object;
@@ -324,9 +320,7 @@ template <class ELFT> void Writer<ELFT>::run() {
     // Flush the output streams and exit immediately.  A full shutdown is a good
     // test that we are keeping track of all allocated memory, but actually
     // freeing it is a waste of time in a regular linker run.
-    outs().flush();
-    errs().flush();
-    _exit(0);
+    exitLld(0);
   }
 }