rtl.h (simplify_replace_fn_rtx): Declare.

gcc/
	* 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.

From-SVN: r153037
This commit is contained in:
Richard Sandiford 2009-10-20 19:50:38 +00:00 committed by Richard Sandiford
parent 6a1868c766
commit 3af4ba41cc
9 changed files with 117 additions and 183 deletions

View File

@ -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>

View File

@ -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:

View File

@ -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;
}
return copy_rtx (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;
}
/* 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);

View File

@ -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;
}

View File

@ -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

View File

@ -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);
}
}
}

View File

@ -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);

View File

@ -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);

View File

@ -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);