This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[ira] IRA regression fix on Itanium
- From: Vladimir Makarov <vmakarov at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 20 Mar 2008 21:36:32 -0400
- Subject: [ira] IRA regression fix on Itanium
This patch mainly fixes last GCC torture regression (too much memory
used for allocno conflicts) of IRA on Itanium.
2008-03-20 Vladimir Makarov <vmakarov@redhat.com>
* ira-int.h (allocno): Rename conflict_allocno_vec and
conflict_allocno_vec_size into conflict_allocno_array and
conflict_allocno_array_size. Remove conflict_allocnos_num.
Rename total_conflict_allocnos_num into conflict_allocnos_num New
members child_renamed_p and conflict_vec_p.
(ALLOCNO_CONFLICT_ALLOCNO_VEC): Rename to
ALLOCNO_CONFLICT_ALLOCNO_ARRAY.
(ALLOCNO_CONFLICT_ALLOCNO_VEC_SIZE): Rename to
ALLOCNO_CONFLICT_ALLOCNO_ARRAY_SIZE.
(ALLOCNO_CHILD_RENAMED_P, ALLOCNO_CONFLICT_VEC_P): New macros.
(EXECUTE_IF_SET_IN_ALLOCNO_SET): Change to
FOR_EACH_ALLOCNO_IN_SET.
(allocno_set_iterator): New typedef.
(allocno_set_iter_init, allocno_set_iter_cond,
allocno_set_iter_next): New functions.
(conflict_vector_profitable_p, allocate_allocno_conflict_vec): New
prototypes.
(allocno_iterator): New typedef.
(allocno_iter_init, allocno_iter_cond): New functions.
(FOR_EACH_ALLOCNO): New macro.
(copy_iterator): New typedef.
(copy_iter_init, copy_iter_cond): New functions.
(FOR_EACH_COPY): New macro.
(allocno_conflict_iterator): New typedef.
(allocno_conflict_iter_init, allocno_conflict_iter_cond,
allocno_conflict_iter_next): New functions.
(conflict_vector_profitable_p, allocate_allocno_conflict_vec): New
prototypes.
(FOR_EACH_ALLOCNO_CONFLICT): New macro.
* ira-conflicts.c (conflicts): Change type.
(CONFLICT_P): Use one more index for conflicts.
(build_conflict_bit_table): Change allocation and initialization
of conflicts.
(mirror_conflicts): Rewrite.
(remove_conflict_allocno_copies): Use FOR_EACH_ALLOCNO.
(build_allocno_conflict_vects): Rename to build_allocno_conflicts.
Rewrite it.
(print_conflicts): Use FOR_EACH_ALLOCNO, don't print star.
(ira_build_conflicts): Use FOR_EACH_ALLOCNO.
* ira-color.c (assign_hard_reg): Use FOR_EACH_ALLOCNO_CONFLICT.
Use min_full_cost for finding register profitability.
(push_allocno_to_stack): Use FOR_EACH_ALLOCNO_CONFLICT.
(setup_allocno_left_conflicts_num, coalesced_allocno_conflict_p):
Ditto.
(move_spill_restore): Use FOR_EACH_ALLOCNO.
(reassign_conflict_allocnos): Ditto. Use
FOR_EACH_ALLOCNO_CONFLICT.
(sort_regnos_for_alter_reg): Use FOR_EACH_ALLOCNO.
(reassign_pseudos): Use FOR_EACH_ALLOCNO_CONFLICT.
* ira-lives.c (make_regno_born, clear_allocno_live,
mark_reg_death, process_single_reg_class_operands,
process_bb_node_lives): Use FOR_EACH_ALLOCNO_IN_SET.
(create_start_finish_chains, print_live_ranges): Use
FOR_EACH_ALLOCNO.
* ira-emit.c (set_allocno_reg): Set up ALLOCNO_CHILD_RENAMED_P.
(set_allocno_somewhere_renamed_p): Use
ALLOCNO_CONFLICT_ALLOCNO_ARRAY.
(ira_emit): Use FOR_EACH_ALLOCNO.
* ira.c (setup_reg_renumber, setup_allocno_assignment_flags,
calculate_allocation_cost, check_allocation,
print_redundant_copies, setup_preferred_alternate_classes): Use
FOR_EACH_ALLOCNO.
* ira-costs.c (print_costs, setup_allocno_cover_class_and_costs,
ira_costs, tune_allocno_costs_and_cover_classes): Use
FOR_EACH_ALLOCNO.
* ira-build.c (check_allocno_conflict_vec): Remove.
(add_to_allocno_conflict_vec): Rename to
allocate_allocno_conflicts. Rewrite.
(allocate_allocno_conflict_bit_vec, allocate_allocno_conflicts,
remove_wrong_conflicts, change_allocno_conflicts): New functions.
(rebuild_regno_allocno_maps): Use FOR_EACH_ALLOCNO.
(create_allocno): Initialize ALLOCNO_CHILD_RENAMED_P and
ALLOCNO_CONFLICT_VEC_P.
(conflict_vector_profitable_p): New function.
(compress_allocno_conflict_vec): Use
ALLOCNO_CONFLICT_ALLOCNO_ARRAY and don't use
ALLOCNO_TOTAL_CONFLICT_ALLOCNOS_NUM.
(compress_conflict_vecs): Use FOR_EACH_ALLOCNO. Check
ALLOCNO_CONFLICT_VEC_P.
(propagate_info_to_cap): Use FOR_EACH_ALLOCNO_CONFLICT.
(finish_allocnos): Use FOR_EACH_ALLOCNO.
(finish_copies): Use FOR_EACH_COPY.
(check_and_add_conflicts): Change second parameter. Use
add_to_allocno_conflicts instead of add_to_allocno_conflict_vec.
(temp_change_bit_vec): New variable.
(ira_flattening): Use FOR_EACH_ALLOCNO and FOR_EACH_COPY. Use
remove_wrong_conflicts, change_allocno_conflicts. Allocate and
free temp_change_bit_vec. Nullify `allocnos' elements for removed
allocnos. Check ALLOCNO_CHILD_RENAMED_P for removing obsolete
conflicts. Don't compress and enumerate allocnos and copies.
Nullify `copies' elements for removed copies. Use
add_to_allocno_conflicts instead of add_to_allocno_conflict_vec.
(ira_build): Use FOR_EACH_ALLOCNO.
Index: ira-conflicts.c
===================================================================
--- ira-conflicts.c (revision 133314)
+++ ira-conflicts.c (working copy)
@@ -51,7 +51,7 @@ static void add_copies (loop_tree_node_t
static void propagate_allocno_info (allocno_t);
static void propagate_info (void);
static void remove_conflict_allocno_copies (void);
-static void build_allocno_conflict_vects (void);
+static void build_allocno_conflicts (void);
static void propagate_modified_regnos (loop_tree_node_t);
static void print_hard_reg_set (FILE *, const char *, HARD_REG_SET);
static void print_conflicts (FILE *, int);
@@ -62,15 +62,15 @@ static void print_conflicts (FILE *, int
#define CLEAR_ALLOCNO_LIVE(I) CLEAR_ALLOCNO_SET_BIT (allocnos_live, I)
#define TEST_ALLOCNO_LIVE(I) TEST_ALLOCNO_SET_BIT (allocnos_live, I)
-/* allocnos_num by allocnos_num array of bits, recording whether two
- allocno's conflict (can't go in the same hardware register).
+/* allocnos_num array of allocnos_num array of bits, recording whether
+ two allocno's conflict (can't go in the same hardware register).
`conflicts' is symmetric after the call to mirror_conflicts. */
-static INT_TYPE *conflicts;
+static INT_TYPE **conflicts;
/* Two macros to test 1 in an element of `conflicts'. */
#define CONFLICT_P(I, J) \
- (conflicts[(I) * allocno_set_words + (unsigned) (J) / INT_BITS] \
+ (conflicts[(I)] [(unsigned) (J) / INT_BITS] \
& ((INT_TYPE) 1 << ((unsigned) (J) % INT_BITS)))
/* Bit mask for allocnos live at current point in the scan. */
@@ -83,26 +83,34 @@ static INT_TYPE *allocnos_live;
static void
build_conflict_bit_table (void)
{
- int i, j, pn, pn_prod;
+ int i, j, num;
+ enum reg_class cover_class;
allocno_live_range_t r;
+ allocno_set_iterator asi;
allocno_set_words = (allocnos_num + INT_BITS - 1) / INT_BITS;
allocnos_live = ira_allocate (sizeof (INT_TYPE) * allocno_set_words);
memset (allocnos_live, 0, sizeof (INT_TYPE) * allocno_set_words);
- conflicts = ira_allocate (sizeof (INT_TYPE)
- * allocnos_num * allocno_set_words);
- memset (conflicts, 0, sizeof (INT_TYPE) * allocnos_num * allocno_set_words);
+ conflicts = ira_allocate (sizeof (INT_TYPE *) * allocnos_num);
+ for (i = 0; i < allocnos_num; i++)
+ {
+ conflicts [i] = ira_allocate (sizeof (INT_TYPE) * allocno_set_words);
+ memset (conflicts [i], 0, sizeof (INT_TYPE) * allocno_set_words);
+ }
for (i = 0; i < max_point; i++)
{
for (r = start_point_ranges [i]; r != NULL; r = r->start_next)
{
- pn = ALLOCNO_NUM (r->allocno);
- SET_ALLOCNO_LIVE (pn);
- pn_prod = pn * allocno_set_words;
- for (j = allocno_set_words - 1; j >= 0; j--)
- conflicts [pn_prod + j] |= allocnos_live [j];
+ num = ALLOCNO_NUM (r->allocno);
+ cover_class = ALLOCNO_COVER_CLASS (r->allocno);
+ SET_ALLOCNO_LIVE (num);
+ FOR_EACH_ALLOCNO_IN_SET (allocnos_live, allocnos_num, j, asi)
+ {
+ if (cover_class == ALLOCNO_COVER_CLASS (allocnos[j]))
+ SET_ALLOCNO_SET_BIT (conflicts [num], j);
+ }
/* Don't set up conflict for the allocno with itself. */
- CLEAR_ALLOCNO_SET_BIT (conflicts + pn_prod, pn);
+ CLEAR_ALLOCNO_SET_BIT (conflicts [num], num);
}
for (r = finish_point_ranges [i]; r != NULL; r = r->finish_next)
@@ -114,32 +122,25 @@ build_conflict_bit_table (void)
static void
mirror_conflicts (void)
{
- int i, j;
+ int i, j, k, start, nw;
unsigned INT_TYPE mask;
- int rw = allocno_set_words;
- int rwb = rw * INT_BITS;
- INT_TYPE *p = conflicts;
- INT_TYPE *q0 = conflicts;
- INT_TYPE *q1, *q2;
+ INT_TYPE *p;
- for (i = allocnos_num - 1, mask = 1; i >= 0; i--, mask <<= 1)
+ for (i = nw = 0, mask = 1; i < allocnos_num; i++, mask <<= 1)
{
+ p = conflicts [i];
if (! mask)
{
mask = 1;
- q0++;
+ nw++;
}
- for (j = allocno_set_words - 1, q1 = q0; j >= 0; j--, q1 += rwb)
+ for (start = j = 0; j < allocno_set_words; j++, start += INT_BITS)
{
unsigned INT_TYPE word;
- for (word = (unsigned INT_TYPE) *p++, q2 = q1;
- word;
- word >>= 1, q2 += rw)
- {
- if (word & 1)
- *q2 |= mask;
- }
+ for (word = (unsigned INT_TYPE) *p++, k = 0; word; word >>= 1, k++)
+ if (word & 1)
+ conflicts [start + k] [nw] |= mask;
}
}
}
@@ -701,14 +702,14 @@ remove_conflict_allocno_copies (void)
{
int i;
allocno_t a;
+ allocno_iterator ai;
copy_t cp, next_cp;
varray_type conflict_allocno_copy_varray;
VARRAY_GENERIC_PTR_NOGC_INIT (conflict_allocno_copy_varray, get_max_uid (),
"copies of conflicting allocnos");
- for (i = 0; i < allocnos_num; i++)
+ FOR_EACH_ALLOCNO (a, ai)
{
- a = allocnos [i];
for (cp = ALLOCNO_COPIES (a); cp != NULL; cp = next_cp)
if (cp->first == a)
next_cp = cp->next_first_allocno_copy;
@@ -727,95 +728,76 @@ remove_conflict_allocno_copies (void)
VARRAY_FREE (conflict_allocno_copy_varray);
}
-/* The function builds conflict vectors of all allocnos from the
- conflict table. */
+/* The function builds conflict vectors or bit conflict vectors of all
+ allocnos from the conflict table. */
static void
-build_allocno_conflict_vects (void)
+build_allocno_conflicts (void)
{
- int i, j, level, px, another_father_pn, conflict_allocnos_num;
- int *level_init_p;
- enum reg_class cover_class;
+ int i, j, px, father_num, another_father_num, free_p;
loop_tree_node_t father;
allocno_t a, father_a, another_a, another_father_a, *conflict_allocnos, *vec;
- INT_TYPE *accumulated_conflicts, *allocno_conflicts, *propagate_conflicts;
+ INT_TYPE *allocno_conflicts;
+ allocno_set_iterator asi;
conflict_allocnos = ira_allocate (sizeof (allocno_t) * allocnos_num);
- level_init_p = ira_allocate (ira_loop_tree_height * sizeof (int));
- memset (level_init_p, 0, ira_loop_tree_height * sizeof (int));
- accumulated_conflicts
- = ira_allocate (ira_loop_tree_height
- * allocno_set_words * sizeof (INT_TYPE));
for (i = max_reg_num () - 1; i >= FIRST_PSEUDO_REGISTER; i--)
for (a = regno_allocno_map [i];
a != NULL;
a = ALLOCNO_NEXT_REGNO_ALLOCNO (a))
{
- cover_class = ALLOCNO_COVER_CLASS (a);
- level = ALLOCNO_LOOP_TREE_NODE (a)->level;
- allocno_conflicts = conflicts + ALLOCNO_NUM (a) * allocno_set_words;
+ allocno_conflicts = conflicts [ALLOCNO_NUM (a)];
px = 0;
- EXECUTE_IF_SET_IN_ALLOCNO_SET (allocno_conflicts, j,
+ FOR_EACH_ALLOCNO_IN_SET (allocno_conflicts, allocnos_num, j, asi)
{
another_a = allocnos [j];
- if (cover_class == ALLOCNO_COVER_CLASS (another_a))
- conflict_allocnos [px++] = another_a;
- });
- conflict_allocnos_num = px;
- if (! level_init_p [level])
- propagate_conflicts = allocno_conflicts;
+ ira_assert (ALLOCNO_COVER_CLASS (a)
+ == ALLOCNO_COVER_CLASS (another_a));
+ conflict_allocnos [px++] = another_a;
+ }
+ if (conflict_vector_profitable_p (a, px))
+ {
+ free_p = TRUE;
+ allocate_allocno_conflict_vec (a, px);
+ vec = ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a);
+ memcpy (vec, conflict_allocnos, sizeof (allocno_t) * px);
+ vec [px] = NULL;
+ ALLOCNO_CONFLICT_ALLOCNOS_NUM (a) = px;
+ }
else
{
- propagate_conflicts
- = accumulated_conflicts + level * allocno_set_words;
- EXECUTE_IF_SET_IN_ALLOCNO_SET (propagate_conflicts, j,
- {
- another_a = allocnos [j];
- ira_assert (cover_class == ALLOCNO_COVER_CLASS (another_a));
- if (! TEST_ALLOCNO_SET_BIT (allocno_conflicts, j))
- conflict_allocnos [px++] = another_a;
- });
- for (j = 0; j < allocno_set_words; j++)
- propagate_conflicts [j] |= allocno_conflicts [j];
+ free_p = FALSE;
+ ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a) = conflicts [ALLOCNO_NUM (a)];
+ ALLOCNO_CONFLICT_ALLOCNO_ARRAY_SIZE (a)
+ = allocno_set_words * sizeof (INT_TYPE);
}
- allocate_allocno_conflicts (a, px);
- vec = ALLOCNO_CONFLICT_ALLOCNO_VEC (a);
- memcpy (vec, conflict_allocnos, sizeof (allocno_t) * px);
- vec [px] = NULL;
- ALLOCNO_CONFLICT_ALLOCNOS_NUM (a) = conflict_allocnos_num;
- ALLOCNO_TOTAL_CONFLICT_ALLOCNOS_NUM (a) = px;
- level_init_p [level] = FALSE;
if ((father = ALLOCNO_LOOP_TREE_NODE (a)->father) == NULL
|| (father_a = father->regno_allocno_map [i]) == NULL)
- continue;
- level--;
- ira_assert (level == ALLOCNO_LOOP_TREE_NODE (father_a)->level
- && cover_class == ALLOCNO_COVER_CLASS (father_a));
- if (! level_init_p [level])
{
- level_init_p [level] = TRUE;
- memset (accumulated_conflicts + level * allocno_set_words, 0,
- allocno_set_words * sizeof (INT_TYPE));
+ if (free_p)
+ ira_free (conflicts [ALLOCNO_NUM (a)]);
+ continue;
}
- EXECUTE_IF_SET_IN_ALLOCNO_SET (propagate_conflicts, j,
+ ira_assert (ALLOCNO_COVER_CLASS (a) == ALLOCNO_COVER_CLASS (father_a));
+ father_num = ALLOCNO_NUM (father_a);
+ FOR_EACH_ALLOCNO_IN_SET (allocno_conflicts, allocnos_num, j, asi)
{
another_a = allocnos [j];
+ ira_assert (ALLOCNO_COVER_CLASS (a)
+ == ALLOCNO_COVER_CLASS (another_a));
if ((another_father_a = (father->regno_allocno_map
[ALLOCNO_REGNO (another_a)])) == NULL)
continue;
- another_father_pn = ALLOCNO_NUM (another_father_a);
- if (another_father_pn < 0)
- continue;
+ another_father_num = ALLOCNO_NUM (another_father_a);
+ ira_assert (another_father_num >= 0);
ira_assert (ALLOCNO_COVER_CLASS (another_a)
== ALLOCNO_COVER_CLASS (another_father_a));
- if (cover_class == ALLOCNO_COVER_CLASS (another_a))
- SET_ALLOCNO_SET_BIT
- (accumulated_conflicts + allocno_set_words * level,
- another_father_pn);
- });
+ SET_ALLOCNO_SET_BIT (conflicts [father_num], another_father_num);
+ }
+ if (free_p)
+ ira_free (conflicts [ALLOCNO_NUM (a)]);
}
- ira_free (accumulated_conflicts);
- ira_free (level_init_p);
ira_free (conflict_allocnos);
+ ira_free (conflicts);
}
@@ -867,15 +849,15 @@ print_hard_reg_set (FILE *file, const ch
static void
print_conflicts (FILE *file, int reg_p)
{
- int i;
+ allocno_t a;
+ allocno_iterator ai;
- for (i = 0; i < allocnos_num; i++)
+ FOR_EACH_ALLOCNO (a, ai)
{
- int j;
- allocno_t a, conflict_a, *allocno_vec;
+ allocno_t conflict_a;
+ allocno_conflict_iterator aci;
basic_block bb;
- a = allocnos [i];
if (reg_p)
fprintf (file, ";; r%d", ALLOCNO_REGNO (a));
else
@@ -888,9 +870,8 @@ print_conflicts (FILE *file, int reg_p)
fprintf (file, ")");
}
fprintf (file, " conflicts:");
- allocno_vec = ALLOCNO_CONFLICT_ALLOCNO_VEC (a);
- if (allocno_vec != NULL)
- for (j = 0; (conflict_a = allocno_vec [j]) != NULL; j++)
+ if (ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a) != NULL)
+ FOR_EACH_ALLOCNO_CONFLICT (a, conflict_a, aci)
{
if (reg_p)
fprintf (file, " r%d,", ALLOCNO_REGNO (conflict_a));
@@ -904,8 +885,6 @@ print_conflicts (FILE *file, int reg_p)
fprintf (file, "l%d)",
ALLOCNO_LOOP_TREE_NODE (conflict_a)->loop->num);
}
- if (j + 1 == ALLOCNO_CONFLICT_ALLOCNOS_NUM (a))
- fprintf (file, "*");
}
print_hard_reg_set (file, "\n;; total conflict hard regs:",
ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a));
@@ -929,8 +908,8 @@ debug_conflicts (int reg_p)
void
ira_build_conflicts (void)
{
- int i;
allocno_t a;
+ allocno_iterator ai;
build_conflict_bit_table ();
mirror_conflicts ();
@@ -940,10 +919,9 @@ ira_build_conflicts (void)
propagate_info ();
/* We need finished conflict table for the subsequent call. */
remove_conflict_allocno_copies ();
- build_allocno_conflict_vects ();
- for (i = 0; i < allocnos_num; i++)
+ build_allocno_conflicts ();
+ FOR_EACH_ALLOCNO (a, ai)
{
- a = allocnos [i];
if (ALLOCNO_CALLS_CROSSED_NUM (a) == 0)
continue;
if (! flag_caller_saves)
Index: ira-int.h
===================================================================
--- ira-int.h (revision 133314)
+++ ira-int.h (working copy)
@@ -237,15 +237,15 @@ struct allocno
the list are not intersected and ordered by decreasing their
program points*. */
allocno_live_range_t live_ranges;
- /* Vector of conflicting allocnos with NULL end marker (first
- initial and then accumulated conflict allocnos). Only allocnos
- with the same cover class are in the vector. */
- allocno_t *conflict_allocno_vec;
+ /* Vector of conflicting allocnos with NULL end marker if
+ CONFLICT_VEC_P is true or conflict bit vector otherwise. Only
+ allocnos with the same cover class are in the vector or in the
+ bit vector. */
+ void *conflict_allocno_array;
/* Allocated size of the previous array. */
- int conflict_allocno_vec_size;
- /* Numbers of initial and total (with) accumulated conflicts in the
- previous array. */
- int conflict_allocnos_num, total_conflict_allocnos_num;
+ unsigned int conflict_allocno_array_size;
+ /* Number of accumulated conflicts in the previous array. */
+ int conflict_allocnos_num;
/* Initial and accumulated hard registers conflicting with this
allocno and as a consequences can not be assigned to the
allocno. */
@@ -268,6 +268,9 @@ struct allocno
/* TRUE if the correspdonding pseudo-register has disjoint live
ranges and the other allocnos except this one changed regno. */
unsigned int somewhere_renamed_p : 1;
+ /* TRUE if the allocno child has been renamed, in other words, got a
+ new pseudo-register. */
+ unsigned int child_renamed_p : 1;
/* In the reload, we should not reassign a hard register to the
allocno got memory if the flag value is TRUE. */
unsigned int dont_reassign_p : 1;
@@ -285,6 +288,10 @@ struct allocno
/* TRUE if it is put on the stack to make other allocnos
colorable. */
unsigned int may_be_spilled_p : 1;
+ /* TRUE if conflicts for given allocno are represented by vector of
+ pointer to the allocnos. Otherwise, we use a bit vector where a
+ bit with given index represents allocno with the same number. */
+ unsigned int conflict_vec_p : 1;
/* Array of additional costs (accumulated and the one updated during
coloring) for hard regno of allocno cover class. If given
allocno represents a set of allocnos the current costs represents
@@ -319,11 +326,11 @@ struct allocno
#define ALLOCNO_LOOP_TREE_NODE(A) ((A)->loop_tree_node)
#define ALLOCNO_CAP(A) ((A)->cap)
#define ALLOCNO_CAP_MEMBER(A) ((A)->cap_member)
-#define ALLOCNO_CONFLICT_ALLOCNO_VEC(A) ((A)->conflict_allocno_vec)
-#define ALLOCNO_CONFLICT_ALLOCNO_VEC_SIZE(A) ((A)->conflict_allocno_vec_size)
-#define ALLOCNO_CONFLICT_ALLOCNOS_NUM(A) ((A)->conflict_allocnos_num)
-#define ALLOCNO_TOTAL_CONFLICT_ALLOCNOS_NUM(A) \
- ((A)->total_conflict_allocnos_num)
+#define ALLOCNO_CONFLICT_ALLOCNO_ARRAY(A) ((A)->conflict_allocno_array)
+#define ALLOCNO_CONFLICT_ALLOCNO_ARRAY_SIZE(A) \
+ ((A)->conflict_allocno_array_size)
+#define ALLOCNO_CONFLICT_ALLOCNOS_NUM(A) \
+ ((A)->conflict_allocnos_num)
#define ALLOCNO_CONFLICT_HARD_REGS(A) ((A)->conflict_hard_regs)
#define ALLOCNO_TOTAL_CONFLICT_HARD_REGS(A) ((A)->total_conflict_hard_regs)
#define ALLOCNO_NREFS(A) ((A)->nrefs)
@@ -335,6 +342,7 @@ struct allocno
#define ALLOCNO_MEM_OPTIMIZED_DEST(A) ((A)->mem_optimized_dest)
#define ALLOCNO_MEM_OPTIMIZED_DEST_P(A) ((A)->mem_optimized_dest_p)
#define ALLOCNO_SOMEWHERE_RENAMED_P(A) ((A)->somewhere_renamed_p)
+#define ALLOCNO_CHILD_RENAMED_P(A) ((A)->child_renamed_p)
#define ALLOCNO_DONT_REASSIGN_P(A) ((A)->dont_reassign_p)
#ifdef STACK_REGS
#define ALLOCNO_NO_STACK_REG_P(A) ((A)->no_stack_reg_p)
@@ -343,6 +351,7 @@ struct allocno
#define ALLOCNO_IN_GRAPH_P(A) ((A)->in_graph_p)
#define ALLOCNO_ASSIGNED_P(A) ((A)->assigned_p)
#define ALLOCNO_MAY_BE_SPILLED_P(A) ((A)->may_be_spilled_p)
+#define ALLOCNO_CONFLICT_VEC_P(A) ((A)->conflict_vec_p)
#define ALLOCNO_MODE(A) ((A)->mode)
#define ALLOCNO_COPIES(A) ((A)->allocno_copies)
#define ALLOCNO_HARD_REG_COSTS(A) ((A)->hard_reg_costs)
@@ -369,7 +378,8 @@ struct allocno
extern allocno_t *regno_allocno_map;
/* Array of references to all allocnos. The order number of the
- allocno corresponds to the index in the array. */
+ allocno corresponds to the index in the array. Removed allocnos
+ have NULL element value. */
extern allocno_t *allocnos;
/* Sizes of the previous array. */
@@ -403,7 +413,8 @@ struct allocno_copy
};
/* Array of references to copies. The order number of the copy
- corresponds to the index in the array. */
+ corresponds to the index in the array. Removed allocnos
+ have NULL element value. */
extern copy_t *copies;
/* Size of the previous array. */
@@ -465,26 +476,81 @@ extern int max_nregs;
((R) [(unsigned) (I) / INT_BITS] \
& ((INT_TYPE) 1 << ((unsigned) (I) % INT_BITS)))
-/* For each allocno set in ALLOCNO_SET, set ALLOCNO to that
- allocno, and execute CODE. */
-#define EXECUTE_IF_SET_IN_ALLOCNO_SET(ALLOCNO_SET, ALLOCNO, CODE) \
-do { \
- int i_; \
- int allocno_; \
- INT_TYPE *p_ = (ALLOCNO_SET); \
- \
- for (i_ = allocno_set_words - 1, allocno_ = 0; i_ >= 0; \
- i_--, allocno_ += INT_BITS) \
- { \
- unsigned INT_TYPE word_ = (unsigned INT_TYPE) *p_++; \
- \
- for ((ALLOCNO) = allocno_; word_; word_ >>= 1, (ALLOCNO)++) \
- { \
- if (word_ & 1) \
- {CODE;} \
- } \
- } \
-} while (0)
+
+/* The iterator for allocno set. */
+typedef struct {
+
+ /* The allocno bit vector. */
+ INT_TYPE *vec;
+
+ /* The number of the current element in the vector (of type
+ allocno_t or INT_TYPE). */
+ unsigned int word_num;
+
+ /* The number of element (bits) in the bit vector. */
+ unsigned int nel;
+
+ /* The current bit index of bit vector. */
+ unsigned int bit_num;
+
+ /* The word of bit vector currently visited. */
+ unsigned INT_TYPE word;
+} allocno_set_iterator;
+
+/* Initialize the iterator I for allocnos bit vector VEC of length
+ NEL. */
+static inline void
+allocno_set_iter_init (allocno_set_iterator *i, INT_TYPE *vec, int nel)
+{
+ i->vec = vec;
+ i->word_num = 0;
+ i->nel = nel;
+ i->bit_num = 0;
+ i->word = nel == 0 ? 0 : vec [0];
+}
+
+/* Return TRUE if we have more allocnos to visit, in which case *N is
+ set to the allocno number to be visited. Otherwise, return
+ FALSE. */
+static inline int
+allocno_set_iter_cond (allocno_set_iterator *i, int *n)
+{
+ /* Skip words that are zeros. */
+ for (; i->word == 0; i->word = i->vec [i->word_num])
+ {
+ i->word_num++;
+ i->bit_num = i->word_num * INT_BITS;
+
+ /* If we have reached the end, break. */
+ if (i->bit_num >= i->nel)
+ return FALSE;
+ }
+
+ /* Skip bits that are zero. */
+ for (; (i->word & 1) == 0; i->word >>= 1)
+ i->bit_num++;
+
+ *n = (int) i->bit_num;
+
+ return TRUE;
+}
+
+/* Advance to the next allocno. */
+static inline void
+allocno_set_iter_next (allocno_set_iterator *i)
+{
+ i->word >>= 1;
+ i->bit_num++;
+}
+
+/* Loop over all elements of ALLOCNO set given by VEC and NEL. In
+ each iteration, N is set to the number of next allocno. ITER is an
+ instance of allocno_set_iterator used to iterate the allocnos in
+ the set. */
+#define FOR_EACH_ALLOCNO_IN_SET(VEC, NEL, N, ITER) \
+ for (allocno_set_iter_init (&(ITER), (VEC), (NEL)); \
+ allocno_set_iter_cond (&(ITER), &(N)); \
+ allocno_set_iter_next (&(ITER)))
/* ira.c: */
@@ -612,6 +678,8 @@ extern void traverse_loop_tree (int, loo
void (*) (loop_tree_node_t),
void (*) (loop_tree_node_t));
extern allocno_t create_allocno (int, int, loop_tree_node_t);
+extern int conflict_vector_profitable_p (allocno_t, int);
+extern void allocate_allocno_conflict_vec (allocno_t, int);
extern void allocate_allocno_conflicts (allocno_t, int);
extern void add_allocno_conflict (allocno_t, allocno_t);
extern void print_expanded_allocno (allocno_t);
@@ -671,6 +739,190 @@ extern void ira_emit (int);
+/* The iterator for all allocnos. */
+typedef struct {
+ /* The number of the current element in ALLOCNOS. */
+ int n;
+} allocno_iterator;
+
+/* Initialize the iterator I. */
+static inline void
+allocno_iter_init (allocno_iterator *i)
+{
+ i->n = 0;
+}
+
+/* Return TRUE if we have more allocnos to visit, in which case *A is
+ set to the allocno to be visited. Otherwise, return FALSE. */
+static inline int
+allocno_iter_cond (allocno_iterator *i, allocno_t *a)
+{
+ int n;
+
+ for (n = i->n; n < allocnos_num; n++)
+ if (allocnos [n] != NULL)
+ {
+ *a = allocnos [n];
+ i->n = n + 1;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/* Loop over all allocnos. In each iteration, A is set to the next
+ allocno. ITER is an instance of allocno_iterator used to iterate
+ the allocnos. */
+#define FOR_EACH_ALLOCNO(A, ITER) \
+ for (allocno_iter_init (&(ITER)); \
+ allocno_iter_cond (&(ITER), &(A));)
+
+
+
+
+/* The iterator for copies. */
+typedef struct {
+ /* The number of the current element in COPIES. */
+ int n;
+} copy_iterator;
+
+/* Initialize the iterator I. */
+static inline void
+copy_iter_init (copy_iterator *i)
+{
+ i->n = 0;
+}
+
+/* Return TRUE if we have more copies to visit, in which case *CP is
+ set to the copy to be visited. Otherwise, return FALSE. */
+static inline int
+copy_iter_cond (copy_iterator *i, copy_t *cp)
+{
+ int n;
+
+ for (n = i->n; n < copies_num; n++)
+ if (copies [n] != NULL)
+ {
+ *cp = copies [n];
+ i->n = n + 1;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/* Loop over all copies. In each iteration, C is set to the next
+ copy. ITER is an instance of copy_iterator used to iterate
+ the copies. */
+#define FOR_EACH_COPY(C, ITER) \
+ for (copy_iter_init (&(ITER)); \
+ copy_iter_cond (&(ITER), &(C));)
+
+
+
+
+/* The iterator for allocno conflicts. */
+typedef struct {
+
+ /* TRUE if the conflicts are represented by vectors of allocnos. */
+ int allocno_conflict_vec_p;
+
+ /* The conflict vector or conflict bit vector. */
+ void *vec;
+
+ /* The number of the current element in the vector (of type
+ allocno_t or INT_TYPE). */
+ unsigned int word_num;
+
+ /* The bit vector size. */
+ unsigned int size;
+
+ /* The current bit index of bit vector. */
+ unsigned int bit_num;
+
+ /* The word of bit vector currently visited. */
+ unsigned INT_TYPE word;
+} allocno_conflict_iterator;
+
+/* Initialize the iterator I with ALLOCNO conflicts. */
+static inline void
+allocno_conflict_iter_init (allocno_conflict_iterator *i, allocno_t allocno)
+{
+ i->allocno_conflict_vec_p = ALLOCNO_CONFLICT_VEC_P (allocno);
+ i->vec = ALLOCNO_CONFLICT_ALLOCNO_ARRAY (allocno);
+ i->word_num = 0;
+ if (i->allocno_conflict_vec_p)
+ i->size = i->bit_num = i->word = 0;
+ else
+ {
+ i->size
+ = MIN (((allocnos_num + INT_BITS - 1) / INT_BITS) * sizeof (INT_TYPE),
+ ALLOCNO_CONFLICT_ALLOCNO_ARRAY_SIZE (allocno));
+ i->bit_num = 0;
+ i->word = ((INT_TYPE *) i->vec) [0];
+ }
+}
+
+/* Return TRUE if we have more allocnos to visit, in which case *A is
+ set to the allocno to be visited. Otherwise, return FALSE. */
+static inline int
+allocno_conflict_iter_cond (allocno_conflict_iterator *i, allocno_t *a)
+{
+ allocno_t conflict_allocno;
+
+ if (i->allocno_conflict_vec_p)
+ {
+ conflict_allocno = ((allocno_t *) i->vec) [i->word_num];
+ if (conflict_allocno == NULL)
+ return FALSE;
+ *a = conflict_allocno;
+ return TRUE;
+ }
+ else
+ {
+ /* Skip words that are zeros. */
+ for (; i->word == 0; i->word = ((INT_TYPE *) i->vec) [i->word_num])
+ {
+ i->word_num++;
+
+ /* If we have reached the end, break. */
+ if (i->word_num * sizeof (INT_TYPE) >= i->size)
+ return FALSE;
+
+ i->bit_num = i->word_num * INT_BITS;
+ }
+
+ /* Skip bits that are zero. */
+ for (; (i->word & 1) == 0; i->word >>= 1)
+ i->bit_num++;
+
+ *a = allocnos [i->bit_num];
+
+ return TRUE;
+ }
+}
+
+/* Advance to the next conflicting allocno. */
+static inline void
+allocno_conflict_iter_next (allocno_conflict_iterator *i)
+{
+ if (i->allocno_conflict_vec_p)
+ i->word_num++;
+ else
+ {
+ i->word >>= 1;
+ i->bit_num++;
+ }
+}
+
+/* Loop over all elements of ALLOCNO conflicts. In each iteration, A
+ is set to the next conflicting allocno. ITER is an instance of
+ allocno_conflict_iterator used to iterate the conflicts. */
+#define FOR_EACH_ALLOCNO_CONFLICT(ALLOCNO, A, ITER) \
+ for (allocno_conflict_iter_init (&(ITER), (ALLOCNO)); \
+ allocno_conflict_iter_cond (&(ITER), &(A)); \
+ allocno_conflict_iter_next (&(ITER)))
+
+
+
/* The function returns nonzero if hard registers starting with
HARD_REGNO and containing value of MODE are not in set
HARD_REGSET. */
Index: ira-color.c
===================================================================
--- ira-color.c (revision 133314)
+++ ira-color.c (working copy)
@@ -270,8 +270,8 @@ assign_hard_reg (allocno_t allocno, int
enum reg_class cover_class, class;
enum machine_mode mode;
allocno_t a, conflict_allocno;
- allocno_t *allocno_vec;
allocno_t another_allocno;
+ allocno_conflict_iterator aci;
copy_t cp, next_cp;
static int costs [FIRST_PSEUDO_REGISTER], full_costs [FIRST_PSEUDO_REGISTER];
#ifdef STACK_REGS
@@ -298,7 +298,6 @@ assign_hard_reg (allocno_t allocno, int
a = ALLOCNO_NEXT_COALESCED_ALLOCNO (a))
{
mem_cost += ALLOCNO_UPDATED_MEMORY_COST (a);
- allocno_vec = ALLOCNO_CONFLICT_ALLOCNO_VEC (a);
IOR_HARD_REG_SET (conflicting_regs,
ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a));
allocate_and_copy_costs (&ALLOCNO_UPDATED_HARD_REG_COSTS (a),
@@ -318,7 +317,7 @@ assign_hard_reg (allocno_t allocno, int
costs [i] += cost;
full_costs [i] += cost;
}
- for (i = 0; (conflict_allocno = allocno_vec [i]) != NULL; i++)
+ FOR_EACH_ALLOCNO_CONFLICT (a, conflict_allocno, aci)
/* Reload can give another class so we need to check all
allocnos. */
if (retry_p || bitmap_bit_p (consideration_allocno_bitmap,
@@ -437,7 +436,7 @@ assign_hard_reg (allocno_t allocno, int
ira_assert (hard_regno >= 0);
}
}
- if (min_cost > mem_cost)
+ if (min_full_cost > mem_cost)
best_hard_regno = -1;
fail:
if (best_hard_regno < 0
@@ -630,10 +629,10 @@ delete_allocno_from_bucket (allocno_t al
static void
push_allocno_to_stack (allocno_t allocno)
{
- int i, conflicts_num, conflict_size, size;
+ int conflicts_num, conflict_size, size;
allocno_t a, conflict_allocno;
- allocno_t *allocno_vec;
enum reg_class cover_class;
+ allocno_conflict_iterator aci;
ALLOCNO_IN_GRAPH_P (allocno) = FALSE;
VARRAY_PUSH_GENERIC_PTR (allocno_stack_varray, allocno);
@@ -646,8 +645,7 @@ push_allocno_to_stack (allocno_t allocno
for (a = ALLOCNO_NEXT_COALESCED_ALLOCNO (allocno);;
a = ALLOCNO_NEXT_COALESCED_ALLOCNO (a))
{
- allocno_vec = ALLOCNO_CONFLICT_ALLOCNO_VEC (a);
- for (i = 0; (conflict_allocno = allocno_vec [i]) != NULL; i++)
+ FOR_EACH_ALLOCNO_CONFLICT (a, conflict_allocno, aci)
if (bitmap_bit_p (coloring_allocno_bitmap,
ALLOCNO_NUM (conflict_allocno)))
{
@@ -1026,9 +1024,9 @@ setup_allocno_left_conflicts_num (allocn
{
int i, hard_regs_num, hard_regno, conflict_allocnos_size;
allocno_t a, conflict_allocno;
- allocno_t *allocno_vec;
enum reg_class cover_class;
HARD_REG_SET temp_set;
+ allocno_conflict_iterator aci;
cover_class = ALLOCNO_COVER_CLASS (allocno);
hard_regs_num = class_hard_regs_num [cover_class];
@@ -1063,8 +1061,7 @@ setup_allocno_left_conflicts_num (allocn
for (a = ALLOCNO_NEXT_COALESCED_ALLOCNO (allocno);;
a = ALLOCNO_NEXT_COALESCED_ALLOCNO (a))
{
- allocno_vec = ALLOCNO_CONFLICT_ALLOCNO_VEC (a);
- for (i = 0; (conflict_allocno = allocno_vec [i]) != NULL; i++)
+ FOR_EACH_ALLOCNO_CONFLICT (a, conflict_allocno, aci)
if (bitmap_bit_p (consideration_allocno_bitmap,
ALLOCNO_NUM (conflict_allocno)))
{
@@ -1176,8 +1173,8 @@ merge_allocnos (allocno_t a1, allocno_t
static int
coalesced_allocno_conflict_p (allocno_t a1, allocno_t a2, int reload_p)
{
- allocno_t a, conflict_allocno, *allocno_vec;
- int i;
+ allocno_t a, conflict_allocno;
+ allocno_conflict_iterator aci;
if (allocno_coalesced_p)
{
@@ -1207,8 +1204,7 @@ coalesced_allocno_conflict_p (allocno_t
}
else
{
- allocno_vec = ALLOCNO_CONFLICT_ALLOCNO_VEC (a);
- for (i = 0; (conflict_allocno = allocno_vec [i]) != NULL; i++)
+ FOR_EACH_ALLOCNO_CONFLICT (a, conflict_allocno, aci)
if (conflict_allocno == a1
|| (allocno_coalesced_p
&& bitmap_bit_p (processed_coalesced_allocno_bitmap,
@@ -1643,21 +1639,21 @@ do_coloring (void)
static void
move_spill_restore (void)
{
- int i, cost, changed_p, regno, hard_regno, hard_regno2, index;
+ int cost, changed_p, regno, hard_regno, hard_regno2, index;
int enter_freq, exit_freq;
enum machine_mode mode;
enum reg_class class;
allocno_t a, father_allocno, subloop_allocno;
loop_tree_node_t father, loop_node, subloop_node;
+ allocno_iterator ai;
for (;;)
{
changed_p = FALSE;
if (internal_flag_ira_verbose > 0 && ira_dump_file != NULL)
fprintf (ira_dump_file, "New iteration of spill/restore move\n");
- for (i = 0; i < allocnos_num; i++)
+ FOR_EACH_ALLOCNO (a, ai)
{
- a = allocnos [i];
regno = ALLOCNO_REGNO (a);
loop_node = ALLOCNO_LOOP_TREE_NODE (a);
if (ALLOCNO_CAP_MEMBER (a) != NULL
@@ -1804,16 +1800,17 @@ setup_curr_costs (allocno_t a)
void
reassign_conflict_allocnos (int start_regno, int no_call_cross_p)
{
- int i, j, allocnos_to_color_num;
- allocno_t a, conflict_a, *allocno_vec;
+ int i, allocnos_to_color_num;
+ allocno_t a, conflict_a;
+ allocno_conflict_iterator aci;
enum reg_class cover_class;
bitmap allocnos_to_color;
+ allocno_iterator ai;
allocnos_to_color = ira_allocate_bitmap ();
allocnos_to_color_num = 0;
- for (i = 0; i < allocnos_num; i++)
+ FOR_EACH_ALLOCNO (a, ai)
{
- a = allocnos [i];
if (! ALLOCNO_ASSIGNED_P (a)
&& ! bitmap_bit_p (allocnos_to_color, ALLOCNO_NUM (a)))
{
@@ -1832,8 +1829,7 @@ reassign_conflict_allocnos (int start_re
if (ALLOCNO_REGNO (a) < start_regno
|| (cover_class = ALLOCNO_COVER_CLASS (a)) == NO_REGS)
continue;
- allocno_vec = ALLOCNO_CONFLICT_ALLOCNO_VEC (a);
- for (j = 0; (conflict_a = allocno_vec [j]) != NULL; j++)
+ FOR_EACH_ALLOCNO_CONFLICT (a, conflict_a, aci)
{
ira_assert (cover_class == ALLOCNO_COVER_CLASS (conflict_a));
if ((no_call_cross_p && ALLOCNO_CALLS_CROSSED_NUM (conflict_a) != 0)
@@ -2052,6 +2048,7 @@ sort_regnos_for_alter_reg (int *pseudo_r
int max_regno = max_reg_num ();
int i, regno, num, slot_num;
allocno_t allocno, a;
+ allocno_iterator ai;
allocno_t *spilled_coalesced_allocnos;
processed_coalesced_allocno_bitmap = ira_allocate_bitmap ();
@@ -2131,10 +2128,10 @@ sort_regnos_for_alter_reg (int *pseudo_r
qsort (pseudo_regnos, n, sizeof (int), coalesced_pseudo_reg_slot_compare);
/* Uncoalesce allocnos which is necessary for (re)assigning during
the reload. */
- for (i = 0; i < allocnos_num; i++)
+ FOR_EACH_ALLOCNO (a, ai)
{
- ALLOCNO_FIRST_COALESCED_ALLOCNO (allocnos [i]) = allocnos [i];
- ALLOCNO_NEXT_COALESCED_ALLOCNO (allocnos [i]) = allocnos [i];
+ ALLOCNO_FIRST_COALESCED_ALLOCNO (a) = a;
+ ALLOCNO_NEXT_COALESCED_ALLOCNO (a) = a;
}
ira_free (regno_coalesced_allocno_num);
ira_free (regno_coalesced_allocno_cost);
@@ -2283,9 +2280,10 @@ reassign_pseudos (int *spilled_pseudo_re
HARD_REG_SET *pseudo_forbidden_regs,
HARD_REG_SET *pseudo_previous_regs, bitmap spilled)
{
- int i, j, m, n, regno, changed_p;
- allocno_t a, conflict_a, *allocno_vec;
+ int i, m, n, regno, changed_p;
+ allocno_t a, conflict_a;
HARD_REG_SET forbidden_regs;
+ allocno_conflict_iterator aci;
if (num > 1)
qsort (spilled_pseudo_regs, num, sizeof (int), pseudo_reg_compare);
@@ -2327,8 +2325,7 @@ reassign_pseudos (int *spilled_pseudo_re
{
regno = spilled_pseudo_regs [i];
a = regno_allocno_map [regno];
- allocno_vec = ALLOCNO_CONFLICT_ALLOCNO_VEC (a);
- for (j = 0; (conflict_a = allocno_vec [j]) != NULL; j++)
+ FOR_EACH_ALLOCNO_CONFLICT (a, conflict_a, aci)
if (ALLOCNO_HARD_REGNO (conflict_a) < 0
&& ! ALLOCNO_DONT_REASSIGN_P (conflict_a)
&& ! bitmap_bit_p (consideration_allocno_bitmap,
Index: ira-lives.c
===================================================================
--- ira-lives.c (revision 133314)
+++ ira-lives.c (working copy)
@@ -100,16 +100,17 @@ make_regno_born (int regno)
int i;
allocno_t a;
allocno_live_range_t p;
+ allocno_set_iterator asi;
if (regno < FIRST_PSEUDO_REGISTER)
{
SET_HARD_REG_BIT (hard_regs_live, regno);
- EXECUTE_IF_SET_IN_ALLOCNO_SET (allocnos_live, i,
+ FOR_EACH_ALLOCNO_IN_SET (allocnos_live, allocnos_num, i, asi)
{
SET_HARD_REG_BIT (ALLOCNO_CONFLICT_HARD_REGS (allocnos [i]), regno);
SET_HARD_REG_BIT (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (allocnos [i]),
regno);
- });
+ }
return;
}
a = ira_curr_regno_allocno_map [regno];
@@ -204,6 +205,7 @@ clear_allocno_live (allocno_t a)
{
int i;
enum reg_class cover_class;
+ allocno_set_iterator asi;
if (bitmap_bit_p (allocnos_live_bitmap, ALLOCNO_NUM (a)))
{
@@ -215,10 +217,10 @@ clear_allocno_live (allocno_t a)
&& (curr_reg_pressure [cover_class]
<= available_class_regs [cover_class]))
{
- EXECUTE_IF_SET_IN_ALLOCNO_SET (allocnos_live, i,
+ FOR_EACH_ALLOCNO_IN_SET (allocnos_live, allocnos_num, i, asi)
{
update_allocno_pressure_excess_length (allocnos [i]);
- });
+ }
high_pressure_start_point [cover_class] = -1;
}
}
@@ -348,6 +350,7 @@ mark_reg_death (rtx reg)
{
int i;
int regno = REGNO (reg);
+ allocno_set_iterator asi;
if (regno >= FIRST_PSEUDO_REGISTER)
{
@@ -376,10 +379,10 @@ mark_reg_death (rtx reg)
&& (curr_reg_pressure [cover_class]
<= available_class_regs [cover_class]))
{
- EXECUTE_IF_SET_IN_ALLOCNO_SET (allocnos_live, i,
+ FOR_EACH_ALLOCNO_IN_SET (allocnos_live, allocnos_num, i, asi)
{
update_allocno_pressure_excess_length (allocnos [i]);
- });
+ }
high_pressure_start_point [cover_class] = -1;
}
ira_assert (curr_reg_pressure [cover_class] >= 0);
@@ -547,6 +550,7 @@ process_single_reg_class_operands (int i
enum reg_class cl, cover_class;
rtx operand;
allocno_t operand_a, a;
+ allocno_set_iterator asi;
for (i = 0; i < recog_data.n_operands; i++)
{
@@ -594,7 +598,7 @@ process_single_reg_class_operands (int i
}
}
- EXECUTE_IF_SET_IN_ALLOCNO_SET (allocnos_live, px,
+ FOR_EACH_ALLOCNO_IN_SET (allocnos_live, allocnos_num, px, asi)
{
a = allocnos [px];
cover_class = ALLOCNO_COVER_CLASS (a);
@@ -608,7 +612,7 @@ process_single_reg_class_operands (int i
IOR_HARD_REG_SET (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a),
reg_class_contents [cl]);
}
- });
+ }
}
}
@@ -625,6 +629,7 @@ process_bb_node_lives (loop_tree_node_t
edge_iterator ei;
bitmap_iterator bi;
bitmap reg_live_in;
+ allocno_set_iterator asi;
int px = 0;
bb = loop_tree_node->bb;
@@ -694,11 +699,11 @@ process_bb_node_lives (loop_tree_node_t
if (e != NULL)
{
#ifdef STACK_REGS
- EXECUTE_IF_SET_IN_ALLOCNO_SET (allocnos_live, px,
+ FOR_EACH_ALLOCNO_IN_SET (allocnos_live, allocnos_num, px, asi)
{
ALLOCNO_NO_STACK_REG_P (allocnos [px]) = TRUE;
ALLOCNO_TOTAL_NO_STACK_REG_P (allocnos [px]) = TRUE;
- });
+ }
for (px = FIRST_STACK_REG; px <= LAST_STACK_REG; px++)
make_regno_born_and_died (px);
#endif
@@ -753,7 +758,7 @@ process_bb_node_lives (loop_tree_node_t
get_call_invalidated_used_regs (insn, &clobbered_regs, FALSE);
IOR_HARD_REG_SET (cfun->emit->call_used_regs, clobbered_regs);
- EXECUTE_IF_SET_IN_ALLOCNO_SET (allocnos_live, i,
+ FOR_EACH_ALLOCNO_IN_SET (allocnos_live, allocnos_num, i, asi)
{
allocno_t a = allocnos [i];
@@ -769,7 +774,7 @@ process_bb_node_lives (loop_tree_node_t
SET_HARD_REG_SET (ALLOCNO_CONFLICT_HARD_REGS (a));
SET_HARD_REG_SET (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a));
}
- });
+ }
}
/* Mark any allocnos set in INSN as live, and mark them as
@@ -830,10 +835,10 @@ process_bb_node_lives (loop_tree_node_t
}
curr_point++;
}
- EXECUTE_IF_SET_IN_ALLOCNO_SET (allocnos_live, i,
+ FOR_EACH_ALLOCNO_IN_SET (allocnos_live, allocnos_num, i, asi)
{
make_regno_dead (ALLOCNO_REGNO (allocnos [i]));
- });
+ }
curr_point++;
}
/* Propagate register pressure: */
@@ -853,8 +858,8 @@ process_bb_node_lives (loop_tree_node_t
static void
create_start_finish_chains (void)
{
- int i;
allocno_t a;
+ allocno_iterator ai;
allocno_live_range_t r;
start_point_ranges
@@ -863,9 +868,8 @@ create_start_finish_chains (void)
finish_point_ranges
= ira_allocate (max_point * sizeof (allocno_live_range_t));
memset (finish_point_ranges, 0, max_point * sizeof (allocno_live_range_t));
- for (i = 0; i < allocnos_num; i++)
+ FOR_EACH_ALLOCNO (a, ai)
{
- a = allocnos [i];
for (r = ALLOCNO_LIVE_RANGES (a); r != NULL; r = r->next)
{
r->start_next = start_point_ranges [r->start];
@@ -914,10 +918,11 @@ debug_allocno_live_ranges (allocno_t a)
static void
print_live_ranges (FILE *f)
{
- int i;
+ allocno_t a;
+ allocno_iterator ai;
- for (i = 0; i < allocnos_num; i++)
- print_allocno_live_ranges (f, allocnos [i]);
+ FOR_EACH_ALLOCNO (a, ai)
+ print_allocno_live_ranges (f, a);
}
void
Index: ira-emit.c
===================================================================
--- ira-emit.c (revision 133314)
+++ ira-emit.c (working copy)
@@ -251,6 +251,7 @@ subloop_tree_node_p (loop_tree_node_t su
static void
set_allocno_reg (allocno_t allocno, rtx reg)
{
+ int regno;
allocno_t a;
loop_tree_node_t node;
@@ -260,6 +261,20 @@ set_allocno_reg (allocno_t allocno, rtx
a = ALLOCNO_NEXT_REGNO_ALLOCNO (a))
if (subloop_tree_node_p (ALLOCNO_LOOP_TREE_NODE (a), node))
ALLOCNO_REG (a) = reg;
+ regno = ALLOCNO_REGNO (allocno);
+ for (a = allocno;;)
+ {
+ if ((a = ALLOCNO_CAP (a)) == NULL)
+ {
+ node = node->father;
+ if (node == NULL)
+ break;
+ a = node->regno_allocno_map [regno];
+ }
+ if (a == NULL || ALLOCNO_CHILD_RENAMED_P (a))
+ break;
+ ALLOCNO_CHILD_RENAMED_P (a) = TRUE;
+ }
}
/* The following function returns nonzero if move insn of SRC_ALLOCNO
@@ -446,13 +461,12 @@ change_loop (loop_tree_node_t node)
static void
set_allocno_somewhere_renamed_p (void)
{
- int i;
unsigned int regno;
allocno_t allocno;
+ allocno_iterator ai;
- for (i = 0; i < allocnos_num; i++)
+ FOR_EACH_ALLOCNO (allocno, ai)
{
- allocno = allocnos [i];
regno = ALLOCNO_REGNO (allocno);
if (bitmap_bit_p (renamed_regno_bitmap, regno)
&& REGNO (ALLOCNO_REG (allocno)) == regno)
@@ -830,12 +844,11 @@ add_range_and_copies_from_move_list (str
{
from = move->from;
to = move->to;
- if (ALLOCNO_CONFLICT_ALLOCNO_VEC (to) == NULL)
+ if (ALLOCNO_CONFLICT_ALLOCNO_ARRAY (to) == NULL)
{
if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
- fprintf (ira_dump_file,
- " Allocate conflict vector of size %d for a%dr%d\n",
- n, ALLOCNO_NUM (to), REGNO (ALLOCNO_REG (to)));
+ fprintf (ira_dump_file, " Allocate conflicts for a%dr%d\n",
+ ALLOCNO_NUM (to), REGNO (ALLOCNO_REG (to)));
allocate_allocno_conflicts (to, n);
}
bitmap_clear_bit (live_through, ALLOCNO_REGNO (from));
@@ -942,13 +955,14 @@ add_ranges_and_copies (void)
void
ira_emit (int loops_p)
{
- int i;
basic_block bb;
edge_iterator ei;
edge e;
+ allocno_t a;
+ allocno_iterator ai;
- for (i = 0; i < allocnos_num; i++)
- ALLOCNO_REG (allocnos [i]) = regno_reg_rtx [ALLOCNO_REGNO (allocnos [i])];
+ FOR_EACH_ALLOCNO (a, ai)
+ ALLOCNO_REG (a) = regno_reg_rtx [ALLOCNO_REGNO (a)];
if (! loops_p)
return;
at_bb_start = ira_allocate (sizeof (struct move *) * last_basic_block);
Index: ira-build.c
===================================================================
--- ira-build.c (revision 133314)
+++ ira-build.c (working copy)
@@ -54,8 +54,10 @@ static void compress_calls (void);
static void finish_calls (void);
static void initiate_allocnos (void);
-static void check_allocno_conflict_vec (allocno_t, int);
-static void add_to_allocno_conflict_vec (allocno_t, allocno_t);
+static void allocate_allocno_conflict_bit_vec (allocno_t);
+static void add_to_allocno_conflicts (allocno_t, allocno_t);
+static void remove_wrong_conflicts (allocno_t);
+static void change_allocno_conflicts (allocno_t, allocno_t *);
static void compress_allocno_conflict_vec (allocno_t);
static void compress_conflict_vecs (void);
static allocno_t create_cap_allocno (allocno_t);
@@ -88,7 +90,7 @@ static allocno_live_range_t merge_ranges
allocno_live_range_t);
static loop_tree_node_t common_loop_tree_node_dominator (loop_tree_node_t,
loop_tree_node_t);
-static void check_and_add_conflicts (allocno_t, allocno_t *);
+static void check_and_add_conflicts (allocno_t, allocno_t);
static void add_conflict_with_underlying_allocnos (allocno_t,
loop_tree_node_t, int);
@@ -110,12 +112,14 @@ loop_tree_node_t ira_loop_nodes;
allocno_t *regno_allocno_map;
/* Array of references to all allocnos and their size. The order
- number of the allocno corresponds to the index in the array. */
+ number of the allocno corresponds to the index in the array.
+ Removed allocnos have NULL element value. */
allocno_t *allocnos;
int allocnos_num;
/* Array of references to copies and its size. The order number of
- the copy corresponds to the index in the array. */
+ the copy corresponds to the index in the array. Removed allocnos
+ have NULL element value. */
copy_t *copies;
int copies_num;
@@ -342,10 +346,11 @@ static void
rebuild_regno_allocno_maps (void)
{
unsigned int l;
- int i, max_regno, regno;
+ int max_regno, regno;
allocno_t a;
loop_tree_node_t loop_tree_node;
loop_p loop;
+ allocno_iterator ai;
max_regno = max_reg_num ();
for (l = 0; VEC_iterate (loop_p, ira_loops.larray, l, loop); l++)
@@ -360,9 +365,8 @@ rebuild_regno_allocno_maps (void)
ira_free (regno_allocno_map);
regno_allocno_map = ira_allocate (max_regno * sizeof (allocno_t));
memset (regno_allocno_map, 0, max_regno * sizeof (allocno_t));
- for (i = 0; i < allocnos_num; i++)
+ FOR_EACH_ALLOCNO (a, ai)
{
- a = allocnos [i];
if (ALLOCNO_CAP_MEMBER (a) != NULL)
continue;
regno = ALLOCNO_REGNO (a);
@@ -504,9 +508,8 @@ create_allocno (int regno, int cap_p, lo
ALLOCNO_CAP (a) = NULL;
ALLOCNO_CAP_MEMBER (a) = NULL;
ALLOCNO_NUM (a) = allocnos_num;
- ALLOCNO_CONFLICT_ALLOCNO_VEC (a) = NULL;
+ ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a) = NULL;
ALLOCNO_CONFLICT_ALLOCNOS_NUM (a) = 0;
- ALLOCNO_TOTAL_CONFLICT_ALLOCNOS_NUM (a) = 0;
CLEAR_HARD_REG_SET (ALLOCNO_CONFLICT_HARD_REGS (a));
CLEAR_HARD_REG_SET (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a));
ALLOCNO_NREFS (a) = 0;
@@ -522,10 +525,12 @@ create_allocno (int regno, int cap_p, lo
ALLOCNO_MEM_OPTIMIZED_DEST (a) = NULL;
ALLOCNO_MEM_OPTIMIZED_DEST_P (a) = FALSE;
ALLOCNO_SOMEWHERE_RENAMED_P (a) = FALSE;
+ ALLOCNO_CHILD_RENAMED_P (a) = FALSE;
ALLOCNO_DONT_REASSIGN_P (a) = FALSE;
ALLOCNO_IN_GRAPH_P (a) = FALSE;
ALLOCNO_ASSIGNED_P (a) = FALSE;
ALLOCNO_MAY_BE_SPILLED_P (a) = FALSE;
+ ALLOCNO_CONFLICT_VEC_P (a) = FALSE;
ALLOCNO_MODE (a) = (regno < 0 ? VOIDmode : PSEUDO_REGNO_MODE (regno));
ALLOCNO_COPIES (a) = NULL;
ALLOCNO_HARD_REG_COSTS (a) = NULL;
@@ -549,62 +554,213 @@ create_allocno (int regno, int cap_p, lo
return a;
}
-/* The function allocates conflict vector of A for NUM allocnos. */
+/* The function returns TRUE if conflict vector with NUM elemnents is
+ more profitable than conflict bit vector for A. */
+int
+conflict_vector_profitable_p (allocno_t a ATTRIBUTE_UNUSED, int num)
+{
+ int nw = (allocnos_num + INT_BITS - 1) / INT_BITS;
+
+ return sizeof (allocno_t) * num < 2 * nw * sizeof (INT_TYPE);
+}
+
+/* The function allocates and initialize conflict vector of A for NUM
+ allocnos. */
void
-allocate_allocno_conflicts (allocno_t a, int num)
+allocate_allocno_conflict_vec (allocno_t a, int num)
{
- ira_assert (ALLOCNO_CONFLICT_ALLOCNO_VEC (a) == NULL);
- ALLOCNO_CONFLICT_ALLOCNO_VEC (a)
- = ira_allocate (sizeof (allocno_t) * (num + 1));
- ALLOCNO_CONFLICT_ALLOCNO_VEC (a) [0] = NULL;
+ int size;
+ allocno_t *vec;
+
+ ira_assert (ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a) == NULL);
+ num++; /* for NULL end marker */
+ size = sizeof (allocno_t) * num;
+ vec = ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a) = ira_allocate (size);
+ vec [0] = NULL;
ALLOCNO_CONFLICT_ALLOCNOS_NUM (a) = 0;
- ALLOCNO_TOTAL_CONFLICT_ALLOCNOS_NUM (a) = 0;
- ALLOCNO_CONFLICT_ALLOCNO_VEC_SIZE (a) = num;
+ ALLOCNO_CONFLICT_ALLOCNO_ARRAY_SIZE (a) = size;
+ ALLOCNO_CONFLICT_VEC_P (a) = TRUE;
}
-/* The function checks that conflict vector of A has enough space to
- contain NUM allocno references. If the space is not enough, the
- function expands the conflict vector. */
+/* The function allocates and initializes conflict bit vector of A. */
static void
-check_allocno_conflict_vec (allocno_t a, int num)
+allocate_allocno_conflict_bit_vec (allocno_t a)
{
- int size;
- allocno_t *vec;
+ unsigned int size;
- ira_assert (ALLOCNO_CONFLICT_ALLOCNO_VEC (a) != NULL);
- if (ALLOCNO_CONFLICT_ALLOCNO_VEC_SIZE (a) >= num)
- return;
- size = 3 * num / 2 + 1;
- vec = ira_allocate (sizeof (allocno_t) * (size + 1));
- memcpy (vec, ALLOCNO_CONFLICT_ALLOCNO_VEC (a),
- sizeof (allocno_t)
- * (ALLOCNO_TOTAL_CONFLICT_ALLOCNOS_NUM (a) + 1));
- ira_free (ALLOCNO_CONFLICT_ALLOCNO_VEC (a));
- ALLOCNO_CONFLICT_ALLOCNO_VEC (a) = vec;
- ALLOCNO_CONFLICT_ALLOCNO_VEC_SIZE (a) = size;
+ ira_assert (ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a) == NULL);
+ size = (allocnos_num + INT_BITS - 1) / INT_BITS * sizeof (INT_TYPE);
+ ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a) = ira_allocate (size);
+ memset (ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a), 0, size);
+ ALLOCNO_CONFLICT_ALLOCNO_ARRAY_SIZE (a) = size;
+ ALLOCNO_CONFLICT_VEC_P (a) = FALSE;
+}
+
+/* The function allocates and initializes conflict vector or conflict
+ bit vector of A for NUM allocnos whatever is more profitable. */
+void
+allocate_allocno_conflicts (allocno_t a, int num)
+{
+ if (conflict_vector_profitable_p (a, num))
+ allocate_allocno_conflict_vec (a, num);
+ else
+ allocate_allocno_conflict_bit_vec (a);
}
-/* The function adds A2 to conflict vector of A1. */
+/* The function adds A2 to to the conflicts of A1. */
static void
-add_to_allocno_conflict_vec (allocno_t a1, allocno_t a2)
+add_to_allocno_conflicts (allocno_t a1, allocno_t a2)
{
- int size;
- allocno_t *vec;
+ int num;
+ unsigned int size;
- size = ALLOCNO_TOTAL_CONFLICT_ALLOCNOS_NUM (a1);
- check_allocno_conflict_vec (a1, size + 1);
- vec = ALLOCNO_CONFLICT_ALLOCNO_VEC (a1);
- vec [size] = a2;
- vec [size + 1] = NULL;
- ALLOCNO_TOTAL_CONFLICT_ALLOCNOS_NUM (a1)++;
+ if (ALLOCNO_CONFLICT_VEC_P (a1))
+ {
+ allocno_t *vec;
+
+ num = ALLOCNO_CONFLICT_ALLOCNOS_NUM (a1) + 2;
+ if (ALLOCNO_CONFLICT_ALLOCNO_ARRAY_SIZE (a1) >= num * sizeof (allocno_t))
+ vec = ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a1);
+ else
+ {
+ size = (3 * num / 2 + 1) * sizeof (allocno_t);
+ vec = ira_allocate (size);
+ memcpy (vec, ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a1),
+ sizeof (allocno_t) * ALLOCNO_CONFLICT_ALLOCNOS_NUM (a1));
+ ira_free (ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a1));
+ ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a1) = vec;
+ ALLOCNO_CONFLICT_ALLOCNO_ARRAY_SIZE (a1) = size;
+ }
+ vec [num - 2] = a2;
+ vec [num - 1] = NULL;
+ ALLOCNO_CONFLICT_ALLOCNOS_NUM (a1)++;
+ }
+ else
+ {
+ int nw;
+ INT_TYPE *vec;
+
+ num = ALLOCNO_NUM (a2);
+ nw = num / INT_BITS + 1;
+ size = nw * sizeof (INT_TYPE);
+ if (ALLOCNO_CONFLICT_ALLOCNO_ARRAY_SIZE (a1) >= size)
+ vec = ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a1);
+ else
+ {
+ size = (3 * nw / 2 + 1) * sizeof (INT_TYPE);
+ vec = ira_allocate (size);
+ memcpy (vec, ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a1),
+ ALLOCNO_CONFLICT_ALLOCNO_ARRAY_SIZE (a1));
+ memset ((char *) vec + ALLOCNO_CONFLICT_ALLOCNO_ARRAY_SIZE (a1),
+ 0, size - ALLOCNO_CONFLICT_ALLOCNO_ARRAY_SIZE (a1));
+ ira_free (ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a1));
+ ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a1) = vec;
+ ALLOCNO_CONFLICT_ALLOCNO_ARRAY_SIZE (a1) = size;
+ }
+ SET_ALLOCNO_SET_BIT (vec, num);
+ }
}
/* The function adds A1 to conflict vector of A2 and vise versa. */
void
add_allocno_conflict (allocno_t a1, allocno_t a2)
{
- add_to_allocno_conflict_vec (a1, a2);
- add_to_allocno_conflict_vec (a2, a1);
+ add_to_allocno_conflicts (a1, a2);
+ add_to_allocno_conflicts (a2, a1);
+}
+
+/* Remove conflicts of A which are wrong now. */
+static void
+remove_wrong_conflicts (allocno_t a)
+{
+ int n, i;
+ allocno_t conflict_a;
+
+ if (ALLOCNO_CONFLICT_VEC_P (a))
+ {
+ allocno_t *allocno_vec;
+
+ allocno_vec = ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a);
+ for (n = i = 0; (conflict_a = allocno_vec [i]) != NULL; i++)
+ {
+ if (allocno_live_ranges_intersect_p (a, conflict_a))
+ allocno_vec [n++] = conflict_a;
+ else
+ {
+ if (internal_flag_ira_verbose > 4 && ira_dump_file != NULL)
+ fprintf (ira_dump_file,
+ " Remove conflict a%dr%d -> a%dr%d\n",
+ ALLOCNO_NUM (a), REGNO (ALLOCNO_REG (a)),
+ ALLOCNO_NUM (conflict_a),
+ REGNO (ALLOCNO_REG (conflict_a)));
+
+ }
+ }
+ allocno_vec [n] = NULL;
+ ALLOCNO_CONFLICT_ALLOCNOS_NUM (a) = n;
+ }
+ else
+ {
+ INT_TYPE *allocno_bit_vec;
+ allocno_set_iterator asi;
+
+ allocno_bit_vec = ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a);
+ n = MIN (allocnos_num,
+ (int) ALLOCNO_CONFLICT_ALLOCNO_ARRAY_SIZE (a) * CHAR_BIT);
+ FOR_EACH_ALLOCNO_IN_SET (allocno_bit_vec, n, i, asi)
+ {
+ conflict_a = allocnos [i];
+ if (! allocno_live_ranges_intersect_p (a, conflict_a))
+ {
+ CLEAR_ALLOCNO_SET_BIT (allocno_bit_vec, i);
+ if (internal_flag_ira_verbose > 4 && ira_dump_file != NULL)
+ fprintf (ira_dump_file,
+ " Remove conflict a%dr%d -> a%dr%d\n",
+ ALLOCNO_NUM (a), REGNO (ALLOCNO_REG (a)),
+ ALLOCNO_NUM (conflict_a),
+ REGNO (ALLOCNO_REG (conflict_a)));
+ }
+ }
+ }
+}
+
+/* Temporary bit vector used to change conflicts. */
+static INT_TYPE *temp_change_bit_vec;
+
+/* Change conflicts of A according to regno map REGNO_ALLOCNO_MAP. */
+static void
+change_allocno_conflicts (allocno_t a, allocno_t *regno_allocno_map)
+{
+ int n, i;
+ allocno_t conflict_a;
+
+ if (ALLOCNO_CONFLICT_VEC_P (a))
+ {
+ allocno_t *allocno_vec;
+
+ allocno_vec = ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a);
+ for (i = 0; (conflict_a = allocno_vec [i]) != NULL; i++)
+ allocno_vec [i] = regno_allocno_map [REGNO (ALLOCNO_REG (conflict_a))];
+ }
+ else
+ {
+ int nw;
+ INT_TYPE *allocno_bit_vec;
+ allocno_set_iterator asi;
+
+ allocno_bit_vec = ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a);
+ n = MIN (allocnos_num,
+ (int) ALLOCNO_CONFLICT_ALLOCNO_ARRAY_SIZE (a) * CHAR_BIT);
+ nw = (n + INT_BITS - 1) / INT_BITS;
+ memcpy (temp_change_bit_vec, allocno_bit_vec, nw * sizeof (INT_TYPE));
+ memset (allocno_bit_vec, 0, nw * sizeof (INT_TYPE));
+ FOR_EACH_ALLOCNO_IN_SET (temp_change_bit_vec, n, i, asi)
+ {
+ conflict_a = allocnos [i];
+ conflict_a = regno_allocno_map [REGNO (ALLOCNO_REG (conflict_a))];
+ SET_ALLOCNO_SET_BIT (allocno_bit_vec, ALLOCNO_NUM (conflict_a));
+ }
+ }
}
/* The array used to find duplications in conflict vecs of
@@ -621,12 +777,11 @@ compress_allocno_conflict_vec (allocno_t
allocno_t *vec, conflict_a;
int i, j;
- vec = ALLOCNO_CONFLICT_ALLOCNO_VEC (a);
+ ira_assert (ALLOCNO_CONFLICT_VEC_P (a));
+ vec = ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a);
curr_allocno_conflict_check_tick++;
for (i = j = 0; (conflict_a = vec [i]) != NULL; i++)
{
- if (ALLOCNO_CONFLICT_ALLOCNOS_NUM (a) == i)
- ALLOCNO_CONFLICT_ALLOCNOS_NUM (a) = j;
if (allocno_conflict_check [ALLOCNO_NUM (conflict_a)]
!= curr_allocno_conflict_check_tick)
{
@@ -635,9 +790,7 @@ compress_allocno_conflict_vec (allocno_t
vec [j++] = conflict_a;
}
}
- if (ALLOCNO_CONFLICT_ALLOCNOS_NUM (a) == i)
- ALLOCNO_CONFLICT_ALLOCNOS_NUM (a) = j;
- ALLOCNO_TOTAL_CONFLICT_ALLOCNOS_NUM (a) = j;
+ ALLOCNO_CONFLICT_ALLOCNOS_NUM (a) = j;
vec [j] = NULL;
}
@@ -646,13 +799,15 @@ compress_allocno_conflict_vec (allocno_t
static void
compress_conflict_vecs (void)
{
- int i;
+ allocno_t a;
+ allocno_iterator ai;
allocno_conflict_check = ira_allocate (sizeof (int) * allocnos_num);
memset (allocno_conflict_check, 0, sizeof (int) * allocnos_num);
curr_allocno_conflict_check_tick = 0;
- for (i = 0; i < allocnos_num; i++)
- compress_allocno_conflict_vec (allocnos [i]);
+ FOR_EACH_ALLOCNO (a, ai)
+ if (ALLOCNO_CONFLICT_VEC_P (a))
+ compress_allocno_conflict_vec (a);
ira_free (allocno_conflict_check);
}
@@ -713,17 +868,17 @@ create_cap_allocno (allocno_t a)
static void
propagate_info_to_cap (allocno_t cap)
{
- int i, regno, conflicts_num;
+ int regno, conflicts_num;
enum reg_class cover_class;
allocno_t a, conflict_allocno, conflict_father_allocno;
allocno_t another_a, father_a;
- allocno_t *allocno_vec;
loop_tree_node_t father;
copy_t cp, next_cp;
+ allocno_conflict_iterator aci;
ira_assert (ALLOCNO_FIRST_COALESCED_ALLOCNO (cap) == cap
&& ALLOCNO_NEXT_COALESCED_ALLOCNO (cap) == cap
- && ALLOCNO_CONFLICT_ALLOCNO_VEC (cap) == NULL
+ && ALLOCNO_CONFLICT_ALLOCNO_ARRAY (cap) == NULL
&& ALLOCNO_CALLS_CROSSED_NUM (cap) == 0);
a = ALLOCNO_CAP_MEMBER (cap);
father = ALLOCNO_LOOP_TREE_NODE (cap);
@@ -773,25 +928,20 @@ propagate_info_to_cap (allocno_t cap)
add_allocno_copy (cap, father_a, cp->freq, cp->insn,
cp->loop_tree_node);
}
- allocno_vec = ALLOCNO_CONFLICT_ALLOCNO_VEC (a);
- if (allocno_vec != NULL)
+ if (ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a) != NULL)
{
conflicts_num = 0;
- for (i = 0;
- (conflict_allocno = allocno_vec [i]) != NULL;
- i++)
+ FOR_EACH_ALLOCNO_CONFLICT (a, conflict_allocno, aci)
conflicts_num++;
allocate_allocno_conflicts (cap, conflicts_num);
- for (conflicts_num = i = 0;
- (conflict_allocno = allocno_vec [i]) != NULL;
- i++)
+ FOR_EACH_ALLOCNO_CONFLICT (a, conflict_allocno, aci)
{
regno = ALLOCNO_REGNO (conflict_allocno);
conflict_father_allocno = father->regno_allocno_map [regno];
if (conflict_father_allocno == NULL)
conflict_father_allocno = ALLOCNO_CAP (conflict_allocno);
if (conflict_father_allocno != NULL
- && (ALLOCNO_CONFLICT_ALLOCNO_VEC (conflict_father_allocno)
+ && (ALLOCNO_CONFLICT_ALLOCNO_ARRAY (conflict_father_allocno)
!= NULL))
add_allocno_conflict (cap, conflict_father_allocno);
}
@@ -800,11 +950,10 @@ propagate_info_to_cap (allocno_t cap)
{
fprintf (ira_dump_file, " Propagate info to cap ");
print_expanded_allocno (cap);
- allocno_vec = ALLOCNO_CONFLICT_ALLOCNO_VEC (cap);
- if (allocno_vec != NULL)
+ if (ALLOCNO_CONFLICT_ALLOCNO_ARRAY (cap) != NULL)
{
fprintf (ira_dump_file, "\n Conflicts:");
- for (i = 0; (conflict_allocno = allocno_vec [i]) != NULL; i++)
+ FOR_EACH_ALLOCNO_CONFLICT (cap, conflict_allocno, aci)
{
fprintf (ira_dump_file, " a%d(r%d,",
ALLOCNO_NUM (conflict_allocno),
@@ -895,8 +1044,8 @@ finish_allocno (allocno_t a)
allocno_live_range_t r, next_r;
enum reg_class cover_class = ALLOCNO_COVER_CLASS (a);
- if (ALLOCNO_CONFLICT_ALLOCNO_VEC (a) != NULL)
- ira_free (ALLOCNO_CONFLICT_ALLOCNO_VEC (a));
+ if (ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a) != NULL)
+ ira_free (ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a));
if (ALLOCNO_HARD_REG_COSTS (a) != NULL)
free_cost_vector (ALLOCNO_HARD_REG_COSTS (a), cover_class);
if (ALLOCNO_CONFLICT_HARD_REG_COSTS (a) != NULL)
@@ -918,10 +1067,11 @@ finish_allocno (allocno_t a)
static void
finish_allocnos (void)
{
- int i;
+ allocno_t a;
+ allocno_iterator ai;
- for (i = 0; i < allocnos_num; i++)
- finish_allocno (allocnos [i]);
+ FOR_EACH_ALLOCNO (a, ai)
+ finish_allocno (a);
ira_free (regno_allocno_map);
VARRAY_FREE (allocno_varray);
free_alloc_pool (allocno_pool);
@@ -1159,10 +1309,11 @@ finish_copy (copy_t cp)
static void
finish_copies (void)
{
- int i;
+ copy_t cp;
+ copy_iterator ci;
- for (i = 0; i < copies_num; i++)
- finish_copy (copies [i]);
+ FOR_EACH_COPY (cp, ci)
+ finish_copy (cp);
VARRAY_FREE (copy_varray);
free_alloc_pool (copy_pool);
}
@@ -1593,23 +1744,23 @@ common_loop_tree_node_dominator (loop_tr
static allocno_t *regno_top_level_allocno_map;
-/* The function check conflicts A with allocnos from CONFLICT_VECT and
- add them (more accurately corresponding final IR allocnos) if it is
- necessary. */
+/* The function check conflicts A with allocnos conflicting with
+ OTHER_ALLOCNO and add them (more accurately corresponding final IR
+ allocnos) if it is necessary. */
static void
-check_and_add_conflicts (allocno_t a, allocno_t *conflict_vec)
+check_and_add_conflicts (allocno_t a, allocno_t other_allocno)
{
allocno_t conflict_a;
- int i;
+ allocno_conflict_iterator aci;
- for (i = 0; (conflict_a = conflict_vec [i]) != NULL; i++)
+ FOR_EACH_ALLOCNO_CONFLICT (other_allocno, conflict_a, aci)
{
conflict_a
= regno_top_level_allocno_map [REGNO (ALLOCNO_REG (conflict_a))];
if (allocno_live_ranges_intersect_p (conflict_a, a))
{
- add_to_allocno_conflict_vec (conflict_a, a);
- add_to_allocno_conflict_vec (a, conflict_a);
+ add_to_allocno_conflicts (conflict_a, a);
+ add_to_allocno_conflicts (a, conflict_a);
if (internal_flag_ira_verbose > 4 && ira_dump_file != NULL)
fprintf (ira_dump_file,
" Add underlying conflict a%dr%d-a%dr%d\n",
@@ -1646,7 +1797,7 @@ add_conflict_with_underlying_allocnos (a
&& subloop_a == regno_top_level_allocno_map [REGNO (ALLOCNO_REG
(subloop_a))])
continue;
- check_and_add_conflicts (a, ALLOCNO_CONFLICT_ALLOCNO_VEC (subloop_a));
+ check_and_add_conflicts (a, subloop_a);
add_conflict_with_underlying_allocnos (a, subloop_node, go_deeper_p);
}
}
@@ -1658,18 +1809,20 @@ add_conflict_with_underlying_allocnos (a
void
ira_flattening (int max_regno_before_emit, int max_point_before_emit)
{
- int i, j, k, free, propagate_p, stop_p, keep_p;
- int hard_regs_num, new_allocnos_p, renamed_p, start;
+ int i, j, propagate_p, stop_p, keep_p;
+ int hard_regs_num, new_allocnos_p, renamed_p;
unsigned int n;
enum reg_class cover_class;
rtx call, *allocno_calls;
allocno_t a, father_a, conflict_a, first, second, node_first, node_second;
- allocno_t dominator_a, *allocno_vec;
+ allocno_t dominator_a;
copy_t cp;
loop_tree_node_t father, node, dominator;
allocno_live_range_t r;
bitmap live_allocnos;
bitmap_iterator bi;
+ allocno_iterator ai;
+ copy_iterator ci;
regno_top_level_allocno_map
= ira_allocate (max_reg_num () * sizeof (allocno_t));
@@ -1826,9 +1979,8 @@ ira_flattening (int max_regno_before_emi
{
/* Fix final allocnos attributes concerning calls. */
compress_calls ();
- for (i = 0; i < allocnos_num; i++)
+ FOR_EACH_ALLOCNO (a, ai)
{
- a = allocnos [i];
if (a != regno_top_level_allocno_map [REGNO (ALLOCNO_REG (a))]
|| ALLOCNO_CAP_MEMBER (a) != NULL)
continue;
@@ -1838,9 +1990,8 @@ ira_flattening (int max_regno_before_emi
}
}
/* Mark copies for removing and change allocnos in copies. */
- for (i = 0; i < copies_num; i++)
+ FOR_EACH_COPY (cp, ci)
{
- cp = copies [i];
if (ALLOCNO_CAP_MEMBER (cp->first) != NULL
|| ALLOCNO_CAP_MEMBER (cp->second) != NULL)
{
@@ -1902,9 +2053,8 @@ ira_flattening (int max_regno_before_emi
stored in memory and the value is not changed in the loop.
In this case the allocno lives in the loop and can conflict
with allocnos inside the loop. */
- for (i = 0; i < allocnos_num; i++)
+ FOR_EACH_ALLOCNO (a, ai)
{
- a = allocnos [i];
if (a != regno_top_level_allocno_map [REGNO (ALLOCNO_REG (a))]
|| ALLOCNO_CAP_MEMBER (a) != NULL)
continue;
@@ -1913,96 +2063,57 @@ ira_flattening (int max_regno_before_emi
if ((first = ALLOCNO_MEM_OPTIMIZED_DEST (a)) != NULL)
{
first = regno_top_level_allocno_map [REGNO (ALLOCNO_REG (first))];
- check_and_add_conflicts
- (first, ALLOCNO_CONFLICT_ALLOCNO_VEC (a));
+ check_and_add_conflicts (first, a);
add_conflict_with_underlying_allocnos
(first, ALLOCNO_LOOP_TREE_NODE (a), TRUE);
}
}
}
/* Change allocnos regno, conflicting allocnos, and range allocnos. */
- for (i = 0; i < allocnos_num; i++)
+ temp_change_bit_vec = ira_allocate (((allocnos_num + INT_BITS - 1) / INT_BITS)
+ * sizeof (INT_TYPE));
+ FOR_EACH_ALLOCNO (a, ai)
{
- a = allocnos [i];
if (a != regno_top_level_allocno_map [REGNO (ALLOCNO_REG (a))]
|| ALLOCNO_CAP_MEMBER (a) != NULL)
continue;
ALLOCNO_LOOP_TREE_NODE (a) = ira_loop_tree_root;
ALLOCNO_REGNO (a) = REGNO (ALLOCNO_REG (a));
- allocno_vec = ALLOCNO_CONFLICT_ALLOCNO_VEC (a);
- for (j = 0; (conflict_a = allocno_vec [j]) != NULL; j++)
- allocno_vec [j]
- = regno_top_level_allocno_map [REGNO (ALLOCNO_REG (conflict_a))];
+ change_allocno_conflicts (a, regno_top_level_allocno_map);
for (r = ALLOCNO_LIVE_RANGES (a); r != NULL; r = r->next)
r->allocno = a;
}
+ ira_free (temp_change_bit_vec);
/* Remove allocnos on lower levels of the loop tree and
enumerate allocnos. */
- for (free = 0, i = 0; i < allocnos_num; i++)
+ FOR_EACH_ALLOCNO (a, ai)
{
- a = allocnos [i];
if (ALLOCNO_LOOP_TREE_NODE (a) != ira_loop_tree_root
|| ALLOCNO_CAP_MEMBER (a) != NULL)
{
if (internal_flag_ira_verbose > 4 && ira_dump_file != NULL)
fprintf (ira_dump_file, " Remove a%dr%d\n",
ALLOCNO_NUM (a), REGNO (ALLOCNO_REG (a)));
+ allocnos [ALLOCNO_NUM (a)] = NULL;
finish_allocno (a);
continue;
}
ALLOCNO_CAP (a) = NULL;
- if (new_allocnos_p || ALLOCNO_SOMEWHERE_RENAMED_P (a))
- {
- /* Remove conflicts. */
- allocno_vec = ALLOCNO_CONFLICT_ALLOCNO_VEC (a);
- start = (ALLOCNO_SOMEWHERE_RENAMED_P (a)
- ? 0 : ALLOCNO_CONFLICT_ALLOCNOS_NUM (a));
- for (k = j = start;
- (conflict_a = allocno_vec [j]) != NULL;
- j++)
- {
- if (allocno_live_ranges_intersect_p (a, conflict_a))
- allocno_vec [k++] = conflict_a;
- else
- {
- if (internal_flag_ira_verbose > 4 && ira_dump_file != NULL)
- fprintf (ira_dump_file,
- " Remove conflict a%dr%d - a%dr%d\n",
- ALLOCNO_NUM (a), REGNO (ALLOCNO_REG (a)),
- ALLOCNO_NUM (conflict_a),
- REGNO (ALLOCNO_REG (conflict_a)));
-
- }
- }
- allocno_vec [k] = NULL;
- ALLOCNO_TOTAL_CONFLICT_ALLOCNOS_NUM (a) = k;
- }
- if (i == free)
- {
- free++;
- continue;
- }
- if (internal_flag_ira_verbose > 4 && ira_dump_file != NULL)
- fprintf (ira_dump_file, " Enumerate a%dr%d to a%d\n",
- ALLOCNO_NUM (a), REGNO (ALLOCNO_REG (a)), free);
+ if (ALLOCNO_CHILD_RENAMED_P (a) /*new_allocnos_p*/
+ || ALLOCNO_SOMEWHERE_RENAMED_P (a))
+ remove_wrong_conflicts (a);
ALLOCNO_UPDATED_MEMORY_COST (a) = ALLOCNO_MEMORY_COST (a);
if (! ALLOCNO_ASSIGNED_P (a))
free_allocno_updated_costs (a);
ira_assert (ALLOCNO_UPDATED_HARD_REG_COSTS (a) == NULL);
ira_assert (ALLOCNO_UPDATED_CONFLICT_HARD_REG_COSTS (a) == NULL);
- ALLOCNO_NUM (a) = free;
- allocnos [free++] = a;
}
- for (i = free; i < allocnos_num; i++)
- VARRAY_POP (allocno_varray);
- allocnos = (allocno_t *) &VARRAY_GENERIC_PTR (allocno_varray, 0);
- allocnos_num = VARRAY_ACTIVE_SIZE (allocno_varray);
/* Remove unnecessary copies, and enumerate copies. */
- for (free = i = 0; i < copies_num; i++)
+ FOR_EACH_COPY (cp, ci)
{
- cp = copies [i];
if (cp->loop_tree_node == NULL)
{
+ copies [cp->num] = NULL;
finish_copy (cp);
continue;
}
@@ -2011,21 +2122,7 @@ ira_flattening (int max_regno_before_emi
&& ALLOCNO_LOOP_TREE_NODE (cp->second) == ira_loop_tree_root);
add_allocno_copy_to_list (cp);
swap_allocno_copy_ends_if_necessary (cp);
- if (i == free)
- {
- free++;
- continue;
- }
- if (internal_flag_ira_verbose > 4 && ira_dump_file != NULL)
- fprintf (ira_dump_file,
- " Enumerate cp%d to cp%d\n", cp->num, free);
- cp->num = free;
- copies [free++] = cp;
}
- for (i = free; i < copies_num; i++)
- VARRAY_POP (copy_varray);
- copies = (copy_t *) &VARRAY_GENERIC_PTR (copy_varray, 0);
- copies_num = VARRAY_ACTIVE_SIZE (copy_varray);
rebuild_regno_allocno_maps ();
rebuild_start_finish_chains ();
ira_free (regno_top_level_allocno_map);
@@ -2053,7 +2150,7 @@ ira_flattening (int max_regno_before_emi
ALLOCNO_NUM (conflict_a),
REGNO (ALLOCNO_REG (conflict_a)),
ALLOCNO_NUM (a), REGNO (ALLOCNO_REG (a)));
- add_to_allocno_conflict_vec (a, conflict_a);
+ add_to_allocno_conflicts (a, conflict_a);
if (internal_flag_ira_verbose > 4
&& ira_dump_file != NULL)
fprintf (ira_dump_file,
@@ -2061,7 +2158,7 @@ ira_flattening (int max_regno_before_emi
ALLOCNO_NUM (a), REGNO (ALLOCNO_REG (a)),
ALLOCNO_NUM (conflict_a),
REGNO (ALLOCNO_REG (conflict_a)));
- add_to_allocno_conflict_vec (conflict_a, a);
+ add_to_allocno_conflicts (conflict_a, a);
}
}
bitmap_set_bit (live_allocnos, j);
@@ -2114,14 +2211,18 @@ ira_build (int loops_p)
ira_build_conflicts ();
if (internal_flag_ira_verbose > 0 && ira_dump_file != NULL)
{
- int i, n, nr;
+ int n, nr;
+ allocno_t a;
allocno_live_range_t r;
+ allocno_iterator ai;
- for (nr = n = i = 0; i < allocnos_num; i++)
- n += ALLOCNO_TOTAL_CONFLICT_ALLOCNOS_NUM (allocnos [i]);
- for (nr = i = 0; i < allocnos_num; i++)
- for (r = ALLOCNO_LIVE_RANGES (allocnos [i]); r != NULL; r = r->next)
- nr++;
+ n = 0;
+ FOR_EACH_ALLOCNO (a, ai)
+ n += ALLOCNO_CONFLICT_ALLOCNOS_NUM (a);
+ nr = 0;
+ FOR_EACH_ALLOCNO (a, ai)
+ for (r = ALLOCNO_LIVE_RANGES (a); r != NULL; r = r->next)
+ nr++;
fprintf (ira_dump_file, " regions=%d, blocks=%d, points=%d\n",
VEC_length (loop_p, ira_loops.larray), n_basic_blocks,
max_point);
Index: ira.c
===================================================================
--- ira.c (revision 133314)
+++ ira.c (working copy)
@@ -1175,13 +1175,13 @@ find_reg_equiv_invariant_const (void)
static void
setup_reg_renumber (void)
{
- int i, regno, hard_regno;
+ int regno, hard_regno;
allocno_t a;
+ allocno_iterator ai;
caller_save_needed = 0;
- for (i = 0; i < allocnos_num; i++)
+ FOR_EACH_ALLOCNO (a, ai)
{
- a = allocnos [i];
/* There are no caps at this point. */
ira_assert (ALLOCNO_CAP_MEMBER (a) == NULL);
if (! ALLOCNO_ASSIGNED_P (a))
@@ -1209,12 +1209,12 @@ setup_reg_renumber (void)
static void
setup_allocno_assignment_flags (void)
{
- int i, hard_regno;
+ int hard_regno;
allocno_t a;
+ allocno_iterator ai;
- for (i = 0; i < allocnos_num; i++)
+ FOR_EACH_ALLOCNO (a, ai)
{
- a = allocnos [i];
if (! ALLOCNO_ASSIGNED_P (a))
/* It can happen if A is not referenced but partially anticipated
somewhere in a region. */
@@ -1241,13 +1241,13 @@ setup_allocno_assignment_flags (void)
static void
calculate_allocation_cost (void)
{
- int i, hard_regno, cost;
+ int hard_regno, cost;
allocno_t a;
+ allocno_iterator ai;
overall_cost = reg_cost = mem_cost = 0;
- for (i = 0; i < allocnos_num; i++)
+ FOR_EACH_ALLOCNO (a, ai)
{
- a = allocnos [i];
hard_regno = ALLOCNO_HARD_REGNO (a);
ira_assert (hard_regno < 0
|| ! hard_reg_not_in_set_p
@@ -1290,18 +1290,18 @@ calculate_allocation_cost (void)
static void
check_allocation (void)
{
- allocno_t a, conflict_a, *allocno_vec;
- int i, hard_regno, conflict_hard_regno, j, nregs, conflict_nregs;
-
- for (i = 0; i < allocnos_num; i++)
+ allocno_t a, conflict_a;
+ int hard_regno, conflict_hard_regno, nregs, conflict_nregs;
+ allocno_conflict_iterator aci;
+ allocno_iterator ai;
+
+ FOR_EACH_ALLOCNO (a, ai)
{
- a = allocnos [i];
if (ALLOCNO_CAP_MEMBER (a) != NULL
|| (hard_regno = ALLOCNO_HARD_REGNO (a)) < 0)
continue;
nregs = hard_regno_nregs [hard_regno] [ALLOCNO_MODE (a)];
- allocno_vec = ALLOCNO_CONFLICT_ALLOCNO_VEC (a);
- for (j = 0; (conflict_a = allocno_vec [j]) != NULL; j++)
+ FOR_EACH_ALLOCNO_CONFLICT (a, conflict_a, aci)
if ((conflict_hard_regno = ALLOCNO_HARD_REGNO (conflict_a)) >= 0)
{
conflict_nregs
@@ -1374,13 +1374,13 @@ fix_reg_equiv_init (void)
static void
print_redundant_copies (void)
{
- int i, hard_regno;
+ int hard_regno;
allocno_t a;
copy_t cp, next_cp;
+ allocno_iterator ai;
- for (i = 0; i < allocnos_num; i++)
+ FOR_EACH_ALLOCNO (a, ai)
{
- a = allocnos [i];
if (ALLOCNO_CAP_MEMBER (a) != NULL)
/* It is a cap. */
continue;
@@ -1409,13 +1409,12 @@ print_redundant_copies (void)
static void
setup_preferred_alternate_classes (void)
{
- int i;
enum reg_class cover_class;
allocno_t a;
+ allocno_iterator ai;
- for (i = 0; i < allocnos_num; i++)
+ FOR_EACH_ALLOCNO (a, ai)
{
- a = allocnos [i];
cover_class = ALLOCNO_COVER_CLASS (a);
if (cover_class == NO_REGS)
cover_class = GENERAL_REGS;
Index: ira-costs.c
===================================================================
--- ira-costs.c (revision 133314)
+++ ira-costs.c (working copy)
@@ -1049,16 +1049,18 @@ scan_one_insn (rtx insn)
static void
print_costs (FILE *f)
{
- int i, k;
+ int k;
+ allocno_t a;
+ allocno_iterator ai;
fprintf (f, "\n");
- for (i = 0; i < allocnos_num; i++)
+ FOR_EACH_ALLOCNO (a, ai)
{
- int class;
+ int i, class;
basic_block bb;
- allocno_t a = allocnos [i];
int regno = ALLOCNO_REGNO (a);
+ i = ALLOCNO_NUM (a);
fprintf (f, " a%d(r%d,", i, regno);
if ((bb = ALLOCNO_LOOP_TREE_NODE (a)->bb) != NULL)
fprintf (f, "b%d", bb->index);
@@ -1426,10 +1428,11 @@ setup_allocno_cover_class_and_costs (voi
enum reg_class cover_class, class;
enum machine_mode mode;
allocno_t a;
+ allocno_iterator ai;
- for (i = 0; i < allocnos_num; i++)
+ FOR_EACH_ALLOCNO (a, ai)
{
- a = allocnos [i];
+ i = ALLOCNO_NUM (a);
mode = ALLOCNO_MODE (a);
cover_class = class_translate [allocno_pref [i]];
ira_assert (allocno_pref [i] == NO_REGS || cover_class != NO_REGS);
@@ -1542,7 +1545,8 @@ finish_ira_costs_once (void)
void
ira_costs (void)
{
- int i;
+ allocno_t a;
+ allocno_iterator ai;
total_costs = ira_allocate (max_struct_costs_size * allocnos_num);
allocno_pref_buffer = ira_allocate (sizeof (enum reg_class) * allocnos_num);
@@ -1550,9 +1554,9 @@ ira_costs (void)
setup_allocno_cover_class_and_costs ();
/* Because we could process operands only as subregs, check mode of
the registers themselves too. */
- for (i = 0; i < allocnos_num; i++)
- if (register_move_cost [ALLOCNO_MODE (allocnos [i])] == NULL)
- init_register_move_cost (ALLOCNO_MODE (allocnos [i]));
+ FOR_EACH_ALLOCNO (a, ai)
+ if (register_move_cost [ALLOCNO_MODE (a)] == NULL)
+ init_register_move_cost (ALLOCNO_MODE (a));
ira_free (allocno_pref_buffer);
ira_free (total_costs);
}
@@ -1565,17 +1569,17 @@ ira_costs (void)
void
tune_allocno_costs_and_cover_classes (void)
{
- int i, j, k, n, regno, freq;
+ int j, k, n, regno, freq;
int cost, min_cost, *reg_costs;
enum reg_class cover_class, class;
enum machine_mode mode;
allocno_t a;
rtx call, *allocno_calls;
HARD_REG_SET clobbered_regs;
+ allocno_iterator ai;
- for (i = 0; i < allocnos_num; i++)
+ FOR_EACH_ALLOCNO (a, ai)
{
- a = allocnos [i];
cover_class = ALLOCNO_COVER_CLASS (a);
if (cover_class == NO_REGS)
continue;