2012-01-19 Vladimir Makarov <vmakarov@redhat.com>
authorvmakarov <vmakarov@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 19 Jan 2012 20:46:31 +0000 (20:46 +0000)
committervmakarov <vmakarov@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 19 Jan 2012 20:46:31 +0000 (20:46 +0000)
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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@183312 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/ira-build.c
gcc/ira-color.c
gcc/ira-conflicts.c
gcc/ira-costs.c
gcc/ira-emit.c
gcc/ira-int.h
gcc/ira-lives.c
gcc/ira.c

index 6a30fa7..1266cd5 100644 (file)
@@ -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
index 2d8708a..78d0b36 100644 (file)
@@ -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)
 \f
 
 /* 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);
index 92f68bf..c638e58 100644 (file)
@@ -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;
index f2f1311..a0d3609 100644 (file)
@@ -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);
            }
        }
index 4f2f841..8e1e846 100644 (file)
@@ -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]]);
index 01a9442..3dcd324 100644 (file)
@@ -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;
index 6199894..9faabb5 100644 (file)
@@ -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 */
index 9af2f93..f639e12 100644 (file)
@@ -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
index 6db7909..a632284 100644 (file)
--- 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;