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:
parent
693d9e2fe7
commit
f134997fac
|
@ -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
|
||||
|
|
271
gcc/flow.c
271
gcc/flow.c
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue