ELF: Try to create last thunk section at ThunkSectionSpacing bytes before the end.

Now that we have the ability to create short thunks, it is beneficial
for thunk sections to be surrounded by ThunkSectionSpacing bytes
of code on both sides in order to increase the likelihood that the
distance from the thunk to the target will be sufficiently small to
allow for the creation of a short thunk. This is currently the case
for most thunks that we create, except for the last one, which could,
depending on the size of the output section, potentially appear near
the end and therefore have a relatively small amount of code after it.

This patch moves the last thunk section to ThunkSectionSpacing bytes
before the end of the output section, as long as the section is larger
than 2*ThunkSectionSpacing bytes. It reduces the size of Chromium
for Android's .text section by 32KB.

Differential Revision: https://reviews.llvm.org/D44966

llvm-svn: 328889
This commit is contained in:
Peter Collingbourne
2018-03-30 18:32:24 +00:00
parent 03f270c900
commit 5e3ee94562
3 changed files with 42 additions and 29 deletions

View File

@@ -1218,17 +1218,30 @@ ThunkSection *ThunkCreator::getISThunkSec(InputSection *IS) {
//
// We follow a simple but conservative heuristic to place ThunkSections at
// offsets that are multiples of a Target specific branch range.
// For an InputSectionRange that is smaller than the range, a single
// For an InputSectionDescription that is smaller than the range, a single
// ThunkSection at the end of the range will do.
//
// For an InputSectionDescription that is more than twice the size of the range,
// we place the last ThunkSection at range bytes from the end of the
// InputSectionDescription in order to increase the likelihood that the
// distance from a thunk to its target will be sufficiently small to
// allow for the creation of a short thunk.
void ThunkCreator::createInitialThunkSections(
ArrayRef<OutputSection *> OutputSections) {
forEachInputSectionDescription(
OutputSections, [&](OutputSection *OS, InputSectionDescription *ISD) {
if (ISD->Sections.empty())
return;
uint32_t ISDBegin = ISD->Sections.front()->OutSecOff;
uint32_t ISDEnd =
ISD->Sections.back()->OutSecOff + ISD->Sections.back()->getSize();
uint32_t LastThunkLowerBound = -1;
if (ISDEnd - ISDBegin > Target->ThunkSectionSpacing * 2)
LastThunkLowerBound = ISDEnd - Target->ThunkSectionSpacing;
uint32_t ISLimit;
uint32_t PrevISLimit = ISD->Sections.front()->OutSecOff;
uint32_t ThunkUpperBound = PrevISLimit + Target->ThunkSectionSpacing;
uint32_t PrevISLimit = ISDBegin;
uint32_t ThunkUpperBound = ISDBegin + Target->ThunkSectionSpacing;
for (const InputSection *IS : ISD->Sections) {
ISLimit = IS->OutSecOff + IS->getSize();
@@ -1236,6 +1249,8 @@ void ThunkCreator::createInitialThunkSections(
addThunkSection(OS, ISD, PrevISLimit);
ThunkUpperBound = PrevISLimit + Target->ThunkSectionSpacing;
}
if (ISLimit > LastThunkLowerBound)
break;
PrevISLimit = ISLimit;
}
addThunkSection(OS, ISD, ISLimit);

View File

@@ -11,7 +11,7 @@
// RUN: llvm-objdump -d %t2 -start-address=35651584 -stop-address=35651590 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK6 %s
// RUN: llvm-objdump -d %t2 -start-address=36700160 -stop-address=36700168 -triple=armv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK7 %s
// RUN: llvm-objdump -d %t2 -start-address=48234500 -stop-address=48234512 -triple=armv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK8 %s
// RUN: llvm-objdump -d %t2 -start-address=63963140 -stop-address=63963160 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK9 %s
// RUN: llvm-objdump -d %t2 -start-address=53477380 -stop-address=53477392 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK9 %s
// RUN: llvm-objdump -d %t2 -start-address=68157440 -stop-address=68157452 -triple=armv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK10 %s
// RUN: llvm-objdump -d %t2 -start-address=69206016 -stop-address=69206024 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK11 %s
@@ -155,6 +155,13 @@ _start:
ARMFUNCTION 48
THUMBFUNCTION 49
ARMFUNCTION 50
// Expect precreated Thunk Section here
// CHECK9: __Thumbv7ABSLongThunk_afunc34:
// CHECK9-NEXT: 3300004: 40 f2 00 0c movw r12, #0
// CHECK9-NEXT: 3300008: c0 f2 30 2c movt r12, #560
// CHECK9-NEXT: 330000c: 60 47 bx r12
// CHECK9: __Thumbv7ABSLongThunk_tfunc35:
// CHECK9-NEXT: 330000e: ff f4 f7 97 b.w #-15728658 <tfunc35>
THUMBFUNCTION 51
ARMFUNCTION 52
THUMBFUNCTION 53
@@ -165,15 +172,6 @@ _start:
ARMFUNCTION 58
THUMBFUNCTION 59
ARMFUNCTION 60
// Expect precreated Thunk Section here
// CHECK9: __Thumbv7ABSLongThunk_afunc34:
// CHECK9-NEXT: 3d00004: 40 f2 00 0c movw r12, #0
// CHECK9-NEXT: 3d00008: c0 f2 30 2c movt r12, #560
// CHECK9-NEXT: 3d0000c: 60 47 bx r12
// CHECK9: __Thumbv7ABSLongThunk_tfunc35:
// CHECK9-NEXT: 3d0000e: 40 f2 01 0c movw r12, #1
// CHECK9-NEXT: 3d00012: c0 f2 40 2c movt r12, #576
// CHECK9-NEXT: 3d00016: 60 47 bx r12
THUMBFUNCTION 61
ARMFUNCTION 62
THUMBFUNCTION 63
@@ -191,5 +189,5 @@ _start:
bl tfunc35
// CHECK11: tfunc65:
// CHECK11: 4200000: 70 47 bx lr
// CHECK11-NEXT: 4200002: ff f6 ff f7 bl #-5242882
// CHECK11-NEXT: 4200006: 00 f7 02 f0 bl #-5242876
// CHECK11-NEXT: 4200002: ff f4 ff d7 bl #-15728642
// CHECK11-NEXT: 4200006: 00 f5 02 d0 bl #-15728636

View File

@@ -9,8 +9,8 @@
// RUN: llvm-objdump -d %t2 -start-address=4194304 -stop-address=4194310 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK4 %s
// RUN: llvm-objdump -d %t2 -start-address=16777216 -stop-address=16777270 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK5 %s
// RUN: llvm-objdump -d %t2 -start-address=17825792 -stop-address=17825808 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK6 %s
// RUN: llvm-objdump -d %t2 -start-address=31457280 -stop-address=31457286 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK7 %s
// RUN: llvm-objdump -d %t2 -start-address=32505860 -stop-address=32505880 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK8 %s
// RUN: llvm-objdump -d %t2 -start-address=20971524 -stop-address=20971532 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK7 %s
// RUN: llvm-objdump -d %t2 -start-address=31457280 -stop-address=31457286 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK8 %s
// RUN: llvm-objdump -d %t2 -start-address=35651584 -stop-address=35651594 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK9 %s
// RUN: llvm-objdump -d %t2 -start-address=36700160 -stop-address=36700170 -triple=thumbv7a-linux-gnueabihf | FileCheck -check-prefix=CHECK10 %s
@@ -105,6 +105,11 @@ _start:
FUNCTION 16
FUNCTION 17
FUNCTION 18
// Expect another precreated thunk section here
// CHECK7: __Thumbv7ABSLongThunk_tfunc15:
// CHECK7-NEXT: 1400004: ff f4 fc bf b.w #-3145736 <tfunc15>
// CHECK7: __Thumbv7ABSLongThunk_tfunc16:
// CHECK7-NEXT: 1400008: ff f5 fa bf b.w #-2097164 <tfunc16>
FUNCTION 19
FUNCTION 20
FUNCTION 21
@@ -117,17 +122,12 @@ _start:
FUNCTION 28
// tfunc02 is > 16Mb away, expect range extension thunks in precreated thunk
// section
// CHECK7: tfunc28:
// CHECK7-NEXT: 1e00000: 70 47 bx lr
// CHECK7-NEXT: 1e00002: 00 f6 0d 90 b.w #-14680038 <__Thumbv7ABSLongThunk_tfunc02>
// CHECK8: tfunc28:
// CHECK8-NEXT: 1e00000: 70 47 bx lr
// CHECK8-NEXT: 1e00002: 00 f6 0d 90 b.w #-14680038 <__Thumbv7ABSLongThunk_tfunc02>
b.w tfunc02
FUNCTION 29
// Expect another precreated thunk section here
// CHECK8: __Thumbv7ABSLongThunk_tfunc15:
// CHECK8-NEXT: 1f00004: ff f5 fc 97 b.w #-14680072 <tfunc15>
// CHECK8: __Thumbv7ABSLongThunk_tfunc16:
// CHECK8-NEXT: 1f00008: ff f6 fa 97 b.w #-13631500 <tfunc16>
FUNCTION 30
FUNCTION 31
FUNCTION 32
@@ -137,13 +137,13 @@ _start:
bl tfunc16
// CHECK9: tfunc32:
// CHECK9: 2200000: 70 47 bx lr
// CHECK9-NEXT: 2200002: ff f4 ff ff bl #-3145730
// CHECK9-NEXT: 2200006: ff f4 ff ff bl #-3145730
// CHECK9-NEXT: 2200002: ff f5 ff d7 bl #-14680066
// CHECK9-NEXT: 2200006: ff f5 ff d7 bl #-14680066
FUNCTION 33
bl tfunc15
bl tfunc16
// CHECK10: tfunc33:
// CHECK10: 2300000: 70 47 bx lr
// CHECK10-NEXT: 2300002: ff f7 ff f7 bl #-4194306
// CHECK10-NEXT: 2300006: ff f7 ff f7 bl #-4194306
// CHECK10-NEXT: 2300002: ff f4 ff d7 bl #-15728642
// CHECK10-NEXT: 2300006: ff f4 ff d7 bl #-15728642