This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[committed] Fix OpenMP privatization of C++ references to VLAs (PR libgomp/69555)


Hi!

I've committed following fix for various OpenMP gimplification and lowering
issues with privatization of C++ references to VLAs, after
bootstrapping/regtesting it on x86_64-linux and i686-linux.

2016-03-02  Jakub Jelinek  <jakub@redhat.com>

	PR libgomp/69555
	* gimplify.c (gimplify_decl_expr): For decls with REFERENCE_TYPE, also
	gimplify_type_sizes the type they refer to.
	(omp_notice_variable): Handle reference vars to VLAs.
	* omp-low.c (lower_omp_target): Emit setup of OMP_CLAUSE_PRIVATE reference
	to VLA decls in the second pass instead of first pass.

	* testsuite/libgomp.c++/pr69555-1.C: New test.
	* testsuite/libgomp.c++/pr69555-2.C: New test.

--- gcc/gimplify.c.jj	2016-03-02 14:08:00.714169515 +0100
+++ gcc/gimplify.c	2016-03-02 16:59:18.466647210 +0100
@@ -1436,14 +1436,22 @@ gimplify_decl_expr (tree *stmt_p, gimple
   if ((TREE_CODE (decl) == TYPE_DECL
        || TREE_CODE (decl) == VAR_DECL)
       && !TYPE_SIZES_GIMPLIFIED (TREE_TYPE (decl)))
-    gimplify_type_sizes (TREE_TYPE (decl), seq_p);
+    {
+      gimplify_type_sizes (TREE_TYPE (decl), seq_p);
+      if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE)
+	gimplify_type_sizes (TREE_TYPE (TREE_TYPE (decl)), seq_p);
+    }
 
   /* ??? DECL_ORIGINAL_TYPE is streamed for LTO so it needs to be gimplified
      in case its size expressions contain problematic nodes like CALL_EXPR.  */
   if (TREE_CODE (decl) == TYPE_DECL
       && DECL_ORIGINAL_TYPE (decl)
       && !TYPE_SIZES_GIMPLIFIED (DECL_ORIGINAL_TYPE (decl)))
-    gimplify_type_sizes (DECL_ORIGINAL_TYPE (decl), seq_p);
+    {
+      gimplify_type_sizes (DECL_ORIGINAL_TYPE (decl), seq_p);
+      if (TREE_CODE (DECL_ORIGINAL_TYPE (decl)) == REFERENCE_TYPE)
+	gimplify_type_sizes (TREE_TYPE (DECL_ORIGINAL_TYPE (decl)), seq_p);
+    }
 
   if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl))
     {
@@ -6264,16 +6272,30 @@ omp_notice_variable (struct gimplify_omp
 
   if ((n->value & (GOVD_SEEN | GOVD_LOCAL)) == 0
       && (flags & (GOVD_SEEN | GOVD_LOCAL)) == GOVD_SEEN
-      && DECL_SIZE (decl)
-      && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
+      && DECL_SIZE (decl))
     {
-      splay_tree_node n2;
-      tree t = DECL_VALUE_EXPR (decl);
-      gcc_assert (TREE_CODE (t) == INDIRECT_REF);
-      t = TREE_OPERAND (t, 0);
-      gcc_assert (DECL_P (t));
-      n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
-      n2->value |= GOVD_SEEN;
+      if (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
+	{
+	  splay_tree_node n2;
+	  tree t = DECL_VALUE_EXPR (decl);
+	  gcc_assert (TREE_CODE (t) == INDIRECT_REF);
+	  t = TREE_OPERAND (t, 0);
+	  gcc_assert (DECL_P (t));
+	  n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
+	  n2->value |= GOVD_SEEN;
+	}
+      else if (lang_hooks.decls.omp_privatize_by_reference (decl)
+	       && TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)))
+	       && (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))))
+		   != INTEGER_CST))
+	{
+	  splay_tree_node n2;
+	  tree t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)));
+	  gcc_assert (DECL_P (t));
+	  n2 = splay_tree_lookup (ctx->variables, (splay_tree_key) t);
+	  if (n2)
+	    n2->value |= GOVD_SEEN;
+	}
     }
 
   shared = ((flags | n->value) & GOVD_SHARED) != 0;
--- gcc/omp-low.c.jj	2016-03-02 14:07:55.279244149 +0100
+++ gcc/omp-low.c	2016-03-02 16:41:24.916205613 +0100
@@ -16472,13 +16472,7 @@ lower_omp_target (gimple_stmt_iterator *
 		    x = build_fold_addr_expr_loc (clause_loc, x);
 		  }
 		else
-		  {
-		    tree atmp
-		      = builtin_decl_explicit (BUILT_IN_ALLOCA_WITH_ALIGN);
-		    tree rtype = TREE_TYPE (TREE_TYPE (new_var));
-		    tree al = size_int (TYPE_ALIGN (rtype));
-		    x = build_call_expr_loc (clause_loc, atmp, 2, x, al);
-		  }
+		  break;
 
 		x = fold_convert_loc (clause_loc, TREE_TYPE (new_var), x);
 		gimplify_expr (&x, &new_body, NULL, is_gimple_val, fb_rvalue);
@@ -16545,7 +16539,8 @@ lower_omp_target (gimple_stmt_iterator *
 	  }
       /* Handle GOMP_MAP_FIRSTPRIVATE_{POINTER,REFERENCE} in second pass,
 	 so that firstprivate vars holding OMP_CLAUSE_SIZE if needed
-	 are already handled.  */
+	 are already handled.  Similarly OMP_CLAUSE_PRIVATE for VLAs
+	 or references to VLAs.  */
       for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
 	switch (OMP_CLAUSE_CODE (c))
 	  {
@@ -16687,6 +16682,27 @@ lower_omp_target (gimple_stmt_iterator *
 		gimple_seq_add_stmt (&new_body,
 				     gimple_build_assign (new_pvar, x));
 	      }
+	    else if (is_reference (var) && !is_gimple_omp_oacc (ctx->stmt))
+	      {
+		location_t clause_loc = OMP_CLAUSE_LOCATION (c);
+		tree new_var = lookup_decl (var, ctx);
+		tree x = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (new_var)));
+		if (TREE_CONSTANT (x))
+		  break;
+		else
+		  {
+		    tree atmp
+		      = builtin_decl_explicit (BUILT_IN_ALLOCA_WITH_ALIGN);
+		    tree rtype = TREE_TYPE (TREE_TYPE (new_var));
+		    tree al = size_int (TYPE_ALIGN (rtype));
+		    x = build_call_expr_loc (clause_loc, atmp, 2, x, al);
+		  }
+
+		x = fold_convert_loc (clause_loc, TREE_TYPE (new_var), x);
+		gimplify_expr (&x, &new_body, NULL, is_gimple_val, fb_rvalue);
+		gimple_seq_add_stmt (&new_body,
+				     gimple_build_assign (new_var, x));
+	      }
 	    break;
 	  }
 
--- libgomp/testsuite/libgomp.c++/pr69555-1.C.jj	2016-03-02 16:56:09.442214952 +0100
+++ libgomp/testsuite/libgomp.c++/pr69555-1.C	2016-03-02 16:56:09.442214952 +0100
@@ -0,0 +1,114 @@
+// PR libgomp/69555
+// { dg-do run }
+
+#include <omp.h>
+
+__attribute__((noinline, noclone)) void
+f1 (int y)
+{
+  int a[y - 2];
+  int (&c)[y - 2] = a;
+  c[0] = 111;
+  int e = 0;
+
+  #pragma omp parallel private (c) num_threads (4) reduction (+:e)
+  {
+    int v = omp_get_thread_num ();
+    for (int i = 0; i < y - 2; i++)
+      c[i] = i + v;
+    #pragma omp barrier
+    for (int i = 0; i < y - 2; i++)
+      if (c[i] != i + v)
+	e++;
+  }
+  if (c[0] != 111 || e)
+    __builtin_abort ();
+}
+
+__attribute__((noinline, noclone)) void
+f2 (int y)
+{
+  int a[y - 2];
+  int (&c)[y - 2] = a;
+  c[0] = 111;
+
+  #pragma omp task private (c)
+  {
+    int v = omp_get_thread_num ();
+    for (int i = 0; i < y - 2; i++)
+      c[i] = i + v;
+    asm volatile ("" : : "r" (&c[0]) : "memory");
+    for (int i = 0; i < y - 2; i++)
+      if (c[i] != i + v)
+	__builtin_abort ();
+  }
+  if (c[0] != 111)
+    __builtin_abort ();
+}
+
+__attribute__((noinline, noclone)) void
+f3 (int y)
+{
+  int a[y - 2];
+  int (&c)[y - 2] = a;
+  for (int i = 0; i < y - 2; i++)
+    c[i] = i + 4;
+
+  #pragma omp parallel firstprivate (c) num_threads (4)
+  {
+    int v = omp_get_thread_num ();
+    for (int i = 0; i < y - 2; i++)
+      {
+	if (c[i] != i + 4)
+	  __builtin_abort ();
+	c[i] = i + v;
+      }
+    #pragma omp barrier
+    for (int i = 0; i < y - 2; i++)
+      if (c[i] != i + v)
+	__builtin_abort ();
+  }
+  for (int i = 0; i < y - 2; i++)
+    if (c[i] != i + 4)
+      __builtin_abort ();
+}
+
+__attribute__((noinline, noclone)) void
+f4 (int y)
+{
+  int a[y - 2];
+  int (&c)[y - 2] = a;
+  for (int i = 0; i < y - 2; i++)
+    c[i] = i + 4;
+
+  #pragma omp task firstprivate (c)
+  {
+    int v = omp_get_thread_num ();
+    for (int i = 0; i < y - 2; i++)
+      {
+	if (c[i] != i + 4)
+	  __builtin_abort ();
+	c[i] = i + v;
+      }
+    asm volatile ("" : : "r" (&c[0]) : "memory");
+    for (int i = 0; i < y - 2; i++)
+      if (c[i] != i + v)
+	__builtin_abort ();
+  }
+  for (int i = 0; i < y - 2; i++)
+    if (c[i] != i + 4)
+      __builtin_abort ();
+}
+
+int
+main ()
+{
+  f1 (6);
+  f3 (6);
+  #pragma omp parallel num_threads (4)
+  {
+    f2 (6);
+    f4 (6);
+  }
+  return 0;
+}
--- libgomp/testsuite/libgomp.c++/pr69555-2.C.jj	2016-03-02 16:56:09.442214952 +0100
+++ libgomp/testsuite/libgomp.c++/pr69555-2.C	2016-03-02 16:56:09.442214952 +0100
@@ -0,0 +1,58 @@
+// PR libgomp/69555
+// { dg-do run }
+
+__attribute__((noinline, noclone)) void
+f1 (int y)
+{
+  int a[y - 2];
+  int (&c)[y - 2] = a;
+  for (int i = 0; i < y - 2; i++)
+    c[i] = i + 4;
+
+  #pragma omp target firstprivate (c)
+  {
+    for (int i = 0; i < y - 2; i++)
+      {
+	if (c[i] != i + 4)
+	  __builtin_abort ();
+	c[i] = i + 9;
+      }
+    asm volatile ("" : : "r" (&c[0]) : "memory");
+    for (int i = 0; i < y - 2; i++)
+      if (c[i] != i + 9)
+	__builtin_abort ();
+  }
+  for (int i = 0; i < y - 2; i++)
+    if (c[i] != i + 4)
+      __builtin_abort ();
+}
+
+__attribute__((noinline, noclone)) void
+f2 (int y)
+{
+  int a[y - 2];
+  int (&c)[y - 2] = a;
+  for (int i = 0; i < y - 2; i++)
+    c[i] = i + 4;
+
+  #pragma omp target private (c)
+  {
+    for (int i = 0; i < y - 2; i++)
+      c[i] = i + 9;
+    asm volatile ("" : : "r" (&c[0]) : "memory");
+    for (int i = 0; i < y - 2; i++)
+      if (c[i] != i + 9)
+	__builtin_abort ();
+  }
+  for (int i = 0; i < y - 2; i++)
+    if (c[i] != i + 4)
+      __builtin_abort ();
+}
+
+int
+main ()
+{
+  f1 (6);
+  f2 (6);
+  return 0;
+}

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]