This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [gomp] Extra Fortran OpenMP checks, not yet enabled code to handle almost all directives
- From: Diego Novillo <dnovillo at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org, Jakub Jelinek <jakub at redhat dot com>
- Date: Tue, 27 Sep 2005 11:48:14 -0400
- Subject: Re: [gomp] Extra Fortran OpenMP checks, not yet enabled code to handle almost all directives
- References: <20050927141527.GZ1020@devserv.devel.redhat.com>
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)
{