aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorVladimir Makarov <vmakarov@redhat.com>2012-01-19 20:46:31 +0000
committerVladimir Makarov <vmakarov@gcc.gnu.org>2012-01-19 20:46:31 +0000
commit2608d8414085d05d05fae8cba70ac22c8fe2c8d0 (patch)
tree0d29df176c3620279d71202389bdc2b5691fc410 /gcc
parent8e19c582b18e18030c172cca406b5607114f80cc (diff)
downloadgcc-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')
-rw-r--r--gcc/ChangeLog49
-rw-r--r--gcc/ira-build.c162
-rw-r--r--gcc/ira-color.c28
-rw-r--r--gcc/ira-conflicts.c5
-rw-r--r--gcc/ira-costs.c4
-rw-r--r--gcc/ira-emit.c6
-rw-r--r--gcc/ira-int.h15
-rw-r--r--gcc/ira-lives.c2
-rw-r--r--gcc/ira.c21
9 files changed, 193 insertions, 99 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 6a30fa7..1266cd5 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,52 @@
+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>
PR libmudflap/40778
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);
diff --git a/gcc/ira-color.c b/gcc/ira-color.c
index 92f68bf..c638e58 100644
--- a/gcc/ira-color.c
+++ b/gcc/ira-color.c
@@ -1670,7 +1670,6 @@ assign_hard_reg (ira_allocno_t a, bool retry_p)
update_conflict_hard_regno_costs (full_costs, aclass, false);
}
min_cost = min_full_cost = INT_MAX;
-
/* We don't care about giving callee saved registers to allocnos no
living through calls because call clobbered registers are
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)
edge e;
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));
freq = 0;
if (! exit_p)
@@ -2662,14 +2661,19 @@ print_loop_title (ira_loop_tree_node_t loop_tree_node)
edge e;
edge_iterator ei;
- ira_assert (loop_tree_node->loop != NULL);
- 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 == NULL
- ? -1 : loop_tree_node->parent->loop->num),
- loop_tree_node->loop->header->index,
- loop_depth (loop_tree_node->loop));
+ 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,
+ "\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;
subloop_node != NULL;
subloop_node = subloop_node->next)
@@ -2681,7 +2685,7 @@ print_loop_title (ira_loop_tree_node_t loop_tree_node)
&& ((dest_loop_node = IRA_BB_NODE (e->dest)->parent)
!= loop_tree_node))
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:");
EXECUTE_IF_SET_IN_BITMAP (loop_tree_node->all_allocnos, 0, j, bi)
@@ -3011,7 +3015,7 @@ move_spill_restore (void)
fprintf
(ira_dump_file,
" 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);
}
changed_p = true;
diff --git a/gcc/ira-conflicts.c b/gcc/ira-conflicts.c
index f2f1311..a0d3609 100644
--- a/gcc/ira-conflicts.c
+++ b/gcc/ira-conflicts.c
@@ -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 a2 = ira_curr_regno_allocno_map[REGNO (reg2)];
+
if (!allocnos_conflict_for_copy_p (a1, a2) && offset1 == offset2)
{
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)
if ((bb = ALLOCNO_LOOP_TREE_NODE (a)->bb) != NULL)
fprintf (file, "b%d", bb->index);
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);
}
@@ -796,7 +797,7 @@ print_allocno_conflicts (FILE * file, bool reg_p, ira_allocno_t a)
fprintf (file, ",b%d", bb->index);
else
fprintf (file, ",l%d",
- ALLOCNO_LOOP_TREE_NODE (conflict_a)->loop->num);
+ ALLOCNO_LOOP_TREE_NODE (conflict_a)->loop_num);
putc (')', file);
}
}
diff --git a/gcc/ira-costs.c b/gcc/ira-costs.c
index 4f2f8412..8e1e846 100644
--- a/gcc/ira-costs.c
+++ b/gcc/ira-costs.c
@@ -1391,7 +1391,7 @@ print_allocno_costs (FILE *f)
if ((bb = ALLOCNO_LOOP_TREE_NODE (a)->bb) != NULL)
fprintf (f, "b%d", bb->index);
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:");
for (k = 0; k < cost_classes_ptr->num; k++)
{
@@ -1789,7 +1789,7 @@ find_costs_and_classes (FILE *dump_file)
fprintf (dump_file, "b%d", bb->index);
else
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",
reg_class_names[best],
reg_class_names[regno_aclass[i]]);
diff --git a/gcc/ira-emit.c b/gcc/ira-emit.c
index 01a9442..3dcd324 100644
--- a/gcc/ira-emit.c
+++ b/gcc/ira-emit.c
@@ -438,6 +438,7 @@ setup_entered_from_non_parent_p (void)
unsigned 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)
ira_loop_nodes[i].entered_from_non_parent_p
@@ -565,7 +566,8 @@ change_loop (ira_loop_tree_node_t node)
if (node != ira_loop_tree_root)
{
-
+ ira_assert (current_loops != NULL);
+
if (node->bb != NULL)
{
FOR_BB_INSNS (node->bb, insn)
@@ -580,7 +582,7 @@ change_loop (ira_loop_tree_node_t node)
if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
fprintf (ira_dump_file,
" 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;
map = parent->regno_allocno_map;
diff --git a/gcc/ira-int.h b/gcc/ira-int.h
index 6199894..9faabb5 100644
--- a/gcc/ira-int.h
+++ b/gcc/ira-int.h
@@ -87,7 +87,8 @@ struct ira_loop_tree_node
{
/* The node represents basic block if children == NULL. */
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.
SUBLOOP_NEXT is always NULL for BBs. */
ira_loop_tree_node_t subloop_next, next;
@@ -103,6 +104,9 @@ struct ira_loop_tree_node
/* All the following members are defined only for nodes representing
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
allocation. */
bool to_remove_p;
@@ -154,7 +158,7 @@ extern ira_loop_tree_node_t ira_bb_nodes;
/* Two access macros to the nodes representing basic blocks. */
#if defined ENABLE_IRA_CHECKING && (GCC_VERSION >= 2007)
#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)\
{ \
fprintf (stderr, \
@@ -176,8 +180,9 @@ extern ira_loop_tree_node_t ira_loop_nodes;
/* Two access macros to the nodes representing loops. */
#if defined ENABLE_IRA_CHECKING && (GCC_VERSION >= 2007)
#define IRA_LOOP_NODE_BY_INDEX(index) __extension__ \
-(({ ira_loop_tree_node_t const _node = (&ira_loop_nodes[index]);\
- if (_node->children == NULL || _node->bb != NULL || _node->loop == NULL)\
+(({ ira_loop_tree_node_t const _node = (&ira_loop_nodes[index]); \
+ if (_node->children == NULL || _node->bb != NULL \
+ || (_node->loop == NULL && current_loops != NULL)) \
{ \
fprintf (stderr, \
"\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);
extern void ira_free_cost_vector (int *, reg_class_t);
extern void ira_flattening (int, int);
-extern bool ira_build (bool);
+extern bool ira_build (void);
extern void ira_destroy (void);
/* ira-costs.c */
diff --git a/gcc/ira-lives.c b/gcc/ira-lives.c
index 9af2f93..f639e12 100644
--- a/gcc/ira-lives.c
+++ b/gcc/ira-lives.c
@@ -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)
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);
/* Mark each defined value as live. We need to do this for
diff --git a/gcc/ira.c b/gcc/ira.c
index 6db7909..a632284 100644
--- a/gcc/ira.c
+++ b/gcc/ira.c
@@ -718,7 +718,7 @@ ira_print_disposition (FILE *f)
if ((bb = ALLOCNO_LOOP_TREE_NODE (a)->bb) != NULL)
fprintf (f, "b%-3d", bb->index);
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)
fprintf (f, " %3d", ALLOCNO_HARD_REGNO (a));
else
@@ -3614,14 +3614,16 @@ ira (FILE *f)
ira_move_loops_num = ira_additional_jumps_num = 0;
ira_assert (current_loops == NULL);
- flow_loops_find (&ira_loops);
- record_loop_exits ();
- current_loops = &ira_loops;
+ if (flag_ira_region == IRA_REGION_ALL || flag_ira_region == IRA_REGION_MIXED)
+ {
+ flow_loops_find (&ira_loops);
+ record_loop_exits ();
+ current_loops = &ira_loops;
+ }
if (internal_flag_ira_verbose > 0 && ira_dump_file != NULL)
fprintf (ira_dump_file, "Building IRA IR\n");
- loops_p = ira_build (flag_ira_region == IRA_REGION_ALL
- || flag_ira_region == IRA_REGION_MIXED);
+ loops_p = ira_build ();
ira_assert (ira_conflicts_p || !loops_p);
@@ -3745,8 +3747,11 @@ do_reload (void)
flag_ira_share_spill_slots = saved_flag_ira_share_spill_slots;
- flow_loops_free (&ira_loops);
- free_dominance_info (CDI_DOMINATORS);
+ if (current_loops != NULL)
+ {
+ flow_loops_free (&ira_loops);
+ free_dominance_info (CDI_DOMINATORS);
+ }
FOR_ALL_BB (bb)
bb->loop_father = NULL;
current_loops = NULL;