aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJ"orn Rennecke <amylaar@cygnus.co.uk>1998-03-26 15:08:53 +0000
committerJoern Rennecke <amylaar@gcc.gnu.org>1998-03-26 15:08:53 +0000
commite6e52be0731568a32b46ca158cd8ef5c3835f1c6 (patch)
tree6a088845acb08fd98dfcb3a3462b8f9fbd9019e7
parenta9c3c9a520a63a48429b9da74f056878add85643 (diff)
downloadgcc-e6e52be0731568a32b46ca158cd8ef5c3835f1c6.zip
gcc-e6e52be0731568a32b46ca158cd8ef5c3835f1c6.tar.gz
gcc-e6e52be0731568a32b46ca158cd8ef5c3835f1c6.tar.bz2
reload inheritance improvement:
* reload1.c (reg_reloaded_contents, reg_reloaded_insn): Change meaning: index is now hard reg number. (reg_reloaded_valid, reg_reloaded_dead): New variables. (reload_spill_index): Content is now a hard reg number. (reload_as_needed): Change to fit new variable meaning. (forget_old_reloads_1, allocate_reload_reg): Likewise. (choose_reload_regs, emit_reload_insns): Likewise. From-SVN: r18848
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/reload1.c170
2 files changed, 98 insertions, 83 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 7ed217f..a86f834 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,14 @@
+Thu Mar 26 23:00:11 1998 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ reload inheritance improvement:
+ * reload1.c (reg_reloaded_contents, reg_reloaded_insn):
+ Change meaning: index is now hard reg number.
+ (reg_reloaded_valid, reg_reloaded_dead): New variables.
+ (reload_spill_index): Content is now a hard reg number.
+ (reload_as_needed): Change to fit new variable meaning.
+ (forget_old_reloads_1, allocate_reload_reg): Likewise.
+ (choose_reload_regs, emit_reload_insns): Likewise.
+
Thu Mar 26 18:34:13 1998 J"orn Rennecke <amylaar@cygnus.co.uk>
* regclass.c (record_reg_classes): '?' increases cost by two.
diff --git a/gcc/reload1.c b/gcc/reload1.c
index aeb2a62..e1f56d2 100644
--- a/gcc/reload1.c
+++ b/gcc/reload1.c
@@ -114,19 +114,23 @@ static int *reg_max_ref_width;
constant or memory slot. */
static rtx *reg_equiv_init;
-/* During reload_as_needed, element N contains the last pseudo regno
- reloaded into the Nth reload register. This vector is in parallel
- with spill_regs. If that pseudo reg occupied more than one register,
+/* During reload_as_needed, element N contains the last pseudo regno reloaded
+ into hard register N. If that pseudo reg occupied more than one register,
reg_reloaded_contents points to that pseudo for each spill register in
use; all of these must remain set for an inheritance to occur. */
static int reg_reloaded_contents[FIRST_PSEUDO_REGISTER];
/* During reload_as_needed, element N contains the insn for which
- the Nth reload register was last used. This vector is in parallel
- with spill_regs, and its contents are significant only when
- reg_reloaded_contents is significant. */
+ hard register N was last used. Its contents are significant only
+ when reg_reloaded_valid is set for this register. */
static rtx reg_reloaded_insn[FIRST_PSEUDO_REGISTER];
+/* Indicate if reg_reloaded_insn / reg_reloaded_contents is valid */
+static HARD_REG_SET reg_reloaded_valid;
+/* Indicate if the register was dead at the end of the reload.
+ This is only valid if reg_reloaded_contents is set and valid. */
+static HARD_REG_SET reg_reloaded_dead;
+
/* Number of spill-regs so far; number of valid elements of spill_regs. */
static int n_spills;
@@ -3980,11 +3984,7 @@ reload_as_needed (first, live_known)
reg_last_reload_reg = (rtx *) alloca (max_regno * sizeof (rtx));
bzero ((char *) reg_last_reload_reg, max_regno * sizeof (rtx));
reg_has_output_reload = (char *) alloca (max_regno);
- for (i = 0; i < n_spills; i++)
- {
- reg_reloaded_contents[i] = -1;
- reg_reloaded_insn[i] = 0;
- }
+ CLEAR_HARD_REG_SET (reg_reloaded_valid);
/* Reset all offsets on eliminable registers to their initial values. */
#ifdef ELIMINABLE_REGS
@@ -4197,32 +4197,21 @@ reload_as_needed (first, live_known)
}
/* A reload reg's contents are unknown after a label. */
if (GET_CODE (insn) == CODE_LABEL)
- for (i = 0; i < n_spills; i++)
- {
- reg_reloaded_contents[i] = -1;
- reg_reloaded_insn[i] = 0;
- }
+ CLEAR_HARD_REG_SET (reg_reloaded_valid);
/* Don't assume a reload reg is still good after a call insn
if it is a call-used reg. */
else if (GET_CODE (insn) == CALL_INSN)
- for (i = 0; i < n_spills; i++)
- if (call_used_regs[spill_regs[i]])
- {
- reg_reloaded_contents[i] = -1;
- reg_reloaded_insn[i] = 0;
- }
+ AND_COMPL_HARD_REG_SET(reg_reloaded_valid, call_used_reg_set);
/* In case registers overlap, allow certain insns to invalidate
particular hard registers. */
#ifdef INSN_CLOBBERS_REGNO_P
- for (i = 0 ; i < n_spills ; i++)
- if (INSN_CLOBBERS_REGNO_P (insn, spill_regs[i]))
- {
- reg_reloaded_contents[i] = -1;
- reg_reloaded_insn[i] = 0;
- }
+ for (i = 0 ; i < FIRST_PSEUDO_REGISTER; i++)
+ if (TEST_HARD_REG_BIT (reg_reloaded_valid, i)
+ && INSN_CLOBBERS_REGNO_P (insn, i))
+ CLEAR_HARD_REG_BIT (reg_reloaded_valid, i);
#endif
insn = next;
@@ -4272,15 +4261,11 @@ forget_old_reloads_1 (x, ignored)
and it wasn't spilled because this block's total need is 0.
Then some insn might have an optional reload and use this reg. */
for (i = 0; i < nr; i++)
- if (spill_reg_order[regno + i] >= 0
- /* But don't do this if the reg actually serves as an output
- reload reg in the current instruction. */
- && (n_reloads == 0
- || ! TEST_HARD_REG_BIT (reg_is_output_reload, regno + i)))
- {
- reg_reloaded_contents[spill_reg_order[regno + i]] = -1;
- reg_reloaded_insn[spill_reg_order[regno + i]] = 0;
- }
+ /* But don't do this if the reg actually serves as an output
+ reload reg in the current instruction. */
+ if (n_reloads == 0
+ || ! TEST_HARD_REG_BIT (reg_is_output_reload, regno + i))
+ CLEAR_HARD_REG_BIT (reg_reloaded_valid, regno + i);
}
/* Since value of X has changed,
@@ -5005,8 +4990,8 @@ rtx reload_inheritance_insn[MAX_RELOADS];
rather than using reload_in. */
rtx reload_override_in[MAX_RELOADS];
-/* For each reload, the index in spill_regs of the spill register used,
- or -1 if we did not need one of the spill registers for this reload. */
+/* For each reload, the hard register number of the register used,
+ or -1 if we did not need a register for this reload. */
int reload_spill_index[MAX_RELOADS];
/* Find a spill register to use as a reload register for reload R.
@@ -5181,7 +5166,7 @@ allocate_reload_reg (r, insn, last_reload, noerror)
reload_when_needed[r], reload_mode[r]);
reload_reg_rtx[r] = new;
- reload_spill_index[r] = i;
+ reload_spill_index[r] = spill_regs[i];
return 1;
}
}
@@ -5504,32 +5489,32 @@ choose_reload_regs (insn, avoid_return_reg)
if (regno >= 0 && reg_last_reload_reg[regno] != 0)
{
- i = spill_reg_order[REGNO (reg_last_reload_reg[regno])];
+ i = REGNO (reg_last_reload_reg[regno]);
if (reg_reloaded_contents[i] == regno
+ && TEST_HARD_REG_BIT (reg_reloaded_valid, i)
&& (GET_MODE_SIZE (GET_MODE (reg_last_reload_reg[regno]))
>= GET_MODE_SIZE (mode))
- && HARD_REGNO_MODE_OK (spill_regs[i], reload_mode[r])
+ && HARD_REGNO_MODE_OK (i, reload_mode[r])
&& TEST_HARD_REG_BIT (reg_class_contents[(int) reload_reg_class[r]],
- spill_regs[i])
+ i)
&& (reload_nregs[r] == max_group_size
|| ! TEST_HARD_REG_BIT (reg_class_contents[(int) group_class],
- spill_regs[i]))
- && reload_reg_free_p (spill_regs[i], reload_opnum[r],
+ i))
+ && reload_reg_free_p (i, reload_opnum[r],
reload_when_needed[r])
- && reload_reg_free_before_p (spill_regs[i],
- reload_opnum[r],
+ && reload_reg_free_before_p (i, reload_opnum[r],
reload_when_needed[r]))
{
/* If a group is needed, verify that all the subsequent
registers still have their values intact. */
int nr
- = HARD_REGNO_NREGS (spill_regs[i], reload_mode[r]);
+ = HARD_REGNO_NREGS (i, reload_mode[r]);
int k;
for (k = 1; k < nr; k++)
- if (reg_reloaded_contents[spill_reg_order[spill_regs[i] + k]]
- != regno)
+ if (reg_reloaded_contents[i + k] != regno
+ || ! TEST_HARD_REG_BIT (reg_reloaded_valid, i + k))
break;
if (k == nr)
@@ -5550,6 +5535,10 @@ choose_reload_regs (insn, avoid_return_reg)
break;
if (i1 != n_earlyclobbers
+ /* Don't use it if we'd clobber a pseudo reg. */
+ || (spill_reg_order[i] < 0
+ && reload_out[r]
+ && ! TEST_HARD_REG_BIT (reg_reloaded_dead, i))
/* Don't really use the inherited spill reg
if we need it wider than we've got it. */
|| (GET_MODE_SIZE (reload_mode[r])
@@ -5561,7 +5550,7 @@ choose_reload_regs (insn, avoid_return_reg)
/* We can use this as a reload reg. */
/* Mark the register as in use for this part of
the insn. */
- mark_reload_reg_in_use (spill_regs[i],
+ mark_reload_reg_in_use (i,
reload_opnum[r],
reload_when_needed[r],
reload_mode[r]);
@@ -5572,7 +5561,7 @@ choose_reload_regs (insn, avoid_return_reg)
reload_spill_index[r] = i;
for (k = 0; k < nr; k++)
SET_HARD_REG_BIT (reload_reg_used_for_inherit,
- spill_regs[i + k]);
+ i + k);
}
}
}
@@ -5844,7 +5833,7 @@ choose_reload_regs (insn, avoid_return_reg)
i = reload_spill_index[r];
- /* I is nonneg if this reload used one of the spill regs.
+ /* I is nonneg if this reload uses a register.
If reload_reg_rtx[r] is 0, this is an optional reload
that we opted to ignore. */
if (reload_out[r] != 0 && GET_CODE (reload_out[r]) == REG
@@ -5861,9 +5850,9 @@ choose_reload_regs (insn, avoid_return_reg)
if (i >= 0)
{
- nr = HARD_REGNO_NREGS (spill_regs[i], reload_mode[r]);
+ nr = HARD_REGNO_NREGS (i, reload_mode[r]);
while (--nr >= 0)
- SET_HARD_REG_BIT (reg_is_output_reload, spill_regs[i] + nr);
+ SET_HARD_REG_BIT (reg_is_output_reload, i + nr);
}
if (reload_when_needed[r] != RELOAD_OTHER
@@ -5985,6 +5974,9 @@ emit_reload_insns (insn)
int special;
/* Values to be put in spill_reg_store are put here first. */
rtx new_spill_reg_store[FIRST_PSEUDO_REGISTER];
+ HARD_REG_SET reg_reloaded_died;
+
+ CLEAR_HARD_REG_SET (reg_reloaded_died);
for (j = 0; j < reload_n_operands; j++)
input_reload_insns[j] = input_address_reload_insns[j]
@@ -6151,14 +6143,12 @@ emit_reload_insns (insn)
if (optimize && GET_CODE (oldequiv) == REG
&& REGNO (oldequiv) < FIRST_PSEUDO_REGISTER
- && spill_reg_order[REGNO (oldequiv)] >= 0
- && spill_reg_store[spill_reg_order[REGNO (oldequiv)]] != 0
- && find_reg_note (insn, REG_DEAD, reload_in[j])
+ && spill_reg_store[REGNO (oldequiv)]
+ && GET_CODE (old) == REG && dead_or_set_p (insn, old)
/* This is unsafe if operand occurs more than once in current
insn. Perhaps some occurrences weren't reloaded. */
- && count_occurrences (PATTERN (insn), reload_in[j]) == 1)
- delete_output_reload
- (insn, j, spill_reg_store[spill_reg_order[REGNO (oldequiv)]]);
+ && count_occurrences (PATTERN (insn), old) == 1)
+ delete_output_reload (insn, j, spill_reg_store[REGNO (oldequiv)]);
/* Encapsulate both RELOADREG and OLDEQUIV into that mode,
then load RELOADREG from OLDEQUIV. Note that we cannot use
@@ -6566,7 +6556,7 @@ emit_reload_insns (insn)
#endif
&& spill_reg_store[reload_spill_index[j]] != 0
/* This is unsafe if some other reload uses the same reg first. */
- && reload_reg_free_before_p (spill_regs[reload_spill_index[j]],
+ && reload_reg_free_before_p (reload_spill_index[j],
reload_opnum[j], reload_when_needed[j])
&& dead_or_set_p (insn, reload_in[j])
/* This is unsafe if operand occurs more than once in current
@@ -6769,15 +6759,30 @@ emit_reload_insns (insn)
for (p = get_insns (); p; p = NEXT_INSN (p))
if (GET_RTX_CLASS (GET_CODE (p)) == 'i')
{
+ rtx pat = PATTERN (p);
+
/* If this output reload doesn't come from a spill reg,
clear any memory of reloaded copies of the pseudo reg.
If this output reload comes from a spill reg,
reg_has_output_reload will make this do nothing. */
- note_stores (PATTERN (p), forget_old_reloads_1);
+ note_stores (pat, forget_old_reloads_1);
+
+ if (reg_mentioned_p (reload_reg_rtx[j], pat))
+ {
+ if (reload_spill_index[j] < 0
+ && GET_CODE (pat) == SET
+ && SET_SRC (pat) == reload_reg_rtx[j])
+ {
+ int src = REGNO (SET_SRC (pat));
- if (reg_mentioned_p (reload_reg_rtx[j], PATTERN (p))
- && reload_spill_index[j] >= 0)
- new_spill_reg_store[reload_spill_index[j]] = p;
+ reload_spill_index[j] = src;
+ SET_HARD_REG_BIT (reg_is_output_reload, src);
+ if (find_regno_note (insn, REG_DEAD, src))
+ SET_HARD_REG_BIT (reg_reloaded_died, src);
+ }
+ if (reload_spill_index[j] >= 0)
+ new_spill_reg_store[reload_spill_index[j]] = p;
+ }
}
if (reload_when_needed[j] == RELOAD_OTHER)
@@ -6893,14 +6898,14 @@ emit_reload_insns (insn)
register int r = reload_order[j];
register int i = reload_spill_index[r];
- /* I is nonneg if this reload used one of the spill regs.
+ /* I is nonneg if this reload used a register.
If reload_reg_rtx[r] is 0, this is an optional reload
that we opted to ignore. */
if (i >= 0 && reload_reg_rtx[r] != 0)
{
int nr
- = HARD_REGNO_NREGS (spill_regs[i], GET_MODE (reload_reg_rtx[r]));
+ = HARD_REGNO_NREGS (i, GET_MODE (reload_reg_rtx[r]));
int k;
int part_reaches_end = 0;
int all_reaches_end = 1;
@@ -6909,7 +6914,7 @@ emit_reload_insns (insn)
of the value lives to the end. */
for (k = 0; k < nr; k++)
{
- if (reload_reg_reaches_end_p (spill_regs[i] + k, reload_opnum[r],
+ if (reload_reg_reaches_end_p (i + k, reload_opnum[r],
reload_when_needed[r]))
part_reaches_end = 1;
else
@@ -6924,10 +6929,7 @@ emit_reload_insns (insn)
If consecutive registers are used, clear them all. */
for (k = 0; k < nr; k++)
- {
- reg_reloaded_contents[spill_reg_order[spill_regs[i] + k]] = -1;
- reg_reloaded_insn[spill_reg_order[spill_regs[i] + k]] = 0;
- }
+ CLEAR_HARD_REG_BIT (reg_reloaded_valid, i + k);
/* Maybe the spill reg contains a copy of reload_out. */
if (reload_out[r] != 0 && GET_CODE (reload_out[r]) == REG)
@@ -6957,11 +6959,13 @@ emit_reload_insns (insn)
/* Now do the inverse operation. */
for (k = 0; k < nr; k++)
{
- reg_reloaded_contents[spill_reg_order[spill_regs[i] + k]]
+ CLEAR_HARD_REG_BIT (reg_reloaded_dead, i + k);
+ reg_reloaded_contents[i + k]
= (nregno >= FIRST_PSEUDO_REGISTER || nr != nnr
? nregno
: nregno + k);
- reg_reloaded_insn[spill_reg_order[spill_regs[i] + k]] = insn;
+ reg_reloaded_insn[i + k] = insn;
+ SET_HARD_REG_BIT (reg_reloaded_valid, i + k);
}
}
@@ -6970,6 +6974,7 @@ emit_reload_insns (insn)
the register being reloaded. */
else if (reload_out[r] == 0
&& reload_in[r] != 0
+ && spill_reg_order[i] >= 0
&& ((GET_CODE (reload_in[r]) == REG
&& ! reg_has_output_reload[REGNO (reload_in[r])])
|| (GET_CODE (reload_in_reg[r]) == REG
@@ -7004,12 +7009,13 @@ emit_reload_insns (insn)
for (k = 0; k < nr; k++)
{
- reg_reloaded_contents[spill_reg_order[spill_regs[i] + k]]
+ CLEAR_HARD_REG_BIT (reg_reloaded_dead, i + k);
+ reg_reloaded_contents[i + k]
= (nregno >= FIRST_PSEUDO_REGISTER || nr != nnr
? nregno
: nregno + k);
- reg_reloaded_insn[spill_reg_order[spill_regs[i] + k]]
- = insn;
+ reg_reloaded_insn[i + k] = insn;
+ SET_HARD_REG_BIT (reg_reloaded_valid, i + k);
}
}
}
@@ -7019,13 +7025,10 @@ emit_reload_insns (insn)
else if (part_reaches_end)
{
for (k = 0; k < nr; k++)
- if (reload_reg_reaches_end_p (spill_regs[i] + k,
+ if (reload_reg_reaches_end_p (i + k,
reload_opnum[r],
reload_when_needed[r]))
- {
- reg_reloaded_contents[spill_reg_order[spill_regs[i] + k]] = -1;
- reg_reloaded_insn[spill_reg_order[spill_regs[i] + k]] = 0;
- }
+ CLEAR_HARD_REG_BIT (reg_reloaded_valid, i + k);
}
}
@@ -7051,6 +7054,7 @@ emit_reload_insns (insn)
}
}
}
+ IOR_HARD_REG_SET (reg_reloaded_dead, reg_reloaded_died);
}
/* Emit code to perform a reload from IN (which may be a reload register) to