aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/omp-low.c31
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/gomp/pr30421.c39
4 files changed, 77 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 08bff59..252b419 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2007-01-24 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/30421
+ * omp-low.c (lower_omp_for_lastprivate): Add dlist argument.
+ If lower_lastprivate_clauses emits some statements, append them
+ to dlist rather than body_p and to body_p append an initializer.
+ (lower_omp_for): Adjust caller.
+
2007-01-24 Steve Ellcey <sje@cup.hp.com>
* target.h (globalize_decl_name): New.
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index e863568..e5a320d 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -1601,7 +1601,7 @@ omp_reduction_init (tree clause, tree type)
static void
lower_rec_input_clauses (tree clauses, tree *ilist, tree *dlist,
- omp_context *ctx)
+ omp_context *ctx)
{
tree_stmt_iterator diter;
tree c, dtor, copyin_seq, x, args, ptr;
@@ -3986,13 +3986,14 @@ lower_omp_critical (tree *stmt_p, omp_context *ctx)
/* A subroutine of lower_omp_for. Generate code to emit the predicate
for a lastprivate clause. Given a loop control predicate of (V
cond N2), we gate the clause on (!(V cond N2)). The lowered form
- is appended to *BODY_P. */
+ is appended to *DLIST, iterator initialization is appended to
+ *BODY_P. */
static void
lower_omp_for_lastprivate (struct omp_for_data *fd, tree *body_p,
- struct omp_context *ctx)
+ tree *dlist, struct omp_context *ctx)
{
- tree clauses, cond;
+ tree clauses, cond, stmts, vinit, t;
enum tree_code cond_code;
cond_code = fd->cond_code;
@@ -4010,7 +4011,24 @@ lower_omp_for_lastprivate (struct omp_for_data *fd, tree *body_p,
cond = build2 (cond_code, boolean_type_node, fd->v, fd->n2);
clauses = OMP_FOR_CLAUSES (fd->for_stmt);
- lower_lastprivate_clauses (clauses, cond, body_p, ctx);
+ stmts = NULL;
+ lower_lastprivate_clauses (clauses, cond, &stmts, ctx);
+ if (stmts != NULL)
+ {
+ append_to_statement_list (stmts, dlist);
+
+ /* Optimize: v = 0; is usually cheaper than v = some_other_constant. */
+ vinit = fd->n1;
+ if (cond_code == EQ_EXPR
+ && host_integerp (fd->n2, 0)
+ && ! integer_zerop (fd->n2))
+ vinit = build_int_cst (TREE_TYPE (fd->v), 0);
+
+ /* Initialize the iterator variable, so that threads that don't execute
+ any iterations don't execute the lastprivate clauses by accident. */
+ t = build2 (GIMPLE_MODIFY_STMT, void_type_node, fd->v, vinit);
+ gimplify_and_add (t, body_p);
+ }
}
@@ -4066,6 +4084,8 @@ lower_omp_for (tree *stmt_p, omp_context *ctx)
/* Once lowered, extract the bounds and clauses. */
extract_omp_for_data (stmt, &fd);
+ lower_omp_for_lastprivate (&fd, body_p, &dlist, ctx);
+
append_to_statement_list (stmt, body_p);
append_to_statement_list (OMP_FOR_BODY (stmt), body_p);
@@ -4074,7 +4094,6 @@ lower_omp_for (tree *stmt_p, omp_context *ctx)
append_to_statement_list (t, body_p);
/* After the loop, add exit clauses. */
- lower_omp_for_lastprivate (&fd, &dlist, ctx);
lower_reduction_clauses (OMP_FOR_CLAUSES (stmt), body_p, ctx);
append_to_statement_list (dlist, body_p);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 219ef9a..2d9fc84 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2007-01-24 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/30421
+ * gcc.dg/gomp/pr30421.c: New test.
+
2007-01-24 Steve Ellcey <sje@cup.hp.com>
* gcc.target/ia64/versionid-1.c: New test.
diff --git a/gcc/testsuite/gcc.dg/gomp/pr30421.c b/gcc/testsuite/gcc.dg/gomp/pr30421.c
new file mode 100644
index 0000000..901ba3c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/gomp/pr30421.c
@@ -0,0 +1,39 @@
+/* PR middle-end/30421 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fopenmp -Wall" } */
+
+int
+foo ()
+{
+ int a = 0, i;
+
+#pragma omp parallel for firstprivate(a) lastprivate(a)
+ for (i = 0; i < 10; i++)
+ a += i;
+
+ return a;
+}
+
+int
+bar ()
+{
+ int a = 0, i;
+
+#pragma omp parallel for firstprivate(a) lastprivate(a) schedule(static, 2)
+ for (i = 0; i < 10; i++)
+ a += i;
+
+ return a;
+}
+
+int
+baz ()
+{
+ int a = 0, i;
+
+#pragma omp parallel for firstprivate(a) lastprivate(a) schedule(dynamic)
+ for (i = 0; i < 10; i++)
+ a += i;
+
+ return a;
+}