diff mbox series

[avr,committed] Fix cost computation for bit insertions.

Message ID da686a99-84a5-e733-0029-94c11c96a377@gjlay.de
State New
Headers show
Series [avr,committed] Fix cost computation for bit insertions. | expand

Commit Message

Georg-Johann Lay May 23, 2023, 4:57 p.m. UTC
Applied this patchlet that implements proper cost computation of

(set (zero_extract (...) ...))

kind patterns that do single-bit (inverted) bit insertions.


Johann

--

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.


  static int
@@ -14574,6 +14620,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
diff mbox series

Patch

diff --git a/gcc/config/avr/avr.cc b/gcc/config/avr/avr.cc
index 9fa50ca230d..4fa6f5309b2 100644
--- a/gcc/config/avr/avr.cc
+++ b/gcc/config/avr/avr.cc
@@ -11514,6 +11514,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'.  */