diff options
author | Vladimir Makarov <vmakarov@redhat.com> | 2012-01-19 20:46:31 +0000 |
---|---|---|
committer | Vladimir Makarov <vmakarov@gcc.gnu.org> | 2012-01-19 20:46:31 +0000 |
commit | 2608d8414085d05d05fae8cba70ac22c8fe2c8d0 (patch) | |
tree | 0d29df176c3620279d71202389bdc2b5691fc410 /gcc/ira-build.c | |
parent | 8e19c582b18e18030c172cca406b5607114f80cc (diff) | |
download | gcc-2608d8414085d05d05fae8cba70ac22c8fe2c8d0.zip gcc-2608d8414085d05d05fae8cba70ac22c8fe2c8d0.tar.gz gcc-2608d8414085d05d05fae8cba70ac22c8fe2c8d0.tar.bz2 |
re PR rtl-optimization/40761 (IRA memory hog for insanely nested loops)
2012-01-19 Vladimir Makarov <vmakarov@redhat.com>
PR rtl-optimization/40761
* ira-int.h (struct ira_loop_tree_node): Add comment for member
loop. Add new member loop_num.
(IRA_LOOP_NODE_BY_INDEX): Modify the check.
(ira_build): Remove the parameter.
* ira.c (ira_print_disposition): Use loop_num instead of
loop->num.
(ira.c): Do not build CFG loops for one region allocation. Remove
argument from ira_build call.
* ira-build.c (init_loop_tree_node): New function.
(create_loop_tree_nodes): Use it. Separate the case when CFG
loops are not built.
(more_one_region_p): Check current_loops.
(finish_loop_tree_nodes): Separate the case when CFG loops are not
built.
(add_loop_to_tree): Process loop equal to NULL too.
(form_loop_tree): Separate the case when CFG loops are not built.
Use explicitly number for the root.
(rebuild_regno_allocno_maps, create_loop_tree_node_allocnos): Add
an assertion.
(ira_print_expanded_allocno, loop_compare_func): Use loop_num
instead of loop->num.
(mark_loops_for_removal): Ditto. Use loop_num instead of
loop->num.
(mark_all_loops_for_removal): Ditto.
(remove_unnecessary_regions): Separate the case when CFG loops
are not built.
(ira_build): Remove the parameter. Use explicit number of regions
when CFG loops are not built.
* ira-color.c (print_loop_title): Separate the case for the root
node. Use loop_num instead of loop->num.
(move_spill_restore): Use loop_num instead of loop->num.
* ira-emit.c (setup_entered_from_non_parent_p): Add an assertion.
(change_loop): Ditto.
(change_loop): Use loop_num instead of loop->num.
* ira-lives.c (process_bb_node_lives): Ditto.
* ira-costs.c (print_allocno_costs, find_costs_and_classes):
Ditto.
* ira-conflicts.c (print_allocno_conflicts): Ditto.
From-SVN: r183312
Diffstat (limited to 'gcc/ira-build.c')
-rw-r--r-- | gcc/ira-build.c | 162 |
1 files changed, 95 insertions, 67 deletions
diff --git a/gcc/ira-build.c b/gcc/ira-build.c index 2d8708a..78d0b36 100644 --- a/gcc/ira-build.c +++ b/gcc/ira-build.c @@ -93,15 +93,35 @@ int ira_copies_num; basic block. */ static int last_basic_block_before_change; -/* The following function allocates the loop tree nodes. If LOOPS_P - is FALSE, the nodes corresponding to the loops (except the root - which corresponds the all function) will be not allocated but nodes - will still be allocated for basic blocks. */ +/* Initialize some members in loop tree node NODE. Use LOOP_NUM for + the member loop_num. */ static void -create_loop_tree_nodes (bool loops_p) +init_loop_tree_node (struct ira_loop_tree_node *node, int loop_num) +{ + int max_regno = max_reg_num (); + + node->regno_allocno_map + = (ira_allocno_t *) ira_allocate (sizeof (ira_allocno_t) * max_regno); + memset (node->regno_allocno_map, 0, sizeof (ira_allocno_t) * max_regno); + memset (node->reg_pressure, 0, sizeof (node->reg_pressure)); + node->all_allocnos = ira_allocate_bitmap (); + node->modified_regnos = ira_allocate_bitmap (); + node->border_allocnos = ira_allocate_bitmap (); + node->local_copies = ira_allocate_bitmap (); + node->loop_num = loop_num; + node->children = NULL; + node->subloops = NULL; +} + + +/* The following function allocates the loop tree nodes. If + CURRENT_LOOPS is NULL, the nodes corresponding to the loops (except + the root which corresponds the all function) will be not allocated + but nodes will still be allocated for basic blocks. */ +static void +create_loop_tree_nodes (void) { unsigned int i, j; - int max_regno; bool skip_p; edge_iterator ei; edge e; @@ -122,17 +142,21 @@ create_loop_tree_nodes (bool loops_p) ira_bb_nodes[i].border_allocnos = NULL; ira_bb_nodes[i].local_copies = NULL; } + if (current_loops == NULL) + { + ira_loop_nodes = ((struct ira_loop_tree_node *) + ira_allocate (sizeof (struct ira_loop_tree_node))); + init_loop_tree_node (ira_loop_nodes, 0); + return; + } ira_loop_nodes = ((struct ira_loop_tree_node *) ira_allocate (sizeof (struct ira_loop_tree_node) * VEC_length (loop_p, ira_loops.larray))); - max_regno = max_reg_num (); FOR_EACH_VEC_ELT (loop_p, ira_loops.larray, i, loop) { if (loop != ira_loops.tree_root) { ira_loop_nodes[i].regno_allocno_map = NULL; - if (! loops_p) - continue; skip_p = false; FOR_EACH_EDGE (e, ei, loop->header->preds) if (e->src != loop->latch @@ -154,16 +178,7 @@ create_loop_tree_nodes (bool loops_p) if (skip_p) continue; } - ira_loop_nodes[i].regno_allocno_map - = (ira_allocno_t *) ira_allocate (sizeof (ira_allocno_t) * max_regno); - memset (ira_loop_nodes[i].regno_allocno_map, 0, - sizeof (ira_allocno_t) * max_regno); - memset (ira_loop_nodes[i].reg_pressure, 0, - sizeof (ira_loop_nodes[i].reg_pressure)); - ira_loop_nodes[i].all_allocnos = ira_allocate_bitmap (); - ira_loop_nodes[i].modified_regnos = ira_allocate_bitmap (); - ira_loop_nodes[i].border_allocnos = ira_allocate_bitmap (); - ira_loop_nodes[i].local_copies = ira_allocate_bitmap (); + init_loop_tree_node (&ira_loop_nodes[i], loop->num); } } @@ -175,10 +190,11 @@ more_one_region_p (void) unsigned int i; loop_p loop; - FOR_EACH_VEC_ELT (loop_p, ira_loops.larray, i, loop) - if (ira_loop_nodes[i].regno_allocno_map != NULL - && ira_loop_tree_root != &ira_loop_nodes[i]) - return true; + if (current_loops != NULL) + FOR_EACH_VEC_ELT (loop_p, ira_loops.larray, i, loop) + if (ira_loop_nodes[i].regno_allocno_map != NULL + && ira_loop_tree_root != &ira_loop_nodes[i]) + return true; return false; } @@ -205,8 +221,11 @@ finish_loop_tree_nodes (void) unsigned int i; loop_p loop; - FOR_EACH_VEC_ELT (loop_p, ira_loops.larray, i, loop) - finish_loop_tree_node (&ira_loop_nodes[i]); + if (current_loops == NULL) + finish_loop_tree_node (&ira_loop_nodes[0]); + else + FOR_EACH_VEC_ELT (loop_p, ira_loops.larray, i, loop) + finish_loop_tree_node (&ira_loop_nodes[i]); ira_free (ira_loop_nodes); for (i = 0; i < (unsigned int) last_basic_block_before_change; i++) { @@ -227,30 +246,39 @@ finish_loop_tree_nodes (void) /* The following recursive function adds LOOP to the loop tree - hierarchy. LOOP is added only once. */ + hierarchy. LOOP is added only once. If LOOP is NULL we adding + loop designating the whole function when CFG loops are not + built. */ static void add_loop_to_tree (struct loop *loop) { + int loop_num; struct loop *parent; ira_loop_tree_node_t loop_node, parent_node; /* We can not use loop node access macros here because of potential checking and because the nodes are not initialized enough yet. */ - if (loop_outer (loop) != NULL) + if (loop != NULL && loop_outer (loop) != NULL) add_loop_to_tree (loop_outer (loop)); - if (ira_loop_nodes[loop->num].regno_allocno_map != NULL - && ira_loop_nodes[loop->num].children == NULL) + loop_num = loop != NULL ? loop->num : 0; + if (ira_loop_nodes[loop_num].regno_allocno_map != NULL + && ira_loop_nodes[loop_num].children == NULL) { /* We have not added loop node to the tree yet. */ - loop_node = &ira_loop_nodes[loop->num]; + loop_node = &ira_loop_nodes[loop_num]; loop_node->loop = loop; loop_node->bb = NULL; - for (parent = loop_outer (loop); - parent != NULL; - parent = loop_outer (parent)) - if (ira_loop_nodes[parent->num].regno_allocno_map != NULL) - break; + if (loop == NULL) + parent = NULL; + else + { + for (parent = loop_outer (loop); + parent != NULL; + parent = loop_outer (parent)) + if (ira_loop_nodes[parent->num].regno_allocno_map != NULL) + break; + } if (parent == NULL) { loop_node->next = NULL; @@ -299,21 +327,13 @@ setup_loop_tree_level (ira_loop_tree_node_t loop_node, int level) static void form_loop_tree (void) { - unsigned int i; basic_block bb; struct loop *parent; ira_loop_tree_node_t bb_node, loop_node; - loop_p loop; /* We can not use loop/bb node access macros because of potential checking and because the nodes are not initialized enough yet. */ - FOR_EACH_VEC_ELT (loop_p, ira_loops.larray, i, loop) - if (ira_loop_nodes[i].regno_allocno_map != NULL) - { - ira_loop_nodes[i].children = NULL; - ira_loop_nodes[i].subloops = NULL; - } FOR_EACH_BB (bb) { bb_node = &ira_bb_nodes[bb->index]; @@ -323,18 +343,23 @@ form_loop_tree (void) bb_node->children = NULL; bb_node->subloop_next = NULL; bb_node->next = NULL; - for (parent = bb->loop_father; - parent != NULL; - parent = loop_outer (parent)) - if (ira_loop_nodes[parent->num].regno_allocno_map != NULL) - break; + if (current_loops == NULL) + parent = NULL; + else + { + for (parent = bb->loop_father; + parent != NULL; + parent = loop_outer (parent)) + if (ira_loop_nodes[parent->num].regno_allocno_map != NULL) + break; + } add_loop_to_tree (parent); - loop_node = &ira_loop_nodes[parent->num]; + loop_node = &ira_loop_nodes[parent == NULL ? 0 : parent->num]; bb_node->next = loop_node->children; bb_node->parent = loop_node; loop_node->children = bb_node; } - ira_loop_tree_root = IRA_LOOP_NODE_BY_INDEX (ira_loops.tree_root->num); + ira_loop_tree_root = IRA_LOOP_NODE_BY_INDEX (0); ira_loop_tree_height = setup_loop_tree_level (ira_loop_tree_root, 0); ira_assert (ira_loop_tree_root->regno_allocno_map != NULL); } @@ -353,6 +378,7 @@ rebuild_regno_allocno_maps (void) loop_p loop; ira_allocno_iterator ai; + ira_assert (current_loops != NULL); max_regno = max_reg_num (); FOR_EACH_VEC_ELT (loop_p, ira_loops.larray, l, loop) if (ira_loop_nodes[l].regno_allocno_map != NULL) @@ -837,7 +863,7 @@ ira_print_expanded_allocno (ira_allocno_t a) if ((bb = ALLOCNO_LOOP_TREE_NODE (a)->bb) != NULL) fprintf (ira_dump_file, ",b%d", bb->index); else - fprintf (ira_dump_file, ",l%d", ALLOCNO_LOOP_TREE_NODE (a)->loop->num); + fprintf (ira_dump_file, ",l%d", ALLOCNO_LOOP_TREE_NODE (a)->loop_num); if (ALLOCNO_CAP_MEMBER (a) != NULL) { fprintf (ira_dump_file, ":"); @@ -1621,6 +1647,7 @@ create_loop_tree_node_allocnos (ira_loop_tree_node_t loop_node) edge e; VEC (edge, heap) *edges; + ira_assert (current_loops != NULL); FOR_EACH_EDGE (e, ei, loop_node->loop->header->preds) if (e->src != loop_node->loop->latch) create_loop_allocnos (e); @@ -1848,7 +1875,7 @@ loop_compare_func (const void *v1p, const void *v2p) 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; + return l1->loop_num - l2->loop_num; } /* Mark loops which should be removed from regional allocation. We @@ -1870,6 +1897,7 @@ mark_loops_for_removal (void) ira_loop_tree_node_t *sorted_loops; loop_p loop; + ira_assert (current_loops != NULL); sorted_loops = (ira_loop_tree_node_t *) ira_allocate (sizeof (ira_loop_tree_node_t) * VEC_length (loop_p, @@ -1900,7 +1928,7 @@ mark_loops_for_removal (void) 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_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) @@ -1917,6 +1945,7 @@ mark_all_loops_for_removal (void) int i; loop_p loop; + ira_assert (current_loops != NULL); FOR_EACH_VEC_ELT (loop_p, ira_loops.larray, i, loop) if (ira_loop_nodes[i].regno_allocno_map != NULL) { @@ -1931,7 +1960,7 @@ mark_all_loops_for_removal (void) fprintf (ira_dump_file, " Mark loop %d (header %d, freq %d, depth %d) for removal\n", - ira_loop_nodes[i].loop->num, + ira_loop_nodes[i].loop_num, ira_loop_nodes[i].loop->header->index, ira_loop_nodes[i].loop->header->frequency, loop_depth (ira_loop_nodes[i].loop)); @@ -2221,6 +2250,8 @@ remove_low_level_allocnos (void) static void remove_unnecessary_regions (bool all_p) { + if (current_loops == NULL) + return; if (all_p) mark_all_loops_for_removal (); else @@ -3026,23 +3057,20 @@ update_conflict_hard_reg_costs (void) } /* Create a internal representation (IR) for IRA (allocnos, copies, - loop tree nodes). If LOOPS_P is FALSE the nodes corresponding to - the loops (except the root which corresponds the all function) and - correspondingly allocnos for the loops will be not created. Such - parameter value is used for Chaitin-Briggs coloring. The function - returns TRUE if we generate loop structure (besides nodes - representing all function and the basic blocks) for regional - allocation. A true return means that we really need to flatten IR - before the reload. */ + loop tree nodes). The function returns TRUE if we generate loop + structure (besides nodes representing all function and the basic + blocks) for regional allocation. A true return means that we + really need to flatten IR before the reload. */ bool -ira_build (bool loops_p) +ira_build (void) { - df_analyze (); + bool loops_p; + df_analyze (); initiate_cost_vectors (); initiate_allocnos (); initiate_copies (); - create_loop_tree_nodes (loops_p); + create_loop_tree_nodes (); form_loop_tree (); create_allocnos (); ira_costs (); @@ -3111,8 +3139,8 @@ ira_build (bool loops_p) } } fprintf (ira_dump_file, " regions=%d, blocks=%d, points=%d\n", - VEC_length (loop_p, ira_loops.larray), n_basic_blocks, - ira_max_point); + current_loops == NULL ? 1 : VEC_length (loop_p, ira_loops.larray), + n_basic_blocks, ira_max_point); fprintf (ira_dump_file, " allocnos=%d (big %d), copies=%d, conflicts=%d, ranges=%d\n", ira_allocnos_num, nr_big, ira_copies_num, n, nr); |