[PATCH] RISC-V: Adjust __global_pointer$ value to reduce code size.

Palmer Dabbelt palmer@sifive.com
Mon Oct 15 23:43:00 GMT 2018


On Mon, 15 Oct 2018 16:01:37 PDT (-0700), Jim Wilson wrote:
> For RISC-V, the compiler doesn't emit gp-relative references, they are created
> during relaxation.  Before this patch, the gp value is sdata+0x800 which is
> guaranteed to cover as much as sdata+sbss as possible, but when they are
> smaller than 0x1000 we end up wasting some of the gp-relative range.  This
> changes the calculation to shift gp down when possible, while still covering
> all of sdata+sbss.  This reduces code size for a trivial hello world program
> by about 0.5%.  For a more realistic benchmark set, EEMBC Automotive-1.1, I'm
> seeing about 0.1% code size reduction on average.  For large programs, this
> has no effect.
>
> This was tested with riscv{32,64}-{elf,linux} cross binutils build and check,
> there were no regressions.  I did have to update one linker testcase to disable
> relaxation because it assumed that variable accesses in data would not be
> relaxed.  It was also tested with riscv32-elf and riscv64-linux cross gcc
> build and check, and a linux+buildroot build and boot.
>
> Committed.
>
> Jim
>
> 	ld/
> 	* emulparams/elf32lriscv-defs.sh (DATA_START_SYMBOLS): New.
> 	(SDATA_START_SYMBOLS): Define __SDATA_BEGIN__.  Don't define
> 	__global_pointer$.
> 	(OTHER_END_SYMBOLS): New.  Define __global_pointer$.
> 	* testsuite/ld-riscv-elf/pcrel-lo-addend-2.d (#ld): Add --no-relax.
> ---
>  ld/emulparams/elf32lriscv-defs.sh             | 13 ++++++++++++-
>  ld/testsuite/ld-riscv-elf/pcrel-lo-addend-2.d |  2 +-
>  2 files changed, 13 insertions(+), 2 deletions(-)
>
> diff --git a/ld/emulparams/elf32lriscv-defs.sh b/ld/emulparams/elf32lriscv-defs.sh
> index 91015d4471..5ac3b6023d 100644
> --- a/ld/emulparams/elf32lriscv-defs.sh
> +++ b/ld/emulparams/elf32lriscv-defs.sh
> @@ -30,8 +30,19 @@ TEXT_START_ADDR=0x10000
>  MAXPAGESIZE="CONSTANT (MAXPAGESIZE)"
>  COMMONPAGESIZE="CONSTANT (COMMONPAGESIZE)"
>
> -SDATA_START_SYMBOLS="${CREATE_SHLIB-__global_pointer$ = . + 0x800;}
> +DATA_START_SYMBOLS="${CREATE_SHLIB-__DATA_BEGIN__ = .;}"
> +
> +SDATA_START_SYMBOLS="${CREATE_SHLIB-__SDATA_BEGIN__ = .;}
>      *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata .srodata.*)"
>
>  INITIAL_READONLY_SECTIONS=".interp         : { *(.interp) } ${CREATE_PIE-${INITIAL_READONLY_SECTIONS}}"
>  INITIAL_READONLY_SECTIONS="${RELOCATING+${CREATE_SHLIB-${INITIAL_READONLY_SECTIONS}}}"
> +
> +# We must cover as much of sdata as possible if it exists.  If sdata+bss is
> +# smaller than 0x1000 then we should start from bss end to cover as much of
> +# the program as possible.  But we can't allow gp to cover any of rodata, as
> +# the address of variables in rodata may change during relaxation, so we start
> +# from data in that case.

This smells like a bug lurking somewhere.  IIRC we avoided relaxing anything 
that points to a mergeable segment due to these sorts of constraints, are we 
just missing something?  I would consider it a bug if users can end up with 
incorrect relaxations, regardless of where they're targeting the GP.

> +OTHER_END_SYMBOLS="${CREATE_SHLIB-__BSS_END__ = .;
> +    __global_pointer$ = MIN(__SDATA_BEGIN__ + 0x800,
> +		            MAX(__DATA_BEGIN__ + 0x800, __BSS_END__ - 0x800));}"

FWIW, when drag racing linker relaxation I always ended up using an offset of 
0x7C0 instead of 0x800 because of that extra bit of pessimism in the linker 
relaxations that eats a few bytes of offset.  IIRC that saves you something 
like 3 instructions in Dhrystone's inner loop because it allows relaxing 
against the first few bytes of .sdata.

I don't know if it matters any more here, as if I understand how this is all 
working we'll end up with GP pointing quite a way before ".sdata+0x800" for 
small programs and for big programs the extra few symbols will just be noise.

> diff --git a/ld/testsuite/ld-riscv-elf/pcrel-lo-addend-2.d b/ld/testsuite/ld-riscv-elf/pcrel-lo-addend-2.d
> index 9e94c5c399..039de102c3 100644
> --- a/ld/testsuite/ld-riscv-elf/pcrel-lo-addend-2.d
> +++ b/ld/testsuite/ld-riscv-elf/pcrel-lo-addend-2.d
> @@ -1,5 +1,5 @@
>  #name: %pcrel_lo overflow with an addend
>  #source: pcrel-lo-addend-2.s
>  #as: -march=rv32ic
> -#ld: -melf32lriscv
> +#ld: -melf32lriscv --no-relax
>  #error: .*dangerous relocation: %pcrel_lo overflow with an addend



More information about the Binutils mailing list