Provide right LDD offset bound in avr_address_cost
authorSenthil Kumar Selvaraj <senthil_kumar.selvaraj@atmel.com>
Fri, 23 Sep 2016 07:12:35 +0000 (07:12 +0000)
committerSenthil Kumar Selvaraj <saaadhu@gcc.gnu.org>
Fri, 23 Sep 2016 07:12:35 +0000 (07:12 +0000)
This patch fixes cost computation in avr_address_cost - instead of the
hardcoded 61, it uses the already existing MAX_LD_OFFSET(mode) macro.

This showed up when investigating a code size regression in the ivopts
pass. That pass computes address_cost with and without an offset to
decide on the right induction variable candidate(s). The legitimate
address target hook returns false for offsets more than 63, so the
pass calls the TARGET_ADDRESS_COST hook with 62 as the offset.

The avr_address_cost hook returns 18 as the cost, and the ivopts pass
concludes that the cost of address with *any* offset is 18, which is not
true - the higher cost is incurred only with offsets bigger than MAX_LD_OFFSET.
This in turn results in a suboptimal choice of induction variables in the
ivopts pass. The patch changes the hardcoded 61 to use the mode
specific MAX_LD_OFFSET instead.

Regression testing with just that fix showed one additional
compilation timeout. That turned out to be the same as
https://lists.nongnu.org/archive/html/avr-gcc-list/2014-03/msg00010.html
- the middle end takes too much time to decide on the best strategy to
multiply DImode values on a 64 bit host. This already causes timeouts
for a few builtin-arith-overflow-* tests (see
https://gcc.gnu.org/ml/gcc-testresults/2016-09/msg02018.html), so it
isn't really related to this fix. Just providing a cost estimate for
DImode mul fixes the timeout though, so the patch does that by scaling
SImode costs by 2 for DImode muls.

With both changes in, there are no regressions, and the
builtin-arith-overflow-* tests now PASS and don't timeout.

gcc/ChangeLog

2016-09-22  Senthil Kumar Selvaraj  <senthil_kumar.selvaraj@atmel.com>

* config/avr/avr.c (avr_rtx_costs_1): Handle DImode MULT.
(avr_address_cost): Replace 61 with MAX_LD_OFFSET(mode).

From-SVN: r240388

gcc/ChangeLog
gcc/config/avr/avr.c

index 5d993020d80c5c062be2d2a7460fec7d2649c3cf..0c14b4d4a6c52e72822bd2ae5a146a51a57568cc 100644 (file)
@@ -1,3 +1,8 @@
+2016-09-22  Senthil Kumar Selvaraj  <senthil_kumar.selvaraj@atmel.com>
+
+       * config/avr/avr.c (avr_rtx_costs_1): Handle DImode MULT.
+       (avr_address_cost): Replace 61 with MAX_LD_OFFSET(mode).
+
 2016-09-22  Martin Sebor  <msebor@redhat.com>
 
        PR target/77676
index 5ac65b7b82aad1dd185b1db4fc375815531219f4..9cb81061dc09817302cebfe65860eb657b7c44de 100644 (file)
@@ -10293,6 +10293,7 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code ATTRIBUTE_UNUSED,
           break;
 
        case SImode:
+       case DImode:
          if (AVR_HAVE_MUL)
             {
               if (!speed)
@@ -10318,7 +10319,10 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code ATTRIBUTE_UNUSED,
                 *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 5 : 4);
             }
 
-          return true;
+          if (mode == DImode)
+            *total *= 2;
+
+          return true;
 
        default:
          return false;
@@ -10899,7 +10903,7 @@ avr_address_cost (rtx x, machine_mode mode ATTRIBUTE_UNUSED,
       && (REG_P (XEXP (x, 0))
           || GET_CODE (XEXP (x, 0)) == SUBREG))
     {
-      if (INTVAL (XEXP (x, 1)) >= 61)
+      if (INTVAL (XEXP (x, 1)) > MAX_LD_OFFSET(mode))
         cost = 18;
     }
   else if (CONSTANT_ADDRESS_P (x))