[PR82472] Update postorder number for merged partition.

Message ID HE1PR0801MB2746F844B9D5A61EF6B10ABEE74A0@HE1PR0801MB2746.eurprd08.prod.outlook.com
State New
Headers show
Series
  • [PR82472] Update postorder number for merged partition.
Related show

Commit Message

Bin Cheng Oct. 11, 2017, 10:06 a.m.
Hi,
This patch fixes the reported ICE.  Root cause is postorder number is not updated
after merging partitions in SCC.  As a result, reduction partition may not be scheduled
as the last one because partitions are sorted in descending postorder.
Bootstrap and test on x86_64 and AArch64.  Is it OK?

Thanks,
bin
2017-10-10  Bin Cheng  <bin.cheng@arm.com>

	PR tree-optimization/82472
	* tree-loop-distribution.c (sort_partitions_by_post_order): Refine
	comment.
	(break_alias_scc_partitions): Update postorder number.

gcc/testsuite
2017-10-10  Bin Cheng  <bin.cheng@arm.com>

	PR tree-optimization/82472
	* gcc.dg/tree-ssa/pr82472.c: New test.

Comments

Richard Biener Oct. 11, 2017, 12:46 p.m. | #1
On Wed, Oct 11, 2017 at 12:06 PM, Bin Cheng <Bin.Cheng@arm.com> wrote:
> Hi,
> This patch fixes the reported ICE.  Root cause is postorder number is not updated
> after merging partitions in SCC.  As a result, reduction partition may not be scheduled
> as the last one because partitions are sorted in descending postorder.
> Bootstrap and test on x86_64 and AArch64.  Is it OK?

Ok.

Richard.

> Thanks,
> bin
> 2017-10-10  Bin Cheng  <bin.cheng@arm.com>
>
>         PR tree-optimization/82472
>         * tree-loop-distribution.c (sort_partitions_by_post_order): Refine
>         comment.
>         (break_alias_scc_partitions): Update postorder number.
>
> gcc/testsuite
> 2017-10-10  Bin Cheng  <bin.cheng@arm.com>
>
>         PR tree-optimization/82472
>         * gcc.dg/tree-ssa/pr82472.c: New test.

Patch

diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr82472.c b/gcc/testsuite/gcc.dg/tree-ssa/pr82472.c
new file mode 100644
index 0000000..445c95f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr82472.c
@@ -0,0 +1,24 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-loop-distribution" } */
+
+long int xj;
+
+int
+cx (long int *ox, short int mk, char tf)
+{
+  int si, f9;
+  char *p4 = &tf;
+  short int *rm = (tf != 0) ? (short int *)&f9 : &mk;
+
+  for (f9 = 0; f9 < 2; ++f9)
+    {
+      *rm = 0;
+      *p4 = *ox;
+      si = mk;
+      xj = 0;
+      while (p4 < (char *)rm)
+        ++p4;
+    }
+
+  return si;
+}
diff --git a/gcc/tree-loop-distribution.c b/gcc/tree-loop-distribution.c
index 26b8b9a..9ffac53 100644
--- a/gcc/tree-loop-distribution.c
+++ b/gcc/tree-loop-distribution.c
@@ -1939,7 +1939,8 @@  build_partition_graph (struct graph *rdg,
   return pg;
 }
 
-/* Sort partitions in PG by post order and store them in PARTITIONS.  */
+/* Sort partitions in PG in descending post order and store them in
+   PARTITIONS.  */
 
 static void
 sort_partitions_by_post_order (struct graph *pg,
@@ -1948,7 +1949,7 @@  sort_partitions_by_post_order (struct graph *pg,
   int i;
   struct pg_vdata *data;
 
-  /* Now order the remaining nodes in postorder.  */
+  /* Now order the remaining nodes in descending postorder.  */
   qsort (pg->vertices, pg->n_vertices, sizeof (vertex), pgcmp);
   partitions->truncate (0);
   for (i = 0; i < pg->n_vertices; ++i)
@@ -2044,7 +2045,7 @@  break_alias_scc_partitions (struct graph *rdg,
 			    vec<struct partition *> *partitions,
 			    vec<ddr_p> *alias_ddrs)
 {
-  int i, j, num_sccs, num_sccs_no_alias;
+  int i, j, k, num_sccs, num_sccs_no_alias;
   /* Build partition dependence graph.  */
   graph *pg = build_partition_graph (rdg, partitions, false);
 
@@ -2117,18 +2118,26 @@  break_alias_scc_partitions (struct graph *rdg,
 	  for (j = 0; partitions->iterate (j, &first); ++j)
 	    if (cbdata.vertices_component[j] == i)
 	      break;
-	  for (++j; partitions->iterate (j, &partition); ++j)
+	  for (k = j + 1; partitions->iterate (k, &partition); ++k)
 	    {
 	      struct pg_vdata *data;
 
-	      if (cbdata.vertices_component[j] != i)
+	      if (cbdata.vertices_component[k] != i)
 		continue;
 
+	      /* Update postorder number so that merged reduction partition is
+		 sorted after other partitions.  */
+	      if (!partition_reduction_p (first)
+		  && partition_reduction_p (partition))
+		{
+		  gcc_assert (pg->vertices[k].post < pg->vertices[j].post);
+		  pg->vertices[j].post = pg->vertices[k].post;
+		}
 	      partition_merge_into (NULL, first, partition, FUSE_SAME_SCC);
-	      (*partitions)[j] = NULL;
+	      (*partitions)[k] = NULL;
 	      partition_free (partition);
-	      data = (struct pg_vdata *)pg->vertices[j].data;
-	      gcc_assert (data->id == j);
+	      data = (struct pg_vdata *)pg->vertices[k].data;
+	      gcc_assert (data->id == k);
 	      data->partition = NULL;
 	    }
 	}