summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2014-04-24 23:17:32 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2014-04-24 23:17:32 +0200
commitf7468577f88cbfe33e0a5e9a2104a32f7e45c44f (patch)
tree58c72224fbdd8cfd29b26acb0ed228ad9bf56b58 /gcc
parent2f7ac5ce576962dc7610d8cb3e0b107b05d77bbf (diff)
downloadgcc-f7468577f88cbfe33e0a5e9a2104a32f7e45c44f.tar.gz
tree.h (OMP_CLAUSE_LINEAR_GIMPLE_SEQ): Define.
* tree.h (OMP_CLAUSE_LINEAR_GIMPLE_SEQ): Define. * gimplify.c (omp_is_private): Change last argument's type to int. Only diagnose lastprivate if the simd argument is 1, only diagnose linear if the simd argument is 2. (gimplify_omp_for): Adjust omp_is_private callers. When adding lastprivate or private, add the clause to OMP_FOR_CLAUSES. Pass GOVD_EXPLICIT to omp_add_variable. For simd with collapse == 1 create OMP_CLAUSE_LINEAR rather than OMP_CLAUSE_PRIVATE for var. If var != decl and decl is in OMP_CLAUSE_LINEAR, gimplify decl increment to OMP_CLAUSE_LINEAR_GIMPLE_SEQ. * omp-low.c (scan_sharing_clauses, lower_lastprivate_clauses): Handle OMP_CLAUSE_LINEAR_GIMPLE_SEQ. * tree-nested.c (convert_nonlocal_omp_clauses, convert_local_omp_clauses): Handle OMP_CLAUSE_LINEAR. * testsuite/libgomp.c/simd-7.c: New test. * testsuite/libgomp.c/simd-8.c: New test. * testsuite/libgomp.c/simd-9.c: New test. * testsuite/libgomp.c/loop-16.c: New test. From-SVN: r209760
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog17
-rw-r--r--gcc/gimplify.c63
-rw-r--r--gcc/omp-low.c14
-rw-r--r--gcc/tree-nested.c22
-rw-r--r--gcc/tree.h3
5 files changed, 105 insertions, 14 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 6100b75683b..f2fce0da6b6 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,20 @@
+2014-04-24 Jakub Jelinek <jakub@redhat.com>
+
+ * tree.h (OMP_CLAUSE_LINEAR_GIMPLE_SEQ): Define.
+ * gimplify.c (omp_is_private): Change last argument's type to int.
+ Only diagnose lastprivate if the simd argument is 1, only diagnose
+ linear if the simd argument is 2.
+ (gimplify_omp_for): Adjust omp_is_private callers. When adding
+ lastprivate or private, add the clause to OMP_FOR_CLAUSES. Pass
+ GOVD_EXPLICIT to omp_add_variable. For simd with collapse == 1
+ create OMP_CLAUSE_LINEAR rather than OMP_CLAUSE_PRIVATE for var.
+ If var != decl and decl is in OMP_CLAUSE_LINEAR, gimplify decl
+ increment to OMP_CLAUSE_LINEAR_GIMPLE_SEQ.
+ * omp-low.c (scan_sharing_clauses, lower_lastprivate_clauses): Handle
+ OMP_CLAUSE_LINEAR_GIMPLE_SEQ.
+ * tree-nested.c (convert_nonlocal_omp_clauses,
+ convert_local_omp_clauses): Handle OMP_CLAUSE_LINEAR.
+
2014-04-24 Segher Boessenkool <segher@kernel.crashing.org>
PR target/60822
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index d7470fbb0a6..008a2528644 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -5796,7 +5796,7 @@ omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code)
to the contrary in the innermost scope, generate an error. */
static bool
-omp_is_private (struct gimplify_omp_ctx *ctx, tree decl, bool simd)
+omp_is_private (struct gimplify_omp_ctx *ctx, tree decl, int simd)
{
splay_tree_node n;
@@ -5830,13 +5830,13 @@ omp_is_private (struct gimplify_omp_ctx *ctx, tree decl, bool simd)
else if ((n->value & GOVD_REDUCTION) != 0)
error ("iteration variable %qE should not be reduction",
DECL_NAME (decl));
- else if (simd && (n->value & GOVD_LASTPRIVATE) != 0)
+ else if (simd == 1 && (n->value & GOVD_LASTPRIVATE) != 0)
error ("iteration variable %qE should not be lastprivate",
DECL_NAME (decl));
else if (simd && (n->value & GOVD_PRIVATE) != 0)
error ("iteration variable %qE should not be private",
DECL_NAME (decl));
- else if (simd && (n->value & GOVD_LINEAR) != 0)
+ else if (simd == 2 && (n->value & GOVD_LINEAR) != 0)
error ("iteration variable %qE is predetermined linear",
DECL_NAME (decl));
}
@@ -6602,8 +6602,8 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
orig_for_stmt = for_stmt = *expr_p;
- simd = TREE_CODE (for_stmt) == OMP_SIMD
- || TREE_CODE (for_stmt) == CILK_SIMD;
+ simd = (TREE_CODE (for_stmt) == OMP_SIMD
+ || TREE_CODE (for_stmt) == CILK_SIMD);
gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (for_stmt), pre_p,
simd ? ORT_SIMD : ORT_WORKSHARE);
@@ -6659,13 +6659,16 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
/* Make sure the iteration variable is private. */
tree c = NULL_TREE;
+ tree c2 = NULL_TREE;
if (orig_for_stmt != for_stmt)
/* Do this only on innermost construct for combined ones. */;
else if (simd)
{
splay_tree_node n = splay_tree_lookup (gimplify_omp_ctxp->variables,
(splay_tree_key)decl);
- omp_is_private (gimplify_omp_ctxp, decl, simd);
+ omp_is_private (gimplify_omp_ctxp, decl,
+ 1 + (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
+ != 1));
if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
omp_notice_variable (gimplify_omp_ctxp, decl, true);
else if (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
@@ -6691,13 +6694,14 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
: OMP_CLAUSE_PRIVATE);
OMP_CLAUSE_DECL (c) = decl;
OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
+ OMP_FOR_CLAUSES (for_stmt) = c;
omp_add_variable (gimplify_omp_ctxp, decl,
(lastprivate ? GOVD_LASTPRIVATE : GOVD_PRIVATE)
- | GOVD_SEEN);
+ | GOVD_EXPLICIT | GOVD_SEEN);
c = NULL_TREE;
}
}
- else if (omp_is_private (gimplify_omp_ctxp, decl, simd))
+ else if (omp_is_private (gimplify_omp_ctxp, decl, 0))
omp_notice_variable (gimplify_omp_ctxp, decl, true);
else
omp_add_variable (gimplify_omp_ctxp, decl, GOVD_PRIVATE | GOVD_SEEN);
@@ -6714,7 +6718,25 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
gimplify_seq_add_stmt (&for_body, gimple_build_assign (decl, var));
- omp_add_variable (gimplify_omp_ctxp, var, GOVD_PRIVATE | GOVD_SEEN);
+ if (simd && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
+ {
+ c2 = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
+ OMP_CLAUSE_LINEAR_NO_COPYIN (c2) = 1;
+ OMP_CLAUSE_LINEAR_NO_COPYOUT (c2) = 1;
+ OMP_CLAUSE_DECL (c2) = var;
+ OMP_CLAUSE_CHAIN (c2) = OMP_FOR_CLAUSES (for_stmt);
+ OMP_FOR_CLAUSES (for_stmt) = c2;
+ omp_add_variable (gimplify_omp_ctxp, var,
+ GOVD_LINEAR | GOVD_EXPLICIT | GOVD_SEEN);
+ if (c == NULL_TREE)
+ {
+ c = c2;
+ c2 = NULL_TREE;
+ }
+ }
+ else
+ omp_add_variable (gimplify_omp_ctxp, var,
+ GOVD_PRIVATE | GOVD_SEEN);
}
else
var = decl;
@@ -6817,13 +6839,22 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
gcc_unreachable ();
}
+ if (c2)
+ {
+ gcc_assert (c);
+ OMP_CLAUSE_LINEAR_STEP (c2) = OMP_CLAUSE_LINEAR_STEP (c);
+ }
+
if ((var != decl || TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) > 1)
&& orig_for_stmt == for_stmt)
{
for (c = OMP_FOR_CLAUSES (for_stmt); c ; c = OMP_CLAUSE_CHAIN (c))
- if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
- && OMP_CLAUSE_DECL (c) == decl
- && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c) == NULL)
+ if (((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
+ && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c) == NULL)
+ || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
+ && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)
+ && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c) == NULL))
+ && OMP_CLAUSE_DECL (c) == decl)
{
t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
@@ -6835,8 +6866,12 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
gcc_assert (TREE_OPERAND (t, 0) == var);
t = build2 (TREE_CODE (t), TREE_TYPE (decl), decl,
TREE_OPERAND (t, 1));
- gimplify_assign (decl, t,
- &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c));
+ gimple_seq *seq;
+ if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
+ seq = &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c);
+ else
+ seq = &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c);
+ gimplify_assign (decl, t, seq);
}
}
}
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index d0489e136e2..28b2c6aea8c 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -1730,6 +1730,9 @@ scan_sharing_clauses (tree clauses, omp_context *ctx)
if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
&& OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
scan_array_reductions = true;
+ else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
+ && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c))
+ scan_array_reductions = true;
break;
case OMP_CLAUSE_SHARED:
@@ -1816,6 +1819,9 @@ scan_sharing_clauses (tree clauses, omp_context *ctx)
else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
&& OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c))
scan_omp (&OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c), ctx);
+ else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
+ && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c))
+ scan_omp (&OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c), ctx);
}
/* Create a new name for omp child function. Returns an identifier. */
@@ -3803,6 +3809,14 @@ lower_lastprivate_clauses (tree clauses, tree predicate, gimple_seq *stmt_list,
OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c));
OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c) = NULL;
}
+ else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
+ && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c))
+ {
+ lower_omp (&OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c), ctx);
+ gimple_seq_add_seq (stmt_list,
+ OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c));
+ OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c) = NULL;
+ }
x = build_outer_var_ref (var, ctx);
if (is_reference (var))
diff --git a/gcc/tree-nested.c b/gcc/tree-nested.c
index df6923f76ef..9c175de4e9d 100644
--- a/gcc/tree-nested.c
+++ b/gcc/tree-nested.c
@@ -1082,6 +1082,11 @@ convert_nonlocal_omp_clauses (tree *pclauses, struct walk_stmt_info *wi)
need_stmts = true;
goto do_decl_clause;
+ case OMP_CLAUSE_LINEAR:
+ if (OMP_CLAUSE_LINEAR_GIMPLE_SEQ (clause))
+ need_stmts = true;
+ goto do_decl_clause;
+
case OMP_CLAUSE_PRIVATE:
case OMP_CLAUSE_FIRSTPRIVATE:
case OMP_CLAUSE_COPYPRIVATE:
@@ -1157,6 +1162,12 @@ convert_nonlocal_omp_clauses (tree *pclauses, struct walk_stmt_info *wi)
&OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (clause));
break;
+ case OMP_CLAUSE_LINEAR:
+ walk_body (convert_nonlocal_reference_stmt,
+ convert_nonlocal_reference_op, info,
+ &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (clause));
+ break;
+
default:
break;
}
@@ -1605,6 +1616,11 @@ convert_local_omp_clauses (tree *pclauses, struct walk_stmt_info *wi)
need_stmts = true;
goto do_decl_clause;
+ case OMP_CLAUSE_LINEAR:
+ if (OMP_CLAUSE_LINEAR_GIMPLE_SEQ (clause))
+ need_stmts = true;
+ goto do_decl_clause;
+
case OMP_CLAUSE_PRIVATE:
case OMP_CLAUSE_FIRSTPRIVATE:
case OMP_CLAUSE_COPYPRIVATE:
@@ -1685,6 +1701,12 @@ convert_local_omp_clauses (tree *pclauses, struct walk_stmt_info *wi)
&OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (clause));
break;
+ case OMP_CLAUSE_LINEAR:
+ walk_body (convert_local_reference_stmt,
+ convert_local_reference_op, info,
+ &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (clause));
+ break;
+
default:
break;
}
diff --git a/gcc/tree.h b/gcc/tree.h
index 9ad0b6fdd9f..ae4876dd462 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -1330,6 +1330,9 @@ extern void protected_set_expr_location (tree, location_t);
#define OMP_CLAUSE_LINEAR_STEP(NODE) \
OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_LINEAR), 1)
+#define OMP_CLAUSE_LINEAR_GIMPLE_SEQ(NODE) \
+ (OMP_CLAUSE_CHECK (NODE))->omp_clause.gimple_reduction_init
+
#define OMP_CLAUSE_ALIGNED_ALIGNMENT(NODE) \
OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_ALIGNED), 1)