FYI patch: using write to output the file
Rafael EspĂndola via llvm-commits
llvm-commits at lists.llvm.org
Tue Mar 8 15:15:16 PST 2016
The attached patch changes lld to use posix_memalign + write instead of mmap.
When linking "small" binaries like clang there is almost no
difference. When linking scylladb I get a 1.019X slowdown when writing
to tmpfs and a 1.040 speedup when writing to btrfs.
At this stage I would say this just shows there is potential, but we
have to at least benchmark this on a few filesystems.
It would also be interesting to try doing one write for each section.
Cheers,
Rafael
-------------- next part --------------
diff --git a/ELF/Writer.cpp b/ELF/Writer.cpp
index 0dca801..d1ae695 100644
--- a/ELF/Writer.cpp
+++ b/ELF/Writer.cpp
@@ -21,6 +21,12 @@
#include "llvm/Support/StringSaver.h"
#include "llvm/Support/raw_ostream.h"
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <unistd.h>
+
using namespace llvm;
using namespace llvm::ELF;
using namespace llvm::object;
@@ -72,9 +78,9 @@ private:
void assignAddresses();
void assignAddressesRelocatable();
void fixAbsoluteSymbols();
- bool openFile();
void writeHeader();
void writeSections();
+ void writeFile();
bool isDiscarded(InputSectionBase<ELFT> *IS) const;
StringRef getOutputSectionName(InputSectionBase<ELFT> *S) const;
bool needsInterpSection() const {
@@ -88,7 +94,7 @@ private:
void addCommonSymbols(std::vector<DefinedCommon *> &Syms);
void addCopyRelSymbols(std::vector<SharedSymbol<ELFT> *> &Syms);
- std::unique_ptr<llvm::FileOutputBuffer> Buffer;
+ std::unique_ptr<uint8_t[]> Buffer;
BumpPtrAllocator Alloc;
std::vector<OutputSectionBase<ELFT> *> OutputSections;
@@ -215,13 +221,16 @@ template <class ELFT> void Writer<ELFT>::run() {
assignAddressesRelocatable();
}
fixAbsoluteSymbols();
- if (!openFile())
- return;
+ void *Ptr;
+ int R = posix_memalign(&Ptr, 4096, FileSize);
+ assert(R == 0);
+ Buffer.reset((uint8_t *)Ptr);
+ memset(Buffer.get(), 0, FileSize);
writeHeader();
writeSections();
if (HasError)
return;
- check(Buffer->commit());
+ writeFile();
}
namespace {
@@ -1495,8 +1504,20 @@ template <class ELFT> void Writer<ELFT>::fixAbsoluteSymbols() {
}
}
+template <class ELFT> void Writer<ELFT>::writeFile() {
+ // FIXME: use a temp file
+ int FD = open(std::string(Config->OutputFile).c_str(), O_WRONLY | O_CREAT,
+ S_IRWXU);
+ if (FD == -1)
+ fatal("failed to open " + Config->OutputFile);
+ int R = ftruncate(FD, FileSize);
+ assert(R == 0);
+ ssize_t Ret = ::write(FD, Buffer.get(), FileSize);
+ assert(Ret == (ssize_t)FileSize);
+}
+
template <class ELFT> void Writer<ELFT>::writeHeader() {
- uint8_t *Buf = Buffer->getBufferStart();
+ uint8_t *Buf = Buffer.get();
memcpy(Buf, "\177ELF", 4);
auto &FirstObj = cast<ELFFileBase<ELFT>>(*Config->FirstElf);
@@ -1535,19 +1556,9 @@ template <class ELFT> void Writer<ELFT>::writeHeader() {
Sec->writeHeaderTo(++SHdrs);
}
-template <class ELFT> bool Writer<ELFT>::openFile() {
- ErrorOr<std::unique_ptr<FileOutputBuffer>> BufferOrErr =
- FileOutputBuffer::create(Config->OutputFile, FileSize,
- FileOutputBuffer::F_executable);
- if (error(BufferOrErr, "failed to open " + Config->OutputFile))
- return false;
- Buffer = std::move(*BufferOrErr);
- return true;
-}
-
// Write section contents to a mmap'ed file.
template <class ELFT> void Writer<ELFT>::writeSections() {
- uint8_t *Buf = Buffer->getBufferStart();
+ uint8_t *Buf = Buffer.get();
// PPC64 needs to process relocations in the .opd section before processing
// relocations in code-containing sections.
More information about the llvm-commits
mailing list