nios2: Fix PIC function call slowness
authorJoseph Myers <joseph@codesourcery.com>
Wed, 29 Jun 2022 15:55:41 +0000 (15:55 +0000)
committerJoseph Myers <joseph@codesourcery.com>
Wed, 29 Jun 2022 15:55:41 +0000 (15:55 +0000)
commitb01c075e7e6d84da846c2ff9087433a30ebeb0d2
tree4efecf25464036f90f5081b5a9dc3823e09f11e5
parent5097cdf9b8a0f00142c566b7723709db8690e51a
nios2: Fix PIC function call slowness

On Nios II, PIC function calls use R_NIOS2_CALL* relocations, which
may refer to a GOT entry that initially points to a PLT entry to
resolve the function on first call and that is then changed by the
dynamic linker to point directly to the function to be called so
subsequent calls do not go through the dynamic linker.  To quote the
ABI, "A global offset table (GOT) entry referenced using
R_NIOS2_GOT16, R_NIOS2_GOT_LO as well as R_NIOS2_GOT_HA must be
resolved at load time.  A GOT entry referenced only using
R_NIOS2_CALL16, R_NIOS2_CALL_LO as well as R_NIOS2_CALL_HA can
initially refer to a procedure linkage table (PLT) entry and then be
resolved lazily.".

However, GCC wrongly treats function addresses loaded from the GOT
with such relocations as constant.  If the address load is pulled out
of a loop, then every call in the loop looks up the function by name.
This shows up as very slow execution of many glibc testcases in glibc
2.35 and later (tests that call functions from shared libc many times
in a loop), where tests are now built as PIE by default.  Fix this
problem by using gen_rtx_MEM instead of gen_const_mem when loading
addresses for PIC function calls.

Tested with no regressions for cross to nios2-linux-gnu, where many
glibc tests pass that previously timed out.

* config/nios2/nios2.cc (nios2_load_pic_address): Use gen_rtx_MEM
not gen_const_mem for UNSPEC_PIC_CALL_SYM.
gcc/config/nios2/nios2.cc