[PATCH] Prevent coalesce in new-ra when class size == 1
Pat Haugen
pthaugen@us.ibm.com
Thu Jul 22 19:12:00 GMT 2004
This patch prevents the graph coloring register allocator (-fnew-ra) from
coalescing a move when either of the pseudos has a preferred class with
only one hard reg in it. I observed several cases in SPEC (approximately
50 in bzip2 alone) where the DoLoop transformation was being performed but
we did not end up with a branch-on-count loop because new-ra was coalescing
a copy from a pseudo that prefers GENERAL_REGS to a pseudo that prefers
CTR_REGS (PowerPC). The resulting register picked was then from
GENERAL_REGS.
Bootstrapped and regtested on powerpc64-unknown-linux-gnu.
OK for mainline?
-Pat
2004-07-22 Pat Haugen <pthaugen@us.ibm.com>
* colorize.c (ok_class): New.
(coalesce, aggressive_coalesce, extended_coalesce_2): Use it.
Index: gcc/ra-colorize.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/ra-colorize.c,v
retrieving revision 1.18
diff -c -3 -p -r1.18 ra-colorize.c
*** gcc/ra-colorize.c 15 Mar 2004 18:20:39 -0000 1.18
--- gcc/ra-colorize.c 21 Jul 2004 16:16:28 -0000
*************** static void add_web_pair_cost (struct we
*** 92,97 ****
--- 92,98 ----
unsigned HOST_WIDE_INT, unsigned int);
static int comp_web_pairs (const void *, const void *);
static void sort_and_combine_web_pairs (int);
+ static int ok_class (struct web *, struct web *);
static void aggressive_coalesce (void);
static void extended_coalesce_2 (void);
static void check_uncoalesced_moves (void);
*************** coalesce (void)
*** 841,847 ****
}
else if (target->type == PRECOLORED
|| TEST_BIT (sup_igraph, source->id * num_webs + target->id)
! || TEST_BIT (sup_igraph, target->id * num_webs + source->id))
{
remove_move (source, m);
remove_move (target, m);
--- 842,849 ----
}
else if (target->type == PRECOLORED
|| TEST_BIT (sup_igraph, source->id * num_webs + target->id)
! || TEST_BIT (sup_igraph, target->id * num_webs + source->id)
! || !ok_class (target, source))
{
remove_move (source, m);
remove_move (target, m);
*************** sort_and_combine_web_pairs (int for_move
*** 2464,2469 ****
--- 2466,2490 ----
free (sorted);
}
+ /* Returns nonzero if source/target reg classes are ok for coalesce. */
+
+ static int
+ ok_class (struct web *target, struct web *source)
+ {
+ /* Don't coalesce if preferred classes are different and at least one
+ of them has a size of 1. This was preventing things such as the
+ branch on count transformation (i.e. DoLoop) since the target, which
+ prefers the CTR, was being coalesced with a source which preferred
+ GENERAL_REGS. */
+ enum reg_class t_class, s_class;
+ t_class = reg_preferred_class (target->regno);
+ s_class = reg_preferred_class (source->regno);
+ if (t_class != s_class
+ && (num_free_regs[t_class] == 1 || num_free_regs[s_class] == 1))
+ return 0;
+ return 1;
+ }
+
/* Greedily coalesce all moves possible. Begin with the web pair
giving the most saving if coalesced. */
*************** aggressive_coalesce (void)
*** 2487,2493 ****
if (s != t
&& t->type != PRECOLORED
&& !TEST_BIT (sup_igraph, s->id * num_webs + t->id)
! && !TEST_BIT (sup_igraph, t->id * num_webs + s->id))
{
if ((s->type == PRECOLORED && ok (t, s))
|| s->type != PRECOLORED)
--- 2508,2515 ----
if (s != t
&& t->type != PRECOLORED
&& !TEST_BIT (sup_igraph, s->id * num_webs + t->id)
! && !TEST_BIT (sup_igraph, t->id * num_webs + s->id)
! && ok_class (t, s))
{
if ((s->type == PRECOLORED && ok (t, s))
|| s->type != PRECOLORED)
*************** extended_coalesce_2 (void)
*** 2557,2562 ****
--- 2579,2585 ----
dest->id * num_webs + source->id)
&& !TEST_BIT (sup_igraph,
source->id * num_webs + dest->id)
+ && ok_class (dest, source)
&& hard_regs_intersect_p (&source->usable_regs,
&dest->usable_regs))
add_web_pair_cost (dest, source,
More information about the Gcc-patches
mailing list