[gomp3.1] C/C++ min/max reductions
Jakub Jelinek
jakub@redhat.com
Thu Mar 3 19:32:00 GMT 2011
Hi!
This patch adds min/max reduction support for C/C++, which was quite easy
given that the middle-end already needs to support it for Fortran.
Tested on x86_64-linux, committed to gomp-3_1-branch.
2011-03-03 Jakub Jelinek <jakub@redhat.com>
* c-parser.c (c_parser_omp_clause_reduction): Handle min and max.
* c-typeck.c (c_finish_omp_clauses): Handle MIN_EXPR and MAX_EXPR.
* parser.c (cp_parser_omp_clause_reduction): Handle min and max.
* semantics.c (finish_omp_clauses): Handle MIN_EXPR and MAX_EXPR.
* testsuite/libgomp.c/reduction-6.c: New test.
* testsuite/libgomp.c++/reduction-4.C: New test.
--- gcc/c-parser.c.jj 2011-03-03 16:57:07.000000000 +0100
+++ gcc/c-parser.c 2011-03-03 19:49:05.000000000 +0100
@@ -8692,7 +8692,12 @@ c_parser_omp_clause_private (c_parser *p
reduction ( reduction-operator : variable-list )
reduction-operator:
- One of: + * - & ^ | && || */
+ One of: + * - & ^ | && ||
+
+ OpenMP 3.1:
+
+ reduction-operator:
+ One of: + * - & ^ | && || max min */
static tree
c_parser_omp_clause_reduction (c_parser *parser, tree list)
@@ -8728,10 +8733,26 @@ c_parser_omp_clause_reduction (c_parser
case CPP_OR_OR:
code = TRUTH_ORIF_EXPR;
break;
+ case CPP_NAME:
+ {
+ const char *p
+ = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
+ if (strcmp (p, "min") == 0)
+ {
+ code = MIN_EXPR;
+ break;
+ }
+ if (strcmp (p, "max") == 0)
+ {
+ code = MAX_EXPR;
+ break;
+ }
+ }
+ /* FALLTHRU */
default:
c_parser_error (parser,
"expected %<+%>, %<*%>, %<-%>, %<&%>, "
- "%<^%>, %<|%>, %<&&%>, or %<||%>");
+ "%<^%>, %<|%>, %<&&%>, %<||%>, %<min%> or %<max%>");
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
return list;
}
--- gcc/c-typeck.c.jj 2011-02-24 14:20:36.000000000 +0100
+++ gcc/c-typeck.c 2011-03-03 19:27:19.000000000 +0100
@@ -10441,6 +10441,8 @@ c_finish_omp_clauses (tree clauses)
case PLUS_EXPR:
case MULT_EXPR:
case MINUS_EXPR:
+ case MIN_EXPR:
+ case MAX_EXPR:
break;
case BIT_AND_EXPR:
r_name = "&";
--- gcc/cp/parser.c.jj 2011-02-24 14:18:07.000000000 +0100
+++ gcc/cp/parser.c 2011-03-03 19:48:52.000000000 +0100
@@ -23683,7 +23683,12 @@ cp_parser_omp_clause_ordered (cp_parser
reduction ( reduction-operator : variable-list )
reduction-operator:
- One of: + * - & ^ | && || */
+ One of: + * - & ^ | && ||
+
+ OpenMP 3.1:
+
+ reduction-operator:
+ One of: + * - & ^ | && || min max */
static tree
cp_parser_omp_clause_reduction (cp_parser *parser, tree list)
@@ -23720,9 +23725,26 @@ cp_parser_omp_clause_reduction (cp_parse
case CPP_OR_OR:
code = TRUTH_ORIF_EXPR;
break;
+ case CPP_NAME:
+ {
+ tree id = cp_lexer_peek_token (parser->lexer)->u.value;
+ const char *p = IDENTIFIER_POINTER (id);
+
+ if (strcmp (p, "min") == 0)
+ {
+ code = MIN_EXPR;
+ break;
+ }
+ if (strcmp (p, "max") == 0)
+ {
+ code = MAX_EXPR;
+ break;
+ }
+ }
+ /* FALLTHROUGH */
default:
cp_parser_error (parser, "expected %<+%>, %<*%>, %<-%>, %<&%>, %<^%>, "
- "%<|%>, %<&&%>, or %<||%>");
+ "%<|%>, %<&&%>, %<||%>, %<min%> or %<max%>");
resync_fail:
cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
/*or_comma=*/false,
--- gcc/cp/semantics.c.jj 2011-02-28 19:27:17.000000000 +0100
+++ gcc/cp/semantics.c 2011-03-03 19:50:38.000000000 +0100
@@ -3893,6 +3893,8 @@ finish_omp_clauses (tree clauses)
case PLUS_EXPR:
case MULT_EXPR:
case MINUS_EXPR:
+ case MIN_EXPR:
+ case MAX_EXPR:
break;
default:
error ("%qE has invalid type for %<reduction(%s)%>",
--- libgomp/testsuite/libgomp.c/reduction-6.c.jj 2011-03-03 19:44:19.000000000 +0100
+++ libgomp/testsuite/libgomp.c/reduction-6.c 2011-03-03 19:43:38.000000000 +0100
@@ -0,0 +1,29 @@
+/* { dg-do run } */
+
+extern void abort (void);
+int j;
+float f;
+
+int
+main ()
+{
+ j = -10000;
+ f = 1024.0;
+ int i;
+ #pragma omp parallel for reduction (min:f) reduction (max:j)
+ for (i = 0; i < 4; i++)
+ switch (i)
+ {
+ case 0:
+ if (j < -16) j = -16; break;
+ case 1:
+ if (f > -2.0) f = -2.0; break;
+ case 2:
+ if (j < 8) j = 8; if (f > 9.0) f = 9.0; break;
+ case 3:
+ break;
+ }
+ if (j != 8 || f != -2.0)
+ abort ();
+ return 0;
+}
--- libgomp/testsuite/libgomp.c++/reduction-4.C.jj 2011-03-03 19:54:22.000000000 +0100
+++ libgomp/testsuite/libgomp.c++/reduction-4.C 2011-03-03 19:53:49.000000000 +0100
@@ -0,0 +1,54 @@
+// { dg-do run }
+
+extern "C" void abort (void);
+
+template <typename I, typename F>
+void
+foo ()
+{
+ I j = -10000;
+ F f = 1024.0;
+ int i;
+ #pragma omp parallel for reduction (min:f) reduction (max:j)
+ for (i = 0; i < 4; i++)
+ switch (i)
+ {
+ case 0:
+ if (j < -16) j = -16; break;
+ case 1:
+ if (f > -2.0) f = -2.0; break;
+ case 2:
+ if (j < 8) j = 8; if (f > 9.0) f = 9.0; break;
+ case 3:
+ break;
+ }
+ if (j != 8 || f != -2.0)
+ abort ();
+}
+
+int
+main ()
+{
+ int j = -10000;
+ float f = 1024.0;
+ int i;
+ #pragma omp parallel for reduction (min:f) reduction (max:j)
+ for (i = 0; i < 4; i++)
+ switch (i)
+ {
+ case 0:
+ if (j < -16) j = -16; break;
+ case 1:
+ if (f > -2.0) f = -2.0; break;
+ case 2:
+ if (j < 8) j = 8; if (f > 9.0) f = 9.0; break;
+ case 3:
+ break;
+ }
+ if (j != 8 || f != -2.0)
+ abort ();
+ foo <int, float> ();
+ foo <long, double> ();
+ foo <long long, long double> ();
+ return 0;
+}
Jakub
More information about the Gcc-patches
mailing list