This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Yet another reload_reg_free_for_value_p bug
- To: law at cygnus dot com
- Subject: Re: Yet another reload_reg_free_for_value_p bug
- From: Joern Rennecke <amylaar at cygnus dot co dot uk>
- Date: Fri, 22 Oct 1999 22:58:22 +0100
- Cc: gcc-patches at gcc dot gnu dot org, bernds at cygnus dot co dot uk, amylaar at cygnus dot co dot uk
- Newsgroups: cygnus.egcs.patches
In article <7114.938008027@upchuck.cygnus.com> you wrote:
: So the question remains, can we accurately determine what reloads a R_F_O_A
: may conflict with. And I believe the answer is yes. You use the same check
: that's done in find_reloads (preferably in a subroutine if it can be structured
: that way to avoid long term maintenance issues).
We can have more than one RELOAD_OTHER reload for a single operand.
After the reload merging, there is no way to tell if a RELOAD_OTHER
reload pertains just to one or to multiple RELOAD_OTHER reloads for
the same operands, unless we want to go through the replacements array
and look inside which rld[].in the locations are. This gets
even weirder because a match doesn't mean a conflict - but a match in a
following RELOAD_OTHER reload does.
So it seems too expensive to do an accurate test with the existing data.
We can add a new int - could be a small bitfield, e.g. unsigned 7 bits - to
struct reload that indicates the maximum reload number of a reload that
uses the reload in question.
We can then replace the block in find_reloads after this comment block:
/* 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. */
so that it just indicates conflicts instead of changing reload types.
switch (rld[i].when_needed)
{
case RELOAD_FOR_OPADDR_ADDR:
type = RELOAD_FOR_OPERAND_ADDRESS;
break;
case RELOAD_FOR_INPADDR_ADDRESS:
type = RELOAD_FOR_INPUT_ADDRESS;
break;
case RELOAD_FOR_OUTADDR_ADDRESS:
type = RELOAD_FOR_OUTPUT_ADDRESS;
break;
case RELOAD_FOR_OTHER_ADDRESS:
type = RELOAD_OTHER;
break;
default:
continue;
}
for (j = 0; j < n_reloads; j++)
{
if (rld[j].when_needed == type
&& rld[j].opnum == rld[j].opnum
&& (rld[i].secondary_p
? rld[j].secondary_in_reload == i
: reg_mentioned_p (rld[i].in, rld[j].in)))
rld[i].min_compatible = j;
}
When merging such reloads later, the surviving reload gets the maximum
of rld[i].min_compatible of the two constituent reloads.
A reload J of the adjacent class (variable TYPE above) conflicts with
reload I if it has a smaller reload number than min_compatible for I,
i.e. if j < rld[i].min_compatible .
(The test reg_mentioned_p (rld[i].in, rld[j].in) is not exact, we could get
false positives. But trying to match the location in the replacements
array seems too much trouble.)