rs6000: Improve indexed addressing
authorSegher Boessenkool <segher@kernel.crashing.org>
Mon, 1 Jul 2019 15:15:41 +0000 (17:15 +0200)
committerSegher Boessenkool <segher@gcc.gnu.org>
Mon, 1 Jul 2019 15:15:41 +0000 (17:15 +0200)
The function rs6000_force_indexed_or_indirect_mem makes a memory
operand suitable for indexed (or indirect) addressing.  If the memory
address isn't yet valid, it loads the whole thing into a register to
make it valid.  That isn't optimal.  This changes it to load an
address that is the sum of two things into two registers instead.
This results in lower latency code, and if inside loops, a constant
term can be moved outside the loop.

* config/rs6000/rs6000.c (rs6000_force_indexed_or_indirect_mem):
Load both operands of a PLUS into registers separately.

From-SVN: r272886

gcc/ChangeLog
gcc/config/rs6000/rs6000.c

index 1acb4a326249e276c9f878378c87597adc3612ae..868ac766d9ec6f02fc916a09c9431c5b009559f3 100644 (file)
@@ -1,3 +1,8 @@
+2019-07-01  Segher Boessenkool  <segher@kernel.crashing.org>
+
+       * config/rs6000/rs6000.c (rs6000_force_indexed_or_indirect_mem):
+       Load both operands of a PLUS into registers separately.
+
 2019-07-01  Andreas Krebbel  <krebbel@linux.ibm.com>
 
        * config/s390/vector.md: Fix shift count operand printing.
index 5e806736c42140782384f9b500a59f09caa2cebe..f59f3a96237662b9e0921c30e969a83a7b6a96a9 100644 (file)
@@ -32100,7 +32100,16 @@ rs6000_force_indexed_or_indirect_mem (rtx x)
          addr = reg;
        }
 
-      x = replace_equiv_address (x, force_reg (Pmode, addr));
+      if (GET_CODE (addr) == PLUS)
+       {
+         rtx op0 = XEXP (addr, 0);
+         rtx op1 = XEXP (addr, 1);
+         op0 = force_reg (Pmode, op0);
+         op1 = force_reg (Pmode, op1);
+         x = replace_equiv_address (x, gen_rtx_PLUS (Pmode, op0, op1));
+       }
+      else
+       x = replace_equiv_address (x, force_reg (Pmode, addr));
     }
 
   return x;