This is the 2nd try fixing fallout of preserving loop structure over
tracer.  It makes tracer call fix_loop_structure explicitely
(instead of relying on some cfghook setting LOOPS_NEED_FIXUP), it is
quite expected that fixups are needed.

But then we run into the issue that fix_loop_structure does nothing
to fixup loop->latch so this patch adds it, as well as possibly
disambiguating loops that now have multiple latches to be consistent
with loop_optimizer_init.  I duplicated get_loop_latch_edges
(and simplified it) to avoid excessive work here - but maybe we
don't care and prefer simpler code?

Bootstrap and regtest running on x86_64-unknown-linux-gnu.

I'll leave it for comments over the weekend at least.

Thanks,
Richard.

2012-10-26  Richard Guenther  <rguent...@suse.de>

        PR middle-end/53695
        * tracer.c (tracer): Fixup loop structure.
        * cfgloopmanip.c (force_single_succ_latches): Add assert.
        (fix_loop_structure): Re-compute loop latches and disambiguate
        loops with multiple latches if required.

Index: gcc/testsuite/gcc.dg/torture/pr53695.c
===================================================================
*** gcc/testsuite/gcc.dg/torture/pr53695.c      (revision 0)
--- gcc/testsuite/gcc.dg/torture/pr53695.c      (working copy)
***************
*** 0 ****
--- 1,14 ----
+ /* { dg-do compile } */
+ /* { dg-options "-ftracer" } */
+ 
+ void
+ foo (const void **p)
+ {
+   void *labs[] = { &&l1, &&l2, &&l3 };
+ l1:
+   goto *p++;
+ l2:
+   goto *p;
+ l3:
+   ;
+ }
Index: gcc/tracer.c
===================================================================
--- gcc/tracer.c        (revision 192840)
+++ gcc/tracer.c        (working copy)
@@ -379,7 +379,12 @@ tracer (void)
   /* Trace formation is done on the fly inside tail_duplicate */
   changed = tail_duplicate ();
   if (changed)
-    free_dominance_info (CDI_DOMINATORS);
+    {
+      free_dominance_info (CDI_DOMINATORS);
+      calculate_dominance_info (CDI_DOMINATORS);
+      if (current_loops)
+       fix_loop_structure (NULL);
+    }
 
   if (dump_file)
     brief_dump_cfg (dump_file, dump_flags);
Index: gcc/cfgloopmanip.c
===================================================================
--- gcc/cfgloopmanip.c  (revision 192840)
+++ gcc/cfgloopmanip.c  (working copy)
@@ -1586,6 +1586,7 @@ force_single_succ_latches (void)
        continue;
 
       e = find_edge (loop->latch, loop->header);
+      gcc_checking_assert (e != NULL);
 
       split_edge (e);
     }
@@ -1848,6 +1849,32 @@ fix_loop_structure (bitmap changed_bbs)
        }
     }
 
+  /* Then re-compute the single latch if there is one.  */
+  FOR_EACH_LOOP (li, loop, 0)
+    {
+      edge_iterator ei;
+      edge e, latch = NULL;
+      FOR_EACH_EDGE (e, ei, loop->header->preds)
+       if (dominated_by_p (CDI_DOMINATORS, e->src, loop->header))
+         {
+           if (!latch)
+             latch = e;
+           else
+             {
+               latch = NULL;
+               break;
+             }
+         }
+      if (latch
+         && latch->src->loop_father == loop)
+       loop->latch = latch->src;
+      else
+       loop->latch = NULL;
+    }
+
+  if (!loops_state_satisfies_p (LOOPS_MAY_HAVE_MULTIPLE_LATCHES))
+    disambiguate_loops_with_multiple_latches ();
+
   if (loops_state_satisfies_p (LOOPS_HAVE_PREHEADERS))
     create_preheaders (CP_SIMPLE_PREHEADERS);
 

Reply via email to