diff options
author | vmakarov <vmakarov@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-11-25 22:52:37 +0000 |
---|---|---|
committer | vmakarov <vmakarov@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-11-25 22:52:37 +0000 |
commit | ddf888a5b9a8c27f3c66bb4c7008b03c1c2fc571 (patch) | |
tree | 570532edd558acfd1cd74a139d8cf1f249d28173 /gcc/ira-build.c | |
parent | f081d7b0810f26c779fd8123e42eded6839bdba5 (diff) | |
download | gcc-ddf888a5b9a8c27f3c66bb4c7008b03c1c2fc571.tar.gz |
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@142207 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ira-build.c')
-rw-r--r-- | gcc/ira-build.c | 90 |
1 files changed, 76 insertions, 14 deletions
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)); |