[49/61] Make rtl if-conversion more common

Message ID 20250131171232.1018281-51-aleksandar.rakic@htecgroup.com
State New
Headers
Series Improve Mips target |

Commit Message

Aleksandar Rakic Jan. 31, 2025, 5:13 p.m. UTC
  From: "dragan.mladjenovic" <dragan.mladjenovic@rt-rk.com>

Tune ifcvt parameters, so that we get if-conversion in more cases.

gcc/
	* config/mips/mips.cc (mips_rtx_costs): Reduce cost of
	if_then_else pattern.
	(mips_max_noce_ifcvt_seq_cost): New function. Decrease
	maximum permissible cost for the unconditional sequence which
	should be generated during if-conversion (for all non-r6
	targets). This disables if-conversion for non-r6 targets in
	branch-cost-1.c test.
	(mips_noce_conversion_profitable_p): New function.
	(TARGET_MAX_NOCE_IFCVT_SEQ_COST): Define hook.
	(TARGET_NOCE_CONVERSION_PROFITABLE_P): Define hook.

gcc/testsuite/

	* gcc.target/mips/branch-cost-1.c: Disable for -Os.

Cherry-picked 1d1ac2a7bdbb6a1ab1a90bfcd9fa6e8a96dcb316
and 8f596d9c4336e8f6e0a01fa22634989eda7d51da
from https://github.com/MIPS/gcc

Signed-off-by: Dragan Mladjenovic <dragan.mladjenovic@rt-rk.com>
Signed-off-by: Mihailo Stojanovic <mistojanovic@wavecomp.com>
Signed-off-by: Faraz Shahbazker <fshahbazker@wavecomp.com>
Signed-off-by: Aleksandar Rakic <aleksandar.rakic@htecgroup.com>
---
 gcc/config/mips/mips.cc                       | 65 +++++++++++++++++++
 gcc/testsuite/gcc.target/mips/branch-cost-1.c |  2 +-
 2 files changed, 66 insertions(+), 1 deletion(-)
  

Patch

diff --git a/gcc/config/mips/mips.cc b/gcc/config/mips/mips.cc
index 51d9812151a..0b155c107c2 100644
--- a/gcc/config/mips/mips.cc
+++ b/gcc/config/mips/mips.cc
@@ -70,6 +70,7 @@  along with GCC; see the file COPYING3.  If not see
 #include "opts.h"
 #include "tm-constrs.h"
 #include "print-rtl.h"
+#include "ifcvt.h"
 
 /* This file should be included last.  */
 #include "target-def.h"
@@ -5618,6 +5619,12 @@  mips_rtx_costs (rtx x, machine_mode mode, int outer_code,
 	}
       return false;
 
+    case IF_THEN_ELSE:
+	  if (reg_or_0_operand (XEXP (x, 1), VOIDmode)
+	      || reg_or_0_operand (XEXP (x, 2), VOIDmode))
+	    *total = 0;
+	 return false;
+
     default:
       return false;
     }
@@ -25641,6 +25648,58 @@  mips_bit_clear_p (enum machine_mode mode, unsigned HOST_WIDE_INT m)
 
   return false;
 }
+
+/* Implement TARGET_MAX_NOCE_IFCVT_SEQ_COST.  */
+
+static unsigned int
+mips_max_noce_ifcvt_seq_cost (edge e)
+{
+  bool predictable_p = predictable_edge_p (e);
+
+  /* If we have a parameter set, use that, otherwise take a guess using
+     BRANCH_COST.  */
+  if (predictable_p)
+    {
+      if (OPTION_SET_P (param_max_rtl_if_conversion_predictable_cost))
+	return param_max_rtl_if_conversion_predictable_cost;
+    }
+  else
+    {
+      if (OPTION_SET_P (param_max_rtl_if_conversion_unpredictable_cost))
+	return param_max_rtl_if_conversion_unpredictable_cost;
+    }
+
+  return BRANCH_COST (true, predictable_p)
+     * COSTS_N_INSNS (mips_isa_rev == 6 ? 4 : 3);
+}
+
+/* Return true if SEQ is a good candidate as a replacement for the
+   if-convertible sequence described in IF_INFO.  */
+
+static bool
+mips_noce_conversion_profitable_p (rtx_insn *seq, struct noce_if_info *if_info)
+{
+  bool speed = if_info->speed_p;
+  unsigned cost = 0;
+  rtx set;
+
+    for (rtx_insn *insn = seq; insn; insn = NEXT_INSN (insn))
+    {
+      set = single_set (insn);
+      if (set)
+	cost += pattern_cost (set, speed);
+      else
+	cost++;
+    }
+
+  if (cost <= if_info->original_cost)
+    return true;
+  /* When compiling for size, we can make a reasonably accurately guess
+     at the size growth.  When compiling for speed, use the maximum.  */
+  return speed && cost <= if_info->max_seq_cost;
+}
+
+
 /* Initialize the GCC target structure.  */
 #undef TARGET_ASM_ALIGNED_HI_OP
 #define TARGET_ASM_ALIGNED_HI_OP "\t.half\t"
@@ -25976,6 +26035,12 @@  mips_bit_clear_p (enum machine_mode mode, unsigned HOST_WIDE_INT m)
 #undef TARGET_SCHED_FUSION_PRIORITY
 #define TARGET_SCHED_FUSION_PRIORITY mips_sched_fusion_priority
 
+#undef TARGET_MAX_NOCE_IFCVT_SEQ_COST
+#define TARGET_MAX_NOCE_IFCVT_SEQ_COST mips_max_noce_ifcvt_seq_cost
+
+#undef TARGET_NOCE_CONVERSION_PROFITABLE_P
+#define TARGET_NOCE_CONVERSION_PROFITABLE_P mips_noce_conversion_profitable_p
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 #include "gt-mips.h"
diff --git a/gcc/testsuite/gcc.target/mips/branch-cost-1.c b/gcc/testsuite/gcc.target/mips/branch-cost-1.c
index 7f7ebbe5fc9..006a29a7361 100644
--- a/gcc/testsuite/gcc.target/mips/branch-cost-1.c
+++ b/gcc/testsuite/gcc.target/mips/branch-cost-1.c
@@ -1,5 +1,5 @@ 
 /* { dg-options "-mbranch-cost=1 (HAS_MOVN)" } */
-/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-Os" } { "" } } */
 NOMIPS16 int
 foo (int x, int y, int z, int k)
 {