This is the mail archive of the gcc@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]

Indirect memory addresses vs. lra


I'm trying to write a back-end for an architecture (s12z - the ISA you can 
download from [1]).  This arch accepts indirect memory addresses.   That is to 
say, those of the form (mem (mem (...)))  and although my TARGET_LEGITIMATE_ADDRESS
function returns true for such addresses, LRA insists on reloading them out of 
existence.

For example, when compiling a code fragment:

  volatile unsigned char *led = 0x2F2;
  *led = 1;

the ira dump file shows:

(insn 7 6 8 2 (set (mem/f/c:PSI (reg/f:PSI 9 y) [3 led+0 S4 A8])
        (const_int 754 [0x2f2])) "/home/jmd/MemMem/memmem.c":15:27 96 {movpsi}
     (nil))
(insn 8 7 14 2 (set (mem/v:QI (mem/f/c:PSI (reg/f:PSI 9 y) [3 led+0 S4 A8]) [0 *led_7+0 S1 A8])
        (const_int 1 [0x1])) "/home/jmd/MemMem/memmem.c":16:8 98 {movqi}
     (nil))

which is a perfectly valid insn, and the most efficient assembler for it is:
mov.p #0x2f2, y
mov.b #1, [0,y]

However the reload dump shows this has been changed to:

(insn 7 6 22 2 (set (mem/f/c:PSI (reg/f:PSI 9 y) [3 led+0 S4 A8])
        (const_int 754 [0x2f2])) "/home/jmd/MemMem/memmem.c":15:27 96 {movpsi}
     (nil))
(insn 22 7 8 2 (set (reg:PSI 8 x [22])
        (mem/f/c:PSI (reg/f:PSI 9 y) [3 led+0 S4 A8])) "/home/jmd/MemMem/memmem.c":16:8 96 {movpsi}
     (nil))
(insn 8 22 14 2 (set (mem/v:QI (reg:PSI 8 x [22]) [0 *led_7+0 S1 A8])
        (const_int 1 [0x1])) "/home/jmd/MemMem/memmem.c":16:8 98 {movqi}
     (nil))

and ends up as:

mov.p #0x2f2, y
mov.p (0,y) x
mov.b #1, (0,x)

So this wastes a register (which leads to other issues which I don't want to go 
into in this email).

After a lot of debugging I tracked down the part of lra which is doing this 
reload to the function process_addr_reg at lra-constraints.c:1378

 if (! REG_P (reg))
    {
      if (check_only_p)
        return true;
      /* Always reload memory in an address even if the target supports such addresses.  */
      new_reg = lra_create_new_reg_with_unique_value (mode, reg, cl, "address");
      before_p = true;
    }

Changing this to

 if (! REG_P (reg))
    {
      if (check_only_p)
        return true;
      return false;
    }

solves my immediate problem.  However I imagine there was a reason for doing 
this reload, and presumably a better way of avoiding it.

Can someone explain the reason for this reload, and how I can best ensure that 
indirect memory operands are left in the compiled code?



[1] https://www.nxp.com/docs/en/reference-manual/S12ZCPU_RM_V1.pdf

-- 
Avoid eavesdropping.  Send strong encrypted email.
PGP Public key ID: 1024D/2DE827B3 
fingerprint = 8797 A26D 0854 2EAB 0285  A290 8A67 719C 2DE8 27B3
See http://sks-keyservers.net or any PGP keyserver for public key.

Attachment: signature.asc
Description: PGP signature


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