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; -/* 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) } -/* 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); }