This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[gomp] fix default(shared) vs nested parallels
- From: Richard Henderson <rth at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 29 Sep 2005 16:06:29 -0700
- Subject: [gomp] fix default(shared) vs nested parallels
Previously we'd ICE because we hadn't injected shared(var) annotations
into all enclosing scopes.
r~
* c-decl.c (struct c_scope): Add location.
(define_label): Use lookup_name_no_remap.
(c_omp_remap_decl_1): Add pscope argument. Use it instead of
current_omp_parallel_scope.
(c_omp_remap_decl): Pass it current_omp_parallel_scope.
(maybe_remap_for_omp_parallel): New.
(lookup_name): Use it.
(c_begin_omp_parallel): Initialize location field.
Index: c-decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-decl.c,v
retrieving revision 1.662.4.9
diff -u -p -d -r1.662.4.9 c-decl.c
--- c-decl.c 29 Sep 2005 09:04:46 -0000 1.662.4.9
+++ c-decl.c 29 Sep 2005 23:02:19 -0000
@@ -332,6 +332,10 @@ struct c_scope GTY((chain_next ("%h.oute
OpenMP parallel scope. */
tree omp_shared;
+ /* A locus for the start of the omp parallel block, for use when
+ generating default(none) error messages. */
+ location_t location;
+
/* The depth of this scope. Used to keep the ->shadowed chain of
bindings sorted innermost to outermost. */
unsigned int depth : 28;
@@ -2604,7 +2608,7 @@ define_label (location_t location, tree
/*invisible=*/false, /*nested=*/false);
}
- if (!in_system_header && lookup_name (name))
+ if (!in_system_header && lookup_name_no_remap (name))
warning (OPT_Wtraditional, "%Htraditional C lacks a separate namespace "
"for labels, identifier %qE conflicts", &location, name);
@@ -2757,8 +2761,8 @@ c_omp_sharing_predetermined (tree decl)
/* Inject a new binding for OLD in scope S. If SHARED is zero, then we
want a variable of sharing class private; otherwise we want a variable
of sharing class shared. If SHARED is negative, then we're being
- called from lookup_name and should add the mapping to the currently
- active parallel construct.
+ called from lookup_name and should add the mapping to the parallel
+ construct PSCOPE.
Sometimes we can optimize away a binding -- global variables being
marked shared is semantically a no-op. If FORCE_P is true, this
@@ -2766,7 +2770,8 @@ c_omp_sharing_predetermined (tree decl)
generated by default(none). */
static tree
-c_omp_remap_decl_1 (struct c_scope *s, tree old, int shared, bool force_p)
+c_omp_remap_decl_1 (struct c_scope *s, struct c_scope *pscope,
+ tree old, int shared, bool force_p)
{
tree new;
@@ -2789,8 +2794,8 @@ c_omp_remap_decl_1 (struct c_scope *s, t
tree c = make_node (OMP_CLAUSE_SHARED);
OMP_CLAUSE_OUTER_DECL (c) = old;
OMP_CLAUSE_INNER_DECL (c) = new;
- OMP_CLAUSE_CHAIN (c) = current_omp_parallel_scope->omp_shared;
- current_omp_parallel_scope->omp_shared = c;
+ OMP_CLAUSE_CHAIN (c) = pscope->omp_shared;
+ pscope->omp_shared = c;
}
return new;
@@ -2806,7 +2811,45 @@ c_omp_remap_decl (tree old, bool shared_
force_p = (current_omp_parallel_scope
&& current_omp_parallel_scope->omp_default_none);
- return c_omp_remap_decl_1 (current_scope, old, shared_p, force_p);
+ return c_omp_remap_decl_1 (current_scope, NULL, old, shared_p, force_p);
+}
+
+/* A subroutine of lookup_name. Check whether a use of B needs an error
+ based on default(none) clauses; inject new bindings as needed into
+ omp parallel scopes for variables that need to be shared or private.
+ In all cases, return the binding that's in effect in the current scope
+ after any remapping. */
+
+static struct c_binding *
+maybe_remap_for_omp_parallel (struct c_scope *pscope, struct c_binding *b)
+{
+ bool did_error = false;
+
+ /* When remapping shared, recurse to the outer-most scope for which the
+ test is relevant. */
+ if (!omp_remap_private
+ && b->depth < pscope->depth
+ && pscope->outer_omp_parallel)
+ b = maybe_remap_for_omp_parallel (pscope->outer_omp_parallel, b);
+
+ /* Check that the any default(none) clause is honored. */
+ if (pscope->omp_default_none
+ && c_omp_sharing_implicitly_determined (pscope, b))
+ {
+ error ("%qE not specified in enclosing %<#pragma omp parallel%>", b->id);
+ error ("%Henclosing %<#pragma omp parallel%>", &pscope->location);
+ did_error = true;
+ }
+
+ /* Re-bind the decl to something in scope of the omp parallel. */
+ if (b->depth < pscope->depth)
+ {
+ int shared = omp_remap_private ? 0 : -1;
+ c_omp_remap_decl_1 (pscope, pscope, b->decl, shared, did_error);
+ b = I_SYMBOL_BINDING (b->id);
+ }
+
+ return b;
}
/* Look up NAME in the current scope and its superiors
@@ -2818,31 +2861,13 @@ tree
lookup_name (tree name)
{
struct c_binding *b = I_SYMBOL_BINDING (name);
- struct c_scope *pscope = current_omp_parallel_scope;
if (b == NULL || b->invisible)
return NULL;
- if (pscope
- && (TREE_CODE (b->decl) == VAR_DECL
- || TREE_CODE (b->decl) == PARM_DECL))
- {
- bool did_error = false;
-
- /* Check that the any default(none) clause is honored. */
- if (pscope->omp_default_none
- && c_omp_sharing_implicitly_determined (pscope, b))
- {
- error ("%qE not specified in enclosing %<#pragma omp parallel%>",
- name);
- did_error = true;
- }
-
- /* Re-bind the decl to something in scope of the omp parallel. */
- if (b->depth < pscope->depth)
- return c_omp_remap_decl_1 (pscope, b->decl, omp_remap_private ? 0 : -1,
- did_error);
- }
+ if ((TREE_CODE (b->decl) == VAR_DECL || TREE_CODE (b->decl) == PARM_DECL)
+ && current_omp_parallel_scope)
+ b = maybe_remap_for_omp_parallel (current_omp_parallel_scope, b);
return b->decl;
}
@@ -7862,6 +7887,7 @@ c_begin_omp_parallel (enum omp_clause_de
current_scope->keep = 1;
current_scope->omp_parallel_body = 1;
current_scope->omp_default_none = (def == OMP_CLAUSE_DEFAULT_NONE);
+ current_scope->location = input_location;
current_omp_parallel_scope = current_scope;
return block;
Index: testsuite/gcc.dg/gomp/parallel-1.c
===================================================================
RCS file: testsuite/gcc.dg/gomp/parallel-1.c
diff -N testsuite/gcc.dg/gomp/parallel-1.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ testsuite/gcc.dg/gomp/parallel-1.c 29 Sep 2005 23:02:19 -0000
@@ -0,0 +1,17 @@
+// { dg-do compile }
+
+void foo()
+{
+ int i;
+
+ #pragma omp parallel
+ {
+ #pragma omp parallel
+ {
+ #pragma omp parallel
+ {
+ i++;
+ }
+ }
+ }
+}
Index: testsuite/gcc.dg/gomp/parallel-2.c
===================================================================
RCS file: testsuite/gcc.dg/gomp/parallel-2.c
diff -N testsuite/gcc.dg/gomp/parallel-2.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ testsuite/gcc.dg/gomp/parallel-2.c 29 Sep 2005 23:02:19 -0000
@@ -0,0 +1,17 @@
+// { dg-do compile }
+
+void foo()
+{
+ int i;
+
+ #pragma omp parallel default(none) // { dg-error "enclosing" }
+ {
+ #pragma omp parallel
+ {
+ #pragma omp parallel default(none) // { dg-error "enclosing" }
+ {
+ i++; // { dg-error "not specified" }
+ }
+ }
+ }
+}