http://gcc.gnu.org/bugzilla/show_bug.cgi?id=9702

--- Comment #9 from Oleg Endo <olegendo at gcc dot gnu.org> ---
As it has been mentioned in https://bugs.launchpad.net/gcc-linaro/+bug/625233
the ARM back end does not use GCC's constant pool handling for constants (in
varasm.c), but rather implements its own per-function constant pool handling. 
So does the SH back end.  Both do very similar things, as both architectures
have almost the same constraints/properties in this regard.

On SH PC relative constants must be ahead of the instruction that does the PC
relative load and it must be within a certain range.  The assembler does not
allow PC relative loads across sections, as this would require it to be able to
alter the code in case something goes out of range.  This means that constant
pools must be in the same section as the compiled function.

After collecting all the referenced constants during compilation of a function,
the SH machine dependent reorg pass inserts constant pools after barriers and
splits basic blocks if needed in order to satisfy the displacement constraints
of PC relative load instructions.  The ARM reorg pass does pretty much the
same.

As far as I understand it, the constant pool handling in varasm.c does not have
such functionality.  Constant pool sharing (among multiple functions) is done
by recording all referenced constants while functions are being compiled and
then dumping the whole pool at once.  This is not good enough for ARM or SH.

Since constant pool placement has an impact on instruction lengths of branch
instructions, shared constant pools would require running some sort of IPA
before running the machine dependent reorg RTL passes on each function, which
is not possible (see comment in function.h above #define crtl).  Even if that
worked, when -ffunction-sections is used, sharing of constant pools becomes
impossible at compile time and must be done at link time after
sorting/reordering and merging the function text sections.

On SH there's a relaxation option which will annotate the assembly output with
.uses pseudo ops.  This allows the linker to shorten branch instructions and
eliminate branch offsets which are stored in the constant pool (unfortunately
binutils support for this has been broken for a while).  The same approach
could be used for dealing with constant pools in general, maybe with some
additional annotations.

Reply via email to