This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Unreviewed patch (expand_expr:MINUS_EXPR)


Geoff Keating wrote:

>1. It would really have helped if there were more testcases.  Jason,
>do you remember what specifically broke?  Ulrich, can you make up a
>testcase for the optimisation you're missing (perhaps using
>scan-assembler)?

Well, the problem I have is that on S/390, address generation allows
only positive displacements (in the range 0 .. 4096).  Therefore,
code like 'array[-1]' generates a subtract insn to build the address
that is then used for memory access.  This is bad as this causes an
'address generation interlock' because the result of arithmetic
instructions can be used for address generation only after a latency
of 4 cycles (on current hardware).

To improve this situation, I've added code to LEGITIMIZE_ADDRESS to
load a constant into a register, and then use this register as index
register in address generation.  This prevents the AGI, and if there
are multiple related accesses, that constant would in addition be
available for CSE.

This works fine for code like array[-1].  However, if this is rewritten
as *(array - 1), expand_expr gets into the MINUS_EXPR path, where the
current code always falls back to generating an explicit subtract insn
instead of going through LEGITIMIZE_ADDRESS in the first place.

The following test case:


/* Make sure that LEGITIMIZE_ADDRESS is called to handle
   negative displacements.  */

/* { dg-do compile { target s390-*-* } } */
/* { dg-options "-O2" } */

int test (int *addr)
{
  return *(addr - 1);
}

/* { dg-final { scan-assembler "-4096" } } */
/* { dg-final { scan-assembler-not "ahi" } } */


tries to check for this situation on s390.  Without my suggested patch,
the generated code looks like this:

test:
        ahi     %r2,-4
        l       %r2,0(%r2)
        br      %r14

With the patch applied, we get instead:

test:
        lhi     %r1,-4096
        l       %r2,4092(%r2,%r1)
        br      %r14


(%r2 is the input parameter and also return value register; ahi adds
an immediate value to a register, lhi loads an immediate into a register,
and l is a load-from-memory.  br %r14 is the function return.)


Mit freundlichen Gruessen / Best Regards

Ulrich Weigand

--
  Dr. Ulrich Weigand
  Linux for S/390 Design & Development
  IBM Deutschland Entwicklung GmbH, Schoenaicher Str. 220, 71032 Boeblingen
  Phone: +49-7031/16-3727   ---   Email: Ulrich.Weigand@de.ibm.com


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]