@@ -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
@@ -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)));
}
@@ -412,13 +412,14 @@ int currently_expanding_to_rtl;
-/* 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;
@@ -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);
@@ -1076,7 +1076,7 @@ free_nop_pool (void)
}
-/* 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);
}