From b4b0b34181de1e28cd55ed5123b15cef13db858a Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Fri, 17 Apr 2015 08:11:38 +0000 Subject: [PATCH] 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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@235165 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/MC/ELFObjectWriter.cpp | 9 ++++++++- test/MC/ARM/eh-directive-section-comdat.s | 4 ++-- test/MC/ARM/eh-directive-section.s | 6 +++--- test/MC/ARM/eh-link.s | 6 +++--- test/MC/ELF/comdat-reloc.s | 4 ++-- 5 files changed, 18 insertions(+), 11 deletions(-) diff --git a/lib/MC/ELFObjectWriter.cpp b/lib/MC/ELFObjectWriter.cpp index 8cb01c43edd..b293afc56a0 100644 --- a/lib/MC/ELFObjectWriter.cpp +++ b/lib/MC/ELFObjectWriter.cpp @@ -943,6 +943,8 @@ void ELFObjectWriter::computeIndexMap(MCAssembler &Asm, SectionIndexMap[&Section] = Index++; } + std::vector 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(&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( diff --git a/test/MC/ARM/eh-directive-section-comdat.s b/test/MC/ARM/eh-directive-section-comdat.s index 296718f096c..fb2a83b47e4 100644 --- a/test/MC/ARM/eh-directive-section-comdat.s +++ b/test/MC/ARM/eh-directive-section-comdat.s @@ -52,7 +52,7 @@ func1: @ The second, third, and fourth word should correspond to the section index @ of .TEST1, .ARM.extab.TEST1, and .ARM.exidx.TEST1. @------------------------------------------------------------------------------- -@ CHECK: 0000: 01000000 05000000 06000000 08000000 |................| +@ CHECK: 0000: 01000000 05000000 06000000 07000000 |................| @ CHECK: ) @ CHECK: } @@ -96,7 +96,7 @@ func1: @ Check the .ARM.exidx.TEST1 section @------------------------------------------------------------------------------- @ CHECK: Section { -@ CHECK: Index: 8 +@ CHECK: Index: 7 @ CHECK: Name: .ARM.exidx.TEST1 @ CHECK: Type: SHT_ARM_EXIDX (0x70000001) @------------------------------------------------------------------------------- diff --git a/test/MC/ARM/eh-directive-section.s b/test/MC/ARM/eh-directive-section.s index 671d10679d1..53ac48e848b 100644 --- a/test/MC/ARM/eh-directive-section.s +++ b/test/MC/ARM/eh-directive-section.s @@ -109,7 +109,7 @@ func2: @ Check the TEST2 section (without the dot in the beginning) @------------------------------------------------------------------------------- @ CHECK: Section { -@ CHECK: Index: 9 +@ CHECK: Index: 7 @ CHECK: Name: TEST2 @ CHECK: SectionData ( @ CHECK: 0000: 1EFF2FE1 |../.| @@ -143,7 +143,7 @@ func2: @------------------------------------------------------------------------------- @ This section should linked with TEST2 section. @------------------------------------------------------------------------------- -@ CHECK: Link: 9 +@ CHECK: Link: 7 @------------------------------------------------------------------------------- @ The first word should be relocated to the code address in TEST2 section. @@ -175,6 +175,6 @@ func2: @ CHECK: } @ CHECK: Symbol { @ CHECK: Name: func2 -@ CHECK: Section: TEST2 (0x9) +@ CHECK: Section: TEST2 (0x7) @ CHECK: } @ CHECK: ] diff --git a/test/MC/ARM/eh-link.s b/test/MC/ARM/eh-link.s index 0c44c0e2c06..296f9072e0e 100644 --- a/test/MC/ARM/eh-link.s +++ b/test/MC/ARM/eh-link.s @@ -43,7 +43,7 @@ @ CHECK-NEXT: } @ CHECK: Section { -@ CHECK: Index: 9 +@ CHECK: Index: 8 @ CHECK-NEXT: Name: .text @ CHECK-NEXT: Type: SHT_PROGBITS @ CHECK-NEXT: Flags [ @@ -60,7 +60,7 @@ @ CHECK-NEXT: EntrySize: 0 @ CHECK-NEXT: } @ CHECK-NEXT: Section { -@ CHECK-NEXT: Index: 10 +@ CHECK-NEXT: Index: 9 @ CHECK-NEXT: Name: .ARM.exidx @ CHECK-NEXT: Type: SHT_ARM_EXIDX @ CHECK-NEXT: Flags [ @@ -71,7 +71,7 @@ @ CHECK-NEXT: Address: 0x0 @ CHECK-NEXT: Offset: @ CHECK-NEXT: Size: 8 -@ CHECK-NEXT: Link: 9 +@ CHECK-NEXT: Link: 8 @ CHECK-NEXT: Info: 0 @ CHECK-NEXT: AddressAlignment: 4 @ CHECK-NEXT: EntrySize: 0 diff --git a/test/MC/ELF/comdat-reloc.s b/test/MC/ELF/comdat-reloc.s index d893a7b149e..e7aa3d93738 100644 --- a/test/MC/ELF/comdat-reloc.s +++ b/test/MC/ELF/comdat-reloc.s @@ -16,9 +16,9 @@ world: // CHECK: Name: .group // CHECK-NOT: SectionData // CHECK: SectionData -// CHECK-NEXT: 0000: 01000000 06000000 07000000 +// CHECK-NEXT: 0000: 01000000 05000000 07000000 -// CHECK: Index: 6 +// CHECK: Index: 5 // CHECK-NEXT: Name: .text.world // CHECK-NOT: Section { // CHECK: SHF_GROUP -- 2.34.1