rtl.h (for_each_inc_dec_fn): Remove special case for -1.
gcc/ * rtl.h (for_each_inc_dec_fn): Remove special case for -1. (for_each_inc_dec): Take an rtx rather than an rtx *. * cselib.c (cselib_record_autoinc_cb): Update accordingly. (cselib_record_sets): Likewise. * dse.c (emit_inc_dec_insn_before, check_for_inc_dec_1) (check_for_inc_dec): Likewise. * rtlanal.c (for_each_inc_dec_ops): Delete. (for_each_inc_dec_find_inc_dec): Take the MEM as argument, rather than a pointer to the memory address. Replace for_each_inc_dec_ops argument with separate function and data arguments. Abort on non-autoinc addresses. (for_each_inc_dec_find_mem): Delete. (for_each_inc_dec): Take an rtx rather than an rtx *. Use FOR_EACH_SUBRTX_VAR to visit every autoinc MEM. From-SVN: r214657
This commit is contained in:
parent
f7d0b0fc77
commit
8d8e205b92
|
@ -1,3 +1,20 @@
|
|||
2014-08-28 Richard Sandiford <rdsandiford@googlemail.com>
|
||||
|
||||
* rtl.h (for_each_inc_dec_fn): Remove special case for -1.
|
||||
(for_each_inc_dec): Take an rtx rather than an rtx *.
|
||||
* cselib.c (cselib_record_autoinc_cb): Update accordingly.
|
||||
(cselib_record_sets): Likewise.
|
||||
* dse.c (emit_inc_dec_insn_before, check_for_inc_dec_1)
|
||||
(check_for_inc_dec): Likewise.
|
||||
* rtlanal.c (for_each_inc_dec_ops): Delete.
|
||||
(for_each_inc_dec_find_inc_dec): Take the MEM as argument,
|
||||
rather than a pointer to the memory address. Replace
|
||||
for_each_inc_dec_ops argument with separate function and data
|
||||
arguments. Abort on non-autoinc addresses.
|
||||
(for_each_inc_dec_find_mem): Delete.
|
||||
(for_each_inc_dec): Take an rtx rather than an rtx *. Use
|
||||
FOR_EACH_SUBRTX_VAR to visit every autoinc MEM.
|
||||
|
||||
2014-08-28 Richard Sandiford <rdsandiford@googlemail.com>
|
||||
|
||||
* rtl.h (find_all_hard_regs): Declare.
|
||||
|
|
|
@ -2464,7 +2464,7 @@ cselib_record_autoinc_cb (rtx mem ATTRIBUTE_UNUSED, rtx op ATTRIBUTE_UNUSED,
|
|||
|
||||
data->n_sets++;
|
||||
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Record the effects of any sets and autoincs in INSN. */
|
||||
|
@ -2523,7 +2523,7 @@ cselib_record_sets (rtx_insn *insn)
|
|||
|
||||
data.sets = sets;
|
||||
data.n_sets = n_sets_before_autoinc = n_sets;
|
||||
for_each_inc_dec (&insn, cselib_record_autoinc_cb, &data);
|
||||
for_each_inc_dec (PATTERN (insn), cselib_record_autoinc_cb, &data);
|
||||
n_sets = data.n_sets;
|
||||
|
||||
/* Look up the values that are read. Do this before invalidating the
|
||||
|
|
|
@ -894,7 +894,7 @@ emit_inc_dec_insn_before (rtx mem ATTRIBUTE_UNUSED,
|
|||
|
||||
emit_insn_before (new_insn, insn);
|
||||
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Before we delete INSN_INFO->INSN, make sure that the auto inc/dec, if it
|
||||
|
@ -907,7 +907,8 @@ check_for_inc_dec_1 (insn_info_t insn_info)
|
|||
rtx_insn *insn = insn_info->insn;
|
||||
rtx note = find_reg_note (insn, REG_INC, NULL_RTX);
|
||||
if (note)
|
||||
return for_each_inc_dec (&insn, emit_inc_dec_insn_before, insn_info) == 0;
|
||||
return for_each_inc_dec (PATTERN (insn), emit_inc_dec_insn_before,
|
||||
insn_info) == 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -926,7 +927,8 @@ check_for_inc_dec (rtx_insn *insn)
|
|||
insn_info.fixed_regs_live = NULL;
|
||||
note = find_reg_note (insn, REG_INC, NULL_RTX);
|
||||
if (note)
|
||||
return for_each_inc_dec (&insn, emit_inc_dec_insn_before, &insn_info) == 0;
|
||||
return for_each_inc_dec (PATTERN (insn), emit_inc_dec_insn_before,
|
||||
&insn_info) == 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -2807,12 +2807,11 @@ extern int for_each_rtx_in_insn (rtx_insn **, rtx_function, void *);
|
|||
within MEM that sets DEST to SRC + SRCOFF, or SRC if SRCOFF is
|
||||
NULL. The callback is passed the same opaque ARG passed to
|
||||
for_each_inc_dec. Return zero to continue looking for other
|
||||
autoinc operations, -1 to skip OP's operands, and any other value
|
||||
to interrupt the traversal and return that value to the caller of
|
||||
for_each_inc_dec. */
|
||||
autoinc operations or any other value to interrupt the traversal and
|
||||
return that value to the caller of for_each_inc_dec. */
|
||||
typedef int (*for_each_inc_dec_fn) (rtx mem, rtx op, rtx dest, rtx src,
|
||||
rtx srcoff, void *arg);
|
||||
extern int for_each_inc_dec (rtx_insn **, for_each_inc_dec_fn, void *arg);
|
||||
extern int for_each_inc_dec (rtx, for_each_inc_dec_fn, void *arg);
|
||||
|
||||
typedef int (*rtx_equal_p_callback_function) (const_rtx *, const_rtx *,
|
||||
rtx *, rtx *);
|
||||
|
|
107
gcc/rtlanal.c
107
gcc/rtlanal.c
|
@ -3130,49 +3130,32 @@ for_each_rtx_in_insn (rtx_insn **insn, rtx_function f, void *data)
|
|||
|
||||
|
||||
|
||||
/* Data structure that holds the internal state communicated between
|
||||
for_each_inc_dec, for_each_inc_dec_find_mem and
|
||||
for_each_inc_dec_find_inc_dec. */
|
||||
|
||||
struct for_each_inc_dec_ops {
|
||||
/* The function to be called for each autoinc operation found. */
|
||||
for_each_inc_dec_fn fn;
|
||||
/* The opaque argument to be passed to it. */
|
||||
void *arg;
|
||||
/* The MEM we're visiting, if any. */
|
||||
rtx mem;
|
||||
};
|
||||
|
||||
static int for_each_inc_dec_find_mem (rtx *r, void *d);
|
||||
|
||||
/* Find PRE/POST-INC/DEC/MODIFY operations within *R, extract the
|
||||
operands of the equivalent add insn and pass the result to the
|
||||
operator specified by *D. */
|
||||
/* MEM has a PRE/POST-INC/DEC/MODIFY address X. Extract the operands of
|
||||
the equivalent add insn and pass the result to FN, using DATA as the
|
||||
final argument. */
|
||||
|
||||
static int
|
||||
for_each_inc_dec_find_inc_dec (rtx *r, void *d)
|
||||
for_each_inc_dec_find_inc_dec (rtx mem, for_each_inc_dec_fn fn, void *data)
|
||||
{
|
||||
rtx x = *r;
|
||||
struct for_each_inc_dec_ops *data = (struct for_each_inc_dec_ops *)d;
|
||||
|
||||
rtx x = XEXP (mem, 0);
|
||||
switch (GET_CODE (x))
|
||||
{
|
||||
case PRE_INC:
|
||||
case POST_INC:
|
||||
{
|
||||
int size = GET_MODE_SIZE (GET_MODE (data->mem));
|
||||
int size = GET_MODE_SIZE (GET_MODE (mem));
|
||||
rtx r1 = XEXP (x, 0);
|
||||
rtx c = gen_int_mode (size, GET_MODE (r1));
|
||||
return data->fn (data->mem, x, r1, r1, c, data->arg);
|
||||
return fn (mem, x, r1, r1, c, data);
|
||||
}
|
||||
|
||||
case PRE_DEC:
|
||||
case POST_DEC:
|
||||
{
|
||||
int size = GET_MODE_SIZE (GET_MODE (data->mem));
|
||||
int size = GET_MODE_SIZE (GET_MODE (mem));
|
||||
rtx r1 = XEXP (x, 0);
|
||||
rtx c = gen_int_mode (-size, GET_MODE (r1));
|
||||
return data->fn (data->mem, x, r1, r1, c, data->arg);
|
||||
return fn (mem, x, r1, r1, c, data);
|
||||
}
|
||||
|
||||
case PRE_MODIFY:
|
||||
|
@ -3180,69 +3163,43 @@ for_each_inc_dec_find_inc_dec (rtx *r, void *d)
|
|||
{
|
||||
rtx r1 = XEXP (x, 0);
|
||||
rtx add = XEXP (x, 1);
|
||||
return data->fn (data->mem, x, r1, add, NULL, data->arg);
|
||||
}
|
||||
|
||||
case MEM:
|
||||
{
|
||||
rtx save = data->mem;
|
||||
int ret = for_each_inc_dec_find_mem (r, d);
|
||||
data->mem = save;
|
||||
return ret;
|
||||
return fn (mem, x, r1, add, NULL, data);
|
||||
}
|
||||
|
||||
default:
|
||||
return 0;
|
||||
gcc_unreachable ();
|
||||
}
|
||||
}
|
||||
|
||||
/* If *R is a MEM, find PRE/POST-INC/DEC/MODIFY operations within its
|
||||
address, extract the operands of the equivalent add insn and pass
|
||||
the result to the operator specified by *D. */
|
||||
|
||||
static int
|
||||
for_each_inc_dec_find_mem (rtx *r, void *d)
|
||||
{
|
||||
rtx x = *r;
|
||||
if (x != NULL_RTX && MEM_P (x))
|
||||
{
|
||||
struct for_each_inc_dec_ops *data = (struct for_each_inc_dec_ops *) d;
|
||||
int result;
|
||||
|
||||
data->mem = x;
|
||||
|
||||
result = for_each_rtx (&XEXP (x, 0), for_each_inc_dec_find_inc_dec,
|
||||
data);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Traverse *INSN looking for MEMs, and for autoinc operations within
|
||||
them. For each such autoinc operation found, call FN, passing it
|
||||
/* Traverse *LOC looking for MEMs that have autoinc addresses.
|
||||
For each such autoinc operation found, call FN, passing it
|
||||
the innermost enclosing MEM, the operation itself, the RTX modified
|
||||
by the operation, two RTXs (the second may be NULL) that, once
|
||||
added, represent the value to be held by the modified RTX
|
||||
afterwards, and ARG. FN is to return -1 to skip looking for other
|
||||
autoinc operations within the visited operation, 0 to continue the
|
||||
traversal, or any other value to have it returned to the caller of
|
||||
afterwards, and DATA. FN is to return 0 to continue the
|
||||
traversal or any other value to have it returned to the caller of
|
||||
for_each_inc_dec. */
|
||||
|
||||
int
|
||||
for_each_inc_dec (rtx_insn **insn,
|
||||
for_each_inc_dec (rtx x,
|
||||
for_each_inc_dec_fn fn,
|
||||
void *arg)
|
||||
void *data)
|
||||
{
|
||||
struct for_each_inc_dec_ops data;
|
||||
|
||||
data.fn = fn;
|
||||
data.arg = arg;
|
||||
data.mem = NULL;
|
||||
|
||||
return for_each_rtx_in_insn (insn, for_each_inc_dec_find_mem, &data);
|
||||
subrtx_var_iterator::array_type array;
|
||||
FOR_EACH_SUBRTX_VAR (iter, array, x, NONCONST)
|
||||
{
|
||||
rtx mem = *iter;
|
||||
if (mem
|
||||
&& MEM_P (mem)
|
||||
&& GET_RTX_CLASS (GET_CODE (XEXP (mem, 0))) == RTX_AUTOINC)
|
||||
{
|
||||
int res = for_each_inc_dec_find_inc_dec (mem, fn, data);
|
||||
if (res != 0)
|
||||
return res;
|
||||
iter.skip_subrtxes ();
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue