aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorSebastian Pop <sebastian.pop@amd.com>2010-12-15 05:04:30 +0000
committerSebastian Pop <spop@gcc.gnu.org>2010-12-15 05:04:30 +0000
commitab2210870b28990071af15a53ce817a3fc6d5af8 (patch)
treeb6244af510098066a33efd97408230f217050a23 /gcc
parent56fb2b3625d4e32d019024e9c5f8a5d07e185f38 (diff)
downloadgcc-ab2210870b28990071af15a53ce817a3fc6d5af8.zip
gcc-ab2210870b28990071af15a53ce817a3fc6d5af8.tar.gz
gcc-ab2210870b28990071af15a53ce817a3fc6d5af8.tar.bz2
Fix PR45948: add ssa defs from builtin partitions to the last partition.
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ldist-pr45948.c23
-rw-r--r--gcc/tree-loop-distribution.c98
4 files changed, 135 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 1519ede..9818c03 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 60e48b3..a8c6941 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..3e467bd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ldist-pr45948.c
@@ -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" } } */
diff --git a/gcc/tree-loop-distribution.c b/gcc/tree-loop-distribution.c
index b603209..a9ee67f 100644
--- a/gcc/tree-loop-distribution.c
+++ b/gcc/tree-loop-distribution.c
@@ -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);