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
......
...@@ -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,
"\n Loop 0 (parent -1, header bb%d, depth 0)\n bbs:",
NUM_FIXED_BLOCKS);
else
{
ira_assert (current_loops != NULL && loop_tree_node->loop != NULL);
fprintf (ira_dump_file, fprintf (ira_dump_file,
"\n Loop %d (parent %d, header bb%d, depth %d)\n bbs:", "\n Loop %d (parent %d, header bb%d, depth %d)\n bbs:",
loop_tree_node->loop->num, loop_tree_node->loop_num, loop_tree_node->parent->loop_num,
(loop_tree_node->parent == NULL
? -1 : loop_tree_node->parent->loop->num),
loop_tree_node->loop->header->index, loop_tree_node->loop->header->index,
loop_depth (loop_tree_node->loop)); 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,6 +566,7 @@ change_loop (ira_loop_tree_node_t node) ...@@ -565,6 +566,7 @@ 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)
{ {
...@@ -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;
...@@ -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);
if (flag_ira_region == IRA_REGION_ALL || flag_ira_region == IRA_REGION_MIXED)
{
flow_loops_find (&ira_loops); flow_loops_find (&ira_loops);
record_loop_exits (); record_loop_exits ();
current_loops = &ira_loops; 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;
if (current_loops != NULL)
{
flow_loops_free (&ira_loops); flow_loops_free (&ira_loops);
free_dominance_info (CDI_DOMINATORS); 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