re PR middle-end/32018 (ICE on optimization)
authorZdenek Dvorak <dvorakz@suse.cz>
Thu, 24 May 2007 14:02:12 +0000 (16:02 +0200)
committerZdenek Dvorak <rakdver@gcc.gnu.org>
Thu, 24 May 2007 14:02:12 +0000 (14:02 +0000)
PR middle-end/32018
* tree-ssa-threadupdate.c (thread_through_loop_header): Use
set_loop_copy.
(thread_through_all_blocks): Call initialize_original_copy_tables
and free_original_copy_tables.
* cfgloopmanip.c (duplicate_loop, duplicate_loop_to_header_edge):
Use set_loop_copy.
* tree-cfg.c (tree_duplicate_sese_region): Ditto.
* cfghooks.c (duplicate_block): Use get_loop_copy.
* cfg.c: Include cfgloop.h.
(loop_copy): New hash table.
(initialize_original_copy_tables): Initialize loop_copy table.
(free_original_copy_tables): Free loop_copy table.
(copy_original_table_clear, copy_original_table_set,
set_loop_copy, get_loop_copy): New functions.
(set_bb_original, set_bb_copy): Use copy_original_table_set.
* cfgloop.h (struct loop): Remove copy field.
* Makefile.in (cfg.o): Add CFGLOOP_H dependency.
* basic-block.h (set_loop_copy, get_loop_copy): Declare.

From-SVN: r125024

gcc/ChangeLog
gcc/Makefile.in
gcc/basic-block.h
gcc/cfg.c
gcc/cfghooks.c
gcc/cfgloop.h
gcc/cfgloopmanip.c
gcc/tree-cfg.c
gcc/tree-ssa-threadupdate.c

index 89258a3..5b4258a 100644 (file)
@@ -1,3 +1,25 @@
+2007-05-24  Zdenek Dvorak  <dvorakz@suse.cz>
+
+       PR middle-end/32018
+       * tree-ssa-threadupdate.c (thread_through_loop_header): Use
+       set_loop_copy.
+       (thread_through_all_blocks): Call initialize_original_copy_tables
+       and free_original_copy_tables.
+       * cfgloopmanip.c (duplicate_loop, duplicate_loop_to_header_edge):
+       Use set_loop_copy.
+       * tree-cfg.c (tree_duplicate_sese_region): Ditto.
+       * cfghooks.c (duplicate_block): Use get_loop_copy.
+       * cfg.c: Include cfgloop.h.
+       (loop_copy): New hash table.
+       (initialize_original_copy_tables): Initialize loop_copy table.
+       (free_original_copy_tables): Free loop_copy table.
+       (copy_original_table_clear, copy_original_table_set,
+       set_loop_copy, get_loop_copy): New functions.
+       (set_bb_original, set_bb_copy): Use copy_original_table_set.
+       * cfgloop.h (struct loop): Remove copy field.
+       * Makefile.in (cfg.o): Add CFGLOOP_H dependency.
+       * basic-block.h (set_loop_copy, get_loop_copy): Declare.
+
 2007-05-24  H.J. Lu  <hongjiu.lu@intel.com>
 
        * config/i386/i386.c (ix86_handle_option): Handle SSE4.1 for
index 8330a88..8fd1329 100644 (file)
@@ -2517,7 +2517,8 @@ flow.o : flow.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
    $(EXPR_H) $(TM_P_H) $(OBSTACK_H) $(SPLAY_TREE_H) $(TIMEVAR_H) tree-pass.h
 cfg.o : cfg.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(FLAGS_H) \
    $(REGS_H) hard-reg-set.h output.h toplev.h $(FUNCTION_H) except.h $(GGC_H) \
-   $(TM_P_H) $(TIMEVAR_H) $(OBSTACK_H) $(TREE_H) alloc-pool.h $(HASHTAB_H)
+   $(TM_P_H) $(TIMEVAR_H) $(OBSTACK_H) $(TREE_H) alloc-pool.h $(HASHTAB_H) \
+   $(CFGLOOP_H)
 cfghooks.o: cfghooks.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
    $(TREE_H) $(BASIC_BLOCK_H) $(TREE_FLOW_H) $(TIMEVAR_H) toplev.h $(CFGLOOP_H)
 cfgexpand.o : cfgexpand.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
index a3d4dc8..ce0aba0 100644 (file)
@@ -988,6 +988,9 @@ extern void set_bb_original (basic_block, basic_block);
 extern basic_block get_bb_original (basic_block);
 extern void set_bb_copy (basic_block, basic_block);
 extern basic_block get_bb_copy (basic_block);
+void set_loop_copy (struct loop *, struct loop *);
+struct loop *get_loop_copy (struct loop *);
+
 
 extern rtx insert_insn_end_bb_new (rtx, basic_block);
 
index 9f5da32..63d0530 100644 (file)
--- a/gcc/cfg.c
+++ b/gcc/cfg.c
@@ -66,6 +66,7 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
 #include "ggc.h"
 #include "hashtab.h"
 #include "alloc-pool.h"
+#include "cfgloop.h"
 
 /* The obstack on which the flow graph components are allocated.  */
 
@@ -1027,6 +1028,9 @@ scale_bbs_frequencies_gcov_type (basic_block *bbs, int nbbs, gcov_type num,
    copies.  */
 static htab_t bb_original;
 static htab_t bb_copy;
+
+/* And between loops and copies.  */
+static htab_t loop_copy;
 static alloc_pool original_copy_bb_pool;
 
 struct htab_bb_copy_original_entry
@@ -1068,6 +1072,7 @@ initialize_original_copy_tables (void)
   bb_original = htab_create (10, bb_copy_original_hash,
                             bb_copy_original_eq, NULL);
   bb_copy = htab_create (10, bb_copy_original_hash, bb_copy_original_eq, NULL);
+  loop_copy = htab_create (10, bb_copy_original_hash, bb_copy_original_eq, NULL);
 }
 
 /* Free the data structures to maintain mapping between blocks and
@@ -1078,35 +1083,64 @@ free_original_copy_tables (void)
   gcc_assert (original_copy_bb_pool);
   htab_delete (bb_copy);
   htab_delete (bb_original);
+  htab_delete (loop_copy);
   free_alloc_pool (original_copy_bb_pool);
   bb_copy = NULL;
   bb_original = NULL;
+  loop_copy = NULL;
   original_copy_bb_pool = NULL;
 }
 
+/* Removes the value associated with OBJ from table TAB.  */
+
+static void
+copy_original_table_clear (htab_t tab, unsigned obj)
+{
+  void **slot;
+  struct htab_bb_copy_original_entry key, *elt;
+
+  if (!original_copy_bb_pool)
+    return;
+
+  key.index1 = obj;
+  slot = htab_find_slot (tab, &key, NO_INSERT);
+  if (!slot)
+    return;
+
+  elt = *slot;
+  htab_clear_slot (tab, slot);
+  pool_free (original_copy_bb_pool, elt);
+}
+
+/* Sets the value associated with OBJ in table TAB to VAL.
+   Do nothing when data structures are not initialized.  */
+
+static void
+copy_original_table_set (htab_t tab, unsigned obj, unsigned val)
+{
+  struct htab_bb_copy_original_entry **slot;
+  struct htab_bb_copy_original_entry key;
+
+  if (!original_copy_bb_pool)
+    return;
+
+  key.index1 = obj;
+  slot = (struct htab_bb_copy_original_entry **)
+               htab_find_slot (tab, &key, INSERT);
+  if (!*slot)
+    {
+      *slot = pool_alloc (original_copy_bb_pool);
+      (*slot)->index1 = obj;
+    }
+  (*slot)->index2 = val;
+}
+
 /* Set original for basic block.  Do nothing when data structures are not
    initialized so passes not needing this don't need to care.  */
 void
 set_bb_original (basic_block bb, basic_block original)
 {
-  if (original_copy_bb_pool)
-    {
-      struct htab_bb_copy_original_entry **slot;
-      struct htab_bb_copy_original_entry key;
-
-      key.index1 = bb->index;
-      slot =
-       (struct htab_bb_copy_original_entry **) htab_find_slot (bb_original,
-                                                              &key, INSERT);
-      if (*slot)
-       (*slot)->index2 = original->index;
-      else
-       {
-         *slot = pool_alloc (original_copy_bb_pool);
-         (*slot)->index1 = bb->index;
-         (*slot)->index2 = original->index;
-       }
-    }
+  copy_original_table_set (bb_original, bb->index, original->index);
 }
 
 /* Get the original basic block.  */
@@ -1131,24 +1165,7 @@ get_bb_original (basic_block bb)
 void
 set_bb_copy (basic_block bb, basic_block copy)
 {
-  if (original_copy_bb_pool)
-    {
-      struct htab_bb_copy_original_entry **slot;
-      struct htab_bb_copy_original_entry key;
-
-      key.index1 = bb->index;
-      slot =
-       (struct htab_bb_copy_original_entry **) htab_find_slot (bb_copy,
-                                                              &key, INSERT);
-      if (*slot)
-       (*slot)->index2 = copy->index;
-      else
-       {
-         *slot = pool_alloc (original_copy_bb_pool);
-         (*slot)->index1 = bb->index;
-         (*slot)->index2 = copy->index;
-       }
-    }
+  copy_original_table_set (bb_copy, bb->index, copy->index);
 }
 
 /* Get the copy of basic block.  */
@@ -1167,3 +1184,33 @@ get_bb_copy (basic_block bb)
   else
     return NULL;
 }
+
+/* Set copy for LOOP to COPY.  Do nothing when data structures are not
+   initialized so passes not needing this don't need to care.  */
+
+void
+set_loop_copy (struct loop *loop, struct loop *copy)
+{
+  if (!copy)
+    copy_original_table_clear (loop_copy, loop->num);
+  else
+    copy_original_table_set (loop_copy, loop->num, copy->num);
+}
+
+/* Get the copy of LOOP.  */
+
+struct loop *
+get_loop_copy (struct loop *loop)
+{
+  struct htab_bb_copy_original_entry *entry;
+  struct htab_bb_copy_original_entry key;
+
+  gcc_assert (original_copy_bb_pool);
+
+  key.index1 = loop->num;
+  entry = (struct htab_bb_copy_original_entry *) htab_find (loop_copy, &key);
+  if (entry)
+    return get_loop (entry->index2);
+  else
+    return NULL;
+}
index 7f544c3..51405bb 100644 (file)
@@ -928,9 +928,8 @@ duplicate_block (basic_block bb, edge e, basic_block after)
   if (current_loops != NULL)
     {
       struct loop *cloop = bb->loop_father;
-      if (cloop->copy)
-       cloop = cloop->copy;
-      add_bb_to_loop (new_bb, cloop);
+      struct loop *copy = get_loop_copy (cloop);
+      add_bb_to_loop (new_bb, copy ? copy : cloop);
     }
 
   return new_bb;
index 3786986..59815cc 100644 (file)
@@ -123,9 +123,6 @@ struct loop GTY ((chain_next ("%h.next")))
   /* Link to the next (sibling) loop.  */
   struct loop *next;
 
-  /* Loop that is copy of this loop.  */
-  struct loop *copy;
-
   /* Auxiliary info specific to a pass.  */
   PTR GTY ((skip (""))) aux;
 
index 1fadbb4..99b41d7 100644 (file)
@@ -653,7 +653,7 @@ duplicate_loop (struct loop *loop, struct loop *target)
   place_new_loop (cloop);
 
   /* Mark the new loop as copy of LOOP.  */
-  loop->copy = cloop;
+  set_loop_copy (loop, cloop);
 
   /* Add it to target.  */
   flow_loop_tree_node_add (target, cloop);
@@ -917,7 +917,7 @@ duplicate_loop_to_header_edge (struct loop *loop, edge e,
   for (aloop = loop->inner, i = 0; aloop; aloop = aloop->next, i++)
     orig_loops[i] = aloop;
 
-  loop->copy = target;
+  set_loop_copy (loop, target);
 
   first_active = XNEWVEC (basic_block, n);
   if (is_latch)
index 15beeab..83ab930 100644 (file)
@@ -4360,14 +4360,14 @@ tree_duplicate_sese_region (edge entry, edge exit,
        return false;
     }
 
-  loop->copy = loop;
+  set_loop_copy (loop, loop);
 
   /* In case the function is used for loop header copying (which is the primary
      use), ensure that EXIT and its copy will be new latch and entry edges.  */
   if (loop->header == entry->dest)
     {
       copying_header = true;
-      loop->copy = loop_outer (loop);
+      set_loop_copy (loop, loop_outer (loop));
 
       if (!dominated_by_p (CDI_DOMINATORS, loop->latch, exit->src))
        return false;
index 22266bd..6732f2e 100644 (file)
@@ -918,10 +918,10 @@ thread_through_loop_header (struct loop *loop, bool may_peel_loop_headers)
 
       /* The duplicate of the header is the new preheader of the loop.  Ensure
         that it is placed correctly in the loop hierarchy.  */
-      loop->copy = loop_outer (loop);
+      set_loop_copy (loop, loop_outer (loop));
 
       thread_block (header, false);
-      loop->copy = NULL;
+      set_loop_copy (loop, NULL);
       new_preheader = e->dest;
 
       /* Create the new latch block.  This is always necessary, as the latch
@@ -1031,9 +1031,7 @@ thread_through_all_blocks (bool may_peel_loop_headers)
 
   mark_threaded_blocks (threaded_blocks);
 
-  if (current_loops)
-    FOR_EACH_LOOP (li, loop, LI_FROM_INNERMOST)
-      loop->copy = NULL;
+  initialize_original_copy_tables ();
 
   /* First perform the threading requests that do not affect
      loop structure.  */
@@ -1067,6 +1065,8 @@ thread_through_all_blocks (bool may_peel_loop_headers)
     fprintf (dump_file, "\nJumps threaded: %lu\n",
             thread_stats.num_threaded_edges);
 
+  free_original_copy_tables ();
+
   BITMAP_FREE (threaded_blocks);
   threaded_blocks = NULL;
   VEC_free (edge, heap, threaded_edges);