Patchwork [gomp3.1] C/C++ min/max reductions

login
register
mail settings
Submitter Jakub Jelinek
Date March 3, 2011, 7:32 p.m.
Message ID <20110303193239.GX30899@tyan-ft48-01.lab.bos.redhat.com>
Download mbox | patch
Permalink /patch/85329/
State New
Headers show

Comments

Jakub Jelinek - March 3, 2011, 7:32 p.m.
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.


	Jakub

Patch

--- 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;
+}