diff options
author | dje <dje@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-07-29 14:49:22 +0000 |
---|---|---|
committer | dje <dje@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-07-29 14:49:22 +0000 |
commit | 4711b23a824ecef074c0959dfd96290decec2957 (patch) | |
tree | e47884bc158f810bb28401260833e164be0f927e | |
parent | 67f7113c7606c53c4a76d85760e513b4a148483c (diff) | |
download | gcc-4711b23a824ecef074c0959dfd96290decec2957.tar.gz |
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@85300 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/ra-colorize.c | 41 | ||||
-rw-r--r-- | gcc/ra.c | 19 | ||||
-rw-r--r-- | gcc/ra.h | 3 |
4 files changed, 70 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a71b8a2c992..896e6b07850 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +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> * gcov-io.h: Allow zero tag as EOF indicator. diff --git a/gcc/ra-colorize.c b/gcc/ra-colorize.c index 3d248fa40ea..e3118a0cdac 100644 --- a/gcc/ra-colorize.c +++ b/gcc/ra-colorize.c @@ -92,6 +92,7 @@ static void add_web_pair_cost (struct web *, struct web *, 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); @@ -841,7 +842,8 @@ coalesce (void) } 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)) + || TEST_BIT (sup_igraph, target->id * num_webs + source->id) + || !ok_class (target, source)) { remove_move (source, m); remove_move (target, m); @@ -2464,6 +2466,39 @@ sort_and_combine_web_pairs (int for_move) 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 giving the most saving if coalesced. */ @@ -2487,7 +2522,8 @@ aggressive_coalesce (void) 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)) + && !TEST_BIT (sup_igraph, t->id * num_webs + s->id) + && ok_class (t, s)) { if ((s->type == PRECOLORED && ok (t, s)) || s->type != PRECOLORED) @@ -2557,6 +2593,7 @@ extended_coalesce_2 (void) 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, @@ -84,6 +84,7 @@ * use the constraints from asms */ +static int first_hard_reg (HARD_REG_SET); static struct obstack ra_obstack; static void create_insn_info (struct df *); static void free_insn_info (void); @@ -147,6 +148,7 @@ int orig_max_uid; HARD_REG_SET never_use_colors; HARD_REG_SET usable_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 invalid_mode_change_regs; unsigned char byte2bitcount[256]; @@ -212,6 +214,19 @@ hard_regs_count (HARD_REG_SET rs) 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), but also handle MODE_CC moves (but then the operands must already be basically valid. */ @@ -515,6 +530,10 @@ init_ra (void) size = hard_regs_count (rs); num_free_regs[i] = size; 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[]. @@ -503,6 +503,9 @@ extern HARD_REG_SET never_use_colors; extern HARD_REG_SET usable_regs[N_REG_CLASSES]; /* For each class C the count of hardregs in usable_regs[C]. */ 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 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 |