This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
bug fix for reload reg selection
- To: gcc-patches at gcc dot gnu dot org
- Subject: bug fix for reload reg selection
- From: Joern Rennecke <amylaar at cambridge dot redhat dot com>
- Date: Wed, 24 Jan 2001 16:03:37 +0000 (GMT)
- Cc: amylaar at cambridge dot redhat dot com
For a multi-precision add, choose_reload_regs had allocated registers
0 and 1 for a RELOAD_FOR_INPUT reload - using inheritance - and asked
allocate_reload_regs to allocate another two registers for a RELOAD_OTHER
reload, using the same input, pseudo register 215.
alloacte_reload_reg checked register 1 and 2, and was told by
free_for_value_p that this group was OK - register 2 was genuinely free,
while register 1 already held the value that we wanted, pseudo 215.
Now, of course the different words of a multi-word pseudo are not
interchangable. The appended patch makes reload_reg_free_for_value_p
honour this by considering a previously loaded value only as matching
if it was loaded into the very same register - not just into any
partially overlapping register.
Of course, the above described scenario begs the question why pseudo 215
was not inherited for both reloads in the first place. But that is a
different story.
Wed Jan 24 13:55:59 2001 J"orn Rennecke <amylaar@redhat.com>
* reload1.c (reload_reg_free_for_value_p): New parameter start_regno.
Changed all callers. Take it into account when deciding if a
previously loaded value matches.
Index: reload1.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/reload1.c,v
diff -p -r1.287.2.3 -r1.287.2.4
*** reload1.c 2001/01/21 03:45:50
--- reload1.c 2001/01/24 14:10:42
*************** static void clear_reload_reg_in_use PARA
*** 411,417 ****
enum machine_mode));
static int reload_reg_free_p PARAMS ((unsigned int, int,
enum reload_type));
! static int reload_reg_free_for_value_p PARAMS ((int, int, enum reload_type,
rtx, rtx, int, int));
static int free_for_value_p PARAMS ((int, enum machine_mode, int,
enum reload_type, rtx, rtx,
--- 411,418 ----
enum machine_mode));
static int reload_reg_free_p PARAMS ((unsigned int, int,
enum reload_type));
! static int reload_reg_free_for_value_p PARAMS ((int, int, int,
! enum reload_type,
rtx, rtx, int, int));
static int free_for_value_p PARAMS ((int, enum machine_mode, int,
enum reload_type, rtx, rtx,
*************** int reload_spill_index[MAX_RELOADS];
*** 4725,4733 ****
/* Subroutine of free_for_value_p, used to check a single register. */
static int
! reload_reg_free_for_value_p (regno, opnum, type, value, out, reloadnum,
! ignore_address_reloads)
! int regno;
int opnum;
enum reload_type type;
rtx value, out;
--- 4726,4734 ----
/* Subroutine of free_for_value_p, used to check a single register. */
static int
! reload_reg_free_for_value_p (start_regno, regno, opnum, type, value, out,
! reloadnum, ignore_address_reloads)
! int start_regno, regno;
int opnum;
enum reload_type type;
rtx value, out;
*************** reload_reg_free_for_value_p (regno, opnu
*** 4820,4826 ****
<= HARD_REGNO_NREGS (REGNO (reg), GET_MODE (reg)) - (unsigned)1)
&& i != reloadnum)
{
! if (! rld[i].in || ! rtx_equal_p (rld[i].in, value)
|| rld[i].out || out)
{
int time2;
--- 4821,4832 ----
<= HARD_REGNO_NREGS (REGNO (reg), GET_MODE (reg)) - (unsigned)1)
&& i != reloadnum)
{
! rtx value2 = rld[i].in;
!
! if (true_regnum (reg) != start_regno)
! value2 = NULL_RTX;
! if (! value2 || ! rtx_equal_p (value2, value)
! || true_regnum (reg) != start_regno
|| rld[i].out || out)
{
int time2;
*************** reload_reg_free_for_value_p (regno, opnu
*** 4901,4907 ****
case RELOAD_OTHER:
/* If there is no conflict in the input part, handle this
like an output reload. */
! if (! rld[i].in || rtx_equal_p (rld[i].in, value))
{
time2 = MAX_RECOG_OPERANDS * 4 + 4;
/* Earlyclobbered outputs must conflict with inputs. */
--- 4907,4913 ----
case RELOAD_OTHER:
/* If there is no conflict in the input part, handle this
like an output reload. */
! if (! rld[i].in || rtx_equal_p (value2, value))
{
time2 = MAX_RECOG_OPERANDS * 4 + 4;
/* Earlyclobbered outputs must conflict with inputs. */
*************** reload_reg_free_for_value_p (regno, opnu
*** 4923,4929 ****
}
if ((time1 >= time2
&& (! rld[i].in || rld[i].out
! || ! rtx_equal_p (rld[i].in, value)))
|| (out && rld[reloadnum].out_reg
&& time2 >= MAX_RECOG_OPERANDS * 4 + 3))
return 0;
--- 4929,4935 ----
}
if ((time1 >= time2
&& (! rld[i].in || rld[i].out
! || ! rtx_equal_p (value2, value)))
|| (out && rld[reloadnum].out_reg
&& time2 >= MAX_RECOG_OPERANDS * 4 + 3))
return 0;
*************** free_for_value_p (regno, mode, opnum, ty
*** 4974,4981 ****
{
int nregs = HARD_REGNO_NREGS (regno, mode);
while (nregs-- > 0)
! if (! reload_reg_free_for_value_p (regno + nregs, opnum, type, value, out,
! reloadnum, ignore_address_reloads))
return 0;
return 1;
}
--- 4980,4988 ----
{
int nregs = HARD_REGNO_NREGS (regno, mode);
while (nregs-- > 0)
! if (! reload_reg_free_for_value_p (regno, regno + nregs, opnum, type,
! value, out, reloadnum,
! ignore_address_reloads))
return 0;
return 1;
}