[PATCH] PRE TLC, improve fake exit edge placement

Richard Biener rguenther@suse.de
Tue Aug 1 10:46:00 GMT 2017


On Tue, 1 Aug 2017, Richard Biener wrote:

> 
> When working on PR81181 I ran into some things I wanted to clean up
> several times.  First a few PRE cleanups done for the fix.  Second,
> the fake exit edges we add for infinite loops happen to start from
> loop headers rather than latches which is somewhat confusing and
> making PRE dataflow order more confusing than it already is.  The
> patch makes it originate from the source of the closing edge instead
> of from the destination.
> 
> Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.

Applied with three testsuite adjustments which show we do better
DCE now (due to more sensible post-dominators, "sensible" as in
what you'd expect).

The uninit case matches what we do for

int foo (int i)
{
  int j;
  while (i)
    ;
  return j;
}

we warn that 'j' _is_ being used uninitialized rather than maybe.

I couldn't reconstruct a sensible testcase for the split-path testcase
where the 2nd function is now optimized into an empty endless loop.

2017-08-01  Richard Biener  <rguenther@suse.de>

	* tree-ssa-pre.c (print_pre_expr): Handle NULL expr.
	(compute_antic): Seed worklist with exit block predecessors.
	* cfganal.c (dfs_find_deadend): For a cycle return the source
	of the edge closing it.

	* gcc.dg/tree-ssa/ssa-dce-3.c: Adjust.
	* gcc.dg/tree-ssa/split-path-5.c: Remove case with just dead
	endless loop.
	* gcc.dg/uninit-23.c: Adjust.

Index: gcc/tree-ssa-pre.c
===================================================================
--- gcc/tree-ssa-pre.c	(revision 250725)
+++ gcc/tree-ssa-pre.c	(working copy)
@@ -837,7 +840,7 @@ bitmap_set_and (bitmap_set_t dest, bitma
     }
 }
 
-/* Subtract all values and expressions contained in ORIG from DEST.  */
+/* Subtract all expressions contained in ORIG from DEST.  */
 
 static bitmap_set_t
 bitmap_set_subtract (bitmap_set_t dest, bitmap_set_t orig)
@@ -859,7 +862,7 @@ bitmap_set_subtract (bitmap_set_t dest,
   return result;
 }
 
-/* Subtract all the values in bitmap set B from bitmap set A.  */
+/* Subtract all values in bitmap set B from bitmap set A.  */
 
 static void
 bitmap_set_subtract_values (bitmap_set_t a, bitmap_set_t b)
@@ -987,6 +990,11 @@ bitmap_value_insert_into_set (bitmap_set
 static void
 print_pre_expr (FILE *outfile, const pre_expr expr)
 {
+  if (! expr)
+    {
+      fprintf (outfile, "NULL");
+      return;
+    }
   switch (expr->kind)
     {
     case CONSTANT:
@@ -2418,7 +2473,9 @@ compute_antic (void)
   inverted_post_order_compute (&postorder);
 
   auto_sbitmap worklist (last_basic_block_for_fn (cfun) + 1);
-  bitmap_ones (worklist);
+  bitmap_clear (worklist);
+  FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds)
+    bitmap_set_bit (worklist, e->src->index);
   while (changed)
     {
       if (dump_file && (dump_flags & TDF_DETAILS))
Index: gcc/cfganal.c
===================================================================
--- gcc/cfganal.c	(revision 250725)
+++ gcc/cfganal.c	(working copy)
@@ -737,23 +737,24 @@ post_order_compute (int *post_order, boo
 basic_block
 dfs_find_deadend (basic_block bb)
 {
-  bitmap visited = BITMAP_ALLOC (NULL);
+  auto_bitmap visited;
+  basic_block next = bb;
 
   for (;;)
     {
-      if (EDGE_COUNT (bb->succs) == 0
-	  || ! bitmap_set_bit (visited, bb->index))
-        {
-          BITMAP_FREE (visited);
-          return bb;
-        }
+      if (EDGE_COUNT (next->succs) == 0)
+	return next;
 
+      if (! bitmap_set_bit (visited, next->index))
+	return bb;
+
+      bb = next;
       /* If we are in an analyzed cycle make sure to try exiting it.
          Note this is a heuristic only and expected to work when loop
 	 fixup is needed as well.  */
       if (! bb->loop_father
 	  || ! loop_outer (bb->loop_father))
-	bb = EDGE_SUCC (bb, 0)->dest;
+	next = EDGE_SUCC (bb, 0)->dest;
       else
 	{
 	  edge_iterator ei;
@@ -761,7 +762,7 @@ dfs_find_deadend (basic_block bb)
 	  FOR_EACH_EDGE (e, ei, bb->succs)
 	    if (loop_exit_edge_p (bb->loop_father, e))
 	      break;
-	  bb = e ? e->dest : EDGE_SUCC (bb, 0)->dest;
+	  next = e ? e->dest : EDGE_SUCC (bb, 0)->dest;
 	}
     }
 
Index: gcc/testsuite/gcc.dg/tree-ssa/ssa-dce-3.c
===================================================================
--- gcc/testsuite/gcc.dg/tree-ssa/ssa-dce-3.c	(revision 250725)
+++ gcc/testsuite/gcc.dg/tree-ssa/ssa-dce-3.c	(working copy)
@@ -26,9 +26,6 @@ int main(void)
    by marking the j % 7 condition as useful.  See PR45178.  */
 
 /* We should eliminate the inner condition, but the loop must be preserved
-   as it is infinite.  Therefore there should be just one phi node (for i):  */
-/* { dg-final { scan-tree-dump-times "PHI " 1 "cddce1" { xfail *-*-* } } } */
-
-/* And one if (for the exit condition of the loop):  */
-/* { dg-final { scan-tree-dump-times "if " 1 "cddce1" } } */
-
+   as it is infinite.  Therefore there should be just one goto and no PHI.  */
+/* { dg-final { scan-tree-dump-times "PHI " 0 "cddce1" } } */
+/* { dg-final { scan-tree-dump-times "goto" 1 "cddce1" } } */
Index: gcc/testsuite/gcc.dg/tree-ssa/split-path-5.c
===================================================================
--- gcc/testsuite/gcc.dg/tree-ssa/split-path-5.c	(revision 250725)
+++ gcc/testsuite/gcc.dg/tree-ssa/split-path-5.c	(working copy)
@@ -41,20 +41,4 @@ bmhi_init (const char *pattern)
     }
 }
 
-char *
-bmhi_search (const char *string, const int stringlen)
-{
-  int i, j;
-  char *s;
-  for (;;)
-    {
-      while (--j >= 0 && (
-			   {
-			   __typeof__ (s[j]) __x = (s[j]);
-			   ((((__ctype_ptr__ +
-			       sizeof (""[__x]))[(int) (__x)]) &
-			     (01 | 02)) ==
-			    02) ? (int) __x - 'a' +
-			   'A' : (int) __x;}) == pat[j]);
-}}
-/* { dg-final { scan-tree-dump-times "Duplicating join block" 2 "split-paths" } } */
+/* { dg-final { scan-tree-dump-times "Duplicating join block" 1 "split-paths" } } */
Index: gcc/testsuite/gcc.dg/uninit-23.c
===================================================================
--- gcc/testsuite/gcc.dg/uninit-23.c	(revision 250725)
+++ gcc/testsuite/gcc.dg/uninit-23.c	(working copy)
@@ -15,10 +15,10 @@ ql (void)
       for (;;)
       {
         int *go;
-        int *t4 = go;
+        int *t4 = go; /* { dg-warning "is used uninitialized" } */
 
  l1:
-        *t4 = (*t4 != 0) ? 0 : 2; /* { dg-warning "may be used uninitialized" } */
+        *t4 = (*t4 != 0) ? 0 : 2;
       }
 
     if (ij != 0)



More information about the Gcc-patches mailing list