diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2015-04-17 08:11:38 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2015-04-17 08:11:38 +0000 |
commit | 607da974b2a4de3bc4f2d016c9c6c2dfe9bc8471 (patch) | |
tree | 3a5ec6edf75c8019539b642ac30d03111d0fc654 /llvm/lib/MC/ELFObjectWriter.cpp | |
parent | fb2f6c60f2e092749c9cc355a2d324e41f478c31 (diff) | |
download | bcm5719-llvm-607da974b2a4de3bc4f2d016c9c6c2dfe9bc8471.tar.gz bcm5719-llvm-607da974b2a4de3bc4f2d016c9c6c2dfe9bc8471.zip |
Write relocation sections contiguously.
Linkers normally read all the relocations upfront to compute the references
between sections. Putting them together is a bit more cache friendly.
I benchmarked linking a Release+Asserts clang with gold on a vm. I tried all
4 combinations of --gc-sections/no --gc-section hot and cold cache.
I cleared the cache with
echo 3 > /proc/sys/vm/drop_caches
and warmed it up by running the link once before timing the subsequent ones.
With cold cache and --gc-sections the time goes from
1.86130781665 +- 0.01713126697463843 seconds
to
1.82370735105 +- 0.014127522318814516 seconds
With cold cache and no --gc-sections the time goes from
1.6087245435500002 +- 0.012999066825178644 seconds
to
1.5687122041500001 +- 0.013145850126026619 seconds
With hot cache and no --gc-sections the time goes from
0.926200939 ( +- 0.33% ) seconds
to
0.907200079 ( +- 0.31% ) seconds
With hot cache and gc sections the time goes from
1.183038049 ( +- 0.34% ) seconds
to
1.147355862 ( +- 0.39% ) seconds
llvm-svn: 235165
Diffstat (limited to 'llvm/lib/MC/ELFObjectWriter.cpp')
-rw-r--r-- | llvm/lib/MC/ELFObjectWriter.cpp | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/llvm/lib/MC/ELFObjectWriter.cpp b/llvm/lib/MC/ELFObjectWriter.cpp index 8cb01c43edd..b293afc56a0 100644 --- a/llvm/lib/MC/ELFObjectWriter.cpp +++ b/llvm/lib/MC/ELFObjectWriter.cpp @@ -943,6 +943,8 @@ void ELFObjectWriter::computeIndexMap(MCAssembler &Asm, SectionIndexMap[&Section] = Index++; } + std::vector<const MCSectionELF *> RelSections; + for (MCAssembler::iterator it = Asm.begin(), ie = Asm.end(); it != ie; ++it) { const MCSectionData &SD = *it; @@ -956,9 +958,14 @@ void ELFObjectWriter::computeIndexMap(MCAssembler &Asm, if (MCSectionData *RelSD = createRelocationSection(Asm, SD)) { const MCSectionELF *RelSection = static_cast<const MCSectionELF *>(&RelSD->getSection()); - SectionIndexMap[RelSection] = Index++; + RelSections.push_back(RelSection); } } + + // Put relocation sections close together. The linker reads them + // first, so this improves cache locality. + for (const MCSectionELF * Sec: RelSections) + SectionIndexMap[Sec] = Index++; } void ELFObjectWriter::computeSymbolTable( |