]> gcc.gnu.org Git - gcc.git/commitdiff
Fix PR45948: add ssa defs from builtin partitions to the last partition.
authorSebastian Pop <sebastian.pop@amd.com>
Wed, 15 Dec 2010 05:04:30 +0000 (05:04 +0000)
committerSebastian Pop <spop@gcc.gnu.org>
Wed, 15 Dec 2010 05:04:30 +0000 (05:04 +0000)
2010-12-14  Sebastian Pop  <sebastian.pop@amd.com>

PR tree-optimization/45948
* tree-loop-distribution.c (ssa_name_has_uses_outside_loop_p): New.
(stmt_has_scalar_dependences_outside_loop): New.
(stmt_generated_in_another_partition): New.
(add_scalar_computations_to_partition): New.
(rdg_build_partitions): Call add_scalar_computations_to_partition.

* gcc.dg/tree-ssa/ldist-pr45948.c: New.

From-SVN: r167842

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/ldist-pr45948.c [new file with mode: 0644]
gcc/tree-loop-distribution.c

index 1519ede4b8001d1d95f827a173ada4e7a7fe4ac8..9818c03dc53b1c609113a6c2760238d81c9c052a 100644 (file)
@@ -1,3 +1,12 @@
+2010-12-14  Sebastian Pop  <sebastian.pop@amd.com>
+
+       PR tree-optimization/45948
+       * tree-loop-distribution.c (ssa_name_has_uses_outside_loop_p): New.
+       (stmt_has_scalar_dependences_outside_loop): New.
+       (stmt_generated_in_another_partition): New.
+       (add_scalar_computations_to_partition): New.
+       (rdg_build_partitions): Call add_scalar_computations_to_partition.
+
 2010-12-14  Joseph Myers  <joseph@codesourcery.com>
 
        * config/arc/arc.h (LIB_SPEC): Define.
index 60e48b39d0cabc1d7b64f8adbc33f5bc5e827b2c..a8c6941c7634a972bc295d3559df0b6fbccda725 100644 (file)
@@ -1,3 +1,8 @@
+2010-12-14  Sebastian Pop  <sebastian.pop@amd.com>
+
+       PR tree-optimization/45948
+       * gcc.dg/tree-ssa/ldist-pr45948.c: New.
+
 2010-12-14  Jason Merrill  <jason@redhat.com>
 
        PR c++/46930
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ldist-pr45948.c b/gcc/testsuite/gcc.dg/tree-ssa/ldist-pr45948.c
new file mode 100644 (file)
index 0000000..3e467bd
--- /dev/null
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-loop-distribution -fdump-tree-ldist-details" } */
+
+extern void bar(int);
+
+void
+foo (int i, int n)
+{
+  int a[30];
+  int b[30];
+  for (; i < n; i++)
+    a[i] = b[i] = 0;
+
+  while (1)
+    if (b[0])
+      bar (a[i - 1]);
+}
+
+/* We should apply loop distribution and generate 2 memset (0).  */
+
+/* { dg-final { scan-tree-dump "distributed: split to 3" "ldist" } } */
+/* { dg-final { scan-tree-dump-times "__builtin_memset" 4 "ldist" } } */
+/* { dg-final { cleanup-tree-dump "ldist" } } */
index b60320945d46773b998ccfe5c80671751e3b9034..a9ee67ff9cd930d12060eda3b7f5d2e1013d48f1 100644 (file)
@@ -808,6 +808,102 @@ fuse_partitions_with_similar_memory_accesses (struct graph *rdg,
          }
 }
 
+/* Returns true when DEF is an SSA_NAME defined in LOOP and used after
+   the LOOP.  */
+
+static bool
+ssa_name_has_uses_outside_loop_p (tree def, loop_p loop)
+{
+  imm_use_iterator imm_iter;
+  use_operand_p use_p;
+
+  FOR_EACH_IMM_USE_FAST (use_p, imm_iter, def)
+    if (loop != loop_containing_stmt (USE_STMT (use_p)))
+      return true;
+
+  return false;
+}
+
+/* Returns true when STMT defines a scalar variable used after the
+   loop.  */
+
+static bool
+stmt_has_scalar_dependences_outside_loop (gimple stmt)
+{
+  tree name;
+
+  switch (gimple_code (stmt))
+    {
+    case GIMPLE_ASSIGN:
+      name = gimple_assign_lhs (stmt);
+      break;
+
+    case GIMPLE_PHI:
+      name = gimple_phi_result (stmt);
+      break;
+
+    default:
+      return false;
+    }
+
+  return TREE_CODE (name) == SSA_NAME
+    && ssa_name_has_uses_outside_loop_p (name, loop_containing_stmt (stmt));
+}
+
+/* Returns true when STMT will be code generated in a partition of RDG
+   different than PART and that will not be code generated as a
+   builtin.  */
+
+static bool
+stmt_generated_in_another_partition (struct graph *rdg, gimple stmt, int part,
+                                    VEC (bitmap, heap) *partitions)
+{
+  int p;
+  bitmap pp;
+  unsigned i;
+  bitmap_iterator bi;
+
+  FOR_EACH_VEC_ELT (bitmap, partitions, p, pp)
+    if (p != part
+       && !can_generate_builtin (rdg, pp))
+      EXECUTE_IF_SET_IN_BITMAP (pp, 0, i, bi)
+       if (stmt == RDG_STMT (rdg, i))
+         return true;
+
+  return false;
+}
+
+/* For each partition in PARTITIONS that will be code generated using
+   a builtin, add its scalar computations used after the loop to
+   PARTITION.  */
+
+static void
+add_scalar_computations_to_partition (struct graph *rdg,
+                                     VEC (bitmap, heap) *partitions,
+                                     bitmap partition)
+{
+  int p;
+  bitmap pp;
+  unsigned i;
+  bitmap_iterator bi;
+  bitmap l = BITMAP_ALLOC (NULL);
+  bitmap pr = BITMAP_ALLOC (NULL);
+  bool f = false;
+
+  FOR_EACH_VEC_ELT (bitmap, partitions, p, pp)
+    if (can_generate_builtin (rdg, pp))
+      EXECUTE_IF_SET_IN_BITMAP (pp, 0, i, bi)
+       if (stmt_has_scalar_dependences_outside_loop (RDG_STMT (rdg, i))
+           && !stmt_generated_in_another_partition (rdg, RDG_STMT (rdg, i), p,
+                                                    partitions))
+         rdg_flag_vertex_and_dependent (rdg, i, partition, l, pr, &f);
+
+  rdg_flag_loop_exits (rdg, l, partition, pr, &f);
+
+  BITMAP_FREE (pr);
+  BITMAP_FREE (l);
+}
+
 /* Aggregate several components into a useful partition that is
    registered in the PARTITIONS vector.  Partitions will be
    distributed in different loops.  */
@@ -871,6 +967,8 @@ rdg_build_partitions (struct graph *rdg, VEC (rdgc, heap) *components,
       free_rdg_components (comps);
     }
 
+  add_scalar_computations_to_partition (rdg, *partitions, partition);
+
   /* If there is something left in the last partition, save it.  */
   if (bitmap_count_bits (partition) > 0)
     VEC_safe_push (bitmap, heap, *partitions, partition);
This page took 0.139035 seconds and 5 git commands to generate.