[gomp] Fix static vars in #pragma omp parallel block scope in C++ (PR c++/34513)

Jakub Jelinek jakub@redhat.com
Tue Dec 18 00:52:00 GMT 2007


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



More information about the Gcc-patches mailing list