From a4183a15d58747753542074239739de6b98ff4d8 Mon Sep 17 00:00:00 2001 From: Aldy Hernandez Date: Sun, 14 Jul 2013 16:25:52 -0700 Subject: [PATCH] Cilk Plus #pragma simd iteration with Jason. --- gcc/c-family/c-cilkplus.c | 40 ++++++++++++++++---------- gcc/c-family/c-common.h | 4 +-- gcc/c/c-parser.c | 5 ++-- gcc/c/c-typeck.c | 2 +- gcc/cp/cp-cilkplus.c | 3 ++ gcc/cp/parser.c | 7 +++-- gcc/gimplify.c | 3 +- gcc/testsuite/c-c++-common/cilk-plus/PS/for1.c | 4 +-- 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 -- 2.11.4.GIT