On Thu, Sep 03, 2015 at 04:16:50PM +0200, Jakub Jelinek wrote:
> On Wed, Sep 02, 2015 at 05:58:54PM +0200, Jakub Jelinek wrote:
> > Here is the start of the async offloading support I've talked about,
> > but nowait is not supported on the library side yet, only depend clause
> > (and for that I haven't added a testcase yet).
> 
> Added testcase revealed two (small) issues, here is a fix for that together
> with the testcase.

There has been a bug in the testcase (missing map(from:err) in 3 places),
which hid a problem that on target constructs with depend clause (what about
just nowait?) we have to avoid using GOMP_FIRSTPRIVATE_INT or copy value
into temporary and take temporary's address for GOMP_FIRSTPRIVATE unless
we can prove other tasks can't modify the value while waiting for
dependencies (if it is addressable or shared with other threads/tasks,
then we have to use GOMP_FIRSTPRIVATE with address of the real variable,
so that if other tasks change it, we pick up the right values).

2015-09-04  Jakub Jelinek  <ja...@redhat.com>

        * omp-low.c (lower_omp_target): If target has depend
        clauses, avoid using GOMP_MAP_FIRSTPRIVATE_INT unless the
        var is non-addressable and private in the current task.
        Even for GOMP_MAP_FIRSTPRIVATE, if the var is non-addressable,
        but shared or threadprivate, take address of the shared var
        rather than initializing a temporary with the current value.

        * testsuite/libgomp.c/target-25.c (main): Add missing
        map(from: err) clauses to target constructs.

--- gcc/omp-low.c.jj    2015-09-03 16:36:31.000000000 +0200
+++ gcc/omp-low.c       2015-09-04 11:34:45.512416693 +0200
@@ -13236,6 +13236,7 @@ lower_omp_target (gimple_stmt_iterator *
   location_t loc = gimple_location (stmt);
   bool offloaded, data_region;
   unsigned int map_cnt = 0;
+  bool has_depend = false;
 
   offloaded = is_gimple_omp_offloaded (stmt);
   switch (gimple_omp_target_kind (stmt))
@@ -13268,6 +13269,7 @@ lower_omp_target (gimple_stmt_iterator *
       dep_bind = gimple_build_bind (NULL, NULL, make_node (BLOCK));
       lower_depend_clauses (gimple_omp_target_clauses_ptr (stmt),
                            &dep_ilist, &dep_olist);
+      has_depend = true;
     }
 
   tgt_bind = NULL;
@@ -13719,9 +13721,44 @@ lower_omp_target (gimple_stmt_iterator *
            type = TREE_TYPE (ovar);
            if (is_reference (ovar))
              type = TREE_TYPE (type);
+           bool use_firstprivate_int, force_addr;
+           use_firstprivate_int = false;
+           force_addr = false;
            if ((INTEGRAL_TYPE_P (type)
-                 && TYPE_PRECISION (type) <= POINTER_SIZE)
+                && TYPE_PRECISION (type) <= POINTER_SIZE)
                || TREE_CODE (type) == POINTER_TYPE)
+             use_firstprivate_int = true;
+           if (has_depend)
+             {
+               if (is_reference (var))
+                 use_firstprivate_int = false;
+               else if (is_gimple_reg (var))
+                 {
+                   if (DECL_HAS_VALUE_EXPR_P (var))
+                     {
+                       tree v = get_base_address (var);
+                       if (DECL_P (v) && TREE_ADDRESSABLE (v))
+                         {
+                           use_firstprivate_int = false;
+                           force_addr = true;
+                         }
+                       else
+                         switch (TREE_CODE (v))
+                           {
+                           case INDIRECT_REF:
+                           case MEM_REF:
+                             use_firstprivate_int = false;
+                             force_addr = true;
+                             break;
+                           default:
+                             break;
+                           }
+                     }
+                 }
+               else
+                 use_firstprivate_int = false;
+             }
+           if (use_firstprivate_int)
              {
                tkind = GOMP_MAP_FIRSTPRIVATE_INT;
                tree t = var;
@@ -13734,7 +13771,7 @@ lower_omp_target (gimple_stmt_iterator *
              }
            else if (is_reference (var))
              gimplify_assign (x, var, &ilist);
-           else if (is_gimple_reg (var))
+           else if (!force_addr && is_gimple_reg (var))
              {
                tree avar = create_tmp_var (TREE_TYPE (var));
                mark_addressable (avar);
@@ -13867,9 +13904,40 @@ lower_omp_target (gimple_stmt_iterator *
                type = TREE_TYPE (var);
                if (is_reference (var))
                  type = TREE_TYPE (type);
+               bool use_firstprivate_int;
+               use_firstprivate_int = false;
                if ((INTEGRAL_TYPE_P (type)
                     && TYPE_PRECISION (type) <= POINTER_SIZE)
                    || TREE_CODE (type) == POINTER_TYPE)
+                 use_firstprivate_int = true;
+               if (has_depend)
+                 {
+                   tree v = lookup_decl_in_outer_ctx (var, ctx);
+                   if (is_reference (v))
+                     use_firstprivate_int = false;
+                   else if (is_gimple_reg (v))
+                     {
+                       if (DECL_HAS_VALUE_EXPR_P (v))
+                         {
+                           v = get_base_address (v);
+                           if (DECL_P (v) && TREE_ADDRESSABLE (v))
+                             use_firstprivate_int = false;
+                           else
+                             switch (TREE_CODE (v))
+                               {
+                               case INDIRECT_REF:
+                               case MEM_REF:
+                                 use_firstprivate_int = false;
+                                 break;
+                               default:
+                                 break;
+                               }
+                         }
+                     }
+                   else
+                     use_firstprivate_int = false;
+                 }
+               if (use_firstprivate_int)
                  {
                    x = build_receiver_ref (var, false, ctx);
                    if (TREE_CODE (type) != POINTER_TYPE)
--- libgomp/testsuite/libgomp.c/target-25.c.jj  2015-09-04 10:41:52.371881507 
+0200
+++ libgomp/testsuite/libgomp.c/target-25.c     2015-09-04 10:39:16.000000000 
+0200
@@ -23,7 +23,7 @@ main ()
       usleep (7000);
       z = 3;
     }
-    #pragma omp target map(tofrom: x) firstprivate (y) depend(inout: x, z)
+    #pragma omp target map(tofrom: x) map(from: err) firstprivate (y) 
depend(inout: x, z)
     err = (x != 1 || y != 2 || z != 3);
     if (err)
       abort ();
@@ -44,7 +44,7 @@ main ()
     }
     #pragma omp target enter data nowait map (to: w)
     #pragma omp target enter data depend (inout: x, z) map (to: x, y, z)
-    #pragma omp target map (alloc: x, y, z)
+    #pragma omp target map (alloc: x, y, z) map(from: err)
     {
       err = (x != 4 || y != 5 || z != 6);
       x = 7;
@@ -54,7 +54,7 @@ main ()
     if (err)
       abort ();
     #pragma omp taskwait
-    #pragma omp target map (alloc: w)
+    #pragma omp target map (alloc: w) map(from: err)
     {
       err = w != 7;
       w = 17;


        Jakub

Reply via email to