[arm] Reduce cost of insns that are simple reg-reg moves.

Consider this sequence during combine:

Trying 18, 7 -> 22:
   18: r118:SI=r122:SI
      REG_DEAD r122:SI
    7: r114:SI=0x1-r118:SI-ltu(cc:CC_RSB,0)
      REG_DEAD r118:SI
      REG_DEAD cc:CC_RSB
   22: r1:SI=r114:SI
      REG_DEAD r114:SI
Failed to match this instruction:
(set (reg:SI 1 r1 [+4 ])
    (minus:SI (geu:SI (reg:CC_RSB 100 cc)
            (const_int 0 [0]))
        (reg:SI 122)))
Successfully matched this instruction:
(set (reg:SI 114)
    (geu:SI (reg:CC_RSB 100 cc)
        (const_int 0 [0])))
Successfully matched this instruction:
(set (reg:SI 1 r1 [+4 ])
    (minus:SI (reg:SI 114)
        (reg:SI 122)))
allowing combination of insns 18, 7 and 22
original costs 4 + 4 + 4 = 12
replacement costs 8 + 4 = 12

The costs are all correct, but we really don't want this combination
to take place.  The original costs contain an insn that is a simple
move of one pseudo register to another and it is extremely likely that
register allocation will eliminate this insn entirely.  On the other
hand, the resulting sequence really does expand into a sequence that
costs 12 (ie 3 insns).

We don't want to prevent combine from eliminating such moves, as this
can expose more combine opportunities, but we shouldn't rate them as
profitable in themselves.  We can do this be adjusting the costs
slightly so that the benefit of eliminating such a simple insn is
reduced.

We only do this before register allocation; after allocation we give
such insns their full cost.

	* config/arm/arm.c (arm_insn_cost): New function.
	(TARGET_INSN_COST): Override default definition.

From-SVN: r277174
This commit is contained in:
Richard Earnshaw 2019-10-18 19:03:03 +00:00 committed by Richard Earnshaw
parent bbead5babc
commit 24d28a8778
2 changed files with 26 additions and 0 deletions

View File

@ -1,3 +1,8 @@
2019-10-18 Richard Earnshaw <rearnsha@arm.com>
* config/arm/arm.c (arm_insn_cost): New function.
(TARGET_INSN_COST): Override default definition.
2019-10-18 Richard Earnshaw <rearnsha@arm.com> 2019-10-18 Richard Earnshaw <rearnsha@arm.com>
* config/arm/arm.c (arm_rtx_costs_internal, case MINUS): Handle * config/arm/arm.c (arm_rtx_costs_internal, case MINUS): Handle

View File

@ -181,6 +181,7 @@ static bool arm_have_conditional_execution (void);
static bool arm_cannot_force_const_mem (machine_mode, rtx); static bool arm_cannot_force_const_mem (machine_mode, rtx);
static bool arm_legitimate_constant_p (machine_mode, rtx); static bool arm_legitimate_constant_p (machine_mode, rtx);
static bool arm_rtx_costs (rtx, machine_mode, int, int, int *, bool); static bool arm_rtx_costs (rtx, machine_mode, int, int, int *, bool);
static int arm_insn_cost (rtx_insn *, bool);
static int arm_address_cost (rtx, machine_mode, addr_space_t, bool); static int arm_address_cost (rtx, machine_mode, addr_space_t, bool);
static int arm_register_move_cost (machine_mode, reg_class_t, reg_class_t); static int arm_register_move_cost (machine_mode, reg_class_t, reg_class_t);
static int arm_memory_move_cost (machine_mode, reg_class_t, bool); static int arm_memory_move_cost (machine_mode, reg_class_t, bool);
@ -510,6 +511,8 @@ static const struct attribute_spec arm_attribute_table[] =
#define TARGET_RTX_COSTS arm_rtx_costs #define TARGET_RTX_COSTS arm_rtx_costs
#undef TARGET_ADDRESS_COST #undef TARGET_ADDRESS_COST
#define TARGET_ADDRESS_COST arm_address_cost #define TARGET_ADDRESS_COST arm_address_cost
#undef TARGET_INSN_COST
#define TARGET_INSN_COST arm_insn_cost
#undef TARGET_SHIFT_TRUNCATION_MASK #undef TARGET_SHIFT_TRUNCATION_MASK
#define TARGET_SHIFT_TRUNCATION_MASK arm_shift_truncation_mask #define TARGET_SHIFT_TRUNCATION_MASK arm_shift_truncation_mask
@ -11486,6 +11489,24 @@ arm_rtx_costs (rtx x, machine_mode mode ATTRIBUTE_UNUSED, int outer_code,
return result; return result;
} }
static int
arm_insn_cost (rtx_insn *insn, bool speed)
{
int cost;
/* Don't cost a simple reg-reg move at a full insn cost: such moves
will likely disappear during register allocation. */
if (!reload_completed
&& GET_CODE (PATTERN (insn)) == SET
&& REG_P (SET_DEST (PATTERN (insn)))
&& REG_P (SET_SRC (PATTERN (insn))))
return 2;
cost = pattern_cost (PATTERN (insn), speed);
/* If the cost is zero, then it's likely a complex insn. We don't want the
cost of these to be less than something we know about. */
return cost ? cost : COSTS_N_INSNS (2);
}
/* All address computations that can be done are free, but rtx cost returns /* All address computations that can be done are free, but rtx cost returns
the same for practically all of them. So we weight the different types the same for practically all of them. So we weight the different types
of address here in the order (most pref first): of address here in the order (most pref first):