summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAldy Hernandez <aldyh@redhat.com>2013-07-14 16:25:52 -0700
committerAldy Hernandez <aldyh@redhat.com>2013-07-14 16:25:52 -0700
commita4183a15d58747753542074239739de6b98ff4d8 (patch)
tree474ba333feaf0cb7e3a541762b2968ca17aa31ea
parent564a9fa14ef114c12a4c070a92abf9474ee04298 (diff)
downloadgcc-a4183a15d58747753542074239739de6b98ff4d8.tar.gz
Cilk Plus #pragma simd iteration with Jason.aldyh/cilk-simd-merge
-rw-r--r--gcc/c-family/c-cilkplus.c40
-rw-r--r--gcc/c-family/c-common.h4
-rw-r--r--gcc/c/c-parser.c5
-rw-r--r--gcc/c/c-typeck.c2
-rw-r--r--gcc/cp/cp-cilkplus.c3
-rw-r--r--gcc/cp/parser.c7
-rw-r--r--gcc/gimplify.c3
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/PS/for1.c4
8 files changed, 42 insertions, 26 deletions
diff --git a/gcc/c-family/c-cilkplus.c b/gcc/c-family/c-cilkplus.c
index 111321bc9f2..7b80c3f017b 100644
--- a/gcc/c-family/c-cilkplus.c
+++ b/gcc/c-family/c-cilkplus.c
@@ -182,15 +182,23 @@ c_check_cilk_loop_body (tree body)
}
/* Validate a _Cilk_for construct (or a #pragma simd for loop, which
- has the same syntactic restrictions). Returns TRUE if there were
- no errors, FALSE otherwise. LOC is the location of the for. DECL
- is the controlling variable. COND is the condition. INCRP is a
- pointer the increment expression (in case, the increment needs to
- be canonicalized). BODY is the body of the LOOP. */
+ has the same syntactic restrictions).
+
+ Returns TRUE if there were no errors, FALSE otherwise.
+
+ LOC is the location of the for.
+ DECL is the controlling variable.
+ COND is the condition.
+
+ INCRP is a pointer the increment expression (in case the increment
+ needs to be canonicalized).
+
+ BODY is the body of the LOOP.
+ SCAN_BODY is true if the body must be checked. */
static bool
c_check_cilk_loop (location_t loc, tree decl, tree cond, tree *incrp,
- tree body)
+ tree body, bool scan_body)
{
tree incr = *incrp;
@@ -225,8 +233,8 @@ c_check_cilk_loop (location_t loc, tree decl, tree cond, tree *incrp,
if (!INTEGRAL_TYPE_P (TREE_TYPE (decl))
&& !POINTER_TYPE_P (TREE_TYPE (decl)))
{
- error_at (loc, "initialization variable must be of integral "
- "or pointer type");
+ error_at (loc, "induction variable must be of integral "
+ "or pointer type (have %qT)", TREE_TYPE (decl));
return false;
}
@@ -271,7 +279,7 @@ c_check_cilk_loop (location_t loc, tree decl, tree cond, tree *incrp,
return false;
*incrp = incr;
- if (!c_check_cilk_loop_body (body))
+ if (scan_body && !c_check_cilk_loop_body (body))
return false;
return true;
@@ -295,6 +303,7 @@ adjust_clauses_for_omp (tree clauses)
INCR is the increment expression.
BODY is the body of the loop.
CLAUSES are the clauses associated with the pragma simd loop.
+ SCAN_BODY is true if the body of the loop must be verified.
Returns the generated statement. */
@@ -303,11 +312,12 @@ c_finish_cilk_simd_loop (location_t loc,
tree decl,
tree init, tree cond, tree incr,
tree body,
- tree clauses)
+ tree clauses,
+ bool scan_body)
{
location_t rhs_loc;
- if (!c_check_cilk_loop (loc, decl, cond, &incr, body))
+ if (!c_check_cilk_loop (loc, decl, cond, &incr, body, scan_body))
return NULL;
/* In the case of "for (int i = 0...)", init will be a decl. It should
@@ -324,13 +334,13 @@ c_finish_cilk_simd_loop (location_t loc,
return NULL;
}
- init = build_modify_expr (loc, decl, NULL_TREE, NOP_EXPR, rhs_loc,
- init, NULL_TREE);
+ init = build2 (INIT_EXPR, TREE_TYPE (decl), decl, init);
+ DECL_INITIAL (decl) = NULL;
}
// The C++ parser just gives us the rhs.
if (TREE_CODE (init) != MODIFY_EXPR)
- init = build2 (MODIFY_EXPR, void_type_node, decl, init);
+ init = build2 (INIT_EXPR, TREE_TYPE (decl), decl, init);
gcc_assert (TREE_OPERAND (init, 0) == decl);
@@ -393,7 +403,7 @@ c_finish_cilk_clauses (tree clauses)
error_at (OMP_CLAUSE_LOCATION (c2),
"variable appears in more than one clause");
inform (OMP_CLAUSE_LOCATION (c),
- "multiple clause defined here");
+ "other clause defined here");
// Remove problematic clauses.
OMP_CLAUSE_CHAIN (prev) = OMP_CLAUSE_CHAIN (c2);
}
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index 2cf1e14dec7..70d36566e33 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -523,7 +523,7 @@ struct GTY(()) c_language_function {
/* In c-cilkplus.c */
extern tree c_finish_cilk_simd_loop (location_t, tree, tree, tree, tree,
- tree, tree);
+ tree, tree, bool);
extern tree c_finish_cilk_clauses (tree);
/* Language-specific hooks. */
@@ -1143,7 +1143,7 @@ extern enum stv_conv scalar_to_vector (location_t loc, enum tree_code code,
/* In c-cilkplus.c */
extern tree c_finish_cilk_simd_loop (location_t, tree, tree, tree, tree,
- tree, tree);
+ tree, tree, bool);
extern tree c_finish_cilk_clauses (tree);
extern tree c_validate_cilk_plus_loop (tree *, int *, void *);
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index b5c09f9601f..3570912f9e3 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -11090,7 +11090,7 @@ c_parser_cilk_for_statement (c_parser *parser, enum rid for_keyword,
{
error_init:
c_parser_error (parser,
- "expected iteration declaration or initialization");
+ "expected induction variable initialization");
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
"expected %<)%>");
return;
@@ -11137,7 +11137,8 @@ c_parser_cilk_for_statement (c_parser *parser, enum rid for_keyword,
if (!fail)
{
if (for_keyword == RID_FOR)
- c_finish_cilk_simd_loop (loc, decl, init, cond, incr, body, clauses);
+ c_finish_cilk_simd_loop (loc, decl, init, cond, incr, body, clauses,
+ /*scan_body=*/true);
}
stmt = c_end_compound_stmt (loc, block, true);
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index d5e41759976..4a64bb670c3 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -9157,7 +9157,7 @@ c_finish_bc_stmt (location_t loc, tree *label_p, bool is_break)
if (is_break)
error ("break statement within <#pragma simd> loop body");
else
- error ("continue statement within <#pragma simd> loop loop");
+ error ("continue statement within <#pragma simd> loop body");
return NULL_TREE;
default:
diff --git a/gcc/cp/cp-cilkplus.c b/gcc/cp/cp-cilkplus.c
index aa803438e5d..ef3bbef9f2c 100644
--- a/gcc/cp/cp-cilkplus.c
+++ b/gcc/cp/cp-cilkplus.c
@@ -46,6 +46,9 @@ cpp_validate_cilk_plus_loop_aux (tree *tp, int *walk_subtrees, void *data)
if (!tp || !*tp)
return NULL_TREE;
+ // Validate the C common bits.
+ c_validate_cilk_plus_loop (tp, walk_subtrees, data);
+
if (TREE_CODE (*tp) == THROW_EXPR)
{
error_at (loc, "throw expressions are not allowed inside loops "
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index b6c128941ad..224fea184bd 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -10404,7 +10404,7 @@ cp_parser_jump_statement (cp_parser* parser)
break;
case IN_CILK_P_SIMD_FOR:
error_at (token->location,
- "continue statement within <#pragma simd> loop loop");
+ "continue statement within <#pragma simd> loop body");
break;
default:
gcc_unreachable ();
@@ -29077,7 +29077,7 @@ cp_parser_simd_for_init_statement (cp_parser *parser, tree *init,
tree this_pre_body = push_stmt_list ();
if (token->type == CPP_SEMICOLON)
{
- error_at (loc, "expected iteration declaration");
+ error_at (loc, "expected induction variable");
return error_mark_node;
}
@@ -29328,7 +29328,8 @@ cp_parser_cilk_for (cp_parser *parser, enum rid for_keyword, tree clauses)
return error_mark_node;
return c_finish_cilk_simd_loop (loc, decl, init, cond, incr_expr,
- body, clauses);
+ body, clauses,
+ /*scan_body=*/false);
}
else
{
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 3b09ea827b2..a296471e5eb 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -6626,7 +6626,8 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
{
t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
- gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
+ gcc_assert (TREE_CODE (t) == MODIFY_EXPR
+ || TREE_CODE (t) == INIT_EXPR);
decl = TREE_OPERAND (t, 0);
gcc_assert (DECL_P (decl));
gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (decl))
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/PS/for1.c b/gcc/testsuite/c-c++-common/cilk-plus/PS/for1.c
index 04773d12755..e9e140d40f0 100644
--- a/gcc/testsuite/c-c++-common/cilk-plus/PS/for1.c
+++ b/gcc/testsuite/c-c++-common/cilk-plus/PS/for1.c
@@ -15,7 +15,7 @@ void foo()
// Empty initialization is not allowed.
#pragma simd
- for (; i < 5; ++i) // { dg-error "expected iteration decl" }
+ for (; i < 5; ++i) // { dg-error "expected induction variable" }
a[i] = i;
// Empty condition is not allowed.
@@ -36,7 +36,7 @@ void foo()
int i;
};
#pragma simd
- for (struct S ss = { 0 }; ss.i <= 1000; ++ss.i) /* { dg-error "initialization variable must be of integral or pointer type" } */
+ for (struct S ss = { 0 }; ss.i <= 1000; ++ss.i) /* { dg-error "induction variable must be of integral or pointer type" } */
a[ss.i] = b[ss.i];
#pragma simd