aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Kenner <kenner@gcc.gnu.org>1994-05-17 11:30:03 -0400
committerRichard Kenner <kenner@gcc.gnu.org>1994-05-17 11:30:03 -0400
commita533969946ef38da61a5264d06faba0aedfed216 (patch)
tree8eb60e048ff1d62807061501544a20bfe21ea5c3
parent58e09803edf76a4ffeae0e151972d08bf86e8771 (diff)
downloadgcc-a533969946ef38da61a5264d06faba0aedfed216.zip
gcc-a533969946ef38da61a5264d06faba0aedfed216.tar.gz
gcc-a533969946ef38da61a5264d06faba0aedfed216.tar.bz2
(compare_spill_regs): New function.
(reload_as_needed): Sort the spilled regs. (allocate_reload_reg): If we have group needs and failure would be fatal, do not try to do round-robin allocation of the spill regs. From-SVN: r7318
-rw-r--r--gcc/reload1.c30
1 files changed, 27 insertions, 3 deletions
diff --git a/gcc/reload1.c b/gcc/reload1.c
index f9ebc3f..5fa49ed 100644
--- a/gcc/reload1.c
+++ b/gcc/reload1.c
@@ -345,6 +345,7 @@ static void scan_paradoxical_subregs PROTO((rtx));
static int hard_reg_use_compare PROTO((struct hard_reg_n_uses *,
struct hard_reg_n_uses *));
static void order_regs_for_reload PROTO((void));
+static void compare_spill_regs PROTO((short *, short *));
static void reload_as_needed PROTO((rtx, int));
static void forget_old_reloads_1 PROTO((rtx, rtx));
static int reload_reg_class_lower PROTO((short *, short *));
@@ -3588,6 +3589,14 @@ order_regs_for_reload ()
potential_reload_regs[o++] = hard_reg_n_uses[i].regno;
}
+/* Used in reload_as_needed to sort the spilled regs. */
+static int
+compare_spill_regs (r1, r2)
+ short *r1, *r2;
+{
+ return *r1 < *r2 ? -1: 1;
+}
+
/* Reload pseudo-registers into hard regs around each insn as needed.
Additional register load insns are output before the insn that needs it
and perhaps store insns after insns that modify the reloaded pseudo reg.
@@ -3635,6 +3644,11 @@ reload_as_needed (first, live_known)
num_not_at_initial_offset = 0;
+ /* Order the spilled regs, so that allocate_reload_regs can guarantee to
+ pack registers with group needs. */
+ if (n_spills > 1)
+ qsort (spill_regs, n_spills, sizeof (short), compare_spill_regs);
+
for (insn = first; insn;)
{
register rtx next = NEXT_INSN (insn);
@@ -4558,9 +4572,19 @@ allocate_reload_reg (r, insn, last_reload, noerror)
/* I is the index in spill_regs.
We advance it round-robin between insns to use all spill regs
equally, so that inherited reloads have a chance
- of leapfrogging each other. */
-
- for (count = 0, i = last_spill_reg; count < n_spills; count++)
+ of leapfrogging each other. Don't do this, however, when we have
+ group needs and failure would be fatal; if we only have a relatively
+ small number of spill registers, and more than one of them has
+ group needs, then by starting in the middle, we may end up
+ allocating the first one in such a way that we are not left with
+ sufficient groups to handle the rest. */
+
+ if (noerror || ! force_group)
+ i = last_spill_reg;
+ else
+ i = -1;
+
+ for (count = 0; count < n_spills; count++)
{
int class = (int) reload_reg_class[r];