[gomp] Fix Fortan EQUIVALENCE/COMMON/Cray pointee remapping

Jakub Jelinek jakub@redhat.com
Tue Nov 1 16:44:00 GMT 2005


Hi!

The following patch attempts to handle Cray pointees and COMMON/EQUIVALENCE
members.
If COMMON/EQUIVALENCE is privatized, we shouldn't gimplify it its
DECL_VALUE_EXPR, as privatization in this case is supposed to privatize just
the field, not the whole COMMON or EQUIVALENCE.
If COMMON/EQUIVALENCE are shared, we want to gimplify them to their
DECL_VALUE_EXPR immediately (and similarly for any Cray pointees found in
the code).  To make the code debuggable, we want to create private vars
in *.omp_fn.* that have their DECL_VALUE_EXPR remapped to the real location
(for such vars I have added OMP_CLAUSE_PRIVATE_DEBUG flag and
a langhook that tells the middle-end to set that flag).

Ok for gomp?

Fixes several failures, the ones I'm getting now are:

FAIL: gcc.dg/gomp/vla-3.c (test for excess errors)
FAIL: gfortran.dg/gomp/appendix-a/a.24.1.f90  -O   (test for errors, line 19)
FAIL: libgomp.fortran/reduction6.f90  -O*  execution test
FAIL: libgomp.fortran/vla1.f90  -O*  (test for excess errors)
WARNING: libgomp.fortran/vla1.f90  -O*  compilation failed to produce executable

1) vla-3.c is not a regression, has been around for a few days
2) a.24.1.f90 is waiting for feedback from openmp.org
3) reduction6.f90 will need another patch
4) vla1.f90 is what has been discussed yesterday

2005-11-01  Jakub Jelinek  <jakub@redhat.com>

	* tree.h (OMP_CLAUSE_PRIVATE_DEBUG): Define.
	* langhooks.h (struct lang_hooks_for_decls): Add
	omp_disregard_value_expr and omp_private_debug_clause
	hooks.
	* langhooks.c (lhd_bool_tree_bool_false): New function.
	* langhooks-def.h (lhd_bool_tree_bool_false): New prototype.
	(LANG_HOOKS_OMP_DISREGARD_VALUE_EXPR,
	LANG_HOOKS_OMP_PRIVATE_DEBUG_CLAUSE): Define.
	(LANG_HOOKS_DECLS): Add them.
	* gimplify.c (omp_notice_variable): Change return type to bool.
	Return true if DECL_VALUE_EXPR on the decl should be ignored.
	(gimplify_var_or_parm_decl): If omp_notice_variable returned
	true, disregard DECL_VALUE_EXPR on the decl if any.
	(gimplify_adjust_omp_clauses_1): If omp_private_debug_clause
	hook returns true, put the DECL into OMP_CLAUSE_PRIVATE
	clause with OMP_CLAUSE_PRIVATE_DEBUG flag set.
	(gimplify_adjust_omp_clauses): Likewise.
	* omp-low.c (fixup_remapped_decl): Add PRIVATE_DEBUG argument.
	If PRIVATE_DEBUG, copy/remap DECL_VALUE_EXPR even if it is not
	variable-length.
	(scan_sharing_clauses, scan_omp_nested): Adjust caller.
	(expand_rec_input_clauses): Ignore OMP_CLAUSE_PRIVATE
	with OMP_CLAUSE_PRIVATE_DEBUG flag set.
fortran/
	* trans.h (gfc_omp_predetermined_sharing,
	gfc_omp_disregard_value_expr, gfc_omp_private_debug_clause): New
	prototypes.
	(GFC_DECL_COMMON_OR_EQUIV, GFC_DECL_CRAY_POINTEE): Define.
	* trans-openmp.c (gfc_omp_predetermined_sharing,
	gfc_omp_disregard_value_expr, gfc_omp_private_debug_clause): New
	functions.
	* trans-common.c (build_equiv_decl, build_common_decl,
	create_common): Set GFC_DECL_COMMON_OR_EQUIV flag on the decls.
	* trans-decl.c (gfc_finish_cray_pointee): Set GFC_DECL_CRAY_POINTEE
	on the decl.
	* f95-lang.c (LANG_HOOKS_OMP_PREDETERMINED_SHARING,
	LANG_HOOKS_OMP_DISREGARD_VALUE_EXPR,
	LANG_HOOKS_OMP_PRIVATE_DEBUG_CLAUSE): Define.
testsuite/
	* gfortran.dg/gomp/crayptr4.f90: New test.

--- gcc/omp-low.c.jj	2005-11-01 08:52:21.000000000 +0100
+++ gcc/omp-low.c	2005-11-01 16:51:35.000000000 +0100
@@ -391,7 +391,7 @@ install_var_local (tree var, omp_context
    copying the DECL_VALUE_EXPR, and fixing up the type.  */
 
 static void
-fixup_remapped_decl (tree decl, omp_context *ctx)
+fixup_remapped_decl (tree decl, omp_context *ctx, bool private_debug)
 {
   tree new_decl, size;
 
@@ -399,16 +399,17 @@ fixup_remapped_decl (tree decl, omp_cont
 
   TREE_TYPE (new_decl) = remap_type (TREE_TYPE (decl), &ctx->cb);
 
-  if (!TREE_CONSTANT (DECL_SIZE (new_decl)))
+  if ((!TREE_CONSTANT (DECL_SIZE (new_decl)) || private_debug)
+      && DECL_HAS_VALUE_EXPR_P (decl))
     {
-      if (DECL_HAS_VALUE_EXPR_P (decl))
-	{
-	  tree ve = DECL_VALUE_EXPR (decl);
-	  walk_tree (&ve, copy_body_r, &ctx->cb, NULL);
-	  SET_DECL_VALUE_EXPR (new_decl, ve);
-	  DECL_HAS_VALUE_EXPR_P (new_decl) = 1;
-	}
+      tree ve = DECL_VALUE_EXPR (decl);
+      walk_tree (&ve, copy_body_r, &ctx->cb, NULL);
+      SET_DECL_VALUE_EXPR (new_decl, ve);
+      DECL_HAS_VALUE_EXPR_P (new_decl) = 1;
+    }
 
+  if (!TREE_CONSTANT (DECL_SIZE (new_decl)))
+    {
       size = remap_decl (DECL_SIZE (decl), &ctx->cb);
       if (size == error_mark_node)
 	size = TYPE_SIZE (TREE_TYPE (new_decl));
@@ -668,12 +669,14 @@ scan_sharing_clauses (tree clauses, omp_
 	  decl = OMP_CLAUSE_DECL (c);
 	  if (is_variable_sized (decl))
 	    install_var_local (decl, ctx);
-	  fixup_remapped_decl (decl, ctx);
+	  fixup_remapped_decl (decl, ctx,
+			       TREE_CODE (c) == OMP_CLAUSE_PRIVATE
+			       && OMP_CLAUSE_PRIVATE_DEBUG (c));
 	  break;
 
 	case OMP_CLAUSE_SHARED:
 	  decl = OMP_CLAUSE_DECL (c);
-	  fixup_remapped_decl (decl, ctx);
+	  fixup_remapped_decl (decl, ctx, false);
 	  break;
 
 	case OMP_CLAUSE_COPYPRIVATE:
@@ -1056,7 +1059,7 @@ scan_omp_nested (tree *stmt_p, omp_conte
 	case OMP_CLAUSE_PRIVATE:
 	  decl = OMP_CLAUSE_DECL (c);
 	  if (is_variable_sized (decl))
-	    var_sized_list = tree_cons (NULL, decl, var_sized_list);
+	    var_sized_list = tree_cons (NULL, c, var_sized_list);
 	  OMP_CLAUSE_DECL (c) = install_var_local (decl, ctx);
 	  break;
 
@@ -1086,7 +1089,8 @@ scan_omp_nested (tree *stmt_p, omp_conte
      to do this as a separate pass, since we need the pointer and size
      decls installed first.  */
   for (c = var_sized_list; c ; c = TREE_CHAIN (c))
-    fixup_remapped_decl (TREE_VALUE (c), ctx);
+    fixup_remapped_decl (OMP_CLAUSE_DECL (TREE_VALUE (c)), ctx,
+			 OMP_CLAUSE_PRIVATE_DEBUG (TREE_VALUE (c)));
 
   scan_omp (&OMP_BODY (stmt), ctx);
 
@@ -1384,8 +1388,11 @@ expand_rec_input_clauses (tree clauses, 
 
 	  switch (c_kind)
 	    {
-	    case OMP_CLAUSE_SHARED:
 	    case OMP_CLAUSE_PRIVATE:
+	      if (OMP_CLAUSE_PRIVATE_DEBUG (c))
+		continue;
+	      break;
+	    case OMP_CLAUSE_SHARED:
 	    case OMP_CLAUSE_FIRSTPRIVATE:
 	    case OMP_CLAUSE_LASTPRIVATE:
 	    case OMP_CLAUSE_COPYIN:
--- gcc/langhooks.h.jj	2005-10-31 09:43:13.000000000 +0100
+++ gcc/langhooks.h	2005-11-01 15:46:39.000000000 +0100
@@ -201,6 +201,16 @@ struct lang_hooks_for_decls
      predetermined, OMP_CLAUSE_DEFAULT_UNSPECIFIED otherwise.  */
   enum omp_clause_default_kind (*omp_predetermined_sharing) (tree);
 
+  /* Return true if DECL's DECL_VALUE_EXPR (if any) should be
+     disregarded in OpenMP construct, because it is going to be
+     remapped during OpenMP lowering.  SHARED is true if DECL
+     is going to be shared, false if it is going to be privatized.  */
+  bool (*omp_disregard_value_expr) (tree, bool);
+
+  /* Return true if DECL that is shared iff SHARED is true should
+     be put into OMP_CLAUSE_PRIVATE_DEBUG.  */
+  bool (*omp_private_debug_clause) (tree, bool);
+
   /* Build and return code for a default constructor for DECL in
      response to CLAUSE.  Return NULL if nothing to be done.  */
   tree (*omp_clause_default_ctor) (tree clause, tree decl);
--- gcc/tree.h.jj	2005-10-28 23:06:46.000000000 +0200
+++ gcc/tree.h	2005-11-01 15:50:40.000000000 +0100
@@ -343,6 +343,8 @@ struct tree_common GTY(())
 	  SAVE_EXPR
        OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE in
 	  OMP_CLAUSE_LASTPRIVATE
+       OMP_CLAUSE_PRIVATE_DEBUG in
+	  OMP_CLAUSE_PRIVATE
 
    private_flag:
 
@@ -1429,6 +1431,12 @@ struct tree_constructor GTY(())
   TREE_OPERAND (TREE_RANGE_CHECK (NODE, OMP_CLAUSE_PRIVATE, \
 				  OMP_CLAUSE_COPYPRIVATE), 0)
 
+/* True on a PRIVATE clause if its decl is kept around for debugging
+   information only and its DECL_VALUE_EXPR is supposed to point
+   to what it has been remapped to.  */
+#define OMP_CLAUSE_PRIVATE_DEBUG(NODE) \
+  TREE_PUBLIC (OMP_CLAUSE_PRIVATE_CHECK (NODE))
+
 /* True on a LASTPRIVATE clause if a FIRSTPRIVATE clause for the same
    decl is present in the chain.  */
 #define OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE(NODE) \
--- gcc/fortran/trans.h.jj	2005-10-28 23:03:00.000000000 +0200
+++ gcc/fortran/trans.h	2005-11-01 16:08:20.000000000 +0100
@@ -442,6 +442,9 @@ tree builtin_function (const char *, tre
 
 /* In trans-openmp.c */
 bool gfc_omp_privatize_by_reference (tree);
+enum omp_clause_default_kind gfc_omp_predetermined_sharing (tree);
+bool gfc_omp_disregard_value_expr (tree, bool);
+bool gfc_omp_private_debug_clause (tree, bool);
 
 /* Runtime library function decls.  */
 extern GTY(()) tree gfor_fndecl_internal_malloc;
@@ -549,6 +552,8 @@ struct lang_decl		GTY(())
 #define GFC_DECL_PACKED_ARRAY(node) DECL_LANG_FLAG_0(node)
 #define GFC_DECL_PARTIAL_PACKED_ARRAY(node) DECL_LANG_FLAG_1(node)
 #define GFC_DECL_ASSIGN(node) DECL_LANG_FLAG_2(node)
+#define GFC_DECL_COMMON_OR_EQUIV(node) DECL_LANG_FLAG_3(node)
+#define GFC_DECL_CRAY_POINTEE(node) DECL_LANG_FLAG_4(node)
 
 /* An array descriptor.  */
 #define GFC_DESCRIPTOR_TYPE_P(node) TYPE_LANG_FLAG_1(node)
--- gcc/fortran/trans-openmp.c.jj	2005-10-28 23:03:00.000000000 +0200
+++ gcc/fortran/trans-openmp.c	2005-11-01 16:21:44.000000000 +0100
@@ -54,6 +54,82 @@ gfc_omp_privatize_by_reference (tree dec
   return !DECL_ARTIFICIAL (decl) && TREE_CODE (type) == POINTER_TYPE;
 }
 
+/* True if OpenMP sharing attribute of DECL is predetermined.  */
+
+enum omp_clause_default_kind
+gfc_omp_predetermined_sharing (tree decl)
+{
+  /* Cray pointees shouldn't be listed in any clauses and should be
+     gimplified to dereference of the corresponding Cray pointer.
+     Make them all private, so that they are emitted in the debug
+     information.  */
+  if (GFC_DECL_CRAY_POINTEE (decl))
+    return OMP_CLAUSE_DEFAULT_PRIVATE;
+
+  /* COMMON and EQUIVALENCE decls are shared.  They
+     are only referenced through DECL_VALUE_EXPR of the variables
+     contained in them.  If those are privatized, they will not be
+     gimplified to the COMMON or EQUIVALENCE decls.  */
+  if (GFC_DECL_COMMON_OR_EQUIV (decl) && ! DECL_HAS_VALUE_EXPR_P (decl))
+    return OMP_CLAUSE_DEFAULT_SHARED;
+
+  return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
+}
+
+/* Return true if DECL's DECL_VALUE_EXPR (if any) should be
+   disregarded in OpenMP construct, because it is going to be
+   remapped during OpenMP lowering.  SHARED is true if DECL
+   is going to be shared, false if it is going to be privatized.  */
+
+bool
+gfc_omp_disregard_value_expr (tree decl, bool shared)
+{
+  if (GFC_DECL_COMMON_OR_EQUIV (decl)
+      && DECL_HAS_VALUE_EXPR_P (decl))
+    {
+      tree value = DECL_VALUE_EXPR (decl);
+
+      if (TREE_CODE (value) == COMPONENT_REF
+	  && TREE_CODE (TREE_OPERAND (value, 0)) == VAR_DECL
+	  && GFC_DECL_COMMON_OR_EQUIV (TREE_OPERAND (value, 0)))
+	{
+	  /* If variable in COMMON or EQUIVALENCE is privatized, return
+	     true, as just that variable is supposed to be privatized,
+	     not the whole COMMON or whole EQUIVALENCE.
+	     For shared variables in COMMON or EQUIVALENCE, let them be
+	     gimplified to DECL_VALUE_EXPR, so that for multiple shared vars
+	     from the same COMMON or EQUIVALENCE just one sharing of the
+	     whole COMMON or EQUIVALENCE is enough.  */
+	  return ! shared;
+	}
+    }
+  return false;
+}
+
+/* Return true if DECL that is shared iff SHARED is true should
+   be put into OMP_CLAUSE_PRIVATE with OMP_CLAUSE_PRIVATE_DEBUG
+   flag set.  */
+
+bool
+gfc_omp_private_debug_clause (tree decl, bool shared)
+{
+  if (GFC_DECL_CRAY_POINTEE (decl))
+    return true;
+
+  if (GFC_DECL_COMMON_OR_EQUIV (decl)
+      && DECL_HAS_VALUE_EXPR_P (decl))
+    {
+      tree value = DECL_VALUE_EXPR (decl);
+
+      if (TREE_CODE (value) == COMPONENT_REF
+	  && TREE_CODE (TREE_OPERAND (value, 0)) == VAR_DECL
+	  && GFC_DECL_COMMON_OR_EQUIV (TREE_OPERAND (value, 0)))
+	return shared;
+    }
+
+  return false;
+}
+
 
 static inline tree
 gfc_trans_add_clause (tree node, tree tail)
--- gcc/fortran/trans-common.c.jj	2005-10-28 23:03:00.000000000 +0200
+++ gcc/fortran/trans-common.c	2005-11-01 16:11:37.000000000 +0100
@@ -280,6 +280,7 @@ build_equiv_decl (tree union_type, bool 
     {
       decl = gfc_create_var (union_type, "equiv");
       TREE_STATIC (decl) = 1;
+      GFC_DECL_COMMON_OR_EQUIV (decl) = 1;
       return decl;
     }
 
@@ -294,6 +295,7 @@ build_equiv_decl (tree union_type, bool 
 
   TREE_ADDRESSABLE (decl) = 1;
   TREE_USED (decl) = 1;
+  GFC_DECL_COMMON_OR_EQUIV (decl) = 1;
 
   /* The source location has been lost, and doesn't really matter.
      We need to set it to something though.  */
@@ -351,6 +353,7 @@ build_common_decl (gfc_common_head *com,
       TREE_STATIC (decl) = 1;
       DECL_ALIGN (decl) = BIGGEST_ALIGNMENT;
       DECL_USER_ALIGN (decl) = 0;
+      GFC_DECL_COMMON_OR_EQUIV (decl) = 1;
 
       gfc_set_decl_location (decl, &com->where);
 
@@ -498,6 +501,7 @@ create_common (gfc_common_head *com, seg
 			   build3 (COMPONENT_REF, TREE_TYPE (s->field),
 				   decl, s->field, NULL_TREE));
       DECL_HAS_VALUE_EXPR_P (var_decl) = 1;
+      GFC_DECL_COMMON_OR_EQUIV (var_decl) = 1;
 
       if (s->sym->attr.assign)
 	{
--- gcc/fortran/f95-lang.c.jj	2005-10-28 23:03:00.000000000 +0200
+++ gcc/fortran/f95-lang.c	2005-11-01 15:46:39.000000000 +0100
@@ -117,6 +117,9 @@ static void gfc_expand_function (tree);
 #undef LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION
 #undef LANG_HOOKS_CLEAR_BINDING_STACK
 #undef LANG_HOOKS_OMP_PRIVATIZE_BY_REFERENCE
+#undef LANG_HOOKS_OMP_PREDETERMINED_SHARING
+#undef LANG_HOOKS_OMP_DISREGARD_VALUE_EXPR
+#undef LANG_HOOKS_OMP_PRIVATE_DEBUG_CLAUSE
 
 /* Define lang hooks.  */
 #define LANG_HOOKS_NAME                 "GNU F95"
@@ -136,6 +139,9 @@ static void gfc_expand_function (tree);
 #define LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION gfc_expand_function
 #define LANG_HOOKS_CLEAR_BINDING_STACK     gfc_clear_binding_stack
 #define LANG_HOOKS_OMP_PRIVATIZE_BY_REFERENCE	gfc_omp_privatize_by_reference
+#define LANG_HOOKS_OMP_PREDETERMINED_SHARING	gfc_omp_predetermined_sharing
+#define LANG_HOOKS_OMP_DISREGARD_VALUE_EXPR	gfc_omp_disregard_value_expr
+#define LANG_HOOKS_OMP_PRIVATE_DEBUG_CLAUSE	gfc_omp_private_debug_clause
 
 const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
 
--- gcc/fortran/trans-decl.c.jj	2005-11-01 06:14:23.000000000 +0100
+++ gcc/fortran/trans-decl.c	2005-11-01 15:46:39.000000000 +0100
@@ -385,6 +385,7 @@ gfc_finish_cray_pointee (tree decl, gfc_
 
   SET_DECL_VALUE_EXPR (decl, value);
   DECL_HAS_VALUE_EXPR_P (decl) = 1;
+  GFC_DECL_CRAY_POINTEE (decl) = 1;
   /* This is a fake variable just for debugging purposes.  */
   TREE_ASM_WRITTEN (decl) = 1;
 }
--- gcc/langhooks.c.jj	2005-10-31 09:43:13.000000000 +0100
+++ gcc/langhooks.c	2005-11-01 15:53:04.000000000 +0100
@@ -560,6 +560,14 @@ lhd_omp_predetermined_sharing (tree decl
   return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
 }
 
+/* Do nothing (return false).  */
+
+bool
+lhd_bool_tree_bool_false (tree ARG_UNUSED (i), bool ARG_UNUSED (j))
+{
+  return false;
+}
+
 /* Generate code to copy SRC to DST.  */
 
 tree
--- gcc/gimplify.c.jj	2005-10-31 09:43:13.000000000 +0100
+++ gcc/gimplify.c	2005-11-01 16:33:30.000000000 +0100
@@ -284,7 +284,7 @@ delete_omp_context (struct gimplify_omp_
 }
 
 static void omp_add_variable (struct gimplify_omp_ctx *, tree, unsigned int);
-static void omp_notice_variable (struct gimplify_omp_ctx *, tree, bool);
+static bool omp_notice_variable (struct gimplify_omp_ctx *, tree, bool);
 
 /* A subroutine of append_to_statement_list{,_force}.  T is not NULL.  */
 
@@ -1591,8 +1591,8 @@ gimplify_var_or_parm_decl (tree *expr_p)
     }
 
   /* When within an OpenMP context, notice uses of variables.  */
-  if (gimplify_omp_ctxp)
-    omp_notice_variable (gimplify_omp_ctxp, decl, true);
+  if (gimplify_omp_ctxp && omp_notice_variable (gimplify_omp_ctxp, decl, true))
+    return GS_ALL_DONE;
 
   /* If the decl is an alias for another expression, substitute it now.  */
   if (DECL_HAS_VALUE_EXPR_P (decl))
@@ -4280,29 +4280,32 @@ omp_add_variable (struct gimplify_omp_ct
 
 /* Record the fact that DECL was used within the OpenMP context CTX.
    IN_CODE is true when real code uses DECL, and false when we should
-   merely emit default(none) errors.  */
+   merely emit default(none) errors.  Return true if DECL is going to
+   be remapped and thus DECL shouldn't be gimplified into its
+   DECL_VALUE_EXPR (if any).  */
 
-static void
+static bool
 omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code)
 {
   splay_tree_node n;
   unsigned flags = in_code ? GOVD_SEEN : 0;
+  bool ret = false, shared;
 
   if (decl == error_mark_node || TREE_TYPE (decl) == error_mark_node)
-    return;
+    return false;
 
   /* Threadprivate variables are predetermined.  */
   if (is_global_var (decl))
     {
       if (DECL_THREAD_LOCAL_P (decl))
-	return;
+	return false;
 
       if (DECL_HAS_VALUE_EXPR_P (decl))
 	{
 	  tree value = get_base_address (DECL_VALUE_EXPR (decl));
 
 	  if (value && DECL_P (value) && DECL_THREAD_LOCAL_P (value))
-	    return;
+	    return false;
 	}
     }
 
@@ -4345,12 +4348,18 @@ omp_notice_variable (struct gimplify_omp
 	}
 
       omp_add_variable (ctx, decl, flags);
+
+      shared = (flags & GOVD_SHARED) != 0;
+      ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
       goto do_outer;
     }
 
+  shared = ((flags | n->value) & GOVD_SHARED) != 0;
+  ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
+
   /* If nothing changed, there's nothing left to do.  */
   if ((n->value & flags) == flags)
-    return;
+    return ret;
   flags |= n->value;
   n->value = flags;
 
@@ -4358,9 +4367,11 @@ omp_notice_variable (struct gimplify_omp
   /* If the variable is private in the current context, then we don't
      need to propagate anything to an outer context.  */
   if (flags & GOVD_PRIVATE)
-    return;
-  if (ctx->outer_context)
-    omp_notice_variable (ctx->outer_context, decl, in_code);
+    return ret;
+  if (ctx->outer_context
+      && omp_notice_variable (ctx->outer_context, decl, in_code))
+    return true;
+  return ret;
 }
 
 /* Verify that DECL is private within CTX.  If there's specific information
@@ -4497,12 +4508,18 @@ gimplify_adjust_omp_clauses_1 (splay_tre
   unsigned flags = n->value;
   enum tree_code code;
   tree clause;
+  bool private_debug;
 
   if (flags & (GOVD_EXPLICIT | GOVD_LOCAL))
     return 0;
   if ((flags & GOVD_SEEN) == 0)
     return 0;
-  if (flags & GOVD_SHARED)
+  private_debug
+    = lang_hooks.decls.omp_private_debug_clause (decl,
+						 !!(flags & GOVD_SHARED));
+  if (private_debug)
+    code = OMP_CLAUSE_PRIVATE;
+  else if (flags & GOVD_SHARED)
     {
       if (is_global_var (decl))
 	return 0;
@@ -4517,6 +4534,8 @@ gimplify_adjust_omp_clauses_1 (splay_tre
 
   clause = build1 (code, void_type_node, decl);
   OMP_CLAUSE_CHAIN (clause) = *list_p;
+  if (private_debug)
+    OMP_CLAUSE_PRIVATE_DEBUG (clause) = 1;
   *list_p = clause;
 
   return 0;
@@ -4541,6 +4560,15 @@ gimplify_adjust_omp_clauses (tree *list_
 	  decl = OMP_CLAUSE_DECL (c);
 	  n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
 	  remove = !(n->value & GOVD_SEEN);
+	  if (! remove)
+	    {
+	      bool shared = TREE_CODE (c) == OMP_CLAUSE_SHARED;
+	      if (lang_hooks.decls.omp_private_debug_clause (decl, shared))
+		{
+		  TREE_SET_CODE (c, OMP_CLAUSE_PRIVATE);
+		  OMP_CLAUSE_PRIVATE_DEBUG (c) = 1;
+		}
+	    }
 	  break;
 
 	case OMP_CLAUSE_LASTPRIVATE:
--- gcc/langhooks-def.h.jj	2005-10-31 09:43:13.000000000 +0100
+++ gcc/langhooks-def.h	2005-11-01 15:53:52.000000000 +0100
@@ -89,6 +89,7 @@ extern tree lhd_callgraph_analyze_expr (
 /* Declarations for tree gimplification hooks.  */
 extern int lhd_gimplify_expr (tree *, tree *, tree *);
 extern enum omp_clause_default_kind lhd_omp_predetermined_sharing (tree);
+extern bool lhd_bool_tree_bool_false (tree, bool);
 extern tree lhd_omp_assignment (tree, tree, tree);
 
 #define LANG_HOOKS_NAME			"GNU unknown"
@@ -243,6 +244,8 @@ extern tree lhd_make_node (enum tree_cod
 #define LANG_HOOKS_COMDAT_GROUP lhd_comdat_group
 #define LANG_HOOKS_OMP_PRIVATIZE_BY_REFERENCE hook_bool_tree_false
 #define LANG_HOOKS_OMP_PREDETERMINED_SHARING lhd_omp_predetermined_sharing
+#define LANG_HOOKS_OMP_DISREGARD_VALUE_EXPR lhd_bool_tree_bool_false
+#define LANG_HOOKS_OMP_PRIVATE_DEBUG_CLAUSE lhd_bool_tree_bool_false
 #define LANG_HOOKS_OMP_CLAUSE_DEFAULT_CTOR hook_tree_tree_tree_null
 #define LANG_HOOKS_OMP_CLAUSE_COPY_CTOR lhd_omp_assignment
 #define LANG_HOOKS_OMP_CLAUSE_ASSIGN_OP lhd_omp_assignment
@@ -260,6 +263,8 @@ extern tree lhd_make_node (enum tree_cod
   LANG_HOOKS_COMDAT_GROUP, \
   LANG_HOOKS_OMP_PRIVATIZE_BY_REFERENCE, \
   LANG_HOOKS_OMP_PREDETERMINED_SHARING, \
+  LANG_HOOKS_OMP_DISREGARD_VALUE_EXPR, \
+  LANG_HOOKS_OMP_PRIVATE_DEBUG_CLAUSE, \
   LANG_HOOKS_OMP_CLAUSE_DEFAULT_CTOR, \
   LANG_HOOKS_OMP_CLAUSE_COPY_CTOR, \
   LANG_HOOKS_OMP_CLAUSE_ASSIGN_OP, \
--- gcc/testsuite/gfortran.dg/gomp/crayptr4.f90.jj	2005-11-01 17:08:02.000000000 +0100
+++ gcc/testsuite/gfortran.dg/gomp/crayptr4.f90	2005-10-31 14:01:10.000000000 +0100
@@ -0,0 +1,24 @@
+! { dg-do compile }
+! { dg-options "-fopenmp -fcray-pointer" }
+
+subroutine foo (n)
+  integer :: a, b (38), n
+  pointer (ip, a (n + 1))
+
+  b = 2
+  n = 36
+  ip = loc (b)
+!$omp parallel default (none) shared (ip)
+!$omp parallel default (none) shared (ip)
+  a = 1
+!$omp end parallel
+!$omp end parallel
+
+!$omp parallel default (none)
+!$omp parallel default (none) private (ip, b)
+  b = 3
+  ip = loc (b)
+  a = 1
+!$omp end parallel
+!$omp end parallel
+end

	Jakub



More information about the Gcc-patches mailing list