Commit 727d709b by Pat Haugen Committed by David Edelsohn

ra.h (single_reg_in_regclass): Declare.

2004-07-29  Pat Haugen  <pthaugen@us.ibm.com>

        * ra.h (single_reg_in_regclass): Declare.
        * ra.c (single_reg_in_regclass): Define.
        (first_hard_reg): New.
        (init_ra): Initialize single_reg_in_regclass.
        * ra-colorize.c (ok_class): New.
        (coalesce, aggressive_coalesce, extended_coalesce_2): Use it.

From-SVN: r85300
parent a639e504
2004-07-29 Pat Haugen <pthaugen@us.ibm.com>
* ra.h (single_reg_in_regclass): Declare.
* ra.c (single_reg_in_regclass): Define.
(first_hard_reg): New.
(init_ra): Initialize single_reg_in_regclass.
* ra-colorize.c (ok_class): New.
(coalesce, aggressive_coalesce, extended_coalesce_2): Use it.
2004-07-29 Nathan Sidwell <nathan@codesourcery.com> 2004-07-29 Nathan Sidwell <nathan@codesourcery.com>
* gcov-io.h: Allow zero tag as EOF indicator. * gcov-io.h: Allow zero tag as EOF indicator.
......
...@@ -92,6 +92,7 @@ static void add_web_pair_cost (struct web *, struct web *, ...@@ -92,6 +92,7 @@ static void add_web_pair_cost (struct web *, struct web *,
unsigned HOST_WIDE_INT, unsigned int); unsigned HOST_WIDE_INT, unsigned int);
static int comp_web_pairs (const void *, const void *); static int comp_web_pairs (const void *, const void *);
static void sort_and_combine_web_pairs (int); static void sort_and_combine_web_pairs (int);
static int ok_class (struct web *, struct web *);
static void aggressive_coalesce (void); static void aggressive_coalesce (void);
static void extended_coalesce_2 (void); static void extended_coalesce_2 (void);
static void check_uncoalesced_moves (void); static void check_uncoalesced_moves (void);
...@@ -841,7 +842,8 @@ coalesce (void) ...@@ -841,7 +842,8 @@ coalesce (void)
} }
else if (target->type == PRECOLORED else if (target->type == PRECOLORED
|| TEST_BIT (sup_igraph, source->id * num_webs + target->id) || TEST_BIT (sup_igraph, source->id * num_webs + target->id)
|| TEST_BIT (sup_igraph, target->id * num_webs + source->id)) || TEST_BIT (sup_igraph, target->id * num_webs + source->id)
|| !ok_class (target, source))
{ {
remove_move (source, m); remove_move (source, m);
remove_move (target, m); remove_move (target, m);
...@@ -2464,6 +2466,39 @@ sort_and_combine_web_pairs (int for_move) ...@@ -2464,6 +2466,39 @@ sort_and_combine_web_pairs (int for_move)
free (sorted); 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. If only one web has a preferred class with 1 free reg
then set it as the preferred color of the other web. */
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)
{
if (num_free_regs[t_class] == 1)
{
if (num_free_regs[s_class] != 1)
SET_HARD_REG_BIT (source->prefer_colors,
single_reg_in_regclass[t_class]);
return 0;
}
else if (num_free_regs[s_class] == 1)
{
SET_HARD_REG_BIT (target->prefer_colors,
single_reg_in_regclass[s_class]);
return 0;
}
}
return 1;
}
/* Greedily coalesce all moves possible. Begin with the web pair /* Greedily coalesce all moves possible. Begin with the web pair
giving the most saving if coalesced. */ giving the most saving if coalesced. */
...@@ -2487,7 +2522,8 @@ aggressive_coalesce (void) ...@@ -2487,7 +2522,8 @@ aggressive_coalesce (void)
if (s != t if (s != t
&& t->type != PRECOLORED && t->type != PRECOLORED
&& !TEST_BIT (sup_igraph, s->id * num_webs + t->id) && !TEST_BIT (sup_igraph, s->id * num_webs + t->id)
&& !TEST_BIT (sup_igraph, t->id * num_webs + s->id)) && !TEST_BIT (sup_igraph, t->id * num_webs + s->id)
&& ok_class (t, s))
{ {
if ((s->type == PRECOLORED && ok (t, s)) if ((s->type == PRECOLORED && ok (t, s))
|| s->type != PRECOLORED) || s->type != PRECOLORED)
...@@ -2557,6 +2593,7 @@ extended_coalesce_2 (void) ...@@ -2557,6 +2593,7 @@ extended_coalesce_2 (void)
dest->id * num_webs + source->id) dest->id * num_webs + source->id)
&& !TEST_BIT (sup_igraph, && !TEST_BIT (sup_igraph,
source->id * num_webs + dest->id) source->id * num_webs + dest->id)
&& ok_class (dest, source)
&& hard_regs_intersect_p (&source->usable_regs, && hard_regs_intersect_p (&source->usable_regs,
&dest->usable_regs)) &dest->usable_regs))
add_web_pair_cost (dest, source, add_web_pair_cost (dest, source,
......
...@@ -84,6 +84,7 @@ ...@@ -84,6 +84,7 @@
* use the constraints from asms * use the constraints from asms
*/ */
static int first_hard_reg (HARD_REG_SET);
static struct obstack ra_obstack; static struct obstack ra_obstack;
static void create_insn_info (struct df *); static void create_insn_info (struct df *);
static void free_insn_info (void); static void free_insn_info (void);
...@@ -147,6 +148,7 @@ int orig_max_uid; ...@@ -147,6 +148,7 @@ int orig_max_uid;
HARD_REG_SET never_use_colors; HARD_REG_SET never_use_colors;
HARD_REG_SET usable_regs[N_REG_CLASSES]; HARD_REG_SET usable_regs[N_REG_CLASSES];
unsigned int num_free_regs[N_REG_CLASSES]; unsigned int num_free_regs[N_REG_CLASSES];
int single_reg_in_regclass[N_REG_CLASSES];
HARD_REG_SET hardregs_for_mode[NUM_MACHINE_MODES]; HARD_REG_SET hardregs_for_mode[NUM_MACHINE_MODES];
HARD_REG_SET invalid_mode_change_regs; HARD_REG_SET invalid_mode_change_regs;
unsigned char byte2bitcount[256]; unsigned char byte2bitcount[256];
...@@ -212,6 +214,19 @@ hard_regs_count (HARD_REG_SET rs) ...@@ -212,6 +214,19 @@ hard_regs_count (HARD_REG_SET rs)
return count; return count;
} }
/* Returns the first hardreg in HARD_REG_SET RS. Assumes there is at
least one reg in the set. */
static int
first_hard_reg (HARD_REG_SET rs)
{
int c;
for (c = 0; c < FIRST_PSEUDO_REGISTER && !TEST_HARD_REG_BIT (rs, c); c++)
if (c == FIRST_PSEUDO_REGISTER)
abort();
return c;
}
/* Basically like emit_move_insn (i.e. validifies constants and such), /* Basically like emit_move_insn (i.e. validifies constants and such),
but also handle MODE_CC moves (but then the operands must already but also handle MODE_CC moves (but then the operands must already
be basically valid. */ be basically valid. */
...@@ -515,6 +530,10 @@ init_ra (void) ...@@ -515,6 +530,10 @@ init_ra (void)
size = hard_regs_count (rs); size = hard_regs_count (rs);
num_free_regs[i] = size; num_free_regs[i] = size;
COPY_HARD_REG_SET (usable_regs[i], rs); COPY_HARD_REG_SET (usable_regs[i], rs);
if (size == 1)
single_reg_in_regclass[i] = first_hard_reg (rs);
else
single_reg_in_regclass[i] = -1;
} }
/* Setup hardregs_for_mode[]. /* Setup hardregs_for_mode[].
......
...@@ -503,6 +503,9 @@ extern HARD_REG_SET never_use_colors; ...@@ -503,6 +503,9 @@ extern HARD_REG_SET never_use_colors;
extern HARD_REG_SET usable_regs[N_REG_CLASSES]; extern HARD_REG_SET usable_regs[N_REG_CLASSES];
/* For each class C the count of hardregs in usable_regs[C]. */ /* For each class C the count of hardregs in usable_regs[C]. */
extern unsigned int num_free_regs[N_REG_CLASSES]; extern unsigned int num_free_regs[N_REG_CLASSES];
/* For each class C which has num_free_regs[C]==1, the color of the
single register in that class, -1 otherwise. */
extern int single_reg_in_regclass[N_REG_CLASSES];
/* For each mode M the hardregs, which are MODE_OK for M, and have /* For each mode M the hardregs, which are MODE_OK for M, and have
enough space behind them to hold an M value. Additionally enough space behind them to hold an M value. Additionally
if reg R is OK for mode M, but it needs two hardregs, then R+1 will if reg R is OK for mode M, but it needs two hardregs, then R+1 will
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment