Patchwork 2nd try to fix PR53695, loops and tracer

login
register
mail settings
Submitter Richard Guenther
Date Oct. 26, 2012, 12:29 p.m.
Message ID <alpine.LNX.2.00.1210261424570.4063@zhemvz.fhfr.qr>
Download mbox | patch
Permalink /patch/194465/
State New
Headers show

Comments

Richard Guenther - Oct. 26, 2012, 12:29 p.m.
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  <rguenther@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:
+   ;
+ }

Patch

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);