Commit 2608d841 by Vladimir Makarov Committed by Vladimir Makarov

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
parent 8e19c582
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.
2012-01-19 Jakub Jelinek <jakub@redhat.com> 2012-01-19 Jakub Jelinek <jakub@redhat.com>
PR libmudflap/40778 PR libmudflap/40778
......
...@@ -93,15 +93,35 @@ int ira_copies_num; ...@@ -93,15 +93,35 @@ int ira_copies_num;
basic block. */ basic block. */
static int last_basic_block_before_change; static int last_basic_block_before_change;
/* The following function allocates the loop tree nodes. If LOOPS_P /* Initialize some members in loop tree node NODE. Use LOOP_NUM for
is FALSE, the nodes corresponding to the loops (except the root the member loop_num. */
which corresponds the all function) will be not allocated but nodes
will still be allocated for basic blocks. */
static void 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; unsigned int i, j;
int max_regno;
bool skip_p; bool skip_p;
edge_iterator ei; edge_iterator ei;
edge e; edge e;
...@@ -122,17 +142,21 @@ create_loop_tree_nodes (bool loops_p) ...@@ -122,17 +142,21 @@ create_loop_tree_nodes (bool loops_p)
ira_bb_nodes[i].border_allocnos = NULL; ira_bb_nodes[i].border_allocnos = NULL;
ira_bb_nodes[i].local_copies = 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_loop_nodes = ((struct ira_loop_tree_node *)
ira_allocate (sizeof (struct ira_loop_tree_node) ira_allocate (sizeof (struct ira_loop_tree_node)
* VEC_length (loop_p, ira_loops.larray))); * VEC_length (loop_p, ira_loops.larray)));
max_regno = max_reg_num ();
FOR_EACH_VEC_ELT (loop_p, ira_loops.larray, i, loop) FOR_EACH_VEC_ELT (loop_p, ira_loops.larray, i, loop)
{ {
if (loop != ira_loops.tree_root) if (loop != ira_loops.tree_root)
{ {
ira_loop_nodes[i].regno_allocno_map = NULL; ira_loop_nodes[i].regno_allocno_map = NULL;
if (! loops_p)
continue;
skip_p = false; skip_p = false;
FOR_EACH_EDGE (e, ei, loop->header->preds) FOR_EACH_EDGE (e, ei, loop->header->preds)
if (e->src != loop->latch if (e->src != loop->latch
...@@ -154,16 +178,7 @@ create_loop_tree_nodes (bool loops_p) ...@@ -154,16 +178,7 @@ create_loop_tree_nodes (bool loops_p)
if (skip_p) if (skip_p)
continue; continue;
} }
ira_loop_nodes[i].regno_allocno_map init_loop_tree_node (&ira_loop_nodes[i], loop->num);
= (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 ();
} }
} }
...@@ -175,10 +190,11 @@ more_one_region_p (void) ...@@ -175,10 +190,11 @@ more_one_region_p (void)
unsigned int i; unsigned int i;
loop_p loop; loop_p loop;
FOR_EACH_VEC_ELT (loop_p, ira_loops.larray, i, loop) if (current_loops != NULL)
if (ira_loop_nodes[i].regno_allocno_map != NULL FOR_EACH_VEC_ELT (loop_p, ira_loops.larray, i, loop)
&& ira_loop_tree_root != &ira_loop_nodes[i]) if (ira_loop_nodes[i].regno_allocno_map != NULL
return true; && ira_loop_tree_root != &ira_loop_nodes[i])
return true;
return false; return false;
} }
...@@ -205,8 +221,11 @@ finish_loop_tree_nodes (void) ...@@ -205,8 +221,11 @@ finish_loop_tree_nodes (void)
unsigned int i; unsigned int i;
loop_p loop; loop_p loop;
FOR_EACH_VEC_ELT (loop_p, ira_loops.larray, i, loop) if (current_loops == NULL)
finish_loop_tree_node (&ira_loop_nodes[i]); 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); ira_free (ira_loop_nodes);
for (i = 0; i < (unsigned int) last_basic_block_before_change; i++) for (i = 0; i < (unsigned int) last_basic_block_before_change; i++)
{ {
...@@ -227,30 +246,39 @@ finish_loop_tree_nodes (void) ...@@ -227,30 +246,39 @@ finish_loop_tree_nodes (void)
/* The following recursive function adds LOOP to the loop tree /* 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 static void
add_loop_to_tree (struct loop *loop) add_loop_to_tree (struct loop *loop)
{ {
int loop_num;
struct loop *parent; struct loop *parent;
ira_loop_tree_node_t loop_node, parent_node; ira_loop_tree_node_t loop_node, parent_node;
/* We can not use loop node access macros here because of potential /* We can not use loop node access macros here because of potential
checking and because the nodes are not initialized enough checking and because the nodes are not initialized enough
yet. */ yet. */
if (loop_outer (loop) != NULL) if (loop != NULL && loop_outer (loop) != NULL)
add_loop_to_tree (loop_outer (loop)); add_loop_to_tree (loop_outer (loop));
if (ira_loop_nodes[loop->num].regno_allocno_map != NULL loop_num = loop != NULL ? loop->num : 0;
&& ira_loop_nodes[loop->num].children == NULL) 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. */ /* 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->loop = loop;
loop_node->bb = NULL; loop_node->bb = NULL;
for (parent = loop_outer (loop); if (loop == NULL)
parent != NULL; parent = NULL;
parent = loop_outer (parent)) else
if (ira_loop_nodes[parent->num].regno_allocno_map != NULL) {
break; 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) if (parent == NULL)
{ {
loop_node->next = NULL; loop_node->next = NULL;
...@@ -299,21 +327,13 @@ setup_loop_tree_level (ira_loop_tree_node_t loop_node, int level) ...@@ -299,21 +327,13 @@ setup_loop_tree_level (ira_loop_tree_node_t loop_node, int level)
static void static void
form_loop_tree (void) form_loop_tree (void)
{ {
unsigned int i;
basic_block bb; basic_block bb;
struct loop *parent; struct loop *parent;
ira_loop_tree_node_t bb_node, loop_node; ira_loop_tree_node_t bb_node, loop_node;
loop_p loop;
/* We can not use loop/bb node access macros because of potential /* We can not use loop/bb node access macros because of potential
checking and because the nodes are not initialized enough checking and because the nodes are not initialized enough
yet. */ 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) FOR_EACH_BB (bb)
{ {
bb_node = &ira_bb_nodes[bb->index]; bb_node = &ira_bb_nodes[bb->index];
...@@ -323,18 +343,23 @@ form_loop_tree (void) ...@@ -323,18 +343,23 @@ form_loop_tree (void)
bb_node->children = NULL; bb_node->children = NULL;
bb_node->subloop_next = NULL; bb_node->subloop_next = NULL;
bb_node->next = NULL; bb_node->next = NULL;
for (parent = bb->loop_father; if (current_loops == NULL)
parent != NULL; parent = NULL;
parent = loop_outer (parent)) else
if (ira_loop_nodes[parent->num].regno_allocno_map != NULL) {
break; 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); 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->next = loop_node->children;
bb_node->parent = loop_node; bb_node->parent = loop_node;
loop_node->children = bb_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_loop_tree_height = setup_loop_tree_level (ira_loop_tree_root, 0);
ira_assert (ira_loop_tree_root->regno_allocno_map != NULL); ira_assert (ira_loop_tree_root->regno_allocno_map != NULL);
} }
...@@ -353,6 +378,7 @@ rebuild_regno_allocno_maps (void) ...@@ -353,6 +378,7 @@ rebuild_regno_allocno_maps (void)
loop_p loop; loop_p loop;
ira_allocno_iterator ai; ira_allocno_iterator ai;
ira_assert (current_loops != NULL);
max_regno = max_reg_num (); max_regno = max_reg_num ();
FOR_EACH_VEC_ELT (loop_p, ira_loops.larray, l, loop) FOR_EACH_VEC_ELT (loop_p, ira_loops.larray, l, loop)
if (ira_loop_nodes[l].regno_allocno_map != NULL) if (ira_loop_nodes[l].regno_allocno_map != NULL)
...@@ -837,7 +863,7 @@ ira_print_expanded_allocno (ira_allocno_t a) ...@@ -837,7 +863,7 @@ ira_print_expanded_allocno (ira_allocno_t a)
if ((bb = ALLOCNO_LOOP_TREE_NODE (a)->bb) != NULL) if ((bb = ALLOCNO_LOOP_TREE_NODE (a)->bb) != NULL)
fprintf (ira_dump_file, ",b%d", bb->index); fprintf (ira_dump_file, ",b%d", bb->index);
else 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) if (ALLOCNO_CAP_MEMBER (a) != NULL)
{ {
fprintf (ira_dump_file, ":"); fprintf (ira_dump_file, ":");
...@@ -1621,6 +1647,7 @@ create_loop_tree_node_allocnos (ira_loop_tree_node_t loop_node) ...@@ -1621,6 +1647,7 @@ create_loop_tree_node_allocnos (ira_loop_tree_node_t loop_node)
edge e; edge e;
VEC (edge, heap) *edges; VEC (edge, heap) *edges;
ira_assert (current_loops != NULL);
FOR_EACH_EDGE (e, ei, loop_node->loop->header->preds) FOR_EACH_EDGE (e, ei, loop_node->loop->header->preds)
if (e->src != loop_node->loop->latch) if (e->src != loop_node->loop->latch)
create_loop_allocnos (e); create_loop_allocnos (e);
...@@ -1848,7 +1875,7 @@ loop_compare_func (const void *v1p, const void *v2p) ...@@ -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) if ((diff = (int) loop_depth (l1->loop) - (int) loop_depth (l2->loop)) != 0)
return diff; return diff;
/* Make sorting stable. */ /* 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 /* Mark loops which should be removed from regional allocation. We
...@@ -1870,6 +1897,7 @@ mark_loops_for_removal (void) ...@@ -1870,6 +1897,7 @@ mark_loops_for_removal (void)
ira_loop_tree_node_t *sorted_loops; ira_loop_tree_node_t *sorted_loops;
loop_p loop; loop_p loop;
ira_assert (current_loops != NULL);
sorted_loops sorted_loops
= (ira_loop_tree_node_t *) ira_allocate (sizeof (ira_loop_tree_node_t) = (ira_loop_tree_node_t *) ira_allocate (sizeof (ira_loop_tree_node_t)
* VEC_length (loop_p, * VEC_length (loop_p,
...@@ -1900,7 +1928,7 @@ mark_loops_for_removal (void) ...@@ -1900,7 +1928,7 @@ mark_loops_for_removal (void)
fprintf fprintf
(ira_dump_file, (ira_dump_file,
" Mark loop %d (header %d, freq %d, depth %d) for removal (%s)\n", " 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, sorted_loops[i]->loop->header->frequency,
loop_depth (sorted_loops[i]->loop), loop_depth (sorted_loops[i]->loop),
low_pressure_loop_node_p (sorted_loops[i]->parent) low_pressure_loop_node_p (sorted_loops[i]->parent)
...@@ -1917,6 +1945,7 @@ mark_all_loops_for_removal (void) ...@@ -1917,6 +1945,7 @@ mark_all_loops_for_removal (void)
int i; int i;
loop_p loop; loop_p loop;
ira_assert (current_loops != NULL);
FOR_EACH_VEC_ELT (loop_p, ira_loops.larray, i, loop) FOR_EACH_VEC_ELT (loop_p, ira_loops.larray, i, loop)
if (ira_loop_nodes[i].regno_allocno_map != NULL) if (ira_loop_nodes[i].regno_allocno_map != NULL)
{ {
...@@ -1931,7 +1960,7 @@ mark_all_loops_for_removal (void) ...@@ -1931,7 +1960,7 @@ mark_all_loops_for_removal (void)
fprintf fprintf
(ira_dump_file, (ira_dump_file,
" Mark loop %d (header %d, freq %d, depth %d) for removal\n", " 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->index,
ira_loop_nodes[i].loop->header->frequency, ira_loop_nodes[i].loop->header->frequency,
loop_depth (ira_loop_nodes[i].loop)); loop_depth (ira_loop_nodes[i].loop));
...@@ -2221,6 +2250,8 @@ remove_low_level_allocnos (void) ...@@ -2221,6 +2250,8 @@ remove_low_level_allocnos (void)
static void static void
remove_unnecessary_regions (bool all_p) remove_unnecessary_regions (bool all_p)
{ {
if (current_loops == NULL)
return;
if (all_p) if (all_p)
mark_all_loops_for_removal (); mark_all_loops_for_removal ();
else else
...@@ -3026,23 +3057,20 @@ update_conflict_hard_reg_costs (void) ...@@ -3026,23 +3057,20 @@ update_conflict_hard_reg_costs (void)
} }
/* Create a internal representation (IR) for IRA (allocnos, copies, /* Create a internal representation (IR) for IRA (allocnos, copies,
loop tree nodes). If LOOPS_P is FALSE the nodes corresponding to loop tree nodes). The function returns TRUE if we generate loop
the loops (except the root which corresponds the all function) and structure (besides nodes representing all function and the basic
correspondingly allocnos for the loops will be not created. Such blocks) for regional allocation. A true return means that we
parameter value is used for Chaitin-Briggs coloring. The function really need to flatten IR before the reload. */
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 bool
ira_build (bool loops_p) ira_build (void)
{ {
df_analyze (); bool loops_p;
df_analyze ();
initiate_cost_vectors (); initiate_cost_vectors ();
initiate_allocnos (); initiate_allocnos ();
initiate_copies (); initiate_copies ();
create_loop_tree_nodes (loops_p); create_loop_tree_nodes ();
form_loop_tree (); form_loop_tree ();
create_allocnos (); create_allocnos ();
ira_costs (); ira_costs ();
...@@ -3111,8 +3139,8 @@ ira_build (bool loops_p) ...@@ -3111,8 +3139,8 @@ ira_build (bool loops_p)
} }
} }
fprintf (ira_dump_file, " regions=%d, blocks=%d, points=%d\n", fprintf (ira_dump_file, " regions=%d, blocks=%d, points=%d\n",
VEC_length (loop_p, ira_loops.larray), n_basic_blocks, current_loops == NULL ? 1 : VEC_length (loop_p, ira_loops.larray),
ira_max_point); n_basic_blocks, ira_max_point);
fprintf (ira_dump_file, fprintf (ira_dump_file,
" allocnos=%d (big %d), copies=%d, conflicts=%d, ranges=%d\n", " allocnos=%d (big %d), copies=%d, conflicts=%d, ranges=%d\n",
ira_allocnos_num, nr_big, ira_copies_num, n, nr); ira_allocnos_num, nr_big, ira_copies_num, n, nr);
......
...@@ -1670,7 +1670,6 @@ assign_hard_reg (ira_allocno_t a, bool retry_p) ...@@ -1670,7 +1670,6 @@ assign_hard_reg (ira_allocno_t a, bool retry_p)
update_conflict_hard_regno_costs (full_costs, aclass, false); update_conflict_hard_regno_costs (full_costs, aclass, false);
} }
min_cost = min_full_cost = INT_MAX; min_cost = min_full_cost = INT_MAX;
/* We don't care about giving callee saved registers to allocnos no /* We don't care about giving callee saved registers to allocnos no
living through calls because call clobbered registers are living through calls because call clobbered registers are
allocated first (it is usual practice to put them first in allocated first (it is usual practice to put them first in
...@@ -2011,7 +2010,7 @@ ira_loop_edge_freq (ira_loop_tree_node_t loop_node, int regno, bool exit_p) ...@@ -2011,7 +2010,7 @@ ira_loop_edge_freq (ira_loop_tree_node_t loop_node, int regno, bool exit_p)
edge e; edge e;
VEC (edge, heap) *edges; VEC (edge, heap) *edges;
ira_assert (loop_node->loop != NULL ira_assert (current_loops != NULL && loop_node->loop != NULL
&& (regno < 0 || regno >= FIRST_PSEUDO_REGISTER)); && (regno < 0 || regno >= FIRST_PSEUDO_REGISTER));
freq = 0; freq = 0;
if (! exit_p) if (! exit_p)
...@@ -2662,14 +2661,19 @@ print_loop_title (ira_loop_tree_node_t loop_tree_node) ...@@ -2662,14 +2661,19 @@ print_loop_title (ira_loop_tree_node_t loop_tree_node)
edge e; edge e;
edge_iterator ei; edge_iterator ei;
ira_assert (loop_tree_node->loop != NULL); if (loop_tree_node->parent == NULL)
fprintf (ira_dump_file, fprintf (ira_dump_file,
"\n Loop %d (parent %d, header bb%d, depth %d)\n bbs:", "\n Loop 0 (parent -1, header bb%d, depth 0)\n bbs:",
loop_tree_node->loop->num, NUM_FIXED_BLOCKS);
(loop_tree_node->parent == NULL else
? -1 : loop_tree_node->parent->loop->num), {
loop_tree_node->loop->header->index, ira_assert (current_loops != NULL && loop_tree_node->loop != NULL);
loop_depth (loop_tree_node->loop)); fprintf (ira_dump_file,
"\n Loop %d (parent %d, header bb%d, depth %d)\n bbs:",
loop_tree_node->loop_num, loop_tree_node->parent->loop_num,
loop_tree_node->loop->header->index,
loop_depth (loop_tree_node->loop));
}
for (subloop_node = loop_tree_node->children; for (subloop_node = loop_tree_node->children;
subloop_node != NULL; subloop_node != NULL;
subloop_node = subloop_node->next) subloop_node = subloop_node->next)
...@@ -2681,7 +2685,7 @@ print_loop_title (ira_loop_tree_node_t loop_tree_node) ...@@ -2681,7 +2685,7 @@ print_loop_title (ira_loop_tree_node_t loop_tree_node)
&& ((dest_loop_node = IRA_BB_NODE (e->dest)->parent) && ((dest_loop_node = IRA_BB_NODE (e->dest)->parent)
!= loop_tree_node)) != loop_tree_node))
fprintf (ira_dump_file, "(->%d:l%d)", fprintf (ira_dump_file, "(->%d:l%d)",
e->dest->index, dest_loop_node->loop->num); e->dest->index, dest_loop_node->loop_num);
} }
fprintf (ira_dump_file, "\n all:"); fprintf (ira_dump_file, "\n all:");
EXECUTE_IF_SET_IN_BITMAP (loop_tree_node->all_allocnos, 0, j, bi) EXECUTE_IF_SET_IN_BITMAP (loop_tree_node->all_allocnos, 0, j, bi)
...@@ -3011,7 +3015,7 @@ move_spill_restore (void) ...@@ -3011,7 +3015,7 @@ move_spill_restore (void)
fprintf fprintf
(ira_dump_file, (ira_dump_file,
" Moving spill/restore for a%dr%d up from loop %d", " Moving spill/restore for a%dr%d up from loop %d",
ALLOCNO_NUM (a), regno, loop_node->loop->num); ALLOCNO_NUM (a), regno, loop_node->loop_num);
fprintf (ira_dump_file, " - profit %d\n", -cost); fprintf (ira_dump_file, " - profit %d\n", -cost);
} }
changed_p = true; changed_p = true;
......
...@@ -419,6 +419,7 @@ process_regs_for_copy (rtx reg1, rtx reg2, bool constraint_p, ...@@ -419,6 +419,7 @@ process_regs_for_copy (rtx reg1, rtx reg2, bool constraint_p,
{ {
ira_allocno_t a1 = ira_curr_regno_allocno_map[REGNO (reg1)]; ira_allocno_t a1 = ira_curr_regno_allocno_map[REGNO (reg1)];
ira_allocno_t a2 = ira_curr_regno_allocno_map[REGNO (reg2)]; ira_allocno_t a2 = ira_curr_regno_allocno_map[REGNO (reg2)];
if (!allocnos_conflict_for_copy_p (a1, a2) && offset1 == offset2) if (!allocnos_conflict_for_copy_p (a1, a2) && offset1 == offset2)
{ {
cp = ira_add_allocno_copy (a1, a2, freq, constraint_p, insn, cp = ira_add_allocno_copy (a1, a2, freq, constraint_p, insn,
...@@ -765,7 +766,7 @@ print_allocno_conflicts (FILE * file, bool reg_p, ira_allocno_t a) ...@@ -765,7 +766,7 @@ print_allocno_conflicts (FILE * file, bool reg_p, ira_allocno_t a)
if ((bb = ALLOCNO_LOOP_TREE_NODE (a)->bb) != NULL) if ((bb = ALLOCNO_LOOP_TREE_NODE (a)->bb) != NULL)
fprintf (file, "b%d", bb->index); fprintf (file, "b%d", bb->index);
else else
fprintf (file, "l%d", ALLOCNO_LOOP_TREE_NODE (a)->loop->num); fprintf (file, "l%d", ALLOCNO_LOOP_TREE_NODE (a)->loop_num);
putc (')', file); putc (')', file);
} }
...@@ -796,7 +797,7 @@ print_allocno_conflicts (FILE * file, bool reg_p, ira_allocno_t a) ...@@ -796,7 +797,7 @@ print_allocno_conflicts (FILE * file, bool reg_p, ira_allocno_t a)
fprintf (file, ",b%d", bb->index); fprintf (file, ",b%d", bb->index);
else else
fprintf (file, ",l%d", fprintf (file, ",l%d",
ALLOCNO_LOOP_TREE_NODE (conflict_a)->loop->num); ALLOCNO_LOOP_TREE_NODE (conflict_a)->loop_num);
putc (')', file); putc (')', file);
} }
} }
......
...@@ -1391,7 +1391,7 @@ print_allocno_costs (FILE *f) ...@@ -1391,7 +1391,7 @@ print_allocno_costs (FILE *f)
if ((bb = ALLOCNO_LOOP_TREE_NODE (a)->bb) != NULL) if ((bb = ALLOCNO_LOOP_TREE_NODE (a)->bb) != NULL)
fprintf (f, "b%d", bb->index); fprintf (f, "b%d", bb->index);
else else
fprintf (f, "l%d", ALLOCNO_LOOP_TREE_NODE (a)->loop->num); fprintf (f, "l%d", ALLOCNO_LOOP_TREE_NODE (a)->loop_num);
fprintf (f, ") costs:"); fprintf (f, ") costs:");
for (k = 0; k < cost_classes_ptr->num; k++) for (k = 0; k < cost_classes_ptr->num; k++)
{ {
...@@ -1789,7 +1789,7 @@ find_costs_and_classes (FILE *dump_file) ...@@ -1789,7 +1789,7 @@ find_costs_and_classes (FILE *dump_file)
fprintf (dump_file, "b%d", bb->index); fprintf (dump_file, "b%d", bb->index);
else else
fprintf (dump_file, "l%d", fprintf (dump_file, "l%d",
ALLOCNO_LOOP_TREE_NODE (a)->loop->num); ALLOCNO_LOOP_TREE_NODE (a)->loop_num);
fprintf (dump_file, ") best %s, allocno %s\n", fprintf (dump_file, ") best %s, allocno %s\n",
reg_class_names[best], reg_class_names[best],
reg_class_names[regno_aclass[i]]); reg_class_names[regno_aclass[i]]);
......
...@@ -438,6 +438,7 @@ setup_entered_from_non_parent_p (void) ...@@ -438,6 +438,7 @@ setup_entered_from_non_parent_p (void)
unsigned int i; unsigned int i;
loop_p loop; loop_p loop;
ira_assert (current_loops != NULL);
FOR_EACH_VEC_ELT (loop_p, ira_loops.larray, i, loop) FOR_EACH_VEC_ELT (loop_p, ira_loops.larray, i, loop)
if (ira_loop_nodes[i].regno_allocno_map != NULL) if (ira_loop_nodes[i].regno_allocno_map != NULL)
ira_loop_nodes[i].entered_from_non_parent_p ira_loop_nodes[i].entered_from_non_parent_p
...@@ -565,7 +566,8 @@ change_loop (ira_loop_tree_node_t node) ...@@ -565,7 +566,8 @@ change_loop (ira_loop_tree_node_t node)
if (node != ira_loop_tree_root) if (node != ira_loop_tree_root)
{ {
ira_assert (current_loops != NULL);
if (node->bb != NULL) if (node->bb != NULL)
{ {
FOR_BB_INSNS (node->bb, insn) FOR_BB_INSNS (node->bb, insn)
...@@ -580,7 +582,7 @@ change_loop (ira_loop_tree_node_t node) ...@@ -580,7 +582,7 @@ change_loop (ira_loop_tree_node_t node)
if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL) if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
fprintf (ira_dump_file, fprintf (ira_dump_file,
" Changing RTL for loop %d (header bb%d)\n", " Changing RTL for loop %d (header bb%d)\n",
node->loop->num, node->loop->header->index); node->loop_num, node->loop->header->index);
parent = ira_curr_loop_tree_node->parent; parent = ira_curr_loop_tree_node->parent;
map = parent->regno_allocno_map; map = parent->regno_allocno_map;
......
...@@ -87,7 +87,8 @@ struct ira_loop_tree_node ...@@ -87,7 +87,8 @@ struct ira_loop_tree_node
{ {
/* The node represents basic block if children == NULL. */ /* The node represents basic block if children == NULL. */
basic_block bb; /* NULL for loop. */ basic_block bb; /* NULL for loop. */
struct loop *loop; /* NULL for BB. */ /* NULL for BB or for loop tree root if we did not build CFG loop tree. */
struct loop *loop;
/* NEXT/SUBLOOP_NEXT is the next node/loop-node of the same parent. /* NEXT/SUBLOOP_NEXT is the next node/loop-node of the same parent.
SUBLOOP_NEXT is always NULL for BBs. */ SUBLOOP_NEXT is always NULL for BBs. */
ira_loop_tree_node_t subloop_next, next; ira_loop_tree_node_t subloop_next, next;
...@@ -103,6 +104,9 @@ struct ira_loop_tree_node ...@@ -103,6 +104,9 @@ struct ira_loop_tree_node
/* All the following members are defined only for nodes representing /* All the following members are defined only for nodes representing
loops. */ loops. */
/* The loop number from CFG loop tree. The root number is 0. */
int loop_num;
/* True if the loop was marked for removal from the register /* True if the loop was marked for removal from the register
allocation. */ allocation. */
bool to_remove_p; bool to_remove_p;
...@@ -154,7 +158,7 @@ extern ira_loop_tree_node_t ira_bb_nodes; ...@@ -154,7 +158,7 @@ extern ira_loop_tree_node_t ira_bb_nodes;
/* Two access macros to the nodes representing basic blocks. */ /* Two access macros to the nodes representing basic blocks. */
#if defined ENABLE_IRA_CHECKING && (GCC_VERSION >= 2007) #if defined ENABLE_IRA_CHECKING && (GCC_VERSION >= 2007)
#define IRA_BB_NODE_BY_INDEX(index) __extension__ \ #define IRA_BB_NODE_BY_INDEX(index) __extension__ \
(({ ira_loop_tree_node_t _node = (&ira_bb_nodes[index]); \ (({ ira_loop_tree_node_t _node = (&ira_bb_nodes[index]); \
if (_node->children != NULL || _node->loop != NULL || _node->bb == NULL)\ if (_node->children != NULL || _node->loop != NULL || _node->bb == NULL)\
{ \ { \
fprintf (stderr, \ fprintf (stderr, \
...@@ -176,8 +180,9 @@ extern ira_loop_tree_node_t ira_loop_nodes; ...@@ -176,8 +180,9 @@ extern ira_loop_tree_node_t ira_loop_nodes;
/* Two access macros to the nodes representing loops. */ /* Two access macros to the nodes representing loops. */
#if defined ENABLE_IRA_CHECKING && (GCC_VERSION >= 2007) #if defined ENABLE_IRA_CHECKING && (GCC_VERSION >= 2007)
#define IRA_LOOP_NODE_BY_INDEX(index) __extension__ \ #define IRA_LOOP_NODE_BY_INDEX(index) __extension__ \
(({ ira_loop_tree_node_t const _node = (&ira_loop_nodes[index]);\ (({ ira_loop_tree_node_t const _node = (&ira_loop_nodes[index]); \
if (_node->children == NULL || _node->bb != NULL || _node->loop == NULL)\ if (_node->children == NULL || _node->bb != NULL \
|| (_node->loop == NULL && current_loops != NULL)) \
{ \ { \
fprintf (stderr, \ fprintf (stderr, \
"\n%s: %d: error in %s: it is not a loop node\n", \ "\n%s: %d: error in %s: it is not a loop node\n", \
...@@ -989,7 +994,7 @@ extern int *ira_allocate_cost_vector (reg_class_t); ...@@ -989,7 +994,7 @@ extern int *ira_allocate_cost_vector (reg_class_t);
extern void ira_free_cost_vector (int *, reg_class_t); extern void ira_free_cost_vector (int *, reg_class_t);
extern void ira_flattening (int, int); extern void ira_flattening (int, int);
extern bool ira_build (bool); extern bool ira_build (void);
extern void ira_destroy (void); extern void ira_destroy (void);
/* ira-costs.c */ /* ira-costs.c */
......
...@@ -1123,7 +1123,7 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node) ...@@ -1123,7 +1123,7 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node)
if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL) if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
fprintf (ira_dump_file, " Insn %u(l%d): point = %d\n", fprintf (ira_dump_file, " Insn %u(l%d): point = %d\n",
INSN_UID (insn), loop_tree_node->parent->loop->num, INSN_UID (insn), loop_tree_node->parent->loop_num,
curr_point); curr_point);
/* Mark each defined value as live. We need to do this for /* Mark each defined value as live. We need to do this for
......
...@@ -718,7 +718,7 @@ ira_print_disposition (FILE *f) ...@@ -718,7 +718,7 @@ ira_print_disposition (FILE *f)
if ((bb = ALLOCNO_LOOP_TREE_NODE (a)->bb) != NULL) if ((bb = ALLOCNO_LOOP_TREE_NODE (a)->bb) != NULL)
fprintf (f, "b%-3d", bb->index); fprintf (f, "b%-3d", bb->index);
else else
fprintf (f, "l%-3d", ALLOCNO_LOOP_TREE_NODE (a)->loop->num); fprintf (f, "l%-3d", ALLOCNO_LOOP_TREE_NODE (a)->loop_num);
if (ALLOCNO_HARD_REGNO (a) >= 0) if (ALLOCNO_HARD_REGNO (a) >= 0)
fprintf (f, " %3d", ALLOCNO_HARD_REGNO (a)); fprintf (f, " %3d", ALLOCNO_HARD_REGNO (a));
else else
...@@ -3614,14 +3614,16 @@ ira (FILE *f) ...@@ -3614,14 +3614,16 @@ ira (FILE *f)
ira_move_loops_num = ira_additional_jumps_num = 0; ira_move_loops_num = ira_additional_jumps_num = 0;
ira_assert (current_loops == NULL); ira_assert (current_loops == NULL);
flow_loops_find (&ira_loops); if (flag_ira_region == IRA_REGION_ALL || flag_ira_region == IRA_REGION_MIXED)
record_loop_exits (); {
current_loops = &ira_loops; flow_loops_find (&ira_loops);
record_loop_exits ();
current_loops = &ira_loops;
}
if (internal_flag_ira_verbose > 0 && ira_dump_file != NULL) if (internal_flag_ira_verbose > 0 && ira_dump_file != NULL)
fprintf (ira_dump_file, "Building IRA IR\n"); fprintf (ira_dump_file, "Building IRA IR\n");
loops_p = ira_build (flag_ira_region == IRA_REGION_ALL loops_p = ira_build ();
|| flag_ira_region == IRA_REGION_MIXED);
ira_assert (ira_conflicts_p || !loops_p); ira_assert (ira_conflicts_p || !loops_p);
...@@ -3745,8 +3747,11 @@ do_reload (void) ...@@ -3745,8 +3747,11 @@ do_reload (void)
flag_ira_share_spill_slots = saved_flag_ira_share_spill_slots; flag_ira_share_spill_slots = saved_flag_ira_share_spill_slots;
flow_loops_free (&ira_loops); if (current_loops != NULL)
free_dominance_info (CDI_DOMINATORS); {
flow_loops_free (&ira_loops);
free_dominance_info (CDI_DOMINATORS);
}
FOR_ALL_BB (bb) FOR_ALL_BB (bb)
bb->loop_father = NULL; bb->loop_father = NULL;
current_loops = NULL; current_loops = NULL;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment