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. 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 -- Alan Modra Australia Development Lab, IBM