Improve cost computation for single-bit bit insertions.

Some miscomputation of rtx_costs lead to sub-optimal code for
single-bit bit insertions.  This patch implements TARGET_INSN_COST,
which has a chance to see the whole insn during insn combination;
in particular the SET_DEST of (set (zero_extract (...) ...)).

gcc/
	* config/avr/avr.cc (avr_insn_cost): New static function.
	(TARGET_INSN_COST): Define to that function.
This commit is contained in:
Georg-Johann Lay 2023-05-23 18:49:19 +02:00
parent 180db383a9
commit 0d2ab259bc

View File

@ -11515,6 +11515,52 @@ avr_rtx_costs (rtx x, machine_mode mode, int outer_code,
}
/* Implement `TARGET_INSN_COST'. */
/* For some insns, it is not enough to look at the cost of the SET_SRC.
In that case, have a look at the entire insn, e.g. during insn combine. */
static int
avr_insn_cost (rtx_insn *insn, bool speed)
{
const int unknown_cost = -1;
int cost = unknown_cost;
rtx set = single_set (insn);
if (set
&& ZERO_EXTRACT == GET_CODE (SET_DEST (set)))
{
// Try find anything that would flip the extracted bit.
bool not_bit_p = false;
subrtx_iterator::array_type array;
FOR_EACH_SUBRTX (iter, array, SET_SRC (set), NONCONST)
{
enum rtx_code code = GET_CODE (*iter);
not_bit_p |= code == NOT || code == XOR || code == GE;
}
// Don't go too deep into the analysis. In almost all cases,
// using BLD/BST is the best we can do for single-bit moves,
// even considering CSE.
cost = COSTS_N_INSNS (2 + not_bit_p);
}
if (cost != unknown_cost)
{
if (avr_log.rtx_costs)
avr_edump ("\n%? (%s) insn_cost=%d\n%r\n",
speed ? "speed" : "size", cost, insn);
return cost;
}
// Resort to what rtlanal.cc::insn_cost() implements as a default
// when targetm.insn_cost() is not implemented.
return pattern_cost (PATTERN (insn), speed);
}
/* Implement `TARGET_ADDRESS_COST'. */
static int
@ -14572,6 +14618,8 @@ avr_float_lib_compare_returns_bool (machine_mode mode, enum rtx_code)
#undef TARGET_ASM_FINAL_POSTSCAN_INSN
#define TARGET_ASM_FINAL_POSTSCAN_INSN avr_asm_final_postscan_insn
#undef TARGET_INSN_COST
#define TARGET_INSN_COST avr_insn_cost
#undef TARGET_REGISTER_MOVE_COST
#define TARGET_REGISTER_MOVE_COST avr_register_move_cost
#undef TARGET_MEMORY_MOVE_COST