From: Jakub Jelinek Date: Tue, 9 Mar 2010 18:53:38 +0000 (+0100) Subject: re PR bootstrap/43299 (Subversion id 157264 breaks powerpc 64-bit bootstraps) X-Git-Tag: releases/gcc-4.5.0~441 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=69b89883e86e2d346d28c17e64681ff87b1f61cb;p=thirdparty%2Fgcc.git re PR bootstrap/43299 (Subversion id 157264 breaks powerpc 64-bit bootstraps) PR debug/43299 * var-tracking.c (adjust_sets): New function. (count_with_sets, add_with_sets): Use it. (get_adjusted_src): New inline function. (add_stores): Use it. * gcc.dg/pr43299.c: New test. From-SVN: r157316 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4b68db52eae1..105d366691bf 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,11 @@ 2010-03-09 Jakub Jelinek + PR debug/43299 + * var-tracking.c (adjust_sets): New function. + (count_with_sets, add_with_sets): Use it. + (get_adjusted_src): New inline function. + (add_stores): Use it. + PR debug/43304 * var-tracking.c (vt_expand_loc_callback) : If dummy, call cselib_dummy_expand_value_rtx_cb instead of diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a874977e3b95..6f3709339880 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2010-03-09 Jakub Jelinek + PR debug/43299 + * gcc.dg/pr43299.c: New test. + PR debug/43290 * g++.dg/eh/unwind2.C: New test. diff --git a/gcc/testsuite/gcc.dg/pr43299.c b/gcc/testsuite/gcc.dg/pr43299.c new file mode 100644 index 000000000000..d71c896893fc --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr43299.c @@ -0,0 +1,28 @@ +/* PR debug/43299 */ +/* { dg-do assemble } */ +/* { dg-options "-g -O2" } */ + +extern void *emit_insn (void *); + +__attribute__((noinline)) +void *gen_load_locked_si (void *x, void *y) +{ + return x; +} + +__attribute__((noinline)) +void *gen_load_locked_di (void *x, void *y) +{ + return x; +} + +void +emit_load_locked (int mode, void *reg, void *mem) +{ + void * (*fn) (void *, void *) = ((void *)0); + if (mode == 9) + fn = gen_load_locked_si; + else if (mode == 10) + fn = gen_load_locked_di; + emit_insn (fn (reg, mem)); +} diff --git a/gcc/var-tracking.c b/gcc/var-tracking.c index 378bb75bdb3b..ece779027934 100644 --- a/gcc/var-tracking.c +++ b/gcc/var-tracking.c @@ -4601,6 +4601,30 @@ count_stores (rtx loc, const_rtx expr ATTRIBUTE_UNUSED, void *cui) count_uses (&loc, cui); } +/* Adjust sets if needed. Currently this optimizes read-only MEM loads + if REG_EQUAL/REG_EQUIV note is present. */ + +static void +adjust_sets (rtx insn, struct cselib_set *sets, int n_sets) +{ + if (n_sets == 1 && MEM_P (sets[0].src) && MEM_READONLY_P (sets[0].src)) + { + /* For read-only MEMs containing some constant, prefer those + constants. */ + rtx note = find_reg_equal_equiv_note (insn), src; + + if (note && CONSTANT_P (XEXP (note, 0))) + { + sets[0].src = src = XEXP (note, 0); + if (GET_CODE (PATTERN (insn)) == COND_EXEC) + src = gen_rtx_IF_THEN_ELSE (GET_MODE (sets[0].dest), + COND_EXEC_TEST (PATTERN (insn)), + src, sets[0].dest); + sets[0].src_elt = cselib_lookup (src, GET_MODE (sets[0].dest), 1); + } + } +} + /* Callback for cselib_record_sets_hook, that counts how many micro operations it takes for uses and stores in an insn after cselib_record_sets has analyzed the sets in an insn, but before it @@ -4617,6 +4641,8 @@ count_with_sets (rtx insn, struct cselib_set *sets, int n_sets) cselib_hook_called = true; + adjust_sets (insn, sets, n_sets); + cui.insn = insn; cui.bb = bb; cui.sets = sets; @@ -4934,6 +4960,21 @@ reverse_op (rtx val, const_rtx expr) return gen_rtx_CONCAT (GET_MODE (v->val_rtx), v->val_rtx, ret); } +/* Return SRC, or, if it is a read-only MEM for which adjust_sets + replated it with a constant from REG_EQUIV/REG_EQUAL note, + that constant. */ + +static inline rtx +get_adjusted_src (struct count_use_info *cui, rtx src) +{ + if (cui->n_sets == 1 + && MEM_P (src) + && MEM_READONLY_P (src) + && CONSTANT_P (cui->sets[0].src)) + return cui->sets[0].src; + return src; +} + /* Add stores (register and memory references) LOC which will be tracked to VTI (bb)->mos. EXPR is the RTL expression containing the store. CUIP->insn is instruction which the LOC is part of. */ @@ -4971,7 +5012,10 @@ add_stores (rtx loc, const_rtx expr, void *cuip) else { if (GET_CODE (expr) == SET && SET_DEST (expr) == loc) - src = var_lowpart (mode2, SET_SRC (expr)); + { + src = get_adjusted_src (cui, SET_SRC (expr)); + src = var_lowpart (mode2, src); + } loc = var_lowpart (mode2, loc); if (src == NULL) @@ -5030,7 +5074,10 @@ add_stores (rtx loc, const_rtx expr, void *cuip) else { if (GET_CODE (expr) == SET && SET_DEST (expr) == loc) - src = var_lowpart (mode2, SET_SRC (expr)); + { + src = get_adjusted_src (cui, SET_SRC (expr)); + src = var_lowpart (mode2, src); + } loc = var_lowpart (mode2, loc); if (src == NULL) @@ -5099,12 +5146,13 @@ add_stores (rtx loc, const_rtx expr, void *cuip) } else if (resolve && GET_CODE (mo->u.loc) == SET) { - nloc = replace_expr_with_values (SET_SRC (expr)); + src = get_adjusted_src (cui, SET_SRC (expr)); + nloc = replace_expr_with_values (src); /* Avoid the mode mismatch between oexpr and expr. */ if (!nloc && mode != mode2) { - nloc = SET_SRC (expr); + nloc = src; gcc_assert (oloc == SET_DEST (expr)); } @@ -5201,6 +5249,8 @@ add_with_sets (rtx insn, struct cselib_set *sets, int n_sets) cselib_hook_called = true; + adjust_sets (insn, sets, n_sets); + cui.insn = insn; cui.bb = bb; cui.sets = sets;