summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVladimir Makarov <vmakarov@redhat.com>2008-11-25 22:52:37 +0000
committerVladimir Makarov <vmakarov@gcc.gnu.org>2008-11-25 22:52:37 +0000
commit30ea859e70a20f65b8abfb28269cd31bcab54941 (patch)
tree570532edd558acfd1cd74a139d8cf1f249d28173
parent5a1c3c109550ee678d41873ab74cb723923c7796 (diff)
downloadgcc-30ea859e70a20f65b8abfb28269cd31bcab54941.tar.gz
invoke.texi (ira-max-loops-num): Change semantics.
2008-11-25 Vladimir Makarov <vmakarov@redhat.com> * doc/invoke.texi (ira-max-loops-num): Change semantics. * ira-int.h (struct ira_loop_tree_node): New member to_remove_p. * ira-color.c (allocno_spill_priority): New function. (remove_allocno_from_bucket_and_push, push_allocno_to_spill): Print more info about the spilled allocno. (push_allocnos_to_stack): Use allocno_spill_priority. Add more checks on bad spill. * ira-build.c (loop_node_to_be_removed_p): Remove. (loop_compare_func, mark_loops_for_removal): New functions. (remove_uneccesary_loop_nodes_from_loop_t): Use member to_remove_p. (remove_unnecessary_allocnos): Call mark_loops_for_removal. * ira.c (ira): Don't change flag_ira_algorithm. * params.def (ira-max-loops-num): Change the value. From-SVN: r142207
-rw-r--r--gcc/ChangeLog22
-rw-r--r--gcc/doc/invoke.texi8
-rw-r--r--gcc/ira-build.c90
-rw-r--r--gcc/ira-color.c41
-rw-r--r--gcc/ira-int.h4
-rw-r--r--gcc/ira.c6
-rw-r--r--gcc/params.def2
7 files changed, 134 insertions, 39 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b29e61178a3..77110a39628 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,25 @@
+2008-11-25 Vladimir Makarov <vmakarov@redhat.com>
+
+ * doc/invoke.texi (ira-max-loops-num): Change semantics.
+
+ * ira-int.h (struct ira_loop_tree_node): New member to_remove_p.
+
+ * ira-color.c (allocno_spill_priority): New function.
+ (remove_allocno_from_bucket_and_push, push_allocno_to_spill):
+ Print more info about the spilled allocno.
+ (push_allocnos_to_stack): Use allocno_spill_priority. Add more
+ checks on bad spill.
+
+ * ira-build.c (loop_node_to_be_removed_p): Remove.
+ (loop_compare_func, mark_loops_for_removal): New functions.
+ (remove_uneccesary_loop_nodes_from_loop_t): Use member
+ to_remove_p.
+ (remove_unnecessary_allocnos): Call mark_loops_for_removal.
+
+ * ira.c (ira): Don't change flag_ira_algorithm.
+
+ * params.def (ira-max-loops-num): Change the value.
+
2008-11-25 Maxim Kuvyrkov <maxim@codesourcery.com>
* config/m68k/m68k.md (extendsidi2, extendsidi2_mem): Merge, clean up.
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 6fabfd781a7..a25f469867a 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -7603,10 +7603,10 @@ be disabled. The default maximum SCC size is 10000.
@item ira-max-loops-num
IRA uses a regional register allocation by default. If a function
-contains loops more than number given by the parameter, non-regional
-register allocator will be used even when option
-@option{-fira-algorithm} is given. The default value of the parameter
-is 20.
+contains loops more than number given by the parameter, only at most
+given number of the most frequently executed loops will form regions
+for the regional register allocation. The default value of the
+parameter is 100.
@end table
@end table
diff --git a/gcc/ira-build.c b/gcc/ira-build.c
index e4ed60141fa..65e4ad76dbb 100644
--- a/gcc/ira-build.c
+++ b/gcc/ira-build.c
@@ -1677,20 +1677,81 @@ low_pressure_loop_node_p (ira_loop_tree_node_t node)
return true;
}
-/* Return TRUE if NODE represents a loop with should be removed from
- regional allocation. We remove a loop with low register pressure
- inside another loop with register pressure. In this case a
- separate allocation of the loop hardly helps (for irregular
- register file architecture it could help by choosing a better hard
- register in the loop but we prefer faster allocation even in this
- case). */
-static bool
-loop_node_to_be_removed_p (ira_loop_tree_node_t node)
+/* Sort loops for marking them for removal. We put already marked
+ loops first, then less frequent loops next, and then outer loops
+ next. */
+static int
+loop_compare_func (const void *v1p, const void *v2p)
+{
+ int diff;
+ ira_loop_tree_node_t l1 = *(const ira_loop_tree_node_t *) v1p;
+ ira_loop_tree_node_t l2 = *(const ira_loop_tree_node_t *) v2p;
+
+ ira_assert (l1->parent != NULL && l2->parent != NULL);
+ if (l1->to_remove_p && ! l2->to_remove_p)
+ return -1;
+ if (! l1->to_remove_p && l2->to_remove_p)
+ return 1;
+ if ((diff = l1->loop->header->frequency - l2->loop->header->frequency) != 0)
+ return diff;
+ if ((diff = (int) loop_depth (l1->loop) - (int) loop_depth (l2->loop)) != 0)
+ return diff;
+ /* Make sorting stable. */
+ return l1->loop->num - l2->loop->num;
+}
+
+
+/* Mark loops which should be removed from regional allocation. We
+ remove a loop with low register pressure inside another loop with
+ register pressure. In this case a separate allocation of the loop
+ hardly helps (for irregular register file architecture it could
+ help by choosing a better hard register in the loop but we prefer
+ faster allocation even in this case). We also remove cheap loops
+ if there are more than IRA_MAX_LOOPS_NUM of them. */
+static void
+mark_loops_for_removal (void)
{
- return (node->parent != NULL && low_pressure_loop_node_p (node->parent)
- && low_pressure_loop_node_p (node));
+ int i, n;
+ ira_loop_tree_node_t *sorted_loops;
+ loop_p loop;
+
+ sorted_loops
+ = (ira_loop_tree_node_t *) ira_allocate (sizeof (ira_loop_tree_node_t)
+ * VEC_length (loop_p,
+ ira_loops.larray));
+ for (n = i = 0; VEC_iterate (loop_p, ira_loops.larray, i, loop); i++)
+ if (ira_loop_nodes[i].regno_allocno_map != NULL)
+ {
+ if (ira_loop_nodes[i].parent == NULL)
+ {
+ /* Don't remove the root. */
+ ira_loop_nodes[i].to_remove_p = false;
+ continue;
+ }
+ sorted_loops[n++] = &ira_loop_nodes[i];
+ ira_loop_nodes[i].to_remove_p
+ = (low_pressure_loop_node_p (ira_loop_nodes[i].parent)
+ && low_pressure_loop_node_p (&ira_loop_nodes[i]));
+ }
+ qsort (sorted_loops, n, sizeof (ira_loop_tree_node_t), loop_compare_func);
+ for (i = 0; n - i + 1 > IRA_MAX_LOOPS_NUM; i++)
+ {
+ sorted_loops[i]->to_remove_p = true;
+ if (internal_flag_ira_verbose > 1 && ira_dump_file != NULL)
+ fprintf
+ (ira_dump_file,
+ " Mark loop %d (header %d, freq %d, depth %d) for removal (%s)\n",
+ sorted_loops[i]->loop->num, sorted_loops[i]->loop->header->index,
+ sorted_loops[i]->loop->header->frequency,
+ loop_depth (sorted_loops[i]->loop),
+ low_pressure_loop_node_p (sorted_loops[i]->parent)
+ && low_pressure_loop_node_p (sorted_loops[i])
+ ? "low pressure" : "cheap loop");
+ }
+ ira_free (sorted_loops);
}
+
/* Definition of vector of loop tree nodes. */
DEF_VEC_P(ira_loop_tree_node_t);
DEF_VEC_ALLOC_P(ira_loop_tree_node_t, heap);
@@ -1710,7 +1771,7 @@ remove_uneccesary_loop_nodes_from_loop_tree (ira_loop_tree_node_t node)
bool remove_p;
ira_loop_tree_node_t subnode;
- remove_p = loop_node_to_be_removed_p (node);
+ remove_p = node->to_remove_p;
if (! remove_p)
VEC_safe_push (ira_loop_tree_node_t, heap, children_vec, node);
start = VEC_length (ira_loop_tree_node_t, children_vec);
@@ -1759,13 +1820,13 @@ remove_unnecessary_allocnos (void)
{
next_a = ALLOCNO_NEXT_REGNO_ALLOCNO (a);
a_node = ALLOCNO_LOOP_TREE_NODE (a);
- if (! loop_node_to_be_removed_p (a_node))
+ if (! a_node->to_remove_p)
prev_a = a;
else
{
for (parent = a_node->parent;
(parent_a = parent->regno_allocno_map[regno]) == NULL
- && loop_node_to_be_removed_p (parent);
+ && parent->to_remove_p;
parent = parent->parent)
;
if (parent_a == NULL)
@@ -1843,6 +1904,7 @@ remove_unnecessary_allocnos (void)
static void
remove_unnecessary_regions (void)
{
+ mark_loops_for_removal ();
children_vec
= VEC_alloc (ira_loop_tree_node_t, heap,
last_basic_block + VEC_length (loop_p, ira_loops.larray));
diff --git a/gcc/ira-color.c b/gcc/ira-color.c
index c3b63cc3d5d..4b9909194d6 100644
--- a/gcc/ira-color.c
+++ b/gcc/ira-color.c
@@ -655,6 +655,17 @@ static ira_allocno_t uncolorable_allocno_bucket;
of given *cover* class in the uncolorable_bucket. */
static int uncolorable_allocnos_num[N_REG_CLASSES];
+/* Return the current spill priority of allocno A. The less the
+ number, the more preferable the allocno for spilling. */
+static int
+allocno_spill_priority (ira_allocno_t a)
+{
+ return (ALLOCNO_TEMP (a)
+ / (ALLOCNO_LEFT_CONFLICTS_NUM (a)
+ * ira_reg_class_nregs[ALLOCNO_COVER_CLASS (a)][ALLOCNO_MODE (a)]
+ + 1));
+}
+
/* Add ALLOCNO to bucket *BUCKET_PTR. ALLOCNO should be not in a bucket
before the call. */
static void
@@ -925,7 +936,12 @@ remove_allocno_from_bucket_and_push (ira_allocno_t allocno, bool colorable_p)
{
fprintf (ira_dump_file, " Pushing");
print_coalesced_allocno (allocno);
- fprintf (ira_dump_file, "%s\n", colorable_p ? "" : "(potential spill)");
+ if (colorable_p)
+ fprintf (ira_dump_file, "\n");
+ else
+ fprintf (ira_dump_file, "(potential spill: %spri=%d, cost=%d)\n",
+ ALLOCNO_BAD_SPILL_P (allocno) ? "bad spill, " : "",
+ allocno_spill_priority (allocno), ALLOCNO_TEMP (allocno));
}
cover_class = ALLOCNO_COVER_CLASS (allocno);
ira_assert ((colorable_p
@@ -959,7 +975,7 @@ push_allocno_to_spill (ira_allocno_t allocno)
delete_allocno_from_bucket (allocno, &uncolorable_allocno_bucket);
ALLOCNO_MAY_BE_SPILLED_P (allocno) = true;
if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
- fprintf (ira_dump_file, " Pushing p%d(%d) (potential spill)\n",
+ fprintf (ira_dump_file, " Pushing p%d(%d) (spill for NO_REGS)\n",
ALLOCNO_NUM (allocno), ALLOCNO_REGNO (allocno));
push_allocno_to_stack (allocno);
}
@@ -1224,21 +1240,18 @@ push_allocnos_to_stack (void)
i++;
ira_assert (ALLOCNO_TEMP (i_allocno) != INT_MAX);
i_allocno_cost = ALLOCNO_TEMP (i_allocno);
- i_allocno_pri
- = (i_allocno_cost
- / (ALLOCNO_LEFT_CONFLICTS_NUM (i_allocno)
- * ira_reg_class_nregs[ALLOCNO_COVER_CLASS
- (i_allocno)]
- [ALLOCNO_MODE (i_allocno)] + 1));
+ i_allocno_pri = allocno_spill_priority (i_allocno);
if (allocno == NULL
|| (! ALLOCNO_BAD_SPILL_P (i_allocno)
&& ALLOCNO_BAD_SPILL_P (allocno))
- || allocno_pri > i_allocno_pri
- || (allocno_pri == i_allocno_pri
- && (allocno_cost > i_allocno_cost
- || (allocno_cost == i_allocno_cost
- && (ALLOCNO_NUM (allocno)
- > ALLOCNO_NUM (i_allocno))))))
+ || (! (ALLOCNO_BAD_SPILL_P (i_allocno)
+ && ! ALLOCNO_BAD_SPILL_P (allocno))
+ && (allocno_pri > i_allocno_pri
+ || (allocno_pri == i_allocno_pri
+ && (allocno_cost > i_allocno_cost
+ || (allocno_cost == i_allocno_cost
+ && (ALLOCNO_NUM (allocno)
+ > ALLOCNO_NUM (i_allocno))))))))
{
allocno = i_allocno;
allocno_cost = i_allocno_cost;
diff --git a/gcc/ira-int.h b/gcc/ira-int.h
index 659c1eeb2ab..5c6b355ecc8 100644
--- a/gcc/ira-int.h
+++ b/gcc/ira-int.h
@@ -98,6 +98,10 @@ struct ira_loop_tree_node
/* All the following members are defined only for nodes representing
loops. */
+ /* True if the loop was marked for removal from the register
+ allocation. */
+ bool to_remove_p;
+
/* Allocnos in the loop corresponding to their regnos. If it is
NULL the loop does not form a separate register allocation region
(e.g. because it has abnormal enter/exit edges and we can not put
diff --git a/gcc/ira.c b/gcc/ira.c
index d7f4e3d0dab..4b6854272f1 100644
--- a/gcc/ira.c
+++ b/gcc/ira.c
@@ -1725,7 +1725,6 @@ ira (FILE *f)
bool loops_p;
int max_regno_before_ira, ira_max_point_before_emit;
int rebuild_p;
- int saved_flag_ira_algorithm;
int saved_flag_ira_share_spill_slots;
basic_block bb;
@@ -1801,9 +1800,6 @@ ira (FILE *f)
ira_assert (current_loops == NULL);
flow_loops_find (&ira_loops);
current_loops = &ira_loops;
- saved_flag_ira_algorithm = flag_ira_algorithm;
- if (optimize && number_of_loops () > (unsigned) IRA_MAX_LOOPS_NUM)
- flag_ira_algorithm = IRA_ALGORITHM_CB;
if (internal_flag_ira_verbose > 0 && ira_dump_file != NULL)
fprintf (ira_dump_file, "Building IRA IR\n");
@@ -1935,8 +1931,6 @@ ira (FILE *f)
bb->loop_father = NULL;
current_loops = NULL;
- flag_ira_algorithm = saved_flag_ira_algorithm;
-
regstat_free_ri ();
regstat_free_n_sets_and_refs ();
diff --git a/gcc/params.def b/gcc/params.def
index 8d30a24a602..50a71339c7f 100644
--- a/gcc/params.def
+++ b/gcc/params.def
@@ -754,7 +754,7 @@ DEFPARAM (PARAM_DF_DOUBLE_QUEUE_THRESHOLD_FACTOR,
DEFPARAM (PARAM_IRA_MAX_LOOPS_NUM,
"ira-max-loops-num",
"max loops number for regional RA",
- 50, 0, 0)
+ 100, 0, 0)
/* Switch initialization conversion will refuse to create arrays that are
bigger than this parameter times the number of switch branches. */