<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>