summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog28
-rw-r--r--gcc/cfgexpand.c42
-rw-r--r--gcc/combine.c76
-rw-r--r--gcc/cselib.c27
-rw-r--r--gcc/gcse.c11
-rw-r--r--gcc/reload1.c27
-rw-r--r--gcc/rtl.h4
-rw-r--r--gcc/simplify-rtx.c59
-rw-r--r--gcc/var-tracking.c26
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);