[PATCH 1/3] backport patch to fix PR65048

Sebastian Pop s.pop@samsung.com
Mon Aug 31 15:33:00 GMT 2015


PR tree-optimization/65048
	* tree-ssa-threadupdate.c (valid_jump_thread_path): New.
	(thread_through_all_blocks): Call valid_jump_thread_path.      Remove invalid
	FSM jump-thread paths.

 PR tree-optimization/65048
 * gcc.dg/tree-ssa/ssa-dom-thread-9.c: New.
---
 .../testsuite/gcc.dg/tree-ssa/ssa-dom-thread-9.c   | 50 ++++++++++++++++++++++
 gcc-4.9/gcc/tree-ssa-threadupdate.c                | 40 ++++++++++++++---
 2 files changed, 84 insertions(+), 6 deletions(-)
 create mode 100644 gcc-4.9/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-9.c

diff --git a/gcc-4.9/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-9.c b/gcc-4.9/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-9.c
new file mode 100644
index 0000000..6be4203
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-9.c
@@ -0,0 +1,50 @@
+/* PR 65048 */
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+
+int a, b, c, d;
+void fn (void);
+
+int
+foo (x)
+{
+  switch (x)
+    {
+    case 'A':
+      return 'T';
+    case 'U':
+      return 'A';
+    }
+}
+
+void
+bar (int x, int y)
+{
+  switch (c)
+    {
+    case 'U':
+      switch (x)
+	{
+	default:
+	  fn ();
+	case 'G':
+	  switch (y)
+	    {
+	    case 'A':
+	      d = 7;
+	    }
+	}
+    }
+}
+
+void
+baz (void)
+{
+  while (1)
+    {
+      a = foo ();
+      b = foo ();
+      bar (a, b);
+    }
+}
+
diff --git a/gcc-4.9/gcc/tree-ssa-threadupdate.c b/gcc-4.9/gcc/tree-ssa-threadupdate.c
index d1b289f..3c7df9a 100644
--- a/gcc-4.9/gcc/tree-ssa-threadupdate.c
+++ b/gcc-4.9/gcc/tree-ssa-threadupdate.c
@@ -1772,6 +1772,21 @@ duplicate_seme_region (edge entry, edge exit,
   return true;
 }
 
+/* Return true when PATH is a valid jump-thread path.  */
+
+static bool
+valid_jump_thread_path (vec<jump_thread_edge *> *path)
+{
+  unsigned len = path->length ();
+
+  /* Check that the path is connected.  */
+  for (unsigned int j = 0; j < len - 1; j++)
+    if ((*path)[j]->e->dest != (*path)[j+1]->e->src)
+      return false;
+
+  return true;
+}
+
 /* Walk through all blocks and thread incoming edges to the appropriate
    outgoing edge for each edge pair recorded in THREADED_EDGES.
 
@@ -1807,12 +1822,25 @@ thread_through_all_blocks (bool may_peel_loop_headers)
       vec<jump_thread_edge *> *path = paths[i];
       edge entry = (*path)[0]->e;
 
-      if ((*path)[0]->type != EDGE_FSM_THREAD
-	  /* Do not jump-thread twice from the same block.  */
-	  || bitmap_bit_p (threaded_blocks, entry->src->index)) {
-	i++;
-	continue;
-      }
+      /* Only code-generate FSM jump-threads in this loop.  */
+      if ((*path)[0]->type != EDGE_FSM_THREAD)
+	{
+	  i++;
+	  continue;
+	}
+
+      /* Do not jump-thread twice from the same block.  */
+      if (bitmap_bit_p (threaded_blocks, entry->src->index)
+	  /* Verify that the jump thread path is still valid: a
+	     previous jump-thread may have changed the CFG, and
+	     invalidated the current path.  */
+	  || !valid_jump_thread_path (path))
+	{
+	  /* Remove invalid FSM jump-thread paths.  */
+	  delete_jump_thread_path (path);
+	  paths.unordered_remove (i);
+	  continue;
+	}
 
       unsigned len = path->length ();
       edge exit = (*path)[len - 1]->e;
-- 
2.1.0.243.g30d45f7



More information about the Gcc-patches mailing list