]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR bootstrap/37859 (Bootstrap failure on mips64octeon-unknown-linux-gnu)
authorVladimir Makarov <vmakarov@redhat.com>
Wed, 19 Nov 2008 21:25:00 +0000 (21:25 +0000)
committerVladimir Makarov <vmakarov@gcc.gnu.org>
Wed, 19 Nov 2008 21:25:00 +0000 (21:25 +0000)
2008-11-19  Vladimir Makarov  <vmakarov@redhat.com>

PR bootstrap/37859
* ira-int.h (struct ira_loop_tree_node): New member
entered_from_non_parent_p.

* ira-color.c (print_loop_title): Print loop bbs.

* ira-emit.c (entered_from_non_parent_p,
setup_entered_from_non_parent_p): New functions.
(not_modified_p): Rename to store_can_be_removed_p.  Check there
is no side entries.
(generate_edge_moves): Use store_can_be_removed_p instead of
not_modified_p.
(ira_emit): Call setup_entered_from_non_parent_p.

* ira-build.c (copy_info_to_removed_store_destinations):
Accumulate CALL_FREQ, CALL_CROSSED_NUM, and
ALLOCNO_EXCESS_PRESSURE_POINTS_NUM.
(ira_flattening): Don't CHECK MEM_OPTIMIZED_DEST[_P], always
update all accumulated attributes.

From-SVN: r142018

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

index eacb5e0e5888790dbbff06b32ac42ac7c998eab7..b21a632bcf5a447a9d84a72bf916b8d1ac8112aa 100644 (file)
@@ -1,4 +1,26 @@
-2008-11-15  Vladimir Makarov  <vmakarov@redhat.com>
+2008-11-19  Vladimir Makarov  <vmakarov@redhat.com>
+
+       PR bootstrap/37859
+       * ira-int.h (struct ira_loop_tree_node): New member
+       entered_from_non_parent_p.
+
+       * ira-color.c (print_loop_title): Print loop bbs.
+
+       * ira-emit.c (entered_from_non_parent_p,
+       setup_entered_from_non_parent_p): New functions.
+       (not_modified_p): Rename to store_can_be_removed_p.  Check there
+       is no side entries.
+       (generate_edge_moves): Use store_can_be_removed_p instead of
+       not_modified_p.
+       (ira_emit): Call setup_entered_from_non_parent_p.
+       
+       * ira-build.c (copy_info_to_removed_store_destinations):
+       Accumulate CALL_FREQ, CALL_CROSSED_NUM, and
+       ALLOCNO_EXCESS_PRESSURE_POINTS_NUM.
+       (ira_flattening): Don't CHECK MEM_OPTIMIZED_DEST[_P], always
+       update all accumulated attributes.
+       
+2008-11-19  Vladimir Makarov  <vmakarov@redhat.com>
 
        PR bootstrap/37790
        * ira-int.h (ira_copy_allocno_live_range_list,
index af1d1747a5bda7cbb0b1b2f908308da3c8251a0b..e4ed60141fa0d796d5c4dc7260eea2dafb2f5484 100644 (file)
@@ -2193,6 +2193,11 @@ copy_info_to_removed_store_destinations (int regno)
       if (ALLOCNO_TOTAL_NO_STACK_REG_P (a))
        ALLOCNO_TOTAL_NO_STACK_REG_P (parent_a) = true;
 #endif
+      ALLOCNO_CALL_FREQ (parent_a) += ALLOCNO_CALL_FREQ (a);
+      ALLOCNO_CALLS_CROSSED_NUM (parent_a)
+       += ALLOCNO_CALLS_CROSSED_NUM (a);
+      ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (parent_a)
+       += ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a);
       merged_p = true;
     }
   return merged_p;
@@ -2208,7 +2213,7 @@ void
 ira_flattening (int max_regno_before_emit, int ira_max_point_before_emit)
 {
   int i, j, num;
-  bool stop_p, keep_p;
+  bool keep_p;
   int hard_regs_num;
   bool new_pseudos_p, merged_p, mem_dest_p;
   unsigned int n;
@@ -2293,26 +2298,15 @@ ira_flattening (int max_regno_before_emit, int ira_max_point_before_emit)
              continue;
            }
          new_pseudos_p = true;
-         first = ALLOCNO_MEM_OPTIMIZED_DEST (a) == NULL ? NULL : a;
-         stop_p = false;
          for (;;)
            {
-             if (first == NULL
-                 && ALLOCNO_MEM_OPTIMIZED_DEST (parent_a) != NULL)
-               first = parent_a;
              ALLOCNO_NREFS (parent_a) -= ALLOCNO_NREFS (a);
              ALLOCNO_FREQ (parent_a) -= ALLOCNO_FREQ (a);
-             if (first != NULL
-                 && ALLOCNO_MEM_OPTIMIZED_DEST (first) == parent_a)
-               stop_p = true;
-             else if (!stop_p)
-               {
-                 ALLOCNO_CALL_FREQ (parent_a) -= ALLOCNO_CALL_FREQ (a);
-                 ALLOCNO_CALLS_CROSSED_NUM (parent_a)
-                   -= ALLOCNO_CALLS_CROSSED_NUM (a);
-                 ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (parent_a)
-                   -= ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a);
-               }
+             ALLOCNO_CALL_FREQ (parent_a) -= ALLOCNO_CALL_FREQ (a);
+             ALLOCNO_CALLS_CROSSED_NUM (parent_a)
+               -= ALLOCNO_CALLS_CROSSED_NUM (a);
+             ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (parent_a)
+               -= ALLOCNO_EXCESS_PRESSURE_POINTS_NUM (a);
              ira_assert (ALLOCNO_CALLS_CROSSED_NUM (parent_a) >= 0
                          && ALLOCNO_NREFS (parent_a) >= 0
                          && ALLOCNO_FREQ (parent_a) >= 0);
index 7343e0c8078a38a4e85b000457d69f2578ad1955..c3b63cc3d5d3b8ab3036fec2b28bd233a5bf81a9 100644 (file)
@@ -1703,15 +1703,32 @@ print_loop_title (ira_loop_tree_node_t loop_tree_node)
 {
   unsigned int j;
   bitmap_iterator bi;
+  ira_loop_tree_node_t subloop_node, dest_loop_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    all:",
+          "\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));
+  for (subloop_node = loop_tree_node->children;
+       subloop_node != NULL;
+       subloop_node = subloop_node->next)
+    if (subloop_node->bb != NULL)
+      {
+       fprintf (ira_dump_file, " %d", subloop_node->bb->index);
+       FOR_EACH_EDGE (e, ei, subloop_node->bb->succs)
+         if (e->dest != EXIT_BLOCK_PTR
+             && ((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);
+      }
+  fprintf (ira_dump_file, "\n    all:");
   EXECUTE_IF_SET_IN_BITMAP (loop_tree_node->all_allocnos, 0, j, bi)
     fprintf (ira_dump_file, " %dr%d", j, ALLOCNO_REGNO (ira_allocnos[j]));
   fprintf (ira_dump_file, "\n    modified regnos:");
index 63c866b641a423ba139fb98c81ef1c2fcbbc4b39..29f3fdf6fa7adb1c4d2ca679a3f58dd25d286260 100644 (file)
@@ -260,12 +260,63 @@ set_allocno_reg (ira_allocno_t allocno, rtx reg)
     }
 }
 
-/* Return TRUE if move of SRC_ALLOCNO to DEST_ALLOCNO does not change
-   value of the destination.  One possible reason for this is the
-   situation when SRC_ALLOCNO is not modified in the corresponding
-   loop.  */
+/* Return true if there is an entry to given loop not from its parent
+   (or grandparent) block.  For example, it is possible for two
+   adjacent loops inside another loop.  */
 static bool
-not_modified_p (ira_allocno_t src_allocno, ira_allocno_t dest_allocno)
+entered_from_non_parent_p (ira_loop_tree_node_t loop_node)
+{
+  ira_loop_tree_node_t bb_node, src_loop_node, parent;
+  edge e;
+  edge_iterator ei;
+
+  for (bb_node = loop_node->children; bb_node != NULL; bb_node = bb_node->next)
+    if (bb_node->bb != NULL)
+      {
+       FOR_EACH_EDGE (e, ei, bb_node->bb->preds)
+         if (e->src != ENTRY_BLOCK_PTR
+             && (src_loop_node = IRA_BB_NODE (e->src)->parent) != loop_node)
+           {
+             for (parent = src_loop_node->parent;
+                  parent != NULL;
+                  parent = parent->parent)
+               if (parent == loop_node)
+                 break;
+             if (parent != NULL)
+               /* That is an exit from a nested loop -- skip it.  */
+               continue;
+             for (parent = loop_node->parent;
+                  parent != NULL;
+                  parent = parent->parent)
+               if (src_loop_node == parent)
+                 break;
+             if (parent == NULL)
+               return true;
+           }
+      }
+  return false;
+}
+
+/* Set up ENTERED_FROM_NON_PARENT_P for each loop region.  */
+static void
+setup_entered_from_non_parent_p (void)
+{
+  unsigned int i;
+  loop_p loop;
+
+  for (i = 0; VEC_iterate (loop_p, ira_loops.larray, i, loop); i++)
+    if (ira_loop_nodes[i].regno_allocno_map != NULL)
+      ira_loop_nodes[i].entered_from_non_parent_p
+       = entered_from_non_parent_p (&ira_loop_nodes[i]);
+}
+
+/* Return TRUE if move of SRC_ALLOCNO (assigned to hard register) to
+   DEST_ALLOCNO (assigned to memory) can be removed beacuse it does
+   not change value of the destination.  One possible reason for this
+   is the situation when SRC_ALLOCNO is not modified in the
+   corresponding loop.  */
+static bool
+store_can_be_removed_p (ira_allocno_t src_allocno, ira_allocno_t dest_allocno)
 {
   int regno, orig_regno;
   ira_allocno_t a;
@@ -278,13 +329,26 @@ not_modified_p (ira_allocno_t src_allocno, ira_allocno_t dest_allocno)
   for (node = ALLOCNO_LOOP_TREE_NODE (src_allocno);
        node != NULL;
        node = node->parent)
-    if ((a = node->regno_allocno_map[orig_regno]) == NULL)
-      break;
-    else if (REGNO (ALLOCNO_REG (a)) == (unsigned) regno)
-      return true;
-    else if (bitmap_bit_p (node->modified_regnos, orig_regno))
-      return false;
-  return node != NULL;
+    {
+      a = node->regno_allocno_map[orig_regno];
+      ira_assert (a != NULL);
+      if (REGNO (ALLOCNO_REG (a)) == (unsigned) regno)
+       /* We achieved the destination and everything is ok.  */
+       return true;
+      else if (bitmap_bit_p (node->modified_regnos, orig_regno))
+       return false;
+      else if (node->entered_from_non_parent_p)
+       /* If there is a path from a destination loop block to the
+          source loop header containing basic blocks of non-parents
+          (grandparents) of the source loop, we should have checked
+          modifications of the pseudo on this path too to decide
+          about possibility to remove the store.  It could be done by
+          solving a data-flow problem.  Unfortunately such global
+          solution would complicate IR flattening.  Therefore we just
+          prohibit removal of the store in such complicated case.  */
+       return false;
+    }
+  gcc_unreachable ();
 }
 
 /* Generate and attach moves to the edge E.  This looks at the final
@@ -322,7 +386,7 @@ generate_edge_moves (edge e)
           change_loop).  */
        if (ALLOCNO_HARD_REGNO (dest_allocno) < 0
            && ALLOCNO_HARD_REGNO (src_allocno) >= 0
-           && not_modified_p (src_allocno, dest_allocno))
+           && store_can_be_removed_p (src_allocno, dest_allocno))
          {
            ALLOCNO_MEM_OPTIMIZED_DEST (src_allocno) = dest_allocno;
            ALLOCNO_MEM_OPTIMIZED_DEST_P (dest_allocno) = true;
@@ -983,6 +1047,7 @@ ira_emit (bool loops_p)
   ira_free_bitmap (used_regno_bitmap);
   ira_free_bitmap (renamed_regno_bitmap);
   ira_free_bitmap (local_allocno_bitmap);
+  setup_entered_from_non_parent_p ();
   FOR_EACH_BB (bb)
     {
       at_bb_start[bb->index] = NULL;
index 7f5479b7b57dcc9b9fd14c780ac38a50943dc014..659c1eeb2ab2ebfdcc8089fb2f286f847358f5a8 100644 (file)
@@ -107,6 +107,11 @@ struct ira_loop_tree_node
      one cap with the same regno in a region).  */
   ira_allocno_t *regno_allocno_map;
 
+  /* True if there is an entry to given loop not from its parent (or
+     grandparent) basic block.  For example, it is possible for two
+     adjacent loops inside another loop.  */
+  bool entered_from_non_parent_p;
+
   /* Maximal register pressure inside loop for given register class
      (defined only for the cover classes).  */
   int reg_pressure[N_REG_CLASSES];