reload.c (find_reloads): If there are multiple RELOAD_FOR_INPUT_ADDRESS / RELOAD_FOR_OUTPUT_ADDRESS...

* reload.c (find_reloads): If there are multiple
	RELOAD_FOR_INPUT_ADDRESS / RELOAD_FOR_OUTPUT_ADDRESS reloads for
	one operand, change RELOAD_FOR_INPADDR_ADDRESS /
	RELOAD_FOR_OUTADDR_ADDRESS for all but the first
	RELOAD_FOR_INPUT_ADDRESS / RELOAD_FOR_OUTPUT_ADDRESS reloads.

From-SVN: r20877
This commit is contained in:
J"orn Rennecke 1998-07-01 13:20:50 +00:00 committed by Joern Rennecke
parent d7921434ac
commit 826e385453
2 changed files with 82 additions and 9 deletions

View File

@ -1,3 +1,11 @@
Wed Jul 1 21:17:36 1998 J"orn Rennecke <amylaar@cygnus.co.uk>
* reload.c (find_reloads): If there are multiple
RELOAD_FOR_INPUT_ADDRESS / RELOAD_FOR_OUTPUT_ADDRESS reloads for
one operand, change RELOAD_FOR_INPADDR_ADDRESS /
RELOAD_FOR_OUTADDR_ADDRESS for all but the first
RELOAD_FOR_INPUT_ADDRESS / RELOAD_FOR_OUTPUT_ADDRESS reloads.
Wed Jul 1 17:23:23 1998 J"orn Rennecke <amylaar@cygnus.co.uk>
* regmove.c (fixup_match_2): Check that P has RTX_CLASS 'i' before

View File

@ -3994,17 +3994,82 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
actually fail are extremely rare, so it turns out to be better to fix
the problem here by not generating cases that choose_reload_regs will
fail for. */
/* There is a similar problem with RELAOD_FOR_INPUT_ADDRESS /
RELOAD_FOR_OUTPUT_ADDRESS when there is more than one of a kind for
a single operand.
We can reduce the register pressure by exploiting that a
RELOAD_FOR_X_ADDR_ADDR that precedes all RELOAD_FOR_X_ADDRESS reloads
does not conflict with any of them. */
{
int op_addr_reloads = 0;
for (i = 0; i < n_reloads; i++)
if (reload_when_needed[i] == RELOAD_FOR_OPERAND_ADDRESS)
op_addr_reloads++;
int first_op_addr_num = -2;
int first_inpaddr_num[MAX_RECOG_OPERANDS];
int first_outpaddr_num[MAX_RECOG_OPERANDS];
int need_change= 0;
/* We use last_op_addr_reload and the contents of the above arrays
first as flags - -2 means no instance encountered, -1 means exactly
one instance encountered.
If more than one instance has been encountered, we store the reload
number of the first reload of the kind in question; reload numbers
are known to be non-negative. */
for (i = 0; i < noperands; i++)
first_inpaddr_num[i] = first_outpaddr_num[i] = -2;
for (i = n_reloads - 1; i >= 0; i--)
{
switch (reload_when_needed[i])
{
case RELOAD_FOR_OPERAND_ADDRESS:
if (! ++first_op_addr_num)
{
first_op_addr_num= i;
need_change = 1;
}
break;
case RELOAD_FOR_INPUT_ADDRESS:
if (! ++first_inpaddr_num[reload_opnum[i]])
{
first_inpaddr_num[reload_opnum[i]] = i;
need_change = 1;
}
break;
case RELOAD_FOR_OUTPUT_ADDRESS:
if (! ++first_outpaddr_num[reload_opnum[i]])
{
first_outpaddr_num[reload_opnum[i]] = i;
need_change = 1;
}
break;
default:
break;
}
}
if (op_addr_reloads > 1)
for (i = 0; i < n_reloads; i++)
if (reload_when_needed[i] == RELOAD_FOR_OPADDR_ADDR)
reload_when_needed[i] = RELOAD_FOR_OPERAND_ADDRESS;
if (need_change)
{
for (i = 0; i < n_reloads; i++)
{
int first_num, type;
switch (reload_when_needed[i])
{
case RELOAD_FOR_OPADDR_ADDR:
first_num = first_op_addr_num;
type = RELOAD_FOR_OPERAND_ADDRESS;
break;
case RELOAD_FOR_INPADDR_ADDRESS:
first_num = first_inpaddr_num[reload_opnum[i]];
type = RELOAD_FOR_INPUT_ADDRESS;
break;
case RELOAD_FOR_OUTADDR_ADDRESS:
first_num = first_outpaddr_num[reload_opnum[i]];
type = RELOAD_FOR_OUTPUT_ADDRESS;
break;
default:
continue;
}
if (i > first_num)
reload_when_needed[i] = type;
}
}
}
/* See if we have any reloads that are now allowed to be merged