Hi! On Wed, 4 Nov 2015 14:10:29 -0800, Cesar Philippidis <ce...@codesourcery.com> wrote: > > [...] > > Thanks. I've applied this patch to trunk.
> gcc/cp/ > * (cp_parser_oacc_single_int_clause): New function. > (cp_parser_oacc_clause_vector_length): Delete. > (cp_parser_omp_clause_num_gangs): Delete. > (cp_parser_omp_clause_num_workers): Delete. > (cp_parser_oacc_all_clauses): Use cp_parser_oacc_single_int_clause > for num_gangs, num_workers and vector_length. Here is a similar patch for the C front end, and it also adds test cases. OK for trunk? During testing I also noticed some "strangeness" (also regarding some similar OpenMP clauses), which I'll file a PR for, later on. commit 70baf3fc0c544fe63b9d3b3bebcca88daf7ce554 Author: Thomas Schwinge <tho...@codesourcery.com> Date: Fri May 5 16:38:52 2017 +0200 OpenACC C front end maintenance: c_parser_oacc_single_int_clause gcc/c/ * c-parser.c (c_parser_omp_clause_num_gangs) (c_parser_omp_clause_num_workers) (c_parser_omp_clause_vector_length): Merge functions into... (c_parser_oacc_single_int_clause): ... this new function. Adjust all users. gcc/testsuite/ * c-c++-common/goacc/parallel-dims-1.c: New file. * c-c++-common/goacc/parallel-dims-2.c: Likewise. --- gcc/c/c-parser.c | 176 ++++++--------------- gcc/testsuite/c-c++-common/goacc/parallel-dims-1.c | 8 + gcc/testsuite/c-c++-common/goacc/parallel-dims-2.c | 134 ++++++++++++++++ 3 files changed, 191 insertions(+), 127 deletions(-) diff --git gcc/c/c-parser.c gcc/c/c-parser.c index 9398652..90d2d17 100644 --- gcc/c/c-parser.c +++ gcc/c/c-parser.c @@ -11339,51 +11339,6 @@ c_parser_omp_clause_nowait (c_parser *parser ATTRIBUTE_UNUSED, tree list) return c; } -/* OpenACC: - num_gangs ( expression ) */ - -static tree -c_parser_omp_clause_num_gangs (c_parser *parser, tree list) -{ - location_t num_gangs_loc = c_parser_peek_token (parser)->location; - if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) - { - location_t expr_loc = c_parser_peek_token (parser)->location; - c_expr expr = c_parser_expression (parser); - expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true); - tree c, t = expr.value; - t = c_fully_fold (t, false, NULL); - - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); - - if (!INTEGRAL_TYPE_P (TREE_TYPE (t))) - { - c_parser_error (parser, "expected integer expression"); - return list; - } - - /* Attempt to statically determine when the number isn't positive. */ - c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t, - build_int_cst (TREE_TYPE (t), 0)); - protected_set_expr_location (c, expr_loc); - if (c == boolean_true_node) - { - warning_at (expr_loc, 0, - "%<num_gangs%> value must be positive"); - t = integer_one_node; - } - - check_no_duplicate_clause (list, OMP_CLAUSE_NUM_GANGS, "num_gangs"); - - c = build_omp_clause (num_gangs_loc, OMP_CLAUSE_NUM_GANGS); - OMP_CLAUSE_NUM_GANGS_EXPR (c) = t; - OMP_CLAUSE_CHAIN (c) = list; - list = c; - } - - return list; -} - /* OpenMP 2.5: num_threads ( expression ) */ @@ -11671,48 +11626,54 @@ c_parser_omp_clause_is_device_ptr (c_parser *parser, tree list) } /* OpenACC: - num_workers ( expression ) */ + num_gangs ( expression ) + num_workers ( expression ) + vector_length ( expression ) */ static tree -c_parser_omp_clause_num_workers (c_parser *parser, tree list) +c_parser_oacc_single_int_clause (c_parser *parser, omp_clause_code code, + tree list) { - location_t num_workers_loc = c_parser_peek_token (parser)->location; - if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) + location_t loc = c_parser_peek_token (parser)->location; + + if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) + return list; + + location_t expr_loc = c_parser_peek_token (parser)->location; + c_expr expr = c_parser_expression (parser); + expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true); + tree c, t = expr.value; + t = c_fully_fold (t, false, NULL); + + c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); + + if (t == error_mark_node) + return list; + else if (!INTEGRAL_TYPE_P (TREE_TYPE (t))) { - location_t expr_loc = c_parser_peek_token (parser)->location; - c_expr expr = c_parser_expression (parser); - expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true); - tree c, t = expr.value; - t = c_fully_fold (t, false, NULL); + error_at (expr_loc, "%qs expression must be integral", + omp_clause_code_name[code]); + return list; + } - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); - - if (!INTEGRAL_TYPE_P (TREE_TYPE (t))) - { - c_parser_error (parser, "expected integer expression"); - return list; - } - - /* Attempt to statically determine when the number isn't positive. */ - c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t, + /* Attempt to statically determine when the number isn't positive. */ + c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t, build_int_cst (TREE_TYPE (t), 0)); - protected_set_expr_location (c, expr_loc); - if (c == boolean_true_node) - { - warning_at (expr_loc, 0, - "%<num_workers%> value must be positive"); - t = integer_one_node; - } - - check_no_duplicate_clause (list, OMP_CLAUSE_NUM_WORKERS, "num_workers"); - - c = build_omp_clause (num_workers_loc, OMP_CLAUSE_NUM_WORKERS); - OMP_CLAUSE_NUM_WORKERS_EXPR (c) = t; - OMP_CLAUSE_CHAIN (c) = list; - list = c; + protected_set_expr_location (c, expr_loc); + if (c == boolean_true_node) + { + warning_at (expr_loc, 0, + "%qs value must be positive", + omp_clause_code_name[code]); + t = integer_one_node; } - return list; + check_no_duplicate_clause (list, code, omp_clause_code_name[code]); + + c = build_omp_clause (loc, code); + OMP_CLAUSE_OPERAND (c, 0) = t; + OMP_CLAUSE_CHAIN (c) = list; + return c; } /* OpenACC: @@ -12354,51 +12315,6 @@ c_parser_omp_clause_untied (c_parser *parser ATTRIBUTE_UNUSED, tree list) return c; } -/* OpenACC: - vector_length ( expression ) */ - -static tree -c_parser_omp_clause_vector_length (c_parser *parser, tree list) -{ - location_t vector_length_loc = c_parser_peek_token (parser)->location; - if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) - { - location_t expr_loc = c_parser_peek_token (parser)->location; - c_expr expr = c_parser_expression (parser); - expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true); - tree c, t = expr.value; - t = c_fully_fold (t, false, NULL); - - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); - - if (!INTEGRAL_TYPE_P (TREE_TYPE (t))) - { - c_parser_error (parser, "expected integer expression"); - return list; - } - - /* Attempt to statically determine when the number isn't positive. */ - c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t, - build_int_cst (TREE_TYPE (t), 0)); - protected_set_expr_location (c, expr_loc); - if (c == boolean_true_node) - { - warning_at (expr_loc, 0, - "%<vector_length%> value must be positive"); - t = integer_one_node; - } - - check_no_duplicate_clause (list, OMP_CLAUSE_VECTOR_LENGTH, "vector_length"); - - c = build_omp_clause (vector_length_loc, OMP_CLAUSE_VECTOR_LENGTH); - OMP_CLAUSE_VECTOR_LENGTH_EXPR (c) = t; - OMP_CLAUSE_CHAIN (c) = list; - list = c; - } - - return list; -} - /* OpenMP 4.0: inbranch notinbranch */ @@ -13283,11 +13199,15 @@ c_parser_oacc_all_clauses (c_parser *parser, omp_clause_mask mask, c_name = "link"; break; case PRAGMA_OACC_CLAUSE_NUM_GANGS: - clauses = c_parser_omp_clause_num_gangs (parser, clauses); + clauses = c_parser_oacc_single_int_clause (parser, + OMP_CLAUSE_NUM_GANGS, + clauses); c_name = "num_gangs"; break; case PRAGMA_OACC_CLAUSE_NUM_WORKERS: - clauses = c_parser_omp_clause_num_workers (parser, clauses); + clauses = c_parser_oacc_single_int_clause (parser, + OMP_CLAUSE_NUM_WORKERS, + clauses); c_name = "num_workers"; break; case PRAGMA_OACC_CLAUSE_PRESENT: @@ -13341,7 +13261,9 @@ c_parser_oacc_all_clauses (c_parser *parser, omp_clause_mask mask, c_name, clauses); break; case PRAGMA_OACC_CLAUSE_VECTOR_LENGTH: - clauses = c_parser_omp_clause_vector_length (parser, clauses); + clauses = c_parser_oacc_single_int_clause (parser, + OMP_CLAUSE_VECTOR_LENGTH, + clauses); c_name = "vector_length"; break; case PRAGMA_OACC_CLAUSE_WAIT: diff --git gcc/testsuite/c-c++-common/goacc/parallel-dims-1.c gcc/testsuite/c-c++-common/goacc/parallel-dims-1.c new file mode 100644 index 0000000..a85d3d3 --- /dev/null +++ gcc/testsuite/c-c++-common/goacc/parallel-dims-1.c @@ -0,0 +1,8 @@ +/* Valid use of OpenACC parallelism dimensions clauses: num_gangs, num_workers, + vector_length. */ + +void f(int i) +{ +#pragma acc parallel num_gangs(i) num_workers(i) vector_length(i) + ; +} diff --git gcc/testsuite/c-c++-common/goacc/parallel-dims-2.c gcc/testsuite/c-c++-common/goacc/parallel-dims-2.c new file mode 100644 index 0000000..30a3d17 --- /dev/null +++ gcc/testsuite/c-c++-common/goacc/parallel-dims-2.c @@ -0,0 +1,134 @@ +/* Invalid use of OpenACC parallelism dimensions clauses: num_gangs, + num_workers, vector_length. */ + +void acc_kernels(int i) +{ +#pragma acc kernels num_gangs(i) /* { dg-error "'num_gangs' is not valid for '#pragma acc kernels'" } */ + ; +#pragma acc kernels num_workers(i) /* { dg-error "'num_workers' is not valid for '#pragma acc kernels'" } */ + ; +#pragma acc kernels vector_length(i) /* { dg-error "'vector_length' is not valid for '#pragma acc kernels'" } */ + ; +} + +void acc_parallel(int i, float f) +{ +#pragma acc parallel num_gangs /* { dg-error "expected '\\(' before end of line" } */ + ; +#pragma acc parallel num_workers /* { dg-error "expected '\\(' before end of line" } */ + ; +#pragma acc parallel vector_length /* { dg-error "expected '\\(' before end of line" } */ + ; + +#pragma acc parallel num_gangs( /* { dg-error "expected (primary-|)expression before end of line" } */ + ; +#pragma acc parallel num_workers( /* { dg-error "expected (primary-|)expression before end of line" } */ + ; +#pragma acc parallel vector_length( /* { dg-error "expected (primary-|)expression before end of line" } */ + ; + +#pragma acc parallel num_gangs() /* { dg-error "expected (primary-|)expression before '\\)' token" } */ + ; +#pragma acc parallel num_workers() /* { dg-error "expected (primary-|)expression before '\\)' token" } */ + ; +#pragma acc parallel vector_length() /* { dg-error "expected (primary-|)expression before '\\)' token" } */ + ; + +#pragma acc parallel num_gangs(1 /* { dg-error "expected '\\)' before end of line" } */ + ; +#pragma acc parallel num_workers(1 /* { dg-error "expected '\\)' before end of line" } */ + ; +#pragma acc parallel vector_length(1 /* { dg-error "expected '\\)' before end of line" } */ + ; + +#pragma acc parallel num_gangs(i /* { dg-error "expected '\\)' before end of line" } */ + ; +#pragma acc parallel num_workers(i /* { dg-error "expected '\\)' before end of line" } */ + ; +#pragma acc parallel vector_length(i /* { dg-error "expected '\\)' before end of line" } */ + ; + +#pragma acc parallel num_gangs(1 i /* { dg-error "expected '\\)' before 'i'" } */ + ; +#pragma acc parallel num_workers(1 i /* { dg-error "expected '\\)' before 'i'" } */ + ; +#pragma acc parallel vector_length(1 i /* { dg-error "expected '\\)' before 'i'" } */ + ; + +#pragma acc parallel num_gangs(1 i) /* { dg-error "expected '\\)' before 'i'" } */ + ; +#pragma acc parallel num_workers(1 i) /* { dg-error "expected '\\)' before 'i'" } */ + ; +#pragma acc parallel vector_length(1 i) /* { dg-error "expected '\\)' before 'i'" } */ + ; + +#pragma acc parallel num_gangs(1, i /* { dg-error "expected '\\)' before ',' token" "TODO" { xfail c } } */ + /* { dg-bogus "expected '\\)' before end of line" "TODO" { xfail c } .-1 } */ + ; +#pragma acc parallel num_workers(1, i /* { dg-error "expected '\\)' before ',' token" "TODO" { xfail c } } */ + /* { dg-bogus "expected '\\)' before end of line" "TODO" { xfail c } .-1 } */ + ; +#pragma acc parallel vector_length(1, i /* { dg-error "expected '\\)' before ',' token" "TODO" { xfail c } } */ + /* { dg-bogus "expected '\\)' before end of line" "TODO" { xfail c } .-1 } */ + ; + +#pragma acc parallel num_gangs(1, i) /* { dg-error "expected '\\)' before ',' token" "TODO" { xfail c } } */ + ; +#pragma acc parallel num_workers(1, i) /* { dg-error "expected '\\)' before ',' token" "TODO" { xfail c } } */ + ; +#pragma acc parallel vector_length(1, i) /* { dg-error "expected '\\)' before ',' token" "TODO" { xfail c } } */ + ; + +#pragma acc parallel num_gangs(num_gangs) /* { dg-error "'num_gangs' (un|was not )declared" } */ + ; +#pragma acc parallel num_workers(num_workers) /* { dg-error "'num_workers' (un|was not )declared" } */ + ; +#pragma acc parallel vector_length(vector_length) /* { dg-error "'vector_length' (un|was not )declared" } */ + ; + +#pragma acc parallel num_gangs(f) /* { dg-error "'num_gangs' expression must be integral" } */ + ; +#pragma acc parallel num_workers(f) /* { dg-error "'num_workers' expression must be integral" } */ + ; +#pragma acc parallel vector_length(f) /* { dg-error "'vector_length' expression must be integral" } */ + ; + +#pragma acc parallel num_gangs((float) 1) /* { dg-error "'num_gangs' expression must be integral" } */ + ; +#pragma acc parallel num_workers((float) 1) /* { dg-error "'num_workers' expression must be integral" } */ + ; +#pragma acc parallel vector_length((float) 1) /* { dg-error "'vector_length' expression must be integral" } */ + ; + +#pragma acc parallel num_gangs(0) /* { dg-warning "'num_gangs' value must be positive" } */ + ; +#pragma acc parallel num_workers(0) /* { dg-warning "'num_workers' value must be positive" } */ + ; +#pragma acc parallel vector_length(0) /* { dg-warning "'vector_length' value must be positive" } */ + ; + +#pragma acc parallel num_gangs((int) -1.2) /* { dg-warning "'num_gangs' value must be positive" } */ + ; +#pragma acc parallel num_workers((int) -1.2) /* { dg-warning "'num_workers' value must be positive" } */ + ; +#pragma acc parallel vector_length((int) -1.2) /* { dg-warning "'vector_length' value must be positive" } */ + ; + +#pragma acc parallel \ + num_gangs(1) /* { dg-error "too many 'num_gangs' clauses" "" { target c } } */ \ + num_workers(1) /* { dg-error "too many 'num_workers' clauses" "" { target c } } */ \ + vector_length(1) /* { dg-error "too many 'vector_length' clauses" "" { target c } } */ \ + num_workers(1) /* { dg-error "too many 'num_workers' clauses" "" { target c++ } } */ \ + vector_length(1) /* { dg-error "too many 'vector_length' clauses" "" { target c++ } } */ \ + num_gangs(1) /* { dg-error "too many 'num_gangs' clauses" "" { target c++ } } */ + ; + +#pragma acc parallel \ + num_gangs(-1) /* { dg-warning "'num_gangs' value must be positive" } */ \ + num_workers() /* { dg-error "expected (primary-|)expression before '\\)' token" } */ \ + vector_length(abc) /* { dg-error "'abc' (un|was not )declared" } */ \ + num_workers(0.5) /* { dg-error "'num_workers' expression must be integral" } */ \ + vector_length(&acc_parallel) /* { dg-error "'vector_length' expression must be integral" } */ \ + num_gangs( /* { dg-error "expected (primary-|)expression before end of line" "TODO" { xfail c } } */ + ; +} Grüße Thomas