diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3982115c31c..49a314aebc7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2016-05-02 Eric Botcazou + + PR rtl-optimization/70886 + * sched-deps.c (estimate_dep_weak): Canonicalize cselib values. + + * cselib.h (rtx_equal_for_cselib_1): Declare. + (rtx_equal_for_cselib_p: New inline function. + * cselib.c (rtx_equal_for_cselib_p): Delete. + (rtx_equal_for_cselib_1): Make public. + 2016-05-02 Uros Bizjak * config/i386/predicates.md (nonimm_ssenomem_operand): New predicate. diff --git a/gcc/cselib.c b/gcc/cselib.c index 2922465cf83..14c7b320b03 100644 --- a/gcc/cselib.c +++ b/gcc/cselib.c @@ -49,7 +49,6 @@ static void unchain_one_value (cselib_val *); static void unchain_one_elt_list (struct elt_list **); static void unchain_one_elt_loc_list (struct elt_loc_list **); static void remove_useless_values (void); -static int rtx_equal_for_cselib_1 (rtx, rtx, machine_mode); static unsigned int cselib_hash_rtx (rtx, int, machine_mode); static cselib_val *new_cselib_val (unsigned int, machine_mode, rtx); static void add_mem_for_addr (cselib_val *, cselib_val *, rtx); @@ -788,15 +787,6 @@ cselib_reg_set_mode (const_rtx x) return GET_MODE (REG_VALUES (REGNO (x))->elt->val_rtx); } -/* Return nonzero if we can prove that X and Y contain the same value, taking - our gathered information into account. */ - -int -rtx_equal_for_cselib_p (rtx x, rtx y) -{ - return rtx_equal_for_cselib_1 (x, y, VOIDmode); -} - /* If x is a PLUS or an autoinc operation, expand the operation, storing the offset, if any, in *OFF. */ @@ -843,7 +833,7 @@ autoinc_split (rtx x, rtx *off, machine_mode memmode) addressing modes. If X and Y are not (known to be) part of addresses, MEMMODE should be VOIDmode. */ -static int +int rtx_equal_for_cselib_1 (rtx x, rtx y, machine_mode memmode) { enum rtx_code code; diff --git a/gcc/cselib.h b/gcc/cselib.h index bb03f83653d..940fe99f648 100644 --- a/gcc/cselib.h +++ b/gcc/cselib.h @@ -82,7 +82,7 @@ extern void cselib_finish (void); extern void cselib_process_insn (rtx_insn *); extern bool fp_setter_insn (rtx_insn *); extern machine_mode cselib_reg_set_mode (const_rtx); -extern int rtx_equal_for_cselib_p (rtx, rtx); +extern int rtx_equal_for_cselib_1 (rtx, rtx, machine_mode); extern int references_value_p (const_rtx, int); extern rtx cselib_expand_value_rtx (rtx, bitmap, int); typedef rtx (*cselib_expand_callback)(rtx, bitmap, int, void *); @@ -125,4 +125,16 @@ canonical_cselib_val (cselib_val *val) return canon; } +/* Return nonzero if we can prove that X and Y contain the same value, taking + our gathered information into account. */ + +static inline int +rtx_equal_for_cselib_p (rtx x, rtx y) +{ + if (x == y) + return 1; + + return rtx_equal_for_cselib_1 (x, y, VOIDmode); +} + #endif /* GCC_CSELIB_H */ diff --git a/gcc/sched-deps.c b/gcc/sched-deps.c index 8f3a124a8fa..5c8e020bb5b 100644 --- a/gcc/sched-deps.c +++ b/gcc/sched-deps.c @@ -4182,22 +4182,29 @@ finish_deps_global (void) dw_t estimate_dep_weak (rtx mem1, rtx mem2) { - rtx r1, r2; - if (mem1 == mem2) /* MEMs are the same - don't speculate. */ return MIN_DEP_WEAK; - r1 = XEXP (mem1, 0); - r2 = XEXP (mem2, 0); + rtx r1 = XEXP (mem1, 0); + rtx r2 = XEXP (mem2, 0); + + if (sched_deps_info->use_cselib) + { + /* We cannot call rtx_equal_for_cselib_p because the VALUEs might be + dangling at this point, since we never preserve them. Instead we + canonicalize manually to get stable VALUEs out of hashing. */ + if (GET_CODE (r1) == VALUE && CSELIB_VAL_PTR (r1)) + r1 = canonical_cselib_val (CSELIB_VAL_PTR (r1))->val_rtx; + if (GET_CODE (r2) == VALUE && CSELIB_VAL_PTR (r2)) + r2 = canonical_cselib_val (CSELIB_VAL_PTR (r2))->val_rtx; + } if (r1 == r2 - || (REG_P (r1) && REG_P (r2) - && REGNO (r1) == REGNO (r2))) + || (REG_P (r1) && REG_P (r2) && REGNO (r1) == REGNO (r2))) /* Again, MEMs are the same. */ return MIN_DEP_WEAK; - else if ((REG_P (r1) && !REG_P (r2)) - || (!REG_P (r1) && REG_P (r2))) + else if ((REG_P (r1) && !REG_P (r2)) || (!REG_P (r1) && REG_P (r2))) /* Different addressing modes - reason to be more speculative, than usual. */ return NO_DEP_WEAK - (NO_DEP_WEAK - UNCERTAIN_DEP_WEAK) / 2;