public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] RTL: Merge rtx_equal_p and hash_rtx functions with their callback variants
@ 2023-06-14 10:15 Uros Bizjak
  2023-06-17 16:51 ` Jeff Law
  0 siblings, 1 reply; 2+ messages in thread
From: Uros Bizjak @ 2023-06-14 10:15 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 999 bytes --]

Use default argument when callback function is not required to merge
rtx_equal_p and hash_rtx functions with their callback variants.

gcc/ChangeLog:

    * cse.cc (hash_rtx_cb): Rename to hash_rtx.
    (hash_rtx): Remove.
    * early-remat.cc (remat_candidate_hasher::equal): Update
    to call rtx_equal_p with rtx_equal_p_callback_function argument.
    * rtl.cc (rtx_equal_p_cb): Rename to rtx_equal_p.
    (rtx_equal_p): Remove.
    * rtl.h (rtx_equal_p): Add rtx_equal_p_callback_function
    argument with NULL default value.
    (rtx_equal_p_cb): Remove function declaration.
    (hash_rtx_cb): Ditto.
    (hash_rtx): Add hash_rtx_callback_function argument
    with NULL default value.
    * sel-sched-ir.cc (free_nop_pool): Update function comment.
    (skip_unspecs_callback): Ditto.
    (vinsn_init): Update to call hash_rtx with
    hash_rtx_callback_function argument.
    (vinsn_equal_p): Ditto.

Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}.

OK for master?

Uros.

[-- Attachment #2: cb.diff.txt --]
[-- Type: text/plain, Size: 15292 bytes --]

diff --git a/gcc/cse.cc b/gcc/cse.cc
index 2bb63ac4105..6f2e0d43185 100644
--- a/gcc/cse.cc
+++ b/gcc/cse.cc
@@ -2208,13 +2208,26 @@ hash_rtx_string (const char *ps)
   return hash;
 }
 
-/* Same as hash_rtx, but call CB on each rtx if it is not NULL.
+/* Hash an rtx.  We are careful to make sure the value is never negative.
+   Equivalent registers hash identically.
+   MODE is used in hashing for CONST_INTs only;
+   otherwise the mode of X is used.
+
+   Store 1 in DO_NOT_RECORD_P if any subexpression is volatile.
+
+   If HASH_ARG_IN_MEMORY_P is not NULL, store 1 in it if X contains
+   a MEM rtx which does not have the MEM_READONLY_P flag set.
+
+   Note that cse_insn knows that the hash code of a MEM expression
+   is just (int) MEM plus the hash code of the address.
+
+   Call CB on each rtx if CB is not NULL.
    When the callback returns true, we continue with the new rtx.  */
 
 unsigned
-hash_rtx_cb (const_rtx x, machine_mode mode,
-             int *do_not_record_p, int *hash_arg_in_memory_p,
-             bool have_reg_qty, hash_rtx_callback_function cb)
+hash_rtx (const_rtx x, machine_mode mode,
+	  int *do_not_record_p, int *hash_arg_in_memory_p,
+	  bool have_reg_qty, hash_rtx_callback_function cb)
 {
   int i, j;
   unsigned hash = 0;
@@ -2234,8 +2247,8 @@ hash_rtx_cb (const_rtx x, machine_mode mode,
   if (cb != NULL
       && ((*cb) (x, mode, &newx, &newmode)))
     {
-      hash += hash_rtx_cb (newx, newmode, do_not_record_p,
-                           hash_arg_in_memory_p, have_reg_qty, cb);
+      hash += hash_rtx (newx, newmode, do_not_record_p,
+			hash_arg_in_memory_p, have_reg_qty, cb);
       return hash;
     }
 
@@ -2355,9 +2368,9 @@ hash_rtx_cb (const_rtx x, machine_mode mode,
 	for (i = 0; i < units; ++i)
 	  {
 	    elt = CONST_VECTOR_ENCODED_ELT (x, i);
-	    hash += hash_rtx_cb (elt, GET_MODE (elt),
-                                 do_not_record_p, hash_arg_in_memory_p,
-                                 have_reg_qty, cb);
+	    hash += hash_rtx (elt, GET_MODE (elt),
+			      do_not_record_p, hash_arg_in_memory_p,
+			      have_reg_qty, cb);
 	  }
 
 	return hash;
@@ -2463,10 +2476,10 @@ hash_rtx_cb (const_rtx x, machine_mode mode,
 	    {
 	      for (i = 1; i < ASM_OPERANDS_INPUT_LENGTH (x); i++)
 		{
-		  hash += (hash_rtx_cb (ASM_OPERANDS_INPUT (x, i),
-                                        GET_MODE (ASM_OPERANDS_INPUT (x, i)),
-                                        do_not_record_p, hash_arg_in_memory_p,
-                                        have_reg_qty, cb)
+		  hash += (hash_rtx (ASM_OPERANDS_INPUT (x, i),
+				     GET_MODE (ASM_OPERANDS_INPUT (x, i)),
+				     do_not_record_p, hash_arg_in_memory_p,
+				     have_reg_qty, cb)
 			   + hash_rtx_string
                            (ASM_OPERANDS_INPUT_CONSTRAINT (x, i)));
 		}
@@ -2502,16 +2515,16 @@ hash_rtx_cb (const_rtx x, machine_mode mode,
 	      goto repeat;
 	    }
 
-	  hash += hash_rtx_cb (XEXP (x, i), VOIDmode, do_not_record_p,
-                               hash_arg_in_memory_p,
-                               have_reg_qty, cb);
+	  hash += hash_rtx (XEXP (x, i), VOIDmode, do_not_record_p,
+			    hash_arg_in_memory_p,
+			    have_reg_qty, cb);
 	  break;
 
 	case 'E':
 	  for (j = 0; j < XVECLEN (x, i); j++)
-	    hash += hash_rtx_cb (XVECEXP (x, i, j), VOIDmode, do_not_record_p,
-                                 hash_arg_in_memory_p,
-                                 have_reg_qty, cb);
+	    hash += hash_rtx (XVECEXP (x, i, j), VOIDmode, do_not_record_p,
+			      hash_arg_in_memory_p,
+			      have_reg_qty, cb);
 	  break;
 
 	case 's':
@@ -2538,27 +2551,6 @@ hash_rtx_cb (const_rtx x, machine_mode mode,
   return hash;
 }
 
-/* Hash an rtx.  We are careful to make sure the value is never negative.
-   Equivalent registers hash identically.
-   MODE is used in hashing for CONST_INTs only;
-   otherwise the mode of X is used.
-
-   Store 1 in DO_NOT_RECORD_P if any subexpression is volatile.
-
-   If HASH_ARG_IN_MEMORY_P is not NULL, store 1 in it if X contains
-   a MEM rtx which does not have the MEM_READONLY_P flag set.
-
-   Note that cse_insn knows that the hash code of a MEM expression
-   is just (int) MEM plus the hash code of the address.  */
-
-unsigned
-hash_rtx (const_rtx x, machine_mode mode, int *do_not_record_p,
-	  int *hash_arg_in_memory_p, bool have_reg_qty)
-{
-  return hash_rtx_cb (x, mode, do_not_record_p,
-                      hash_arg_in_memory_p, have_reg_qty, NULL);
-}
-
 /* Hash an rtx X for cse via hash_rtx.
    Stores 1 in do_not_record if any subexpression is volatile.
    Stores 1 in hash_arg_in_memory if X contains a mem rtx which
diff --git a/gcc/early-remat.cc b/gcc/early-remat.cc
index 1ee63c73c1b..93cef60c790 100644
--- a/gcc/early-remat.cc
+++ b/gcc/early-remat.cc
@@ -504,7 +504,7 @@ private:
 
 early_remat *early_remat::er;
 
-/* rtx_equal_p_cb callback that treats any two SCRATCHes as equal.
+/* rtx_equal_p callback that treats any two SCRATCHes as equal.
    This allows us to compare two copies of a pattern, even though their
    SCRATCHes are always distinct.  */
 
@@ -534,10 +534,8 @@ remat_candidate_hasher::equal (const remat_candidate *cand1,
 {
   return (cand1->regno == cand2->regno
 	  && cand1->constant_p == cand2->constant_p
-	  && (cand1->constant_p
-	      ? rtx_equal_p (cand1->remat_rtx, cand2->remat_rtx)
-	      : rtx_equal_p_cb (cand1->remat_rtx, cand2->remat_rtx,
-				scratch_equal))
+	  && rtx_equal_p (cand1->remat_rtx, cand2->remat_rtx,
+			  cand1->constant_p ? NULL : scratch_equal)
 	  && (!cand1->uses || bitmap_equal_p (cand1->uses, cand2->uses)));
 }
 
diff --git a/gcc/rtl.cc b/gcc/rtl.cc
index 0748427c8d4..0c004947751 100644
--- a/gcc/rtl.cc
+++ b/gcc/rtl.cc
@@ -412,13 +412,14 @@ int currently_expanding_to_rtl;
 
 \f
 
-/* Same as rtx_equal_p, but call CB on each pair of rtx if CB is not NULL.
-   When the callback returns true, we continue with the new pair.
-   Whenever changing this function check if rtx_equal_p below doesn't need
-   changing as well.  */
+/* Return 1 if X and Y are identical-looking rtx's.
+   This is the Lisp function EQUAL for rtx arguments.
+
+   Call CB on each pair of rtx if CB is not NULL.
+   When the callback returns true, we continue with the new pair.  */
 
 int
-rtx_equal_p_cb (const_rtx x, const_rtx y, rtx_equal_p_callback_function cb)
+rtx_equal_p (const_rtx x, const_rtx y, rtx_equal_p_callback_function cb)
 {
   int i;
   int j;
@@ -434,154 +435,7 @@ rtx_equal_p_cb (const_rtx x, const_rtx y, rtx_equal_p_callback_function cb)
   /* Invoke the callback first.  */
   if (cb != NULL
       && ((*cb) (&x, &y, &nx, &ny)))
-    return rtx_equal_p_cb (nx, ny, cb);
-
-  code = GET_CODE (x);
-  /* Rtx's of different codes cannot be equal.  */
-  if (code != GET_CODE (y))
-    return 0;
-
-  /* (MULT:SI x y) and (MULT:HI x y) are NOT equivalent.
-     (REG:SI x) and (REG:HI x) are NOT equivalent.  */
-
-  if (GET_MODE (x) != GET_MODE (y))
-    return 0;
-
-  /* MEMs referring to different address space are not equivalent.  */
-  if (code == MEM && MEM_ADDR_SPACE (x) != MEM_ADDR_SPACE (y))
-    return 0;
-
-  /* Some RTL can be compared nonrecursively.  */
-  switch (code)
-    {
-    case REG:
-      return (REGNO (x) == REGNO (y));
-
-    case LABEL_REF:
-      return label_ref_label (x) == label_ref_label (y);
-
-    case SYMBOL_REF:
-      return XSTR (x, 0) == XSTR (y, 0);
-
-    case DEBUG_EXPR:
-    case VALUE:
-    case SCRATCH:
-    CASE_CONST_UNIQUE:
-      return 0;
-
-    case CONST_VECTOR:
-      if (!same_vector_encodings_p (x, y))
-	return false;
-      break;
-
-    case DEBUG_IMPLICIT_PTR:
-      return DEBUG_IMPLICIT_PTR_DECL (x)
-	     == DEBUG_IMPLICIT_PTR_DECL (y);
-
-    case DEBUG_PARAMETER_REF:
-      return DEBUG_PARAMETER_REF_DECL (x)
-	     == DEBUG_PARAMETER_REF_DECL (y);
-
-    case ENTRY_VALUE:
-      return rtx_equal_p_cb (ENTRY_VALUE_EXP (x), ENTRY_VALUE_EXP (y), cb);
-
-    default:
-      break;
-    }
-
-  /* Compare the elements.  If any pair of corresponding elements
-     fail to match, return 0 for the whole thing.  */
-
-  fmt = GET_RTX_FORMAT (code);
-  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
-    {
-      switch (fmt[i])
-	{
-	case 'w':
-	  if (XWINT (x, i) != XWINT (y, i))
-	    return 0;
-	  break;
-
-	case 'n':
-	case 'i':
-	  if (XINT (x, i) != XINT (y, i))
-	    {
-#ifndef GENERATOR_FILE
-	      if (((code == ASM_OPERANDS && i == 6)
-		   || (code == ASM_INPUT && i == 1))
-		  && XINT (x, i) == XINT (y, i))
-		break;
-#endif
-	      return 0;
-	    }
-	  break;
-
-	case 'p':
-	  if (maybe_ne (SUBREG_BYTE (x), SUBREG_BYTE (y)))
-	    return 0;
-	  break;
-
-	case 'V':
-	case 'E':
-	  /* Two vectors must have the same length.  */
-	  if (XVECLEN (x, i) != XVECLEN (y, i))
-	    return 0;
-
-	  /* And the corresponding elements must match.  */
-	  for (j = 0; j < XVECLEN (x, i); j++)
-	    if (rtx_equal_p_cb (XVECEXP (x, i, j),
-                                XVECEXP (y, i, j), cb) == 0)
-	      return 0;
-	  break;
-
-	case 'e':
-	  if (rtx_equal_p_cb (XEXP (x, i), XEXP (y, i), cb) == 0)
-	    return 0;
-	  break;
-
-	case 'S':
-	case 's':
-	  if ((XSTR (x, i) || XSTR (y, i))
-	      && (! XSTR (x, i) || ! XSTR (y, i)
-		  || strcmp (XSTR (x, i), XSTR (y, i))))
-	    return 0;
-	  break;
-
-	case 'u':
-	  /* These are just backpointers, so they don't matter.  */
-	  break;
-
-	case '0':
-	case 't':
-	  break;
-
-	  /* It is believed that rtx's at this level will never
-	     contain anything but integers and other rtx's,
-	     except for within LABEL_REFs and SYMBOL_REFs.  */
-	default:
-	  gcc_unreachable ();
-	}
-    }
-  return 1;
-}
-
-/* Return 1 if X and Y are identical-looking rtx's.
-   This is the Lisp function EQUAL for rtx arguments.
-   Whenever changing this function check if rtx_equal_p_cb above doesn't need
-   changing as well.  */
-
-int
-rtx_equal_p (const_rtx x, const_rtx y)
-{
-  int i;
-  int j;
-  enum rtx_code code;
-  const char *fmt;
-
-  if (x == y)
-    return 1;
-  if (x == 0 || y == 0)
-    return 0;
+    return rtx_equal_p (nx, ny, cb);
 
   code = GET_CODE (x);
   /* Rtx's of different codes cannot be equal.  */
@@ -630,7 +484,7 @@ rtx_equal_p (const_rtx x, const_rtx y)
 	     == DEBUG_PARAMETER_REF_DECL (y);
 
     case ENTRY_VALUE:
-      return rtx_equal_p (ENTRY_VALUE_EXP (x), ENTRY_VALUE_EXP (y));
+      return rtx_equal_p (ENTRY_VALUE_EXP (x), ENTRY_VALUE_EXP (y), cb);
 
     default:
       break;
@@ -676,12 +530,12 @@ rtx_equal_p (const_rtx x, const_rtx y)
 
 	  /* And the corresponding elements must match.  */
 	  for (j = 0; j < XVECLEN (x, i); j++)
-	    if (rtx_equal_p (XVECEXP (x, i, j),  XVECEXP (y, i, j)) == 0)
+	    if (rtx_equal_p (XVECEXP (x, i, j), XVECEXP (y, i, j), cb) == 0)
 	      return 0;
 	  break;
 
 	case 'e':
-	  if (rtx_equal_p (XEXP (x, i), XEXP (y, i)) == 0)
+	  if (rtx_equal_p (XEXP (x, i), XEXP (y, i), cb) == 0)
 	    return 0;
 	  break;
 
diff --git a/gcc/rtl.h b/gcc/rtl.h
index 988691f5710..3995216b58b 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -3008,7 +3008,12 @@ extern rtx copy_rtx_if_shared (rtx);
 /* In rtl.cc */
 extern unsigned int rtx_size (const_rtx);
 extern rtx shallow_copy_rtx (const_rtx CXX_MEM_STAT_INFO);
-extern int rtx_equal_p (const_rtx, const_rtx);
+
+typedef int (*rtx_equal_p_callback_function) (const_rtx *, const_rtx *,
+					      rtx *, rtx *);
+extern int rtx_equal_p (const_rtx, const_rtx,
+			rtx_equal_p_callback_function = NULL);
+
 extern bool rtvec_all_equal_p (const_rtvec);
 extern bool rtvec_series_p (rtvec, int);
 
@@ -3710,16 +3715,6 @@ typedef int (*for_each_inc_dec_fn) (rtx mem, rtx op, rtx dest, rtx src,
 				    rtx srcoff, void *arg);
 extern int for_each_inc_dec (rtx, for_each_inc_dec_fn, void *arg);
 
-typedef int (*rtx_equal_p_callback_function) (const_rtx *, const_rtx *,
-                                              rtx *, rtx *);
-extern int rtx_equal_p_cb (const_rtx, const_rtx,
-                           rtx_equal_p_callback_function);
-
-typedef int (*hash_rtx_callback_function) (const_rtx, machine_mode, rtx *,
-                                           machine_mode *);
-extern unsigned hash_rtx_cb (const_rtx, machine_mode, int *, int *,
-                             bool, hash_rtx_callback_function);
-
 extern rtx regno_use_in (unsigned int, rtx);
 extern bool auto_inc_p (const_rtx);
 extern bool in_insn_list_p (const rtx_insn_list *, const rtx_insn *);
@@ -4142,7 +4137,11 @@ extern int rtx_to_tree_code (enum rtx_code);
 /* In cse.cc */
 extern int delete_trivially_dead_insns (rtx_insn *, int);
 extern bool exp_equiv_p (const_rtx, const_rtx, int, bool);
-extern unsigned hash_rtx (const_rtx x, machine_mode, int *, int *, bool);
+
+typedef int (*hash_rtx_callback_function) (const_rtx, machine_mode, rtx *,
+					   machine_mode *);
+extern unsigned hash_rtx (const_rtx, machine_mode, int *, int *,
+			  bool, hash_rtx_callback_function = NULL);
 
 /* In dse.cc */
 extern bool check_for_inc_dec (rtx_insn *insn);
diff --git a/gcc/sel-sched-ir.cc b/gcc/sel-sched-ir.cc
index 9241987d4fd..2c82e854b26 100644
--- a/gcc/sel-sched-ir.cc
+++ b/gcc/sel-sched-ir.cc
@@ -1076,7 +1076,7 @@ free_nop_pool (void)
 }
 \f
 
-/* Skip unspec to support ia64 speculation. Called from rtx_equal_p_cb.
+/* Skip unspec to support ia64 speculation. Called from rtx_equal_p.
    The callback is given two rtxes XX and YY and writes the new rtxes
    to NX and NY in case some needs to be skipped.  */
 static int
@@ -1106,7 +1106,7 @@ skip_unspecs_callback (const_rtx *xx, const_rtx *yy, rtx *nx, rtx* ny)
   return 0;
 }
 
-/* Callback, called from hash_rtx_cb.  Helps to hash UNSPEC rtx X in a correct way
+/* Callback, called from hash_rtx.  Helps to hash UNSPEC rtx X in a correct way
    to support ia64 speculation.  When changes are needed, new rtx X and new mode
    NMODE are written, and the callback returns true.  */
 static int
@@ -1188,16 +1188,16 @@ vinsn_init (vinsn_t vi, insn_t insn, bool force_unique_p)
     {
       rtx rhs = VINSN_RHS (vi);
 
-      VINSN_HASH (vi) = hash_rtx_cb (rhs, GET_MODE (rhs),
-                                     NULL, NULL, false, hrcf);
-      VINSN_HASH_RTX (vi) = hash_rtx_cb (VINSN_PATTERN (vi),
-                                         VOIDmode, NULL, NULL,
-                                         false, hrcf);
+      VINSN_HASH (vi) = hash_rtx (rhs, GET_MODE (rhs),
+				  NULL, NULL, false, hrcf);
+      VINSN_HASH_RTX (vi) = hash_rtx (VINSN_PATTERN (vi),
+				      VOIDmode, NULL, NULL,
+				      false, hrcf);
     }
   else
     {
-      VINSN_HASH (vi) = hash_rtx_cb (VINSN_PATTERN (vi), VOIDmode,
-                                     NULL, NULL, false, hrcf);
+      VINSN_HASH (vi) = hash_rtx (VINSN_PATTERN (vi), VOIDmode,
+				  NULL, NULL, false, hrcf);
       VINSN_HASH_RTX (vi) = VINSN_HASH (vi);
     }
 
@@ -1602,10 +1602,10 @@ vinsn_equal_p (vinsn_t x, vinsn_t y)
       gcc_assert (VINSN_RHS (x));
       gcc_assert (VINSN_RHS (y));
 
-      return rtx_equal_p_cb (VINSN_RHS (x), VINSN_RHS (y), repcf);
+      return rtx_equal_p (VINSN_RHS (x), VINSN_RHS (y), repcf);
     }
 
-  return rtx_equal_p_cb (VINSN_PATTERN (x), VINSN_PATTERN (y), repcf);
+  return rtx_equal_p (VINSN_PATTERN (x), VINSN_PATTERN (y), repcf);
 }
 \f
 

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH] RTL: Merge rtx_equal_p and hash_rtx functions with their callback variants
  2023-06-14 10:15 [PATCH] RTL: Merge rtx_equal_p and hash_rtx functions with their callback variants Uros Bizjak
@ 2023-06-17 16:51 ` Jeff Law
  0 siblings, 0 replies; 2+ messages in thread
From: Jeff Law @ 2023-06-17 16:51 UTC (permalink / raw)
  To: Uros Bizjak, gcc-patches



On 6/14/23 04:15, Uros Bizjak via Gcc-patches wrote:
> Use default argument when callback function is not required to merge
> rtx_equal_p and hash_rtx functions with their callback variants.
> 
> gcc/ChangeLog:
> 
>      * cse.cc (hash_rtx_cb): Rename to hash_rtx.
>      (hash_rtx): Remove.
>      * early-remat.cc (remat_candidate_hasher::equal): Update
>      to call rtx_equal_p with rtx_equal_p_callback_function argument.
>      * rtl.cc (rtx_equal_p_cb): Rename to rtx_equal_p.
>      (rtx_equal_p): Remove.
>      * rtl.h (rtx_equal_p): Add rtx_equal_p_callback_function
>      argument with NULL default value.
>      (rtx_equal_p_cb): Remove function declaration.
>      (hash_rtx_cb): Ditto.
>      (hash_rtx): Add hash_rtx_callback_function argument
>      with NULL default value.
>      * sel-sched-ir.cc (free_nop_pool): Update function comment.
>      (skip_unspecs_callback): Ditto.
>      (vinsn_init): Update to call hash_rtx with
>      hash_rtx_callback_function argument.
>      (vinsn_equal_p): Ditto.
> 
> Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}.
> 
> OK for master?
OK
jeff

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2023-06-17 16:51 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-06-14 10:15 [PATCH] RTL: Merge rtx_equal_p and hash_rtx functions with their callback variants Uros Bizjak
2023-06-17 16:51 ` Jeff Law

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).