This patch calculates more accurate shift costs, but makes
the costs for larger offsets no more expensive than the costs
for an unrolled shift.

Ok for trunk?

Johann

--

AVR: target/54378 - Reconsider the default shift costs.

This patch calculates more accurate shift costs, but makes
the costs for larger offsets no more expensive than the costs
for an unrolled shift.

gcc/
        PR target/54378
        * config/avr/avr.cc (avr_default_shift_costs): New static function.
        (avr_rtx_costs_1) [ASHIFT, LSHIFTRT, ASHIFTRT]: Use it
        to determine the default shift costs for shifts with a
        constant shift offset.
    AVR: target/54378 - Reconsider the default shift costs.
    
    This patch calculates more accurate shift costs, but makes
    the costs for larger offsets no more expensive than the costs
    for an unrolled shift.
    
    gcc/
            PR target/54378
            * config/avr/avr.cc (avr_default_shift_costs): New static function.
            (avr_rtx_costs_1) [ASHIFT, LSHIFTRT, ASHIFTRT]: Use it
            to determine the default shift costs for shifts with a
            constant shift offset.

diff --git a/gcc/config/avr/avr.cc b/gcc/config/avr/avr.cc
index 8fab896b70f..245c579a075 100644
--- a/gcc/config/avr/avr.cc
+++ b/gcc/config/avr/avr.cc
@@ -12028,6 +12028,24 @@ avr_operand_rtx_cost (rtx x, machine_mode mode, rtx_code outer,
   return total;
 }
 
+
+/* Return the default shift costs for an n-byte shift with a constant
+   bit offset in terms of cycles (speed) or in terms of words (!speed).  */
+
+static int
+avr_default_shift_costs (int n_bytes, int offset, bool speed)
+{
+  int c_space = 3 + n_bytes;
+  int c_speed = offset <= 4
+    ? (3 + n_bytes) * offset
+    // For larger offsets, don't make the speed costs more costly than
+    // an unrolled shift, because we cannot rollback from an unrolled shift.
+    : n_bytes * offset;
+
+  return COSTS_N_INSNS (speed ? c_speed : c_space);
+}
+
+
 /* Worker function for AVR backend's rtx_cost function.
    X is rtx expression whose cost is to be calculated.
    Return true if the complete cost has been computed.
@@ -12038,8 +12056,11 @@ static bool
 avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code,
 		 int /*opno*/, int *total, bool speed)
 {
-  rtx_code code = GET_CODE (x);
-  HOST_WIDE_INT val;
+  const rtx_code code = GET_CODE (x);
+  const int n_bytes = GET_MODE_SIZE (mode);
+  const HOST_WIDE_INT val1 = BINARY_P (x) && CONST_INT_P (XEXP (x, 1))
+    ? INTVAL (XEXP (x, 1))
+    : -1;
 
   switch (code)
     {
@@ -12054,7 +12075,7 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code,
       return true;
 
     case MEM:
-      *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
+      *total = COSTS_N_INSNS (n_bytes);
       return true;
 
     case NEG:
@@ -12068,7 +12089,7 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code,
 	case E_HImode:
 	case E_PSImode:
 	case E_SImode:
-	  *total = COSTS_N_INSNS (2 * GET_MODE_SIZE (mode) - 1);
+	  *total = COSTS_N_INSNS (2 * n_bytes - 1);
 	  break;
 
 	default:
@@ -12092,19 +12113,19 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code,
       return true;
 
     case NOT:
-      *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
+      *total = COSTS_N_INSNS (n_bytes);
       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
       return true;
 
     case ZERO_EXTEND:
-      *total = COSTS_N_INSNS (GET_MODE_SIZE (mode)
+      *total = COSTS_N_INSNS (n_bytes
 			      - GET_MODE_SIZE (GET_MODE (XEXP (x, 0))));
       *total += avr_operand_rtx_cost (XEXP (x, 0), GET_MODE (XEXP (x, 0)),
 				      code, 0, speed);
       return true;
 
     case SIGN_EXTEND:
-      *total = COSTS_N_INSNS (GET_MODE_SIZE (mode) + 2
+      *total = COSTS_N_INSNS (n_bytes + 2
 			      - GET_MODE_SIZE (GET_MODE (XEXP (x, 0))));
       *total += avr_operand_rtx_cost (XEXP (x, 0), GET_MODE (XEXP (x, 0)),
 				      code, 0, speed);
@@ -12144,13 +12165,13 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code,
       if (GET_CODE (XEXP (x, 0)) == ZERO_EXTEND
 	  && REG_P (XEXP (x, 1)))
 	{
-	  *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
+	  *total = COSTS_N_INSNS (n_bytes);
 	  return true;
 	}
       if (REG_P (XEXP (x, 0))
 	  && GET_CODE (XEXP (x, 1)) == ZERO_EXTEND)
 	{
-	  *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
+	  *total = COSTS_N_INSNS (n_bytes);
 	  return true;
 	}
 
@@ -12159,8 +12180,8 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code,
 	  && REG_P (XEXP (x, 1)))
 	{
 	  int size2 = GET_MODE_SIZE (GET_MODE (XEXP (XEXP (x, 0), 0)));
-	  *total = COSTS_N_INSNS (2 + GET_MODE_SIZE (mode)
-				  + (GET_MODE_SIZE (mode) > 1 + size2));
+	  *total = COSTS_N_INSNS (2 + n_bytes
+				  + (n_bytes > 1 + size2));
 	  return true;
 	}
 
@@ -12249,7 +12270,7 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code,
       if (REG_P (XEXP (x, 0))
 	  && GET_CODE (XEXP (x, 1)) == ZERO_EXTEND)
 	{
-	  *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
+	  *total = COSTS_N_INSNS (n_bytes);
 	  return true;
 	}
       // *sub<HISI:mode>3.sign_extend.<QIPSI:mode>
@@ -12257,8 +12278,8 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code,
 	  && GET_CODE (XEXP (x, 1)) == SIGN_EXTEND)
 	{
 	  int size2 = GET_MODE_SIZE (GET_MODE (XEXP (XEXP (x, 1), 0)));
-	  *total = COSTS_N_INSNS (2 + GET_MODE_SIZE (mode)
-				  + (GET_MODE_SIZE (mode) > 1 + size2));
+	  *total = COSTS_N_INSNS (2 + n_bytes
+				  + (n_bytes > 1 + size2));
 	  return true;
 	}
 
@@ -12321,17 +12342,17 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code,
 	      || LSHIFTRT == GET_CODE (XEXP (x, 0))))
 	{
 	  // "*insv.any_shift.<mode>
-	  *total = COSTS_N_INSNS (1 + GET_MODE_SIZE (mode));
+	  *total = COSTS_N_INSNS (1 + n_bytes);
 	  return true;
 	}
-      *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
+      *total = COSTS_N_INSNS (n_bytes);
       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
       if (!CONST_INT_P (XEXP (x, 1)))
 	*total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
       return true;
 
     case XOR:
-      *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
+      *total = COSTS_N_INSNS (n_bytes);
       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
       *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
       return true;
@@ -12445,12 +12466,12 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code,
       if (!speed)
 	*total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 2 : 1);
       else
-	*total = COSTS_N_INSNS (15 * GET_MODE_SIZE (mode));
+	*total = COSTS_N_INSNS (15 * n_bytes);
       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
       /* For div/mod with const-int divisor we have at least the cost of
 	 loading the divisor. */
       if (CONST_INT_P (XEXP (x, 1)))
-	*total += COSTS_N_INSNS (GET_MODE_SIZE (mode));
+	*total += COSTS_N_INSNS (n_bytes);
       /* Add some overall penaly for clobbering and moving around registers */
       *total += COSTS_N_INSNS (2);
       return true;
@@ -12459,20 +12480,18 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code,
       switch (mode)
 	{
 	case E_QImode:
-	  if (CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) == 4)
+	  if (val1 == 4)
 	    *total = COSTS_N_INSNS (1);
-
 	  break;
 
 	case E_HImode:
-	  if (CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) == 8)
+	  if (val1 == 8)
 	    *total = COSTS_N_INSNS (3);
-
 	  break;
 
 	case E_SImode:
 	  if (CONST_INT_P (XEXP (x, 1)))
-	    switch (INTVAL (XEXP (x, 1)))
+	    switch (val1)
 	      {
 	      case 8:
 	      case 24:
@@ -12512,11 +12531,10 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code,
 	    }
 	  else
 	    {
-	      val = INTVAL (XEXP (x, 1));
-	      if (val == 7)
+	      if (val1 == 7)
 		*total = COSTS_N_INSNS (3);
-	      else if (val >= 0 && val <= 7)
-		*total = COSTS_N_INSNS (val);
+	      else if (val1 >= 0 && val1 <= 7)
+		*total = COSTS_N_INSNS (val1);
 	      else
 		*total = COSTS_N_INSNS (1);
 	    }
@@ -12548,7 +12566,7 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code,
 					      speed);
 	    }
 	  else
-	    switch (INTVAL (XEXP (x, 1)))
+	    switch (val1)
 	      {
 	      case 0:
 		*total = 0;
@@ -12581,9 +12599,8 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code,
 		*total = COSTS_N_INSNS (!speed ? 5 : 10);
 		break;
 	      default:
-		*total = COSTS_N_INSNS (!speed ? 5 : 41);
-		*total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
-						speed);
+		*total = avr_default_shift_costs (n_bytes, val1, speed);
+		break;
 	      }
 	  break;
 
@@ -12593,7 +12610,7 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code,
 	      *total = COSTS_N_INSNS (!speed ? 6 : 73);
 	    }
 	  else
-	    switch (INTVAL (XEXP (x, 1)))
+	    switch (val1)
 	      {
 	      case 0:
 		*total = 0;
@@ -12607,7 +12624,7 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code,
 		*total = COSTS_N_INSNS (5);
 		break;
 	      default:
-		*total = COSTS_N_INSNS (!speed ? 5 : 3 * INTVAL (XEXP (x, 1)));
+		*total = avr_default_shift_costs (n_bytes, val1, speed);
 		break;
 	      }
 	  break;
@@ -12620,7 +12637,7 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code,
 					      speed);
 	    }
 	  else
-	    switch (INTVAL (XEXP (x, 1)))
+	    switch (val1)
 	      {
 	      case 0:
 		*total = 0;
@@ -12640,9 +12657,8 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code,
 		*total = COSTS_N_INSNS (!speed ? 7 : 8);
 		break;
 	      default:
-		*total = COSTS_N_INSNS (!speed ? 7 : 113);
-		*total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
-						speed);
+		*total = avr_default_shift_costs (n_bytes, val1, speed);
+		break;
 	      }
 	  break;
 
@@ -12664,13 +12680,12 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code,
 	    }
 	  else
 	    {
-	      val = INTVAL (XEXP (x, 1));
-	      if (val == 6)
+	      if (val1 == 6)
 		*total = COSTS_N_INSNS (4);
-	      else if (val == 7)
+	      else if (val1 == 7)
 		*total = COSTS_N_INSNS (2);
-	      else if (val >= 0 && val <= 7)
-		*total = COSTS_N_INSNS (val);
+	      else if (val1 >= 0 && val1 <= 7)
+		*total = COSTS_N_INSNS (val1);
 	      else
 		*total = COSTS_N_INSNS (1);
 	    }
@@ -12693,7 +12708,7 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code,
 					      speed);
 	    }
 	  else
-	    switch (INTVAL (XEXP (x, 1)))
+	    switch (val1)
 	      {
 	      case 0:
 		*total = 0;
@@ -12725,9 +12740,8 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code,
 		*total = COSTS_N_INSNS (!speed ? 5 : 8);
 		break;
 	      default:
-		*total = COSTS_N_INSNS (!speed ? 5 : 41);
-		*total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
-						speed);
+		*total = avr_default_shift_costs (n_bytes, val1, speed);
+		break;
 	      }
 	  break;
 
@@ -12737,7 +12751,7 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code,
 	      *total = COSTS_N_INSNS (!speed ? 6 : 73);
 	    }
 	  else
-	    switch (INTVAL (XEXP (x, 1)))
+	    switch (val1)
 	      {
 	      case 0:
 		*total = 0;
@@ -12753,7 +12767,7 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code,
 		*total = COSTS_N_INSNS (4);
 		break;
 	      default:
-		*total = COSTS_N_INSNS (!speed ? 5 : 3 * INTVAL (XEXP (x, 1)));
+		*total = avr_default_shift_costs (n_bytes, val1, speed);
 		break;
 	      }
 	  break;
@@ -12766,7 +12780,7 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code,
 					      speed);
 	    }
 	  else
-	    switch (INTVAL (XEXP (x, 1)))
+	    switch (val1)
 	      {
 	      case 0:
 		*total = 0;
@@ -12786,9 +12800,8 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code,
 		*total = COSTS_N_INSNS (AVR_HAVE_MOVW ? 4 : 5);
 		break;
 	      default:
-		*total = COSTS_N_INSNS (!speed ? 7 : 113);
-		*total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
-						speed);
+		*total = avr_default_shift_costs (n_bytes, val1, speed);
+		break;
 	      }
 	  break;
 
@@ -12816,11 +12829,10 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code,
 	    }
 	  else
 	    {
-	      val = INTVAL (XEXP (x, 1));
-	      if (val == 7)
+	      if (val1 == 7)
 		*total = COSTS_N_INSNS (3);
-	      else if (val >= 0 && val <= 7)
-		*total = COSTS_N_INSNS (val);
+	      else if (val1 >= 0 && val1 <= 7)
+		*total = COSTS_N_INSNS (val1);
 	      else
 		*total = COSTS_N_INSNS (1);
 	    }
@@ -12834,7 +12846,7 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code,
 					      speed);
 	    }
 	  else
-	    switch (INTVAL (XEXP (x, 1)))
+	    switch (val1)
 	      {
 	      case 0:
 		*total = 0;
@@ -12869,9 +12881,8 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code,
 		*total = COSTS_N_INSNS (!speed ? 5 : 9);
 		break;
 	      default:
-		*total = COSTS_N_INSNS (!speed ? 5 : 41);
-		*total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
-						speed);
+		*total = avr_default_shift_costs (n_bytes, val1, speed);
+		break;
 	      }
 	  break;
 
@@ -12881,7 +12892,7 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code,
 	      *total = COSTS_N_INSNS (!speed ? 6 : 73);
 	    }
 	  else
-	    switch (INTVAL (XEXP (x, 1)))
+	    switch (val1)
 	      {
 	      case 0:
 		*total = 0;
@@ -12895,7 +12906,7 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code,
 		*total = COSTS_N_INSNS (5);
 		break;
 	      default:
-		*total = COSTS_N_INSNS (!speed ? 5 : 3 * INTVAL (XEXP (x, 1)));
+		*total = avr_default_shift_costs (n_bytes, val1, speed);
 		break;
 	      }
 	  break;
@@ -12908,7 +12919,7 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code,
 					      speed);
 	    }
 	  else
-	    switch (INTVAL (XEXP (x, 1)))
+	    switch (val1)
 	      {
 	      case 0:
 		*total = 0;
@@ -12928,9 +12939,8 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code,
 		*total = COSTS_N_INSNS (6);
 		break;
 	      default:
-		*total = COSTS_N_INSNS (!speed ? 7 : 113);
-		*total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
-						speed);
+		*total = avr_default_shift_costs (n_bytes, val1, speed);
+		break;
 	      }
 	  break;
 

Reply via email to