diff options
-rw-r--r-- | gcc/ChangeLog | 28 | ||||
-rw-r--r-- | gcc/cfgexpand.c | 42 | ||||
-rw-r--r-- | gcc/combine.c | 76 | ||||
-rw-r--r-- | gcc/cselib.c | 27 | ||||
-rw-r--r-- | gcc/gcse.c | 11 | ||||
-rw-r--r-- | gcc/reload1.c | 27 | ||||
-rw-r--r-- | gcc/rtl.h | 4 | ||||
-rw-r--r-- | gcc/simplify-rtx.c | 59 | ||||
-rw-r--r-- | gcc/var-tracking.c | 26 |
9 files changed, 117 insertions, 183 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2a7d1aa01b1..a31dfe3207b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,31 @@ +2009-10-20 Richard Sandiford <rdsandiford@googlemail.com> + + * rtl.h (simplify_replace_fn_rtx): Declare. + (wrap_constant, unwrap_constant): Delete. + * cfgexpand.c (unwrap_constant, wrap_constant): Delete. + (expand_debug_expr): Don't call wrap_constant. + * combine.c (rtx_subst_pair): Only define for AUTO_INC_DEC. + (auto_adjust_pair): Fold into... + (propagate_for_debug_subst): ...here. Only define for AUTO_INC_DEC. + Just return a new value. + (propagate_for_debug): Use simplify_replace_fn_rtx for AUTO_INC_DEC, + otherwise use simplify_replace_rtx. + * cselib.c (wrap_constant): Reinstate old definition. + (cselib_expand_value_rtx_1): Don't wrap constants. + * gcse.c (try_replace_reg): Don't use copy_rtx in the call to + simplify_replace_rtx. + (bypass_block): Fix formatting in calls to simplify_replace_rtx. + * reload1.c (reload): Skip all uses for an insn before adjusting it. + Use simplify_replace_rtx. + * simplify-rtx.c (simplify_replace_fn_rtx): New function, + adapted from... + (simplify_replace_rtx): ...here. Turn into a wrapper for + simplify_replace_fn_rtx. + (simplify_unary_operation): Don't unwrap CONSTs. + * var-tracking.c (check_wrap_constant): Delete. + (vt_expand_loc_callback): Don't call it. + (vt_expand_loc): Likewise. + 2009-10-20 Pascal Obry <obry@adacore.com> Eric Botcazou <ebotcazou@adacore.com> diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index 8c7c881ea6c..2678d7e7ffe 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -2194,46 +2194,6 @@ round_udiv_adjust (enum machine_mode mode, rtx mod, rtx op1) const1_rtx, const0_rtx); } -/* Wrap modeless constants in CONST:MODE. */ -rtx -wrap_constant (enum machine_mode mode, rtx x) -{ - if (GET_MODE (x) != VOIDmode) - return x; - - if (CONST_INT_P (x) - || GET_CODE (x) == CONST_FIXED - || GET_CODE (x) == CONST_DOUBLE - || GET_CODE (x) == LABEL_REF) - { - gcc_assert (mode != VOIDmode); - - x = gen_rtx_CONST (mode, x); - } - - return x; -} - -/* Remove CONST wrapper added by wrap_constant(). */ -rtx -unwrap_constant (rtx x) -{ - rtx ret = x; - - if (GET_CODE (x) != CONST) - return x; - - x = XEXP (x, 0); - - if (CONST_INT_P (x) - || GET_CODE (x) == CONST_FIXED - || GET_CODE (x) == CONST_DOUBLE - || GET_CODE (x) == LABEL_REF) - ret = x; - - return ret; -} - /* Convert X to MODE, that must be Pmode or ptr_mode, without emitting any rtl. */ @@ -2356,9 +2316,7 @@ expand_debug_expr (tree exp) case COMPLEX_CST: gcc_assert (COMPLEX_MODE_P (mode)); op0 = expand_debug_expr (TREE_REALPART (exp)); - op0 = wrap_constant (GET_MODE_INNER (mode), op0); op1 = expand_debug_expr (TREE_IMAGPART (exp)); - op1 = wrap_constant (GET_MODE_INNER (mode), op1); return gen_rtx_CONCAT (mode, op0, op1); case DEBUG_EXPR_DECL: diff --git a/gcc/combine.c b/gcc/combine.c index af9cea2fe2a..129cd4dff39 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -2264,68 +2264,33 @@ cleanup_auto_inc_dec (rtx src, bool after, enum machine_mode mem_mode) return x; } -#endif /* Auxiliary data structure for propagate_for_debug_stmt. */ struct rtx_subst_pair { - rtx from, to; - bool changed; -#ifdef AUTO_INC_DEC + rtx to; bool adjusted; bool after; -#endif }; -/* Clean up any auto-updates in PAIR->to the first time it is called - for a PAIR. PAIR->adjusted is used to tell whether we've cleaned - up before. */ +/* DATA points to an rtx_subst_pair. Return the value that should be + substituted. */ -static void -auto_adjust_pair (struct rtx_subst_pair *pair ATTRIBUTE_UNUSED) +static rtx +propagate_for_debug_subst (rtx from ATTRIBUTE_UNUSED, void *data) { -#ifdef AUTO_INC_DEC + struct rtx_subst_pair *pair = (struct rtx_subst_pair *)data; + if (!pair->adjusted) { pair->adjusted = true; pair->to = cleanup_auto_inc_dec (pair->to, pair->after, VOIDmode); + return pair->to; } -#endif -} - -/* If *LOC is the same as FROM in the struct rtx_subst_pair passed as - DATA, replace it with a copy of TO. Handle SUBREGs of *LOC as - well. */ - -static int -propagate_for_debug_subst (rtx *loc, void *data) -{ - struct rtx_subst_pair *pair = (struct rtx_subst_pair *)data; - rtx from = pair->from, to = pair->to; - rtx x = *loc, s = x; - - if (rtx_equal_p (x, from) - || (GET_CODE (x) == SUBREG && rtx_equal_p ((s = SUBREG_REG (x)), from))) - { - auto_adjust_pair (pair); - if (pair->to != to) - to = pair->to; - else - to = copy_rtx (to); - if (s != x) - { - gcc_assert (GET_CODE (x) == SUBREG && SUBREG_REG (x) == s); - to = simplify_gen_subreg (GET_MODE (x), to, - GET_MODE (from), SUBREG_BYTE (x)); - } - *loc = wrap_constant (GET_MODE (x), to); - pair->changed = true; - return -1; - } - - return 0; + return copy_rtx (pair->to); } +#endif /* Replace occurrences of DEST with SRC in DEBUG_INSNs between INSN and LAST. If MOVE holds, debug insns must also be moved past @@ -2334,14 +2299,11 @@ propagate_for_debug_subst (rtx *loc, void *data) static void propagate_for_debug (rtx insn, rtx last, rtx dest, rtx src, bool move) { - struct rtx_subst_pair p; - rtx next, move_pos = move ? last : NULL_RTX; - - p.from = dest; - p.to = src; - p.changed = false; + rtx next, move_pos = move ? last : NULL_RTX, loc; #ifdef AUTO_INC_DEC + struct rtx_subst_pair p; + p.to = src; p.adjusted = false; p.after = move; #endif @@ -2353,11 +2315,15 @@ propagate_for_debug (rtx insn, rtx last, rtx dest, rtx src, bool move) next = NEXT_INSN (insn); if (DEBUG_INSN_P (insn)) { - for_each_rtx (&INSN_VAR_LOCATION_LOC (insn), - propagate_for_debug_subst, &p); - if (!p.changed) +#ifdef AUTO_INC_DEC + loc = simplify_replace_fn_rtx (INSN_VAR_LOCATION_LOC (insn), + dest, propagate_for_debug_subst, &p); +#else + loc = simplify_replace_rtx (INSN_VAR_LOCATION_LOC (insn), dest, src); +#endif + if (loc == INSN_VAR_LOCATION_LOC (insn)) continue; - p.changed = false; + INSN_VAR_LOCATION_LOC (insn) = loc; if (move_pos) { remove_insn (insn); diff --git a/gcc/cselib.c b/gcc/cselib.c index 2bf466258f3..aa5f7b022bc 100644 --- a/gcc/cselib.c +++ b/gcc/cselib.c @@ -662,6 +662,19 @@ rtx_equal_for_cselib_p (rtx x, rtx y) return 1; } +/* We need to pass down the mode of constants through the hash table + functions. For that purpose, wrap them in a CONST of the appropriate + mode. */ +static rtx +wrap_constant (enum machine_mode mode, rtx x) +{ + if (!CONST_INT_P (x) && GET_CODE (x) != CONST_FIXED + && (GET_CODE (x) != CONST_DOUBLE || GET_MODE (x) != VOIDmode)) + return x; + gcc_assert (mode != VOIDmode); + return gen_rtx_CONST (mode, x); +} + /* Hash an rtx. Return 0 if we couldn't hash the rtx. For registers and memory locations, we look up their cselib_val structure and return its VALUE element. @@ -1340,21 +1353,9 @@ cselib_expand_value_rtx_1 (rtx orig, struct expand_value_data *evd, default: break; } - if (scopy == NULL_RTX) - { - XEXP (copy, 0) - = gen_rtx_CONST (GET_MODE (XEXP (orig, 0)), XEXP (copy, 0)); - if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, " wrapping const_int result in const to preserve mode %s\n", - GET_MODE_NAME (GET_MODE (XEXP (copy, 0)))); - } scopy = simplify_rtx (copy); if (scopy) - { - if (GET_MODE (copy) != GET_MODE (scopy)) - scopy = wrap_constant (GET_MODE (copy), scopy); - return scopy; - } + return scopy; return copy; } diff --git a/gcc/gcse.c b/gcc/gcse.c index 803ab3e5a14..7ccb05e1d85 100644 --- a/gcc/gcse.c +++ b/gcc/gcse.c @@ -2276,8 +2276,7 @@ try_replace_reg (rtx from, rtx to, rtx insn) with our replacement. */ if (note != 0 && REG_NOTE_KIND (note) == REG_EQUAL) set_unique_reg_note (insn, REG_EQUAL, - simplify_replace_rtx (XEXP (note, 0), from, - copy_rtx (to))); + simplify_replace_rtx (XEXP (note, 0), from, to)); if (!success && set && reg_mentioned_p (from, SET_SRC (set))) { /* If above failed and this is a single set, try to simplify the source of @@ -3038,12 +3037,12 @@ bypass_block (basic_block bb, rtx setcc, rtx jump) src = SET_SRC (pc_set (jump)); if (setcc != NULL) - src = simplify_replace_rtx (src, - SET_DEST (PATTERN (setcc)), - SET_SRC (PATTERN (setcc))); + src = simplify_replace_rtx (src, + SET_DEST (PATTERN (setcc)), + SET_SRC (PATTERN (setcc))); new_rtx = simplify_replace_rtx (src, reg_used->reg_rtx, - SET_SRC (set->expr)); + SET_SRC (set->expr)); /* Jump bypassing may have already placed instructions on edges of the CFG. We can't bypass an outgoing edge that diff --git a/gcc/reload1.c b/gcc/reload1.c index 5581cd66083..e9a0aba83bc 100644 --- a/gcc/reload1.c +++ b/gcc/reload1.c @@ -1257,36 +1257,25 @@ reload (rtx first, int global) for (use = DF_REG_USE_CHAIN (i); use; use = next) { - rtx *loc = DF_REF_LOC (use); - rtx x = *loc; - insn = DF_REF_INSN (use); + + /* Make sure the next ref is for a different instruction, + so that we're not affected by the rescan. */ next = DF_REF_NEXT_REG (use); + while (next && DF_REF_INSN (next) == insn) + next = DF_REF_NEXT_REG (next); if (DEBUG_INSN_P (insn)) { - gcc_assert (x == reg - || (GET_CODE (x) == SUBREG - && SUBREG_REG (x) == reg)); - if (!equiv) { INSN_VAR_LOCATION_LOC (insn) = gen_rtx_UNKNOWN_VAR_LOC (); df_insn_rescan_debug_internal (insn); } else - { - if (x == reg) - *loc = copy_rtx (equiv); - else if (GET_CODE (x) == SUBREG - && SUBREG_REG (x) == reg) - *loc = simplify_gen_subreg (GET_MODE (x), equiv, - GET_MODE (reg), - SUBREG_BYTE (x)); - else - gcc_unreachable (); - *loc = wrap_constant (GET_MODE (x), *loc); - } + INSN_VAR_LOCATION_LOC (insn) + = simplify_replace_rtx (INSN_VAR_LOCATION_LOC (insn), + reg, equiv); } } } diff --git a/gcc/rtl.h b/gcc/rtl.h index 2ed6a522b0d..ee464b7c7f3 100644 --- a/gcc/rtl.h +++ b/gcc/rtl.h @@ -1768,6 +1768,8 @@ extern rtx simplify_subreg (enum machine_mode, rtx, enum machine_mode, unsigned int); extern rtx simplify_gen_subreg (enum machine_mode, rtx, enum machine_mode, unsigned int); +extern rtx simplify_replace_fn_rtx (rtx, const_rtx, + rtx (*fn) (rtx, void *), void *); extern rtx simplify_replace_rtx (rtx, const_rtx, rtx); extern rtx simplify_rtx (const_rtx); extern rtx avoid_constant_pool_reference (rtx); @@ -2409,8 +2411,6 @@ extern void invert_br_probabilities (rtx); extern bool expensive_function_p (int); /* In cfgexpand.c */ extern void add_reg_br_prob_note (rtx last, int probability); -extern rtx wrap_constant (enum machine_mode, rtx); -extern rtx unwrap_constant (rtx); /* In var-tracking.c */ extern unsigned int variable_tracking_main (void); diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c index 217db7a3cdb..f0c4d11e942 100644 --- a/gcc/simplify-rtx.c +++ b/gcc/simplify-rtx.c @@ -350,38 +350,47 @@ simplify_gen_relational (enum rtx_code code, enum machine_mode mode, return gen_rtx_fmt_ee (code, mode, op0, op1); } -/* Replace all occurrences of OLD_RTX in X with NEW_RTX and try to simplify the - resulting RTX. Return a new RTX which is as simplified as possible. */ +/* Replace all occurrences of OLD_RTX in X with FN (X', DATA), where X' + is an expression in X that is equal to OLD_RTX. Canonicalize and + simplify the result. + + If FN is null, assume FN (X', DATA) == copy_rtx (DATA). */ rtx -simplify_replace_rtx (rtx x, const_rtx old_rtx, rtx new_rtx) +simplify_replace_fn_rtx (rtx x, const_rtx old_rtx, + rtx (*fn) (rtx, void *), void *data) { enum rtx_code code = GET_CODE (x); enum machine_mode mode = GET_MODE (x); enum machine_mode op_mode; rtx op0, op1, op2; - /* If X is OLD_RTX, return NEW_RTX. Otherwise, if this is an expression, try - to build a new expression substituting recursively. If we can't do - anything, return our input. */ + /* If X is OLD_RTX, return FN (X, DATA), with a null FN. Otherwise, + if this is an expression, try to build a new expression, substituting + recursively. If we can't do anything, return our input. */ if (rtx_equal_p (x, old_rtx)) - return copy_rtx (new_rtx); + { + if (fn) + return fn (x, data); + else + return copy_rtx ((rtx) data); + } switch (GET_RTX_CLASS (code)) { case RTX_UNARY: op0 = XEXP (x, 0); op_mode = GET_MODE (op0); - op0 = simplify_replace_rtx (op0, old_rtx, new_rtx); + op0 = simplify_replace_fn_rtx (op0, old_rtx, fn, data); if (op0 == XEXP (x, 0)) return x; return simplify_gen_unary (code, mode, op0, op_mode); case RTX_BIN_ARITH: case RTX_COMM_ARITH: - op0 = simplify_replace_rtx (XEXP (x, 0), old_rtx, new_rtx); - op1 = simplify_replace_rtx (XEXP (x, 1), old_rtx, new_rtx); + op0 = simplify_replace_fn_rtx (XEXP (x, 0), old_rtx, fn, data); + op1 = simplify_replace_fn_rtx (XEXP (x, 1), old_rtx, fn, data); if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1)) return x; return simplify_gen_binary (code, mode, op0, op1); @@ -391,8 +400,8 @@ simplify_replace_rtx (rtx x, const_rtx old_rtx, rtx new_rtx) op0 = XEXP (x, 0); op1 = XEXP (x, 1); op_mode = GET_MODE (op0) != VOIDmode ? GET_MODE (op0) : GET_MODE (op1); - op0 = simplify_replace_rtx (op0, old_rtx, new_rtx); - op1 = simplify_replace_rtx (op1, old_rtx, new_rtx); + op0 = simplify_replace_fn_rtx (op0, old_rtx, fn, data); + op1 = simplify_replace_fn_rtx (op1, old_rtx, fn, data); if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1)) return x; return simplify_gen_relational (code, mode, op_mode, op0, op1); @@ -401,9 +410,9 @@ simplify_replace_rtx (rtx x, const_rtx old_rtx, rtx new_rtx) case RTX_BITFIELD_OPS: op0 = XEXP (x, 0); op_mode = GET_MODE (op0); - op0 = simplify_replace_rtx (op0, old_rtx, new_rtx); - op1 = simplify_replace_rtx (XEXP (x, 1), old_rtx, new_rtx); - op2 = simplify_replace_rtx (XEXP (x, 2), old_rtx, new_rtx); + op0 = simplify_replace_fn_rtx (op0, old_rtx, fn, data); + op1 = simplify_replace_fn_rtx (XEXP (x, 1), old_rtx, fn, data); + op2 = simplify_replace_fn_rtx (XEXP (x, 2), old_rtx, fn, data); if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1) && op2 == XEXP (x, 2)) return x; if (op_mode == VOIDmode) @@ -414,7 +423,7 @@ simplify_replace_rtx (rtx x, const_rtx old_rtx, rtx new_rtx) /* The only case we try to handle is a SUBREG. */ if (code == SUBREG) { - op0 = simplify_replace_rtx (SUBREG_REG (x), old_rtx, new_rtx); + op0 = simplify_replace_fn_rtx (SUBREG_REG (x), old_rtx, fn, data); if (op0 == SUBREG_REG (x)) return x; op0 = simplify_gen_subreg (GET_MODE (x), op0, @@ -427,15 +436,15 @@ simplify_replace_rtx (rtx x, const_rtx old_rtx, rtx new_rtx) case RTX_OBJ: if (code == MEM) { - op0 = simplify_replace_rtx (XEXP (x, 0), old_rtx, new_rtx); + op0 = simplify_replace_fn_rtx (XEXP (x, 0), old_rtx, fn, data); if (op0 == XEXP (x, 0)) return x; return replace_equiv_address_nv (x, op0); } else if (code == LO_SUM) { - op0 = simplify_replace_rtx (XEXP (x, 0), old_rtx, new_rtx); - op1 = simplify_replace_rtx (XEXP (x, 1), old_rtx, new_rtx); + op0 = simplify_replace_fn_rtx (XEXP (x, 0), old_rtx, fn, data); + op1 = simplify_replace_fn_rtx (XEXP (x, 1), old_rtx, fn, data); /* (lo_sum (high x) x) -> x */ if (GET_CODE (op0) == HIGH && rtx_equal_p (XEXP (op0, 0), op1)) @@ -452,6 +461,15 @@ simplify_replace_rtx (rtx x, const_rtx old_rtx, rtx new_rtx) } return x; } + +/* Replace all occurrences of OLD_RTX in X with NEW_RTX and try to simplify the + resulting RTX. Return a new RTX which is as simplified as possible. */ + +rtx +simplify_replace_rtx (rtx x, const_rtx old_rtx, rtx new_rtx) +{ + return simplify_replace_fn_rtx (x, old_rtx, 0, new_rtx); +} /* Try to simplify a unary operation CODE whose output mode is to be MODE with input operand OP whose mode was originally OP_MODE. @@ -462,9 +480,6 @@ simplify_unary_operation (enum rtx_code code, enum machine_mode mode, { rtx trueop, tem; - if (GET_CODE (op) == CONST) - op = XEXP (op, 0); - trueop = avoid_constant_pool_reference (op); tem = simplify_const_unary_operation (code, mode, trueop, op_mode); diff --git a/gcc/var-tracking.c b/gcc/var-tracking.c index acc4d13d717..cfcc839b96c 100644 --- a/gcc/var-tracking.c +++ b/gcc/var-tracking.c @@ -6246,24 +6246,6 @@ delete_variable_part (dataflow_set *set, rtx loc, decl_or_value dv, slot = delete_slot_part (set, loc, slot, offset); } -/* Wrap result in CONST:MODE if needed to preserve the mode. */ - -static rtx -check_wrap_constant (enum machine_mode mode, rtx result) -{ - if (!result || GET_MODE (result) == mode) - return result; - - if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, " wrapping result in const to preserve mode %s\n", - GET_MODE_NAME (mode)); - - result = wrap_constant (mode, result); - gcc_assert (GET_MODE (result) == mode); - - return result; -} - /* Callback for cselib_expand_value, that looks for expressions holding the value in the var-tracking hash tables. Return X for standard processing, anything else is to be used as-is. */ @@ -6337,7 +6319,6 @@ vt_expand_loc_callback (rtx x, bitmap regs, int max_depth, void *data) { result = cselib_expand_value_rtx_cb (loc->loc, regs, max_depth, vt_expand_loc_callback, vars); - result = check_wrap_constant (GET_MODE (loc->loc), result); if (result) break; } @@ -6355,14 +6336,11 @@ vt_expand_loc_callback (rtx x, bitmap regs, int max_depth, void *data) static rtx vt_expand_loc (rtx loc, htab_t vars) { - rtx newloc; - if (!MAY_HAVE_DEBUG_INSNS) return loc; - newloc = cselib_expand_value_rtx_cb (loc, scratch_regs, 5, - vt_expand_loc_callback, vars); - loc = check_wrap_constant (GET_MODE (loc), newloc); + loc = cselib_expand_value_rtx_cb (loc, scratch_regs, 5, + vt_expand_loc_callback, vars); if (loc && MEM_P (loc)) loc = targetm.delegitimize_address (loc); |