mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-02-25 16:36:11 +08:00
cprop.c (struct reg_use): Remove.
* cprop.c (struct reg_use): Remove. (reg_use_table): Make an array of RTX. (find_used_regs, constprop_register, local_cprop_pass, bypass_block): Simplify users of reg_use_table. (cprop_insn): Likewise. Iterate if copy propagation succeeded on one of the uses found by find_used_regs. From-SVN: r171999
This commit is contained in:
parent
e532f586e2
commit
c1e2610ec1
@ -1,3 +1,12 @@
|
|||||||
|
2011-04-05 Steven Bosscher <steven@gcc.gnu.org>
|
||||||
|
|
||||||
|
* cprop.c (struct reg_use): Remove.
|
||||||
|
(reg_use_table): Make an array of RTX.
|
||||||
|
(find_used_regs, constprop_register, local_cprop_pass,
|
||||||
|
bypass_block): Simplify users of reg_use_table.
|
||||||
|
(cprop_insn): Likewise. Iterate if copy propagation succeeded
|
||||||
|
on one of the uses found by find_used_regs.
|
||||||
|
|
||||||
2011-04-05 Nathan Froyd <froydnj@codesourcery.com>
|
2011-04-05 Nathan Froyd <froydnj@codesourcery.com>
|
||||||
|
|
||||||
PR bootstrap/48469
|
PR bootstrap/48469
|
||||||
|
58
gcc/cprop.c
58
gcc/cprop.c
@ -53,8 +53,6 @@ along with GCC; see the file COPYING3. If not see
|
|||||||
/* An obstack for our working variables. */
|
/* An obstack for our working variables. */
|
||||||
static struct obstack cprop_obstack;
|
static struct obstack cprop_obstack;
|
||||||
|
|
||||||
struct reg_use {rtx reg_rtx; };
|
|
||||||
|
|
||||||
/* Occurrence of an expression.
|
/* Occurrence of an expression.
|
||||||
There is one per basic block. If a pattern appears more than once the
|
There is one per basic block. If a pattern appears more than once the
|
||||||
last appearance is used. */
|
last appearance is used. */
|
||||||
@ -653,12 +651,12 @@ compute_cprop_data (void)
|
|||||||
/* Maximum number of register uses in an insn that we handle. */
|
/* Maximum number of register uses in an insn that we handle. */
|
||||||
#define MAX_USES 8
|
#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. */
|
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. */
|
/* 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
|
/* 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,
|
in `reg_use_table'. `reg_use_count' is initialized to zero before entry,
|
||||||
@ -687,7 +685,7 @@ find_used_regs (rtx *xptr, void *data ATTRIBUTE_UNUSED)
|
|||||||
if (reg_use_count == MAX_USES)
|
if (reg_use_count == MAX_USES)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
reg_use_table[reg_use_count].reg_rtx = x;
|
reg_use_table[reg_use_count] = x;
|
||||||
reg_use_count++;
|
reg_use_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -997,10 +995,12 @@ constprop_register (rtx insn, rtx from, rtx to)
|
|||||||
static int
|
static int
|
||||||
cprop_insn (rtx insn)
|
cprop_insn (rtx insn)
|
||||||
{
|
{
|
||||||
struct reg_use *reg_used;
|
unsigned i;
|
||||||
int changed = 0;
|
int changed = 0, changed_this_round;
|
||||||
rtx note;
|
rtx note;
|
||||||
|
|
||||||
|
retry:
|
||||||
|
changed_this_round = 0;
|
||||||
reg_use_count = 0;
|
reg_use_count = 0;
|
||||||
note_uses (&PATTERN (insn), find_used_regs, NULL);
|
note_uses (&PATTERN (insn), find_used_regs, NULL);
|
||||||
|
|
||||||
@ -1009,16 +1009,16 @@ cprop_insn (rtx insn)
|
|||||||
if (note)
|
if (note)
|
||||||
find_used_regs (&XEXP (note, 0), NULL);
|
find_used_regs (&XEXP (note, 0), NULL);
|
||||||
|
|
||||||
for (reg_used = ®_use_table[0]; reg_use_count > 0;
|
for (i = 0; i < reg_use_count; i++)
|
||||||
reg_used++, reg_use_count--)
|
|
||||||
{
|
{
|
||||||
unsigned int regno = REGNO (reg_used->reg_rtx);
|
rtx reg_used = reg_use_table[i];
|
||||||
|
unsigned int regno = REGNO (reg_used);
|
||||||
rtx src;
|
rtx src;
|
||||||
struct expr *set;
|
struct expr *set;
|
||||||
|
|
||||||
/* If the register has already been set in this block, there's
|
/* If the register has already been set in this block, there's
|
||||||
nothing we can do. */
|
nothing we can do. */
|
||||||
if (! reg_not_set_p (reg_used->reg_rtx, insn))
|
if (! reg_not_set_p (reg_used, insn))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Find an assignment that sets reg_used and is available
|
/* Find an assignment that sets reg_used and is available
|
||||||
@ -1032,9 +1032,9 @@ cprop_insn (rtx insn)
|
|||||||
/* Constant propagation. */
|
/* Constant propagation. */
|
||||||
if (cprop_constant_p (src))
|
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++;
|
global_const_prop_count++;
|
||||||
if (dump_file != NULL)
|
if (dump_file != NULL)
|
||||||
{
|
{
|
||||||
@ -1051,9 +1051,9 @@ cprop_insn (rtx insn)
|
|||||||
&& REGNO (src) >= FIRST_PSEUDO_REGISTER
|
&& REGNO (src) >= FIRST_PSEUDO_REGISTER
|
||||||
&& REGNO (src) != regno)
|
&& 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++;
|
global_copy_prop_count++;
|
||||||
if (dump_file != NULL)
|
if (dump_file != NULL)
|
||||||
{
|
{
|
||||||
@ -1069,6 +1069,11 @@ cprop_insn (rtx insn)
|
|||||||
and made things worse. */
|
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))
|
if (changed && DEBUG_INSN_P (insn))
|
||||||
@ -1195,8 +1200,8 @@ local_cprop_pass (void)
|
|||||||
{
|
{
|
||||||
basic_block bb;
|
basic_block bb;
|
||||||
rtx insn;
|
rtx insn;
|
||||||
struct reg_use *reg_used;
|
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
cselib_init (0);
|
cselib_init (0);
|
||||||
FOR_EACH_BB (bb)
|
FOR_EACH_BB (bb)
|
||||||
@ -1214,10 +1219,9 @@ local_cprop_pass (void)
|
|||||||
if (note)
|
if (note)
|
||||||
local_cprop_find_used_regs (&XEXP (note, 0), NULL);
|
local_cprop_find_used_regs (&XEXP (note, 0), NULL);
|
||||||
|
|
||||||
for (reg_used = ®_use_table[0]; reg_use_count > 0;
|
for (i = 0; i < reg_use_count; i++)
|
||||||
reg_used++, reg_use_count--)
|
|
||||||
{
|
{
|
||||||
if (do_local_cprop (reg_used->reg_rtx, insn))
|
if (do_local_cprop (reg_use_table[i], insn))
|
||||||
{
|
{
|
||||||
changed = true;
|
changed = true;
|
||||||
break;
|
break;
|
||||||
@ -1226,7 +1230,7 @@ local_cprop_pass (void)
|
|||||||
if (INSN_DELETED_P (insn))
|
if (INSN_DELETED_P (insn))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
while (reg_use_count);
|
while (i < reg_use_count);
|
||||||
}
|
}
|
||||||
cselib_process_insn (insn);
|
cselib_process_insn (insn);
|
||||||
}
|
}
|
||||||
@ -1461,9 +1465,10 @@ bypass_block (basic_block bb, rtx setcc, rtx jump)
|
|||||||
{
|
{
|
||||||
rtx insn, note;
|
rtx insn, note;
|
||||||
edge e, edest;
|
edge e, edest;
|
||||||
int i, change;
|
int change;
|
||||||
int may_be_loop_header;
|
int may_be_loop_header;
|
||||||
unsigned removed_p;
|
unsigned removed_p;
|
||||||
|
unsigned i;
|
||||||
edge_iterator ei;
|
edge_iterator ei;
|
||||||
|
|
||||||
insn = (setcc != NULL) ? setcc : jump;
|
insn = (setcc != NULL) ? setcc : jump;
|
||||||
@ -1513,8 +1518,8 @@ bypass_block (basic_block bb, rtx setcc, rtx jump)
|
|||||||
|
|
||||||
for (i = 0; i < reg_use_count; i++)
|
for (i = 0; i < reg_use_count; i++)
|
||||||
{
|
{
|
||||||
struct reg_use *reg_used = ®_use_table[i];
|
rtx reg_used = reg_use_table[i];
|
||||||
unsigned int regno = REGNO (reg_used->reg_rtx);
|
unsigned int regno = REGNO (reg_used);
|
||||||
basic_block dest, old_dest;
|
basic_block dest, old_dest;
|
||||||
struct expr *set;
|
struct expr *set;
|
||||||
rtx src, new_rtx;
|
rtx src, new_rtx;
|
||||||
@ -1525,7 +1530,7 @@ bypass_block (basic_block bb, rtx setcc, rtx jump)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Check the data flow is valid after edge insertions. */
|
/* 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;
|
continue;
|
||||||
|
|
||||||
src = SET_SRC (pc_set (jump));
|
src = SET_SRC (pc_set (jump));
|
||||||
@ -1535,8 +1540,7 @@ bypass_block (basic_block bb, rtx setcc, rtx jump)
|
|||||||
SET_DEST (PATTERN (setcc)),
|
SET_DEST (PATTERN (setcc)),
|
||||||
SET_SRC (PATTERN (setcc)));
|
SET_SRC (PATTERN (setcc)));
|
||||||
|
|
||||||
new_rtx = simplify_replace_rtx (src, reg_used->reg_rtx,
|
new_rtx = simplify_replace_rtx (src, reg_used, set->src);
|
||||||
set->src);
|
|
||||||
|
|
||||||
/* Jump bypassing may have already placed instructions on
|
/* Jump bypassing may have already placed instructions on
|
||||||
edges of the CFG. We can't bypass an outgoing edge that
|
edges of the CFG. We can't bypass an outgoing edge that
|
||||||
|
Loading…
Reference in New Issue
Block a user