]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR bootstrap/52808 (LTO bootstrap failed with bootstrap-profiled)
authorRichard Guenther <rguenther@suse.de>
Tue, 3 Apr 2012 11:38:04 +0000 (11:38 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Tue, 3 Apr 2012 11:38:04 +0000 (11:38 +0000)
2012-04-03  Richard Guenther  <rguenther@suse.de>

PR tree-optimization/52808
* tracer.c (tail_duplicate): Return whether we have duplicated
any block.
(tracer): If we have duplicated any block, cleanup the CFG.
* cfghooks.c (duplicate_block): If we duplicated a loop
header but not its loop, destroy the loop because it now has
multiple entries.
* tree-ssa-threadupdate.c (thread_through_loop_header): Tell
the cfg manipulation routines we are not creating a multiple
entry loop.

* gcc.dg/pr52808.c: New testcase.

From-SVN: r186104

gcc/ChangeLog
gcc/cfghooks.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr52808.c [new file with mode: 0644]
gcc/tracer.c
gcc/tree-ssa-threadupdate.c

index 7c1d1b3bb206f5a92e26f10d3f954b0e9d6f2f79..74a5a18481144230da3b7152c4a203d8341327c6 100644 (file)
@@ -1,3 +1,16 @@
+2012-04-03  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/52808
+       * tracer.c (tail_duplicate): Return whether we have duplicated
+       any block.
+       (tracer): If we have duplicated any block, cleanup the CFG.
+       * cfghooks.c (duplicate_block): If we duplicated a loop
+       header but not its loop, destroy the loop because it now has
+       multiple entries.
+       * tree-ssa-threadupdate.c (thread_through_loop_header): Tell
+       the cfg manipulation routines we are not creating a multiple
+       entry loop.
+
 2012-04-03  Tristan Gingold  <gingold@adacore.com>
 
        * config/vms/vms-c.c (vms_pragma_nomember_alignment): Handle
index 1dca79a70cf2952d04eb4ab737846ae64e745b21..bc1b7a2f5821de8fcbb874f87275273072017290 100644 (file)
@@ -1009,18 +1009,28 @@ duplicate_block (basic_block bb, edge e, basic_block after)
     {
       struct loop *cloop = bb->loop_father;
       struct loop *copy = get_loop_copy (cloop);
-      add_bb_to_loop (new_bb, copy ? copy : cloop);
-      /* If we copied the loop latch block but not the loop, adjust
-        loop state.
-        ???  If we copied the loop header block but not the loop
-        we might either have created a loop copy or a loop with
-        multiple entries.  In both cases we probably have to
-        ditch the loops and arrange for a fixup.  */
+      /* If we copied the loop header block but not the loop
+        we have created a loop with multiple entries.  Ditch the loop,
+        add the new block to the outer loop and arrange for a fixup.  */
       if (!copy
-         && cloop->latch == bb)
+         && cloop->header == bb)
        {
+         add_bb_to_loop (new_bb, loop_outer (cloop));
+         cloop->header = NULL;
          cloop->latch = NULL;
-         loops_state_set (LOOPS_MAY_HAVE_MULTIPLE_LATCHES);
+         loops_state_set (LOOPS_NEED_FIXUP);
+       }
+      else
+       {
+         add_bb_to_loop (new_bb, copy ? copy : cloop);
+         /* If we copied the loop latch block but not the loop, adjust
+            loop state.  */
+         if (!copy
+             && cloop->latch == bb)
+           {
+             cloop->latch = NULL;
+             loops_state_set (LOOPS_MAY_HAVE_MULTIPLE_LATCHES);
+           }
        }
     }
 
index 7fe8a18ca0fdb43523dbf353b83a666a09ed3523..c757d42d177d5f91314feffa197f0e3856feb88e 100644 (file)
@@ -1,3 +1,8 @@
+2012-04-03  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/52808
+       * gcc.dg/pr52808.c: New testcase.
+
 2012-04-03  Jakub Jelinek  <jakub@redhat.com>
 
        PR tree-optimization/52835
diff --git a/gcc/testsuite/gcc.dg/pr52808.c b/gcc/testsuite/gcc.dg/pr52808.c
new file mode 100644 (file)
index 0000000..b731cb4
--- /dev/null
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O -ftracer" } */
+
+int **fn1 () __attribute__ ((__const__));
+int main ()
+{
+  int i;
+  i = 0;
+  for (;; i++)
+    if (*fn1 ()[i] && !'a' <= 0 && i <= 'z' || *fn1 ()[0] && 'a' <= 'z')
+      return;
+}
index 602e7580d994c4f24be7e5f33e65c70d9541f729..8fb9817dbe9f2353444ec389be4dd7ca2ecd2437 100644 (file)
@@ -59,7 +59,6 @@ static bool better_p (const_edge, const_edge);
 static edge find_best_successor (basic_block);
 static edge find_best_predecessor (basic_block);
 static int find_trace (basic_block, basic_block *);
-static void tail_duplicate (void);
 
 /* Minimal outgoing edge probability considered for superblock formation.  */
 static int probability_cutoff;
@@ -224,7 +223,7 @@ find_trace (basic_block bb, basic_block *trace)
 /* Look for basic blocks in frequency order, construct traces and tail duplicate
    if profitable.  */
 
-static void
+static bool
 tail_duplicate (void)
 {
   fibnode_t *blocks = XCNEWVEC (fibnode_t, last_basic_block);
@@ -236,6 +235,7 @@ tail_duplicate (void)
   gcov_type cover_insns;
   int max_dup_insns;
   basic_block bb;
+  bool changed = false;
 
   /* Create an oversized sbitmap to reduce the chance that we need to
      resize it.  */
@@ -332,6 +332,7 @@ tail_duplicate (void)
                         bb2->index, copy->index, copy->frequency);
 
              bb2 = copy;
+             changed = true;
            }
          mark_bb_seen (bb2);
          bb = bb2;
@@ -353,6 +354,8 @@ tail_duplicate (void)
   free (trace);
   free (counts);
   fibheap_delete (heap);
+
+  return changed;
 }
 
 /* Main entry point to this file.  */
@@ -360,6 +363,8 @@ tail_duplicate (void)
 static unsigned int
 tracer (void)
 {
+  bool changed;
+
   gcc_assert (current_ir_type () == IR_GIMPLE);
 
   if (n_basic_blocks <= NUM_FIXED_BLOCKS + 1)
@@ -370,15 +375,14 @@ tracer (void)
     dump_flow_info (dump_file, dump_flags);
 
   /* Trace formation is done on the fly inside tail_duplicate */
-  tail_duplicate ();
+  changed = tail_duplicate ();
+  if (changed)
+    free_dominance_info (CDI_DOMINATORS);
 
-  /* FIXME: We really only need to do this when we know tail duplication
-            has altered the CFG. */
-  free_dominance_info (CDI_DOMINATORS);
   if (dump_file)
     dump_flow_info (dump_file, dump_flags);
 
-  return 0;
+  return changed ? TODO_cleanup_cfg : 0;
 }
 \f
 static bool
index 000bd3f2e4014cd6376fceb692543a091704eeac..687eee0485ae09cd51934289f3adca3ce2184737 100644 (file)
@@ -1004,8 +1004,12 @@ thread_through_loop_header (struct loop *loop, bool may_peel_loop_headers)
       basic_block *bblocks;
       unsigned nblocks, i;
 
-      /* First handle the case latch edge is redirected.  */
+      /* First handle the case latch edge is redirected.  We are copying
+         the loop header but not creating a multiple entry loop.  Make the
+        cfg manipulation code aware of that fact.  */
+      set_loop_copy (loop, loop);
       loop->latch = thread_single_edge (latch);
+      set_loop_copy (loop, NULL);
       gcc_assert (single_succ (loop->latch) == tgt_bb);
       loop->header = tgt_bb;