/* An obstack for our working variables. */
static struct obstack cprop_obstack;
-struct reg_use {rtx reg_rtx; };
-
/* Occurrence of an expression.
There is one per basic block. If a pattern appears more than once the
last appearance is used. */
/* Maximum number of register uses in an insn that we handle. */
#define MAX_USES 8
-/* Table of uses found in an insn.
+/* Table of uses (registers, both hard and pseudo) found in an insn.
Allocated statically to avoid alloc/free complexity and overhead. */
-static struct reg_use reg_use_table[MAX_USES];
+static rtx reg_use_table[MAX_USES];
/* Index into `reg_use_table' while building it. */
-static int reg_use_count;
+static unsigned reg_use_count;
/* Set up a list of register numbers used in INSN. The found uses are stored
in `reg_use_table'. `reg_use_count' is initialized to zero before entry,
if (reg_use_count == MAX_USES)
return;
- reg_use_table[reg_use_count].reg_rtx = x;
+ reg_use_table[reg_use_count] = x;
reg_use_count++;
}
static int
cprop_insn (rtx insn)
{
- struct reg_use *reg_used;
- int changed = 0;
+ unsigned i;
+ int changed = 0, changed_this_round;
rtx note;
+retry:
+ changed_this_round = 0;
reg_use_count = 0;
note_uses (&PATTERN (insn), find_used_regs, NULL);
if (note)
find_used_regs (&XEXP (note, 0), NULL);
- for (reg_used = ®_use_table[0]; reg_use_count > 0;
- reg_used++, reg_use_count--)
+ for (i = 0; i < reg_use_count; i++)
{
- unsigned int regno = REGNO (reg_used->reg_rtx);
+ rtx reg_used = reg_use_table[i];
+ unsigned int regno = REGNO (reg_used);
rtx src;
struct expr *set;
/* If the register has already been set in this block, there's
nothing we can do. */
- if (! reg_not_set_p (reg_used->reg_rtx, insn))
+ if (! reg_not_set_p (reg_used, insn))
continue;
/* Find an assignment that sets reg_used and is available
/* Constant propagation. */
if (cprop_constant_p (src))
{
- if (constprop_register (insn, reg_used->reg_rtx, src))
+ if (constprop_register (insn, reg_used, src))
{
- changed = 1;
+ changed_this_round = changed = 1;
global_const_prop_count++;
if (dump_file != NULL)
{
&& REGNO (src) >= FIRST_PSEUDO_REGISTER
&& REGNO (src) != regno)
{
- if (try_replace_reg (reg_used->reg_rtx, src, insn))
+ if (try_replace_reg (reg_used, src, insn))
{
- changed = 1;
+ changed_this_round = changed = 1;
global_copy_prop_count++;
if (dump_file != NULL)
{
and made things worse. */
}
}
+
+ /* If try_replace_reg simplified the insn, the regs found
+ by find_used_regs may not be valid anymore. Start over. */
+ if (changed_this_round)
+ goto retry;
}
if (changed && DEBUG_INSN_P (insn))
{
basic_block bb;
rtx insn;
- struct reg_use *reg_used;
bool changed = false;
+ unsigned i;
cselib_init (0);
FOR_EACH_BB (bb)
if (note)
local_cprop_find_used_regs (&XEXP (note, 0), NULL);
- for (reg_used = ®_use_table[0]; reg_use_count > 0;
- reg_used++, reg_use_count--)
+ for (i = 0; i < reg_use_count; i++)
{
- if (do_local_cprop (reg_used->reg_rtx, insn))
+ if (do_local_cprop (reg_use_table[i], insn))
{
changed = true;
break;
if (INSN_DELETED_P (insn))
break;
}
- while (reg_use_count);
+ while (i < reg_use_count);
}
cselib_process_insn (insn);
}
{
rtx insn, note;
edge e, edest;
- int i, change;
+ int change;
int may_be_loop_header;
unsigned removed_p;
+ unsigned i;
edge_iterator ei;
insn = (setcc != NULL) ? setcc : jump;
for (i = 0; i < reg_use_count; i++)
{
- struct reg_use *reg_used = ®_use_table[i];
- unsigned int regno = REGNO (reg_used->reg_rtx);
+ rtx reg_used = reg_use_table[i];
+ unsigned int regno = REGNO (reg_used);
basic_block dest, old_dest;
struct expr *set;
rtx src, new_rtx;
continue;
/* Check the data flow is valid after edge insertions. */
- if (e->insns.r && reg_killed_on_edge (reg_used->reg_rtx, e))
+ if (e->insns.r && reg_killed_on_edge (reg_used, e))
continue;
src = SET_SRC (pc_set (jump));
SET_DEST (PATTERN (setcc)),
SET_SRC (PATTERN (setcc)));
- new_rtx = simplify_replace_rtx (src, reg_used->reg_rtx,
- set->src);
+ new_rtx = simplify_replace_rtx (src, reg_used, set->src);
/* Jump bypassing may have already placed instructions on
edges of the CFG. We can't bypass an outgoing edge that