OpenACC C front end maintenance: c_parser_oacc_single_int_clause
authorThomas Schwinge <thomas@codesourcery.com>
Fri, 12 May 2017 09:33:18 +0000 (11:33 +0200)
committerThomas Schwinge <tschwinge@gcc.gnu.org>
Fri, 12 May 2017 09:33:18 +0000 (11:33 +0200)
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.

From-SVN: r247960

gcc/c/ChangeLog
gcc/c/c-parser.c
gcc/testsuite/ChangeLog
gcc/testsuite/c-c++-common/goacc/parallel-dims-1.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/goacc/parallel-dims-2.c [new file with mode: 0644]

index 497c9b9a62d5e41f095a186b10ead364ad147539..b12f41d5fd370620854c12e1ef59e7ac7b8e302c 100644 (file)
@@ -1,3 +1,11 @@
+2017-05-12  Thomas Schwinge  <thomas@codesourcery.com>
+
+       * 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.
+
 2017-05-11  Nathan Sidwell  <nathan@acm.org>
 
        * gimple-parser.c: Don't #include tree-dump.h.
index 9398652a90aeaa590783e5eb8241317fa90ae2cf..90d2d179152ebeba694b9265b18a8c3c92863370 100644 (file)
@@ -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 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);
+  location_t loc = c_parser_peek_token (parser)->location;
 
-      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
+  if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
+    return list;
 
-      if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
-       {
-         c_parser_error (parser, "expected integer expression");
-         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);
 
-      /* 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;
-       }
+  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
 
-      check_no_duplicate_clause (list, OMP_CLAUSE_NUM_WORKERS, "num_workers");
+  if (t == error_mark_node)
+    return list;
+  else if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
+    {
+      error_at (expr_loc, "%qs expression must be integral",
+               omp_clause_code_name[code]);
+      return list;
+    }
 
-      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;
+  /* 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,
+                 "%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:
index e1e2641d51e7ea316334bc755b7b2843b14c793b..13241be7df4af280e09d89bb3fbdd12d07ad53d5 100644 (file)
@@ -1,5 +1,8 @@
 2017-05-12  Thomas Schwinge  <thomas@codesourcery.com>
 
+       * c-c++-common/goacc/parallel-dims-1.c: New file.
+       * c-c++-common/goacc/parallel-dims-2.c: Likewise.
+
        * c-c++-common/goacc/classify-kernels-unparallelized.c: Adjust.
        * c-c++-common/goacc/classify-kernels.c: Likewise.
        * c-c++-common/goacc/kernels-counter-vars-function-scope.c:
diff --git a/gcc/testsuite/c-c++-common/goacc/parallel-dims-1.c b/gcc/testsuite/c-c++-common/goacc/parallel-dims-1.c
new file mode 100644 (file)
index 0000000..a85d3d3
--- /dev/null
@@ -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 a/gcc/testsuite/c-c++-common/goacc/parallel-dims-2.c b/gcc/testsuite/c-c++-common/goacc/parallel-dims-2.c
new file mode 100644 (file)
index 0000000..30a3d17
--- /dev/null
@@ -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 } } */
+  ;
+}