]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Factor out duplicate code in gimplify_scan_omp_clauses
authorJulian Brown <julian@codesourcery.com>
Mon, 5 Nov 2018 23:51:46 +0000 (15:51 -0800)
committerThomas Schwinge <thomas@codesourcery.com>
Tue, 3 Mar 2020 11:11:41 +0000 (12:11 +0100)
2018-11-10  Julian Brown  <julian@codesourcery.com>

gcc/
* gimplify.c (insert_struct_comp_map, check_base_and_compare_lt): New.
(gimplify_scan_omp_clauses): Outline duplicated code into calls to
above two functions.

(cherry picked from openacc-gcc-9-branch commit
e7f6d3b9a0b10f6b86e83bb19cb54ebd8ca61545)

gcc/ChangeLog.omp
gcc/gimplify.c

index 712ac488baf46994a9223e2a574b8f4fce52b9d0..412c7525918c079ce988be6d9ddcd681265c36c7 100644 (file)
@@ -1,3 +1,9 @@
+2018-11-10  Julian Brown  <julian@codesourcery.com>
+
+       * gimplify.c (insert_struct_comp_map, check_base_and_compare_lt): New.
+       (gimplify_scan_omp_clauses): Outline duplicated code into calls to
+       above two functions.
+
 2015-08-20  Thomas Schwinge  <thomas@codesourcery.com>
            Joseph Myers  <joseph@codesourcery.com>
 
index e59f38261c3699d88199568c68a4a9ecf0de266e..43f67f9fa924c47f9976b620affa7306741e3c73 100644 (file)
@@ -8035,6 +8035,160 @@ gimplify_omp_depend (tree *list_p, gimple_seq *pre_p)
   return 1;
 }
 
+/* Insert a GOMP_MAP_ALLOC or GOMP_MAP_RELEASE node following a
+   GOMP_MAP_STRUCT mapping.  C is an always_pointer mapping.  STRUCT_NODE is
+   the struct node to insert the new mapping after (when the struct node is
+   initially created).  PREV_NODE is the first of two or three mappings for a
+   pointer, and is either:
+     - the node before C, when a pair of mappings is used, e.g. for a C/C++
+       array section.
+     - not the node before C.  This is true when we have a reference-to-pointer
+       type (with a mapping for the reference and for the pointer), or for
+       Fortran derived-type mappings with a GOMP_MAP_TO_PSET.
+   If SCP is non-null, the new node is inserted before *SCP.
+   if SCP is null, the new node is inserted before PREV_NODE.
+   The return type is:
+     - PREV_NODE, if SCP is non-null.
+     - The newly-created ALLOC or RELEASE node, if SCP is null.
+     - The second newly-created ALLOC or RELEASE node, if we are mapping a
+       reference to a pointer.  */
+
+static tree
+insert_struct_comp_map (enum tree_code code, tree c, tree struct_node,
+                       tree prev_node, tree *scp)
+{
+  enum gomp_map_kind mkind
+    = ((code == OMP_TARGET_EXIT_DATA || code == OACC_EXIT_DATA)
+       ? GOMP_MAP_RELEASE : GOMP_MAP_ALLOC);
+
+  tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP);
+  tree cl = scp ? prev_node : c2;
+  OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
+  OMP_CLAUSE_DECL (c2) = unshare_expr (OMP_CLAUSE_DECL (c));
+  OMP_CLAUSE_CHAIN (c2) = scp ? *scp : prev_node;
+  OMP_CLAUSE_SIZE (c2) = TYPE_SIZE_UNIT (ptr_type_node);
+  if (struct_node)
+    OMP_CLAUSE_CHAIN (struct_node) = c2;
+
+  /* We might need to create an additional mapping if we have a reference to a
+     pointer (in C++).  Don't do this if we have something other than a
+     GOMP_MAP_ALWAYS_POINTER though, i.e. a GOMP_MAP_TO_PSET.  */
+  if (OMP_CLAUSE_CHAIN (prev_node) != c
+      && OMP_CLAUSE_CODE (OMP_CLAUSE_CHAIN (prev_node)) == OMP_CLAUSE_MAP
+      && (OMP_CLAUSE_MAP_KIND (OMP_CLAUSE_CHAIN (prev_node))
+         == GOMP_MAP_ALWAYS_POINTER))
+    {
+      tree c4 = OMP_CLAUSE_CHAIN (prev_node);
+      tree c3 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP);
+      OMP_CLAUSE_SET_MAP_KIND (c3, mkind);
+      OMP_CLAUSE_DECL (c3) = unshare_expr (OMP_CLAUSE_DECL (c4));
+      OMP_CLAUSE_SIZE (c3) = TYPE_SIZE_UNIT (ptr_type_node);
+      OMP_CLAUSE_CHAIN (c3) = prev_node;
+      if (!scp)
+       OMP_CLAUSE_CHAIN (c2) = c3;
+      else
+       cl = c3;
+    }
+
+  if (scp)
+    *scp = c2;
+
+  return cl;
+}
+
+/* Called initially with ORIG_BASE non-null, sets PREV_BITPOS and PREV_POFFSET
+   to the offset of the field given in BASE.  Return type is 1 if BASE is equal
+   to *ORIG_BASE after stripping off ARRAY_REF and INDIRECT_REF nodes and
+   calling get_inner_reference, else 0.
+
+   Called subsequently with ORIG_BASE null, compares the offset of the field
+   given in BASE to PREV_BITPOS, PREV_POFFSET. Returns -1 if the base object
+   has changed, 0 if the new value has a higher bit position than that
+   described by the aforementioned arguments, or 1 if the new value is less
+   than them.  Used for (insertion) sorting components after a GOMP_MAP_STRUCT
+   mapping.  */
+
+static int
+check_base_and_compare_lt (tree base, tree *orig_base, tree decl,
+                          poly_int64 *prev_bitpos,
+                          poly_offset_int *prev_poffset)
+{
+  tree offset;
+  poly_int64 bitsize, bitpos;
+  machine_mode mode;
+  int unsignedp, reversep, volatilep = 0;
+  poly_offset_int poffset;
+
+  if (orig_base)
+    {
+      while (TREE_CODE (base) == ARRAY_REF)
+       base = TREE_OPERAND (base, 0);
+
+      if (TREE_CODE (base) == INDIRECT_REF)
+       base = TREE_OPERAND (base, 0);
+    }
+  else
+    {
+      if (TREE_CODE (base) == ARRAY_REF)
+       {
+         while (TREE_CODE (base) == ARRAY_REF)
+           base = TREE_OPERAND (base, 0);
+         if (TREE_CODE (base) != COMPONENT_REF
+             || TREE_CODE (TREE_TYPE (base)) != ARRAY_TYPE)
+           return -1;
+       }
+      else if (TREE_CODE (base) == INDIRECT_REF
+              && TREE_CODE (TREE_OPERAND (base, 0)) == COMPONENT_REF
+              && (TREE_CODE (TREE_TYPE (TREE_OPERAND (base, 0)))
+                  == REFERENCE_TYPE))
+       base = TREE_OPERAND (base, 0);
+    }
+
+  base = get_inner_reference (base, &bitsize, &bitpos, &offset, &mode,
+                             &unsignedp, &reversep, &volatilep);
+
+  if (orig_base)
+    *orig_base = base;
+
+  if ((TREE_CODE (base) == INDIRECT_REF
+       || (TREE_CODE (base) == MEM_REF
+          && integer_zerop (TREE_OPERAND (base, 1))))
+      && DECL_P (TREE_OPERAND (base, 0))
+      && TREE_CODE (TREE_TYPE (TREE_OPERAND (base, 0))) == REFERENCE_TYPE)
+    base = TREE_OPERAND (base, 0);
+
+  gcc_assert (offset == NULL_TREE || poly_int_tree_p (offset));
+
+  if (offset)
+    poffset = wi::to_poly_offset (offset);
+  else
+    poffset = 0;
+
+  if (maybe_ne (bitpos, 0))
+    poffset += bits_to_bytes_round_down (bitpos);
+
+  if (orig_base)
+    {
+      gcc_assert (base == decl);
+
+      *prev_bitpos = bitpos;
+      *prev_poffset = poffset;
+
+      return *orig_base == base;
+    }
+  else
+    {
+      if (base != decl)
+       return -1;
+
+      return (maybe_lt (*prev_poffset, poffset)
+             || (known_eq (*prev_poffset, poffset)
+                 && maybe_lt (*prev_bitpos, bitpos)));
+    }
+
+  return 0;
+}
+
 /* Scan the OMP clauses in *LIST_P, installing mappings into a new
    and previous omp contexts.  */
 
@@ -8546,29 +8700,14 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
                        }
                    }
 
-                 tree offset;
-                 poly_int64 bitsize, bitpos;
-                 machine_mode mode;
-                 int unsignedp, reversep, volatilep = 0;
-                 tree base = OMP_CLAUSE_DECL (c);
-                 while (TREE_CODE (base) == ARRAY_REF)
-                   base = TREE_OPERAND (base, 0);
-                 if (TREE_CODE (base) == INDIRECT_REF)
-                   base = TREE_OPERAND (base, 0);
-                 base = get_inner_reference (base, &bitsize, &bitpos, &offset,
-                                             &mode, &unsignedp, &reversep,
-                                             &volatilep);
-                 tree orig_base = base;
-                 if ((TREE_CODE (base) == INDIRECT_REF
-                      || (TREE_CODE (base) == MEM_REF
-                          && integer_zerop (TREE_OPERAND (base, 1))))
-                     && DECL_P (TREE_OPERAND (base, 0))
-                     && (TREE_CODE (TREE_TYPE (TREE_OPERAND (base, 0)))
-                         == REFERENCE_TYPE))
-                   base = TREE_OPERAND (base, 0);
-                 gcc_assert (base == decl
-                             && (offset == NULL_TREE
-                                 || poly_int_tree_p (offset)));
+                 tree orig_base;
+                 poly_int64 bitpos1;
+                 poly_offset_int offset1;
+
+                 int base_eq_orig_base
+                   = check_base_and_compare_lt (OMP_CLAUSE_DECL (c),
+                                                &orig_base, decl, &bitpos1,
+                                                &offset1);
 
                  splay_tree_node n
                    = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
@@ -8579,7 +8718,7 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
                      tree l = build_omp_clause (OMP_CLAUSE_LOCATION (c),
                                                 OMP_CLAUSE_MAP);
                      OMP_CLAUSE_SET_MAP_KIND (l, GOMP_MAP_STRUCT);
-                     if (orig_base != base)
+                     if (!base_eq_orig_base)
                        OMP_CLAUSE_DECL (l) = unshare_expr (orig_base);
                      else
                        OMP_CLAUSE_DECL (l) = decl;
@@ -8589,32 +8728,8 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
                      struct_map_to_clause->put (decl, l);
                      if (ptr)
                        {
-                         enum gomp_map_kind mkind
-                           = code == OMP_TARGET_EXIT_DATA
-                             ? GOMP_MAP_RELEASE : GOMP_MAP_ALLOC;
-                         tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
-                                                     OMP_CLAUSE_MAP);
-                         OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
-                         OMP_CLAUSE_DECL (c2)
-                           = unshare_expr (OMP_CLAUSE_DECL (c));
-                         OMP_CLAUSE_CHAIN (c2) = *prev_list_p;
-                         OMP_CLAUSE_SIZE (c2)
-                           = TYPE_SIZE_UNIT (ptr_type_node);
-                         OMP_CLAUSE_CHAIN (l) = c2;
-                         if (OMP_CLAUSE_CHAIN (*prev_list_p) != c)
-                           {
-                             tree c4 = OMP_CLAUSE_CHAIN (*prev_list_p);
-                             tree c3
-                               = build_omp_clause (OMP_CLAUSE_LOCATION (c),
-                                                   OMP_CLAUSE_MAP);
-                             OMP_CLAUSE_SET_MAP_KIND (c3, mkind);
-                             OMP_CLAUSE_DECL (c3)
-                               = unshare_expr (OMP_CLAUSE_DECL (c4));
-                             OMP_CLAUSE_SIZE (c3)
-                               = TYPE_SIZE_UNIT (ptr_type_node);
-                             OMP_CLAUSE_CHAIN (c3) = *prev_list_p;
-                             OMP_CLAUSE_CHAIN (c2) = c3;
-                           }
+                         insert_struct_comp_map (code, c, l, *prev_list_p,
+                                                 NULL);
                          *prev_list_p = l;
                          prev_list_p = NULL;
                        }
@@ -8624,7 +8739,7 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
                          *list_p = l;
                          list_p = &OMP_CLAUSE_CHAIN (l);
                        }
-                     if (orig_base != base && code == OMP_TARGET)
+                     if (!base_eq_orig_base && code == OMP_TARGET)
                        {
                          tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
                                                      OMP_CLAUSE_MAP);
@@ -8647,13 +8762,6 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
                      tree *sc = NULL, *scp = NULL;
                      if (GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c)) || ptr)
                        n->value |= GOVD_SEEN;
-                     poly_offset_int o1, o2;
-                     if (offset)
-                       o1 = wi::to_poly_offset (offset);
-                     else
-                       o1 = 0;
-                     if (maybe_ne (bitpos, 0))
-                       o1 += bits_to_bytes_round_down (bitpos);
                      sc = &OMP_CLAUSE_CHAIN (*osc);
                      if (*sc != c
                          && (OMP_CLAUSE_MAP_KIND (*sc)
@@ -8671,44 +8779,14 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
                          break;
                        else
                          {
-                           tree offset2;
-                           poly_int64 bitsize2, bitpos2;
-                           base = OMP_CLAUSE_DECL (*sc);
-                           if (TREE_CODE (base) == ARRAY_REF)
-                             {
-                               while (TREE_CODE (base) == ARRAY_REF)
-                                 base = TREE_OPERAND (base, 0);
-                               if (TREE_CODE (base) != COMPONENT_REF
-                                   || (TREE_CODE (TREE_TYPE (base))
-                                       != ARRAY_TYPE))
-                                 break;
-                             }
-                           else if (TREE_CODE (base) == INDIRECT_REF
-                                    && (TREE_CODE (TREE_OPERAND (base, 0))
-                                        == COMPONENT_REF)
-                                    && (TREE_CODE (TREE_TYPE
-                                                    (TREE_OPERAND (base, 0)))
-                                        == REFERENCE_TYPE))
-                             base = TREE_OPERAND (base, 0);
-                           base = get_inner_reference (base, &bitsize2,
-                                                       &bitpos2, &offset2,
-                                                       &mode, &unsignedp,
-                                                       &reversep, &volatilep);
-                           if ((TREE_CODE (base) == INDIRECT_REF
-                                || (TREE_CODE (base) == MEM_REF
-                                    && integer_zerop (TREE_OPERAND (base,
-                                                                    1))))
-                               && DECL_P (TREE_OPERAND (base, 0))
-                               && (TREE_CODE (TREE_TYPE (TREE_OPERAND (base,
-                                                                       0)))
-                                   == REFERENCE_TYPE))
-                             base = TREE_OPERAND (base, 0);
-                           if (base != decl)
+                           tree sc_decl = OMP_CLAUSE_DECL (*sc);
+                           int same_decl_offset_lt
+                             = check_base_and_compare_lt (sc_decl, NULL, decl,
+                                                          &bitpos1, &offset1);
+                           if (same_decl_offset_lt == -1)
                              break;
                            if (scp)
                              continue;
-                           gcc_assert (offset == NULL_TREE
-                                       || poly_int_tree_p (offset));
                            tree d1 = OMP_CLAUSE_DECL (*sc);
                            tree d2 = OMP_CLAUSE_DECL (c);
                            while (TREE_CODE (d1) == ARRAY_REF)
@@ -8737,14 +8815,7 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
                                remove = true;
                                break;
                              }
-                           if (offset2)
-                             o2 = wi::to_poly_offset (offset2);
-                           else
-                             o2 = 0;
-                           o2 += bits_to_bytes_round_down (bitpos2);
-                           if (maybe_lt (o1, o2)
-                               || (known_eq (o1, o2)
-                                   && maybe_lt (bitpos, bitpos2)))
+                           if (same_decl_offset_lt)
                              {
                                if (ptr)
                                  scp = sc;
@@ -8759,38 +8830,8 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
                                      size_one_node);
                      if (ptr)
                        {
-                         tree c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
-                                                     OMP_CLAUSE_MAP);
-                         tree cl = NULL_TREE;
-                         enum gomp_map_kind mkind
-                           = code == OMP_TARGET_EXIT_DATA
-                             ? GOMP_MAP_RELEASE : GOMP_MAP_ALLOC;
-                         OMP_CLAUSE_SET_MAP_KIND (c2, mkind);
-                         OMP_CLAUSE_DECL (c2)
-                           = unshare_expr (OMP_CLAUSE_DECL (c));
-                         OMP_CLAUSE_CHAIN (c2) = scp ? *scp : *prev_list_p;
-                         OMP_CLAUSE_SIZE (c2)
-                           = TYPE_SIZE_UNIT (ptr_type_node);
-                         cl = scp ? *prev_list_p : c2;
-                         if (OMP_CLAUSE_CHAIN (*prev_list_p) != c)
-                           {
-                             tree c4 = OMP_CLAUSE_CHAIN (*prev_list_p);
-                             tree c3
-                               = build_omp_clause (OMP_CLAUSE_LOCATION (c),
-                                                   OMP_CLAUSE_MAP);
-                             OMP_CLAUSE_SET_MAP_KIND (c3, mkind);
-                             OMP_CLAUSE_DECL (c3)
-                               = unshare_expr (OMP_CLAUSE_DECL (c4));
-                             OMP_CLAUSE_SIZE (c3)
-                               = TYPE_SIZE_UNIT (ptr_type_node);
-                             OMP_CLAUSE_CHAIN (c3) = *prev_list_p;
-                             if (!scp)
-                               OMP_CLAUSE_CHAIN (c2) = c3;
-                             else
-                               cl = c3;
-                           }
-                         if (scp)
-                           *scp = c2;
+                         tree cl = insert_struct_comp_map (code, c, NULL,
+                                                           *prev_list_p, scp);
                          if (sc == prev_list_p)
                            {
                              *sc = cl;