On 10/20/2017 02:12 AM, Richard Biener wrote:
On Fri, Oct 20, 2017 at 4:03 AM, Sandra Loosemore
<san...@codesourcery.com> wrote:
This is the set of nios2 optimization patches that I've previously
mentioned in these threads:

https://gcc.gnu.org/ml/gcc/2017-10/msg00016.html
https://gcc.gnu.org/ml/gcc-patches/2017-10/msg00957.html

To give an overview of what this is for....

The nios2 backend currently generates quite bad code for memory
accesses with addresses involving symbolic constants.  Like a typical
RISC machine, nios2 requires splitting such 32-bit constants into
HIGH/LO_SUM pairs.  Currently this happens in expand, and address
expressions involving such constants are always converted to use a
register indirect form.

One part of the problem is that the backend currently doesn't
recognize that LO_SUM is a legitimate address form (it's register
indirect with a constant offset using the %lo relocation).  That's
fixed in these patches.

A harder problem is that doing the high/lo_sum splitting in expand
inhibits subsequent optimizations.  One such problem arises when you
have accesses to multiple fields in a static structure object.  Expand
sees this as many (symbol + offset) expressions involving the same
symbol with different constant offsets.  What we should be doing in
that case is CSE'ing the symbol address computation rather than
splitting every such expression individually.

This patch series attacks that problem by deferring splitting to the
split1 pass, which happens after cse and fwprop optimizations.
Deferring the splitting also requires that TARGET_LEGITIMATE_ADDRESS_P
accept these symbolic constant expressions until the splitting takes
place, and that code that might generate 32-bit constants in other
places (e.g., the movsi expander) must not do so after they are
supposed to have been split.

How do other targets handle this situation?  Naiively I'd have handled
the splitting at reload/LRA time ... (which would make the flag
to test reload_completed)

The problem with this is that the HIGH/LO_SUM split requires a scratch register, so it has to be done before register allocation; reload_completed is too late. Early on when I started working on this problem, I did various experiments with this, including fiddling with the insn patterns and constraints, trying to use TARGET_SECONDARY_RELOAD to manage the scratch register, etc, but I could never get it to work without completely stomping on all the unsplit symbols before reload.

I also considered a separate target-specific pass to do the splitting, but once I got it to work with the regular split mechanism I was quite happy with the design except for the "have we split yet?" hook. :-P

There are quite a number of targets using lo_sum but I'm not sure they
share the issue with symbolic constants.

Nios II resembles a simplified MIPS-ish architecture so that was where I looked first. It does some complicated stuff with trying to match up HIGH and LO_SUM pairs after the fact, and I didn't really want to go there. I looked at some other backends as well but didn't see anything I could directly copy.

-Sandra

Reply via email to