<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Aug 13, 2015 at 11:37 AM, Rafael Espindola via llvm-commits <span dir="ltr"><<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: rafael<br>
Date: Thu Aug 13 13:37:23 2015<br>
New Revision: 244934<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=244934&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=244934&view=rev</a><br>
Log:<br>
Template OutputSection only over Is64Bit.<br>
<br>
This is a bit more c++ code, but:<br>
* It is less machine code: lld's text is 44688 bytes smaller.<br>
* It should be a bit more efficient in the non native endian case.<br>
* It should be a bit more efficient on architectures with slow unaligned access.<br></blockquote><div><br></div><div>Feel free to add this sort of thing to a TODO list of interesting things to look at in the future, but please avoid doing microoptimization-without-a-measured-performance-benefit until we have a working linker (and then, hopefully dropping the "without-a-measured-performance-benefit"). Almost every single one of these "NFC" patches are stepping on Michael's toes and holding up real "FC" patches that are what we need to get a working linker.</div><div><br></div><div>-- Sean Silva</div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
Modified:<br>
    lld/trunk/ELF/Writer.cpp<br>
<br>
Modified: lld/trunk/ELF/Writer.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=244934&r1=244933&r2=244934&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=244934&r1=244933&r2=244934&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/ELF/Writer.cpp (original)<br>
+++ lld/trunk/ELF/Writer.cpp Thu Aug 13 13:37:23 2015<br>
@@ -32,14 +32,15 @@ namespace {<br>
 // Chunks cannot belong to more than one OutputSections. The writer<br>
 // creates multiple OutputSections and assign them unique,<br>
 // non-overlapping file offsets and VAs.<br>
-template <class ELFT> class OutputSection {<br>
+template <bool Is64Bits> class OutputSection {<br>
 public:<br>
-  typedef typename llvm::object::ELFFile<ELFT>::uintX_t uintX_t;<br>
-  typedef typename llvm::object::ELFFile<ELFT>::Elf_Shdr Elf_Shdr;<br>
+  typedef typename std::conditional<Is64Bits, uint64_t, uint32_t>::type uintX_t;<br>
+  typedef<br>
+      typename std::conditional<Is64Bits, Elf64_Shdr, Elf32_Shdr>::type HeaderT;<br>
<br>
   OutputSection(StringRef Name, uint32_t sh_type, uintX_t sh_flags)<br>
       : Name(Name) {<br>
-    memset(&Header, 0, sizeof(Elf_Shdr));<br>
+    memset(&Header, 0, sizeof(HeaderT));<br>
     Header.sh_type = sh_type;<br>
     Header.sh_flags = sh_flags;<br>
   }<br>
@@ -47,7 +48,8 @@ public:<br>
   void setFileOffset(uintX_t Off) { Header.sh_offset = Off; }<br>
   void addChunk(Chunk *C);<br>
   std::vector<Chunk *> &getChunks() { return Chunks; }<br>
-  void writeHeaderTo(Elf_Shdr *SHdr);<br>
+  template <endianness E><br>
+  void writeHeaderTo(typename ELFFile<ELFType<E, Is64Bits>>::Elf_Shdr *SHdr);<br>
   StringRef getName() { return Name; }<br>
   void setNameOffset(uintX_t Offset) { Header.sh_name = Offset; }<br>
<br>
@@ -58,7 +60,7 @@ public:<br>
<br>
 private:<br>
   StringRef Name;<br>
-  Elf_Shdr Header;<br>
+  HeaderT Header;<br>
   std::vector<Chunk *> Chunks;<br>
 };<br>
<br>
@@ -79,8 +81,8 @@ private:<br>
<br>
   SymbolTable *Symtab;<br>
   std::unique_ptr<llvm::FileOutputBuffer> Buffer;<br>
-  llvm::SpecificBumpPtrAllocator<OutputSection<ELFT>> CAlloc;<br>
-  std::vector<OutputSection<ELFT> *> OutputSections;<br>
+  llvm::SpecificBumpPtrAllocator<OutputSection<ELFT::Is64Bits>> CAlloc;<br>
+  std::vector<OutputSection<ELFT::Is64Bits> *> OutputSections;<br>
<br>
   uintX_t FileSize;<br>
   uintX_t SizeOfHeaders;<br>
@@ -118,7 +120,7 @@ template <class ELFT> void Writer<ELFT>:<br>
   error(Buffer->commit());<br>
 }<br>
<br>
-template <class ELFT> void OutputSection<ELFT>::addChunk(Chunk *C) {<br>
+template <bool Is64Bits> void OutputSection<Is64Bits>::addChunk(Chunk *C) {<br>
   Chunks.push_back(C);<br>
   uintX_t Off = Header.sh_size;<br>
   Off = RoundUpToAlignment(Off, C->getAlign());<br>
@@ -127,8 +129,20 @@ template <class ELFT> void OutputSection<br>
   Header.sh_size = Off;<br>
 }<br>
<br>
-template <class ELFT> void OutputSection<ELFT>::writeHeaderTo(Elf_Shdr *SHdr) {<br>
-  *SHdr = Header;<br>
+template <bool Is64Bits><br>
+template <endianness E><br>
+void OutputSection<Is64Bits>::writeHeaderTo(<br>
+    typename ELFFile<ELFType<E, Is64Bits>>::Elf_Shdr *SHdr) {<br>
+  SHdr->sh_name = Header.sh_name;<br>
+  SHdr->sh_type = Header.sh_type;<br>
+  SHdr->sh_flags = Header.sh_flags;<br>
+  SHdr->sh_addr = Header.sh_addr;<br>
+  SHdr->sh_offset = Header.sh_offset;<br>
+  SHdr->sh_size = Header.sh_size;<br>
+  SHdr->sh_link = Header.sh_link;<br>
+  SHdr->sh_info = Header.sh_info;<br>
+  SHdr->sh_addralign = Header.sh_addralign;<br>
+  SHdr->sh_entsize = Header.sh_entsize;<br>
 }<br>
<br>
 namespace {<br>
@@ -161,17 +175,18 @@ template <bool Is64Bits> struct DenseMap<br>
<br>
 // Create output section objects and add them to OutputSections.<br>
 template <class ELFT> void Writer<ELFT>::createSections() {<br>
-  SmallDenseMap<SectionKey<ELFT::Is64Bits>, OutputSection<ELFT> *> Map;<br>
+  SmallDenseMap<SectionKey<ELFT::Is64Bits>, OutputSection<ELFT::Is64Bits> *><br>
+      Map;<br>
   for (std::unique_ptr<ObjectFileBase> &FileB : Symtab->ObjectFiles) {<br>
     auto &File = cast<ObjectFile<ELFT>>(*FileB);<br>
     for (SectionChunk<ELFT> *C : File.getChunks()) {<br>
       const Elf_Shdr *H = C->getSectionHdr();<br>
       SectionKey<ELFT::Is64Bits> Key{C->getSectionName(), H->sh_type,<br>
                                      H->sh_flags};<br>
-      OutputSection<ELFT> *&Sec = Map[Key];<br>
+      OutputSection<ELFT::Is64Bits> *&Sec = Map[Key];<br>
       if (!Sec) {<br>
         Sec = new (CAlloc.Allocate())<br>
-            OutputSection<ELFT>(Key.Name, Key.sh_type, Key.sh_flags);<br>
+            OutputSection<ELFT::Is64Bits>(Key.Name, Key.sh_type, Key.sh_flags);<br>
         OutputSections.push_back(Sec);<br>
       }<br>
       Sec->addChunk(C);<br>
@@ -179,8 +194,8 @@ template <class ELFT> void Writer<ELFT>:<br>
   }<br>
 }<br>
<br>
-template <class ELFT><br>
-static bool compSec(OutputSection<ELFT> *A, OutputSection<ELFT> *B) {<br>
+template <bool Is64Bits><br>
+static bool compSec(OutputSection<Is64Bits> *A, OutputSection<Is64Bits> *B) {<br>
   // Place SHF_ALLOC sections first.<br>
   return (A->getFlags() & SHF_ALLOC) && !(B->getFlags() & SHF_ALLOC);<br>
 }<br>
@@ -192,9 +207,10 @@ template <class ELFT> void Writer<ELFT>:<br>
   uintX_t VA = 0x1000; // The first page is kept unmapped.<br>
   uintX_t FileOff = SizeOfHeaders;<br>
<br>
-  std::stable_sort(OutputSections.begin(), OutputSections.end(), compSec<ELFT>);<br>
+  std::stable_sort(OutputSections.begin(), OutputSections.end(),<br>
+                   compSec<ELFT::Is64Bits>);<br>
<br>
-  for (OutputSection<ELFT> *Sec : OutputSections) {<br>
+  for (OutputSection<ELFT::Is64Bits> *Sec : OutputSections) {<br>
     if (Sec->getFlags() & SHF_ALLOC) {<br>
       Sec->setVA(VA);<br>
       VA += RoundUpToAlignment(Sec->getSize(), PageSize);<br>
@@ -267,9 +283,9 @@ template <class ELFT> void Writer<ELFT>:<br>
   auto SHdrs = reinterpret_cast<Elf_Shdr_Impl<ELFT> *>(Buf + EHdr->e_shoff);<br>
   // First entry is null.<br>
   ++SHdrs;<br>
-  for (OutputSection<ELFT> *Sec : OutputSections) {<br>
+  for (OutputSection<ELFT::Is64Bits> *Sec : OutputSections) {<br>
     Sec->setNameOffset(StrTabBuilder.getOffset(Sec->getName()));<br>
-    Sec->writeHeaderTo(SHdrs++);<br>
+    Sec->template writeHeaderTo<ELFT::TargetEndianness>(SHdrs++);<br>
   }<br>
<br>
   // String table.<br>
@@ -295,7 +311,7 @@ template <class ELFT> void Writer<ELFT>:<br>
 // Write section contents to a mmap'ed file.<br>
 template <class ELFT> void Writer<ELFT>::writeSections() {<br>
   uint8_t *Buf = Buffer->getBufferStart();<br>
-  for (OutputSection<ELFT> *Sec : OutputSections) {<br>
+  for (OutputSection<ELFT::Is64Bits> *Sec : OutputSections) {<br>
     uint8_t *SecBuf = Buf + Sec->getOffset();<br>
     for (Chunk *C : Sec->getChunks())<br>
       C->writeTo(SecBuf);<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div></div>