This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[gomp] Fix static vars in #pragma omp parallel block scope in C++ (PR c++/34513)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Diego Novillo <dnovillo at google dot com>, Richard Henderson <rth at redhat dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Mon, 17 Dec 2007 19:28:28 -0500
- Subject: [gomp] Fix static vars in #pragma omp parallel block scope in C++ (PR c++/34513)
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
Unlike C where for
#pragma omp parallel
{
static int x;
...
}
OMP_PARALLEL_BODY is a BIND_EXPR, which contains a stmt_list with another
BIND_EXPR as its body (and the inner BIND_EXPR contains x among its vars),
C++ contains just one BIND_EXPR. lower_omp_parallel records the vars from
the par_bind into the newly created child function (so it goes into
child_cfun->unexpanded_var_list and isn't in parent's unexpanded_var_list),
so when build_cgraph_edges is called (for the parent, for the child only
rebuild_cgraph_edges is called),
/* Look for initializers of constant variables and private statics. */
for (step = cfun->unexpanded_var_list;
step;
step = TREE_CHAIN (step))
{
tree decl = TREE_VALUE (step);
if (TREE_CODE (decl) == VAR_DECL
&& (TREE_STATIC (decl) && !DECL_EXTERNAL (decl))
&& flag_unit_at_a_time)
varpool_finalize_decl (decl);
else if (TREE_CODE (decl) == VAR_DECL && DECL_INITIAL (decl))
walk_tree (&DECL_INITIAL (decl), record_reference, node, visited_nodes);
}
doesn't hit on the static vars. Either we could duplicate this code in
expand_omp_parallel, or we can just change C++ FE to do what the C FE does
(where TREE_STATIC vars surely aren't in the outermost BIND_EXPR).
Patch below does the latter, bootstrapped/regtested on x86_64-linux. Ok for
trunk?
BTW, I have noticed that probably some dominance changes cause no combined
loops to be recognized on the trunk (works in 4.2). Will debug tomorrow.
2007-12-17 Jakub Jelinek <jakub@redhat.com>
PR c++/34513
* parser.c (cp_parser_omp_parallel): For non-combined parallel
call cp_parser_statement rather than
cp_parser_already_scoped_statement.
* testsuite/libgomp.c/pr34513.c: New test.
* testsuite/libgomp.c++/pr34513.C: New test.
--- gcc/cp/parser.c.jj 2007-12-17 13:23:29.000000000 +0100
+++ gcc/cp/parser.c 2007-12-17 23:04:41.000000000 +0100
@@ -20271,7 +20271,7 @@ cp_parser_omp_parallel (cp_parser *parse
switch (p_kind)
{
case PRAGMA_OMP_PARALLEL:
- cp_parser_already_scoped_statement (parser);
+ cp_parser_statement (parser, NULL_TREE, false, NULL);
par_clause = clauses;
break;
--- libgomp/testsuite/libgomp.c/pr34513.c.jj 2007-12-17 23:09:53.000000000 +0100
+++ libgomp/testsuite/libgomp.c/pr34513.c 2007-12-17 23:39:19.000000000 +0100
@@ -0,0 +1,33 @@
+/* PR c++/34513 */
+/* { dg-do run } */
+
+#include <omp.h>
+
+extern void abort ();
+
+static int errors = 0;
+static int thrs = 4;
+
+int
+main ()
+{
+ omp_set_dynamic (0);
+
+ #pragma omp parallel num_threads (thrs)
+ {
+ static int shrd = 0;
+
+ #pragma omp atomic
+ shrd += 1;
+
+ #pragma omp barrier
+
+ if (shrd != thrs)
+ #pragma omp atomic
+ errors += 1;
+ }
+
+ if (errors)
+ abort ();
+ return 0;
+}
--- libgomp/testsuite/libgomp.c++/pr34513.C.jj 2007-12-17 23:09:53.000000000 +0100
+++ libgomp/testsuite/libgomp.c++/pr34513.C 2007-12-17 23:39:06.000000000 +0100
@@ -0,0 +1,32 @@
+// PR c++/34513
+// { dg-do run }
+
+#include <omp.h>
+
+extern "C" void abort ();
+
+static int errors = 0;
+static int thrs = 4;
+
+int
+main ()
+{
+ omp_set_dynamic (0);
+
+ #pragma omp parallel num_threads (thrs)
+ {
+ static int shrd = 0;
+
+ #pragma omp atomic
+ shrd += 1;
+
+ #pragma omp barrier
+
+ if (shrd != thrs)
+ #pragma omp atomic
+ errors += 1;
+ }
+
+ if (errors)
+ abort ();
+}
Jakub