flow.c (count_reg_sets_1): Remove.

* flow.c (count_reg_sets_1): Remove.
        (count_reg_sets, count_reg_references): Remove.
        (recompute_reg_usage): Implement with update_life_info.
        Reallocate life data.

From-SVN: r33470
This commit is contained in:
Richard Henderson 2000-04-27 00:07:34 -07:00 committed by Richard Henderson
parent 693d9e2fe7
commit f134997fac
2 changed files with 9 additions and 269 deletions

View File

@ -1,3 +1,10 @@
2000-04-26 Richard Henderson <rth@cygnus.com>
* flow.c (count_reg_sets_1): Remove.
(count_reg_sets, count_reg_references): Remove.
(recompute_reg_usage): Implement with update_life_info.
Reallocate life data.
2000-04-26 Richard Henderson <rth@cygnus.com>
* flow.c (update_life_info): Consider blocks null to mean the

View File

@ -353,9 +353,6 @@ void dump_flow_info PARAMS ((FILE *));
void debug_flow_info PARAMS ((void));
static void dump_edge_info PARAMS ((FILE *, edge, int));
static void count_reg_sets_1 PARAMS ((rtx, int));
static void count_reg_sets PARAMS ((rtx, int));
static void count_reg_references PARAMS ((rtx, int));
static void invalidate_mems_from_autoinc PARAMS ((struct propagate_block_info *,
rtx));
static void remove_fake_successors PARAMS ((basic_block));
@ -5534,208 +5531,6 @@ compute_immediate_dominators (idom, dominators)
sbitmap_vector_free (tmp);
}
/* Count for a single SET rtx, X. */
static void
count_reg_sets_1 (x, loop_depth)
rtx x;
int loop_depth;
{
register int regno;
register rtx reg = SET_DEST (x);
/* Find the register that's set/clobbered. */
while (GET_CODE (reg) == SUBREG || GET_CODE (reg) == ZERO_EXTRACT
|| GET_CODE (reg) == SIGN_EXTRACT
|| GET_CODE (reg) == STRICT_LOW_PART)
reg = XEXP (reg, 0);
if (GET_CODE (reg) == PARALLEL
&& GET_MODE (reg) == BLKmode)
{
register int i;
for (i = XVECLEN (reg, 0) - 1; i >= 0; i--)
count_reg_sets_1 (XVECEXP (reg, 0, i), loop_depth);
return;
}
if (GET_CODE (reg) == REG)
{
regno = REGNO (reg);
if (regno >= FIRST_PSEUDO_REGISTER)
{
/* Count (weighted) references, stores, etc. This counts a
register twice if it is modified, but that is correct. */
REG_N_SETS (regno)++;
REG_N_REFS (regno) += loop_depth + 1;
}
}
}
/* Increment REG_N_SETS for each SET or CLOBBER found in X; also increment
REG_N_REFS by the current loop depth for each SET or CLOBBER found. */
static void
count_reg_sets (x, loop_depth)
rtx x;
int loop_depth;
{
register RTX_CODE code = GET_CODE (x);
if (code == SET || code == CLOBBER)
count_reg_sets_1 (x, loop_depth);
else if (code == PARALLEL)
{
register int i;
for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
{
code = GET_CODE (XVECEXP (x, 0, i));
if (code == SET || code == CLOBBER)
count_reg_sets_1 (XVECEXP (x, 0, i), loop_depth);
}
}
}
/* Increment REG_N_REFS by the current loop depth each register reference
found in X. */
static void
count_reg_references (x, loop_depth)
rtx x;
int loop_depth;
{
register RTX_CODE code;
retry:
code = GET_CODE (x);
switch (code)
{
case LABEL_REF:
case SYMBOL_REF:
case CONST_INT:
case CONST:
case CONST_DOUBLE:
case PC:
case ADDR_VEC:
case ADDR_DIFF_VEC:
case ASM_INPUT:
return;
#ifdef HAVE_cc0
case CC0:
return;
#endif
case CLOBBER:
/* If we are clobbering a MEM, mark any registers inside the address
as being used. */
if (GET_CODE (XEXP (x, 0)) == MEM)
count_reg_references (XEXP (XEXP (x, 0), 0), loop_depth);
return;
case SUBREG:
/* While we're here, optimize this case. */
x = SUBREG_REG (x);
/* In case the SUBREG is not of a register, don't optimize */
if (GET_CODE (x) != REG)
{
count_reg_references (x, loop_depth);
return;
}
/* ... fall through ... */
case REG:
if (REGNO (x) >= FIRST_PSEUDO_REGISTER)
REG_N_REFS (REGNO (x)) += loop_depth + 1;
return;
case SET:
{
register rtx testreg = SET_DEST (x);
int mark_dest = 0;
/* If storing into MEM, don't show it as being used. But do
show the address as being used. */
if (GET_CODE (testreg) == MEM)
{
count_reg_references (XEXP (testreg, 0), loop_depth);
count_reg_references (SET_SRC (x), loop_depth);
return;
}
/* Storing in STRICT_LOW_PART is like storing in a reg
in that this SET might be dead, so ignore it in TESTREG.
but in some other ways it is like using the reg.
Storing in a SUBREG or a bit field is like storing the entire
register in that if the register's value is not used
then this SET is not needed. */
while (GET_CODE (testreg) == STRICT_LOW_PART
|| GET_CODE (testreg) == ZERO_EXTRACT
|| GET_CODE (testreg) == SIGN_EXTRACT
|| GET_CODE (testreg) == SUBREG)
{
/* Modifying a single register in an alternate mode
does not use any of the old value. But these other
ways of storing in a register do use the old value. */
if (GET_CODE (testreg) == SUBREG
&& !(REG_SIZE (SUBREG_REG (testreg)) > REG_SIZE (testreg)))
;
else
mark_dest = 1;
testreg = XEXP (testreg, 0);
}
/* If this is a store into a register,
recursively scan the value being stored. */
if ((GET_CODE (testreg) == PARALLEL
&& GET_MODE (testreg) == BLKmode)
|| GET_CODE (testreg) == REG)
{
count_reg_references (SET_SRC (x), loop_depth);
if (mark_dest)
count_reg_references (SET_DEST (x), loop_depth);
return;
}
}
break;
default:
break;
}
/* Recursively scan the operands of this expression. */
{
register const char *fmt = GET_RTX_FORMAT (code);
register int i;
for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
{
if (fmt[i] == 'e')
{
/* Tail recursive case: save a function call level. */
if (i == 0)
{
x = XEXP (x, 0);
goto retry;
}
count_reg_references (XEXP (x, i), loop_depth);
}
else if (fmt[i] == 'E')
{
register int j;
for (j = 0; j < XVECLEN (x, i); j++)
count_reg_references (XVECEXP (x, i, j), loop_depth);
}
}
}
}
/* Recompute register set/reference counts immediately prior to register
allocation.
@ -5760,70 +5555,8 @@ recompute_reg_usage (f, loop_step)
rtx f ATTRIBUTE_UNUSED;
int loop_step ATTRIBUTE_UNUSED;
{
rtx insn;
int i, max_reg;
int index;
int loop_depth;
/* Clear out the old data. */
max_reg = max_reg_num ();
for (i = FIRST_PSEUDO_REGISTER; i < max_reg; i++)
{
REG_N_SETS (i) = 0;
REG_N_REFS (i) = 0;
}
/* Scan each insn in the chain and count how many times each register is
set/used. */
for (index = 0; index < n_basic_blocks; index++)
{
basic_block bb = BASIC_BLOCK (index);
loop_depth = bb->loop_depth;
for (insn = bb->head; insn; insn = NEXT_INSN (insn))
{
if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
{
rtx links;
/* This call will increment REG_N_SETS for each SET or CLOBBER
of a register in INSN. It will also increment REG_N_REFS
by the loop depth for each set of a register in INSN. */
count_reg_sets (PATTERN (insn), loop_depth);
/* count_reg_sets does not detect autoincrement address modes, so
detect them here by looking at the notes attached to INSN. */
for (links = REG_NOTES (insn); links; links = XEXP (links, 1))
{
if (REG_NOTE_KIND (links) == REG_INC)
/* Count (weighted) references, stores, etc. This
counts a register twice if it is modified, but
that is correct. */
REG_N_SETS (REGNO (XEXP (links, 0)))++;
}
/* This call will increment REG_N_REFS by the current loop depth
for each reference to a register in INSN. */
count_reg_references (PATTERN (insn), loop_depth);
/* count_reg_references will not include counts for arguments to
function calls, so detect them here by examining the
CALL_INSN_FUNCTION_USAGE data. */
if (GET_CODE (insn) == CALL_INSN)
{
rtx note;
for (note = CALL_INSN_FUNCTION_USAGE (insn);
note;
note = XEXP (note, 1))
if (GET_CODE (XEXP (note, 0)) == USE)
count_reg_references (XEXP (XEXP (note, 0), 0),
loop_depth);
}
}
if (insn == bb->end)
break;
}
}
allocate_reg_life_data ();
update_life_info (NULL, UPDATE_LIFE_LOCAL, PROP_REG_INFO);
}
/* Optionally removes all the REG_DEAD and REG_UNUSED notes from a set of