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]

Re: [gomp] Extra Fortran OpenMP checks, not yet enabled code to handle almost all directives


On September 27, 2005 10:15, Jakub Jelinek wrote:

> Shouldn't OMP_SINGLE have 2 expressions rather than one BTW?  Clauses
> and body.
>
Indeed.

I implemented the obvious approach.  We could get away with an atomic 
decrement and a racy read of the flag, but this is just as good.


	* c-parser.c (c_parser_omp_directive): Handle OMP_SINGLE
	* gcc/gimplify.c (gimplify_omp_single): New.
	(gimplify_expr): Call it.
	* tree-pretty-print.c (dump_generic_node): Handle OMP_SINGLE.
	* tree.def (OMP_SINGLE): Add second operand.
	* tree.h (OMP_SINGLE_CLAUSES): Define.
	(OMP_SINGLE_BODY): Define.

libgomp/

	* testsuite/libgomp.dg/omp-single-1.c: New test.
	* testsuite/libgomp.dg/shared-1.c: Return 0.
	Add prototype for abort.
	* testsuite/libgomp.dg/shared-2.c: Likewise.

Index: gcc/c-parser.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-parser.c,v
retrieving revision 2.17.4.22
diff -d -u -p -r2.17.4.22 c-parser.c
--- gcc/c-parser.c	26 Sep 2005 15:25:54 -0000	2.17.4.22
+++ gcc/c-parser.c	27 Sep 2005 15:42:08 -0000
@@ -6808,7 +6808,10 @@ c_parser_omp_directive (c_parser *parser
 	break;
 
       case PRAGMA_OMP_SINGLE:
+	stmt = push_stmt_list ();
 	c_parser_statement (parser);
+	stmt = pop_stmt_list (stmt);
+	add_stmt (build (OMP_SINGLE, void_type_node, clause, stmt));
 	break;
 
       case PRAGMA_OMP_MASTER:
Index: gcc/gimplify.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gimplify.c,v
retrieving revision 2.135.4.19
diff -d -u -p -r2.135.4.19 gimplify.c
--- gcc/gimplify.c	26 Sep 2005 04:10:16 -0000	2.135.4.19
+++ gcc/gimplify.c	27 Sep 2005 15:42:09 -0000
@@ -4914,6 +4914,68 @@ gimplify_omp_atomic (tree *expr_p, tree 
   return gimplify_omp_atomic_pipeline (expr_p, pre_p, addr, rhs, 
index);
 }
 
+/* Gimplify an OMP_SINGLE statement.  */
+
+static enum gimplify_status
+gimplify_omp_single (tree *expr_p, tree *pre_p)
+{
+  tree t, sem, crit_body, tmp;
+  
+  /* Expand to the following semaphore protection:
+
+     	OMP_ATOMIC <.single_tid.XXXX, .single_tid.XXXX - 1>
+	if (.single_tid.XXXX == 0)
+	  body;
+	
+     .single_tid.XXXX is a global static variable initialized to 1 and
+     associated with this single construct.  Exactly one thread will
+     leave it at zero and execute BODY.
+
+     If the clause nowait is not present, add a barrier after the if().
+     FIXME, may need to add a flush after the assignment to
+     .single_tid.XXXX.  */
+  sem = create_tmp_var_raw (integer_type_node, ".single_tid");
+  DECL_CONTEXT (sem) = NULL_TREE;
+  DECL_INITIAL (sem) = integer_one_node;
+  TREE_PUBLIC (sem) = 1;
+  TREE_STATIC (sem) = 1;
+  DECL_COMMON (sem) = 1;
+  DECL_ARTIFICIAL (sem) = 1;
+  DECL_IGNORED_P (sem) = 1;
+  cgraph_varpool_finalize_decl (sem);
+
+  /* OMP_CRITICAL <NULL, { .single_tid.XXXX--; tmp = .single_tid.XXXX>  
*/
+  tmp = create_tmp_var (integer_type_node, NULL);
+  crit_body = alloc_stmt_list ();
+  t = build (MODIFY_EXPR, void_type_node,
+	     sem,
+	     build (MINUS_EXPR, integer_type_node, sem, integer_one_node));
+  append_to_statement_list (t, &crit_body);
+  t = build (MODIFY_EXPR, void_type_node, tmp, sem);
+  append_to_statement_list (t, &crit_body);
+  t = build (OMP_CRITICAL, void_type_node, NULL_TREE, crit_body);
+  gimplify_and_add (t, pre_p);
+
+  /* if (tmp == 0)
+        body;  */
+  t = build2 (EQ_EXPR, boolean_type_node, tmp, integer_zero_node);
+  t = build3 (COND_EXPR, void_type_node, t, OMP_SINGLE_BODY (*expr_p), 
NULL);
+  gimplify_and_add (t, pre_p);
+
+  for (t = OMP_SINGLE_CLAUSES (*expr_p); t; t = TREE_CHAIN (t))
+    if (TREE_CODE (t) == OMP_CLAUSE_NOWAIT)
+      {
+	*expr_p = build_empty_stmt ();
+	return GS_OK;
+      }
+
+  t = built_in_decls[BUILT_IN_GOMP_BARRIER];
+  t = build_function_call_expr (t, NULL);
+  *expr_p = t;
+
+  return GS_OK;
+}
+
 
 /*  Gimplifies the expression tree pointed to by EXPR_P.  Return 0 if
     gimplification failed.
@@ -5380,6 +5442,10 @@ gimplify_expr (tree *expr_p, tree *pre_p
 	  ret = gimplify_omp_atomic (expr_p, pre_p);
 	  break;
 
+	case OMP_SINGLE:
+	  ret = gimplify_omp_single (expr_p, pre_p);
+	  break;
+
 	default:
 	  switch (TREE_CODE_CLASS (TREE_CODE (*expr_p)))
 	    {
Index: gcc/tree-pretty-print.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-pretty-print.c,v
retrieving revision 2.61.4.13
diff -d -u -p -r2.61.4.13 tree-pretty-print.c
--- gcc/tree-pretty-print.c	25 Sep 2005 22:39:26 -0000	2.61.4.13
+++ gcc/tree-pretty-print.c	27 Sep 2005 15:42:09 -0000
@@ -1615,6 +1615,18 @@ dump_generic_node (pretty_printer *buffe
       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, 
false);
       break;
 
+    case OMP_SINGLE:
+      pp_string (buffer, "#pragma omp single");
+      newline_and_indent (buffer, spc + 2);
+      pp_character (buffer, '{');
+      newline_and_indent (buffer, spc + 4);
+      dump_generic_node (buffer, OMP_SINGLE_BODY (node), spc + 4, 
flags,
+			 false);
+      newline_and_indent (buffer, spc + 2);
+      pp_character (buffer, '}');
+      is_expr = false;
+      break;
+
     case OMP_CLAUSE_PRIVATE:
       pp_string (buffer, "private (");
       dump_generic_node (buffer, OMP_PRIVATE_VARS (node), spc, flags, 
false);
Index: gcc/tree.def
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.def,v
retrieving revision 1.116.4.13
diff -d -u -p -r1.116.4.13 tree.def
--- gcc/tree.def	25 Sep 2005 07:27:33 -0000	1.116.4.13
+++ gcc/tree.def	27 Sep 2005 15:42:09 -0000
@@ -981,8 +981,9 @@ DEFTREECODE (OMP_SECTIONS, "omp_sections
 DEFTREECODE (OMP_SECTION, "omp_section", tcc_statement, 1)
 
 /* OpenMP - #pragma omp single
+   Operand 0: OMP_SINGLE_CLAUSES: List of clauses.
    Operand 0: OMP_SINGLE_BODY: Single section body.  */
-DEFTREECODE (OMP_SINGLE, "omp_single", tcc_statement, 1)
+DEFTREECODE (OMP_SINGLE, "omp_single", tcc_statement, 2)
 
 /* OpenMP - #pragma omp critical [name]
    Operand 0: OMP_CRITICAL_NAME: Identifier for critical section.
Index: gcc/tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.h,v
retrieving revision 1.735.4.15
diff -d -u -p -r1.735.4.15 tree.h
--- gcc/tree.h	26 Sep 2005 15:25:56 -0000	1.735.4.15
+++ gcc/tree.h	27 Sep 2005 15:42:10 -0000
@@ -1408,6 +1408,11 @@ struct tree_constructor GTY(())
 #define OMP_CRITICAL_BODY(NODE)		\
   		TREE_OPERAND (OMP_CRITICAL_CHECK (NODE), 1)
 
+#define OMP_SINGLE_CLAUSES(NODE)	\
+		TREE_OPERAND (OMP_SINGLE_CHECK (NODE), 0)
+#define OMP_SINGLE_BODY(NODE)		\
+  		TREE_OPERAND (OMP_SINGLE_CHECK (NODE), 1)
+
 #define OMP_PRIVATE_VARS(NODE)		\
   		TREE_OPERAND (OMP_CLAUSE_PRIVATE_CHECK (NODE), 0)
 #define OMP_SHARED_VARS(NODE)		\
Index: libgomp/testsuite/libgomp.dg/omp-single-1.c
===================================================================
RCS file: libgomp/testsuite/libgomp.dg/omp-single-1.c
diff -N libgomp/testsuite/libgomp.dg/omp-single-1.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ libgomp/testsuite/libgomp.dg/omp-single-1.c	27 Sep 2005 15:42:06 
-0000
@@ -0,0 +1,19 @@
+extern void abort (void);
+
+main()
+{
+  int i = 0;
+
+  #pragma omp parallel shared (i)
+    {
+      #pragma omp single
+	{
+	  i++;
+	}
+    }
+
+  if (i != 1)
+    abort ();
+
+  return 0;
+}
Index: libgomp/testsuite/libgomp.dg/shared-1.c
===================================================================
RCS file: /cvs/gcc/gcc/libgomp/testsuite/libgomp.dg/Attic/shared-1.c,v
retrieving revision 1.1.2.1
diff -d -u -p -r1.1.2.1 shared-1.c
--- libgomp/testsuite/libgomp.dg/shared-1.c	26 Sep 2005 15:35:17 -0000	
1.1.2.1
+++ libgomp/testsuite/libgomp.dg/shared-1.c	27 Sep 2005 15:42:06 -0000
@@ -1,3 +1,5 @@
+extern void abort (void);
+
 struct Y
 {
   int l[5][10];
@@ -52,4 +54,5 @@ parallel (int a, int b)
 main()
 {
   parallel (1, 2);
+  return 0;
 }
Index: libgomp/testsuite/libgomp.dg/shared-2.c
===================================================================
RCS file: /cvs/gcc/gcc/libgomp/testsuite/libgomp.dg/Attic/shared-2.c,v
retrieving revision 1.1.2.1
diff -d -u -p -r1.1.2.1 shared-2.c
--- libgomp/testsuite/libgomp.dg/shared-2.c	26 Sep 2005 15:35:17 -0000	
1.1.2.1
+++ libgomp/testsuite/libgomp.dg/shared-2.c	27 Sep 2005 15:42:06 -0000
@@ -1,6 +1,8 @@
 #include <stdio.h>
 #include <omp.h>
 
+extern void abort (void);
+
 void
 parallel (int a, int b)
 {


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