This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[gomp] fix parallel for and parallel sections


Previously we were ignoring the parallel part of the directive.

The best thing to do appears to be to treat these as separate
directives.  I do have specialized routines in libgomp to handle
these cases, but with all the transformations needed to handle
OMP_PARALLEL correctly, it may well be easier to recognize the
combined case after the fact.  I.e. "Oh, look, the only thing in
the parallel body is the OMP_FOR.  That means I can...".

And in the meantime, this produces code that is correct, if not
as efficient as it might be.


r~


        * c-common.h (c_split_parallel_clauses): Declare.
        * c-omp.c (c_split_parallel_clauses): New.
        * c-parser.c (c_parser_omp_directive): Split PRAGMA_OMP_PARALLEL_FOR
        and PRAGMA_OMP_PARALLEL_SECTIONS into separate OMP_PARALLEL and
        work-sharing constructs.

Index: c-common.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-common.h,v
retrieving revision 1.294.4.6
diff -u -p -r1.294.4.6 c-common.h
--- c-common.h	24 Sep 2005 22:57:39 -0000	1.294.4.6
+++ c-common.h	25 Sep 2005 22:28:45 -0000
@@ -939,6 +939,7 @@ extern void c_finish_omp_barrier (void);
 extern void c_finish_omp_atomic (enum tree_code, tree, tree);
 extern void c_finish_omp_flush (void);
 extern tree c_finish_omp_for (tree, tree, tree, tree, tree);
+extern void c_split_parallel_clauses (tree, tree *, tree *);
 
 /* In order for the format checking to accept the C frontend
    diagnostic framework extensions, you must include this file before
Index: c-omp.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/c-omp.c,v
retrieving revision 1.1.2.6
diff -u -p -r1.1.2.6 c-omp.c
--- c-omp.c	24 Sep 2005 22:57:40 -0000	1.1.2.6
+++ c-omp.c	25 Sep 2005 22:28:45 -0000
@@ -157,6 +157,53 @@ c_finish_omp_flush (void)
 }
 
 
+/* Divide CLAUSES into two lists: those that apply to a parallel construct,
+   and those that apply to a work-sharing construct.  Place the results in
+   *PAR_CLAUSES and *WS_CLAUSES respectively.  In addition, add a nowait
+   clause to the work-sharing list.  */
+
+void
+c_split_parallel_clauses (tree clauses, tree *par_clauses, tree *ws_clauses)
+{
+  tree c, next;
+
+  *par_clauses = NULL;
+  *ws_clauses = NULL;
+
+  for (; clauses ; clauses = next)
+    {
+      next = TREE_CHAIN (clauses);
+
+      switch (TREE_CODE (TREE_VALUE (clauses)))
+	{
+	case OMP_CLAUSE_PRIVATE:
+	case OMP_CLAUSE_SHARED:
+	case OMP_CLAUSE_FIRSTPRIVATE:
+	case OMP_CLAUSE_REDUCTION:
+	case OMP_CLAUSE_COPYIN:
+	case OMP_CLAUSE_IF:
+	case OMP_CLAUSE_NUM_THREADS:
+	  TREE_CHAIN (clauses) = *par_clauses;
+	  *par_clauses = clauses;
+	  break;
+
+	case OMP_CLAUSE_ORDERED:
+	case OMP_CLAUSE_SCHEDULE:
+	case OMP_CLAUSE_LASTPRIVATE:
+	  TREE_CHAIN (clauses) = *ws_clauses;
+	  *ws_clauses = clauses;
+	  break;
+
+	default:
+	  gcc_unreachable ();
+	}
+    }
+
+  c = build (OMP_CLAUSE_NOWAIT, NULL_TREE);
+  c = tree_cons (NULL_TREE, c, *ws_clauses);
+  *ws_clauses = c;
+}
+
 /* Validate and emit code for the OpenMP directive #pragma omp for.
    INIT, COND, INCR and BODY are the four basic elements of the loop
    (initialization expression, controlling predicate, increment
Index: c-parser.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-parser.c,v
retrieving revision 2.17.4.20
diff -u -p -r2.17.4.20 c-parser.c
--- c-parser.c	25 Sep 2005 21:11:02 -0000	2.17.4.20
+++ c-parser.c	25 Sep 2005 22:28:45 -0000
@@ -6760,7 +6760,7 @@ c_parser_omp_atomic_expression (c_parser
 static void
 c_parser_omp_directive (c_parser *parser)
 {
-  tree stmt, clause;
+  tree stmt, clause, par_clause, ws_clause;
   enum pragma_omp_kind code = c_parser_peek_token (parser)->omp_kind;
 
   /* Parse the pragma header.  */
@@ -6771,12 +6771,24 @@ c_parser_omp_directive (c_parser *parser
   switch (code)
     {
       case PRAGMA_OMP_PARALLEL:
-	stmt = c_parser_compound_statement (parser);
+	stmt = push_stmt_list ();
+	c_parser_statement (parser);
+	stmt = pop_stmt_list (stmt);
 	add_stmt (build (OMP_PARALLEL, void_type_node, clause, stmt));
 	break;
 
-      case PRAGMA_OMP_FOR:
       case PRAGMA_OMP_PARALLEL_FOR:
+	stmt = push_stmt_list ();
+	c_split_parallel_clauses (clause, &par_clause, &ws_clause);
+	if (c_parser_next_token_is_keyword (parser, RID_FOR))
+	  c_parser_for_statement (parser, true, ws_clause);
+	else
+	  c_parser_error (parser, "for statement expected");
+	stmt = pop_stmt_list (stmt);
+	add_stmt (build (OMP_PARALLEL, void_type_node, par_clause, stmt));
+	break;
+
+      case PRAGMA_OMP_FOR:
 	if (c_parser_next_token_is_keyword (parser, RID_FOR))
 	  c_parser_for_statement (parser, true, clause);
 	else
@@ -6784,6 +6796,13 @@ c_parser_omp_directive (c_parser *parser
 	break;
 
       case PRAGMA_OMP_PARALLEL_SECTIONS:
+	stmt = push_stmt_list ();
+	c_split_parallel_clauses (clause, &par_clause, &ws_clause);
+	c_parser_omp_sections_body (parser, ws_clause);
+	stmt = pop_stmt_list (stmt);
+	add_stmt (build (OMP_PARALLEL, void_type_node, par_clause, stmt));
+	break;
+
       case PRAGMA_OMP_SECTIONS:
 	c_parser_omp_sections_body (parser, clause);
 	break;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]