diff mbox

[RS6000,7/7] Address cost

Message ID 20150624005546.GB1723@bubble.grove.modra.org
State New
Headers show

Commit Message

Alan Modra June 24, 2015, 12:55 a.m. UTC
The rs6000 backend currently uses an address cost of zero.  This made
sense prior to -mcmodel=medium/large, but medium/large model addresses
before splitting are really two insns.  So we should cost them one
more than other addresses.

This patch also adjusts rs6000_rtx_cost to use the new address cost,
and puts CONST, HIGH and SYMBOL_REF in their own case since they are
handling memory addresses, not MEMs.

	* config/rs6000/rs6000.c (rs6000_address_cost): New function.
	(TARGET_ADDRESS_COST): Define as rs6000_address_cost.
	(rs6000_rtx_costs): Use rs6000_address_cost for MEM.  Do not
	cost CONST, HIGH and SYMBOL_REF as for MEM.  Handle LO_SUM.

Comments

Segher Boessenkool July 8, 2015, 4:52 p.m. UTC | #1
On Wed, Jun 24, 2015 at 10:25:46AM +0930, Alan Modra wrote:
> @@ -30720,14 +30721,20 @@ rs6000_rtx_costs (rtx x, machine_mode mode, int outer_code,
>  			      - (outer_code == SET ? 1 : 0));
>        return true;
>  
> -    case CONST:
> -    case HIGH:
> -    case SYMBOL_REF:
>      case MEM:
>        /* When optimizing for size, MEM should be slightly more expensive
>  	 than generating address, e.g., (plus (reg) (const)).
>  	 L1 cache latency is about two instructions.  */
>        *total = !speed ? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
> +      *total += COSTS_N_INSNS (rs6000_address_cost (XEXP (x, 0), mode,
> +						    0, speed));

So the unit of address cost is whole insns?  Eww.

> +      return true;
> +
> +    case CONST:
> +    case HIGH:
> +    case LO_SUM:
> +    case SYMBOL_REF:
> +      *total = COSTS_N_INSNS (1);
>        return true;

Why is the cost of CONST only one insn?  Shouldn't you take the (address)
cost of whatever is inside it?


Segher
diff mbox

Patch

diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 0218d0f..96c23ca 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -1117,6 +1117,7 @@  static tree rs6000_builtin_vectorized_libmass (tree, tree, tree);
 static void rs6000_emit_set_long_const (rtx, HOST_WIDE_INT);
 static int rs6000_memory_move_cost (machine_mode, reg_class_t, bool);
 static bool rs6000_debug_rtx_costs (rtx, machine_mode, int, int, int *, bool);
+static int rs6000_address_cost (rtx, machine_mode, addr_space_t, bool);
 static int rs6000_debug_address_cost (rtx, machine_mode, addr_space_t,
 				      bool);
 static int rs6000_debug_adjust_cost (rtx_insn *, rtx, rtx_insn *, int);
@@ -1523,7 +1524,7 @@  static const struct attribute_spec rs6000_attribute_table[] =
 #undef TARGET_RTX_COSTS
 #define TARGET_RTX_COSTS rs6000_rtx_costs
 #undef TARGET_ADDRESS_COST
-#define TARGET_ADDRESS_COST hook_int_rtx_mode_as_bool_0
+#define TARGET_ADDRESS_COST rs6000_address_cost
 
 #undef TARGET_DWARF_REGISTER_SPAN
 #define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
@@ -30720,14 +30721,20 @@  rs6000_rtx_costs (rtx x, machine_mode mode, int outer_code,
 			      - (outer_code == SET ? 1 : 0));
       return true;
 
-    case CONST:
-    case HIGH:
-    case SYMBOL_REF:
     case MEM:
       /* When optimizing for size, MEM should be slightly more expensive
 	 than generating address, e.g., (plus (reg) (const)).
 	 L1 cache latency is about two instructions.  */
       *total = !speed ? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
+      *total += COSTS_N_INSNS (rs6000_address_cost (XEXP (x, 0), mode,
+						    0, speed));
+      return true;
+
+    case CONST:
+    case HIGH:
+    case LO_SUM:
+    case SYMBOL_REF:
+      *total = COSTS_N_INSNS (1);
       return true;
 
     case LABEL_REF:
@@ -31009,6 +31016,26 @@  rs6000_debug_rtx_costs (rtx x, machine_mode mode, int outer_code,
   return ret;
 }
 
+/* Say that before being split, -mcmodel=medium/large UNSPEC_TOCREL
+   addresses cost one more insn than other addresses.  */
+
+static int
+rs6000_address_cost (rtx x,
+		     machine_mode mode ATTRIBUTE_UNUSED,
+		     addr_space_t as ATTRIBUTE_UNUSED,
+		     bool speed ATTRIBUTE_UNUSED)
+{
+  if (TARGET_CMODEL == CMODEL_SMALL)
+    return 0;
+
+  if (GET_CODE (x) == PLUS)
+    x = XEXP (x, 0);
+  if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TOCREL)
+    return 1;
+
+  return 0;
+}
+
 /* Debug form of ADDRESS_COST that is selected if -mdebug=cost.  */
 
 static int