aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-family
diff options
context:
space:
mode:
authorJulian Brown <julian@codesourcery.com>2023-03-01 14:22:25 +0000
committerJulian Brown <julian@codesourcery.com>2023-07-03 21:40:59 +0000
commit6336f8eaeb26af8729592754c01ffba0c5ece32b (patch)
tree70de864e8f7a333a65669d597d900111f4f06f0c /gcc/c-family
parent5d491f7ae2f99d60d70f6bb2dff5db11ba1328a4 (diff)
OpenMP: Support strided and shaped-array updates for C++
This patch adds support for OpenMP 5.0 strided updates and the array-shaping operator ("([x][y][z]) foo[0:n]..."). This is mostly for C++ only so far, though necessary changes have been made to the C FE to adjust for changes to shared data structures. In terms of the implementation of various bits: - The OMP_ARRAY_SECTION tree code has been extended to take a 'stride' argument, and changes have been made throughout semantics.cc, etc. to take the new field into account -- including bounds checking. - A new type of cast operator has been added to represent the OpenMP array-shaping operator: OMP_ARRAYSHAPE_CAST_EXPR (1). - The address tokenization mechanism from previous patches has been extended with two new access kinds to represent noncontiguous array updates. - New mapping kinds have been added to represent noncontiguous updates: those which may be subject to array shaping, or have non-unit strides. These are processed by omp-low.cc into a kind of descriptor that is passed to the libgomp runtime (2). The current patch reuses an extended version of the helper code for omp_target_memcpy_rect, which may generate very many small host-device or device-host copies. (The "descriptor" has also been designed so reusing that functionality is relatively straightforward.) Optimising those multiple copies, e.g. by packing them into a single transfer when it would be beneficial, is left as the subject of a future patch. This patch has some adjustments to the omp-low.cc code after Chung-Lin's patch "OpenMP 5.0: Allow multiple clauses mapping same variable" (325f085897efca59879a64704ab15f1763ecb807), relative to the version last posted for mainline. Notes: (1) In a bit more detail: the array-shaping operator has the same precedence as a C-style cast, but applies to the whole expression, including array-section specifiers. We parse it initially as if it applies to the "value" of the whole expression: ([x][y]) ptr[0:10:2][1:5:2] i.e., something like: ([x][y]) (ptr[0:10:2][1:5:2]) or as if the cast applies to the innermost/right-hand side array section. Then, a little later in parsing (cp_parser_omp_var_list_no_open), we rewrite it to apply to the inner pointer instead: (([x][y]) ptr)[0:10:2][1:5:2] and that means a genuine multi-dimensional array or an array-shaped pointer can be handled pretty much the same for the rest of compilation. We use VIEW_CONVERT_EXPR for the "cast", unless we're processing a template definition, where we use a new tree code instead. (2) The new map kinds work like this. An update directive starts out with OMP_CLAUSE_TO or OMP_CLAUSE_FROM clauses representing the block in question and the direction of the needed transfer. If we detect a noncontiguous update, we emit a list of mapping nodes (type OMP_CLAUSE_MAP, with new kinds, so the "mapping group" machinery in gimplify.cc can be reused): OMP_CLAUSE_TO --> GOMP_MAP_TO_GRID (VIEW_CONVERT_EXPR<int[x][y]>(ptr) [len: <element-size>]) GOMP_MAP_GRID_DIM 0 [len: 10] (i.e. [0:10:2]) GOMP_MAP_GRID_STRIDE 2 GOMP_MAP_GRID_DIM 1 [len: 5] (i.e. [1:5:2]) GOMP_MAP_GRID_STRIDE 2 During omp-low.cc, this sequence is reformulated into: GOMP_MAP_TO_GRID (ptr) [len: <whole array size>] GOMP_MAP_TO_PSET (&ptr_desc [len: <desc size>]) "ptr_desc" is a struct, stored statically or constructed on the (host) stack, containing arrays representing the size of the whole array, the rectangular subregion to transfer, and the stride with which to walk over elements in each dimension. 2023-07-03 Julian Brown <julian@codesourcery.com> gcc/c-family/ * c-common.h (expand_array_base): Update prototype. * c-omp.cc (c_omp_address_inspector::map_supported_p): Support VIEW_CONVERT_EXPR and ADDR_EXPR codes. (omp_expand_grid_dim): New function. (omp_handle_noncontig_array): New function. (c_omp_address_inspector:expand_array_base): Remove DECL_P parameter. Support noncontiguous array updates. (c_omp_address_inspector::expand_component_selector): Support noncontiguous array updates. (c_omp_address_inspector::expand_map_clause): Update calls to expand_array_base. * c-pretty-print.cc (c_pretty_printer::postfix_expression): Add OMP_ARRAY_SECTION stride support. gcc/c/ * c-parser.cc (c_parser_postfix_expression_after_primary): Dummy stride support (for now). (struct omp_dim): Add stride support. (c_parser_omp_variable_list): Likewise. * c-tree.h (build_omp_array_section): Update prototype. * c-typeck.cc (mark_exp_read): Add stride support for OMP_ARRAY_SECTION. (build_omp_array_section): Add stride support. (handle_omp_array_sections_1): Add minimal stride support. gcc/cp/ * cp-objcp-common.cc (cp_common_init_ts): Add array-shape cast support. * cp-tree.def (OMP_ARRAYSHAPE_CAST_EXPR): Add tree code. * cp-tree.h (DECLTYPE_FOR_OMP_ARRAYSHAPE_CAST): Add flag. (cp_omp_create_arrayshape_type, cp_build_omp_arrayshape_cast): Add prototypes. (grok_omp_array_section, build_omp_array_section): Add stride parameters. * decl.cc (create_anon_array_type): New function. (cp_omp_create_arrayshape_type): New function. * decl2.cc (grok_omp_array_section): Add stride parameter. (min_vis_expr_r): Add OMP_ARRAYSHAPE_CAST_EXPR support. * error.cc (dump_expr): Add stride support for OMP_ARRAY_SECTION. * mangle.cc (write_expression): Add OMP_ARRAYSHAPE_CAST_EXPR support. * operators.def (OMP_ARRAYSHAPE_CAST_EXPR): Add. * parser.cc (cp_parser_new): Initialise omp_array_shaping_op_p and omp_has_array_shape_p fields. (cp_parser_statement_expr): Don't allow array shaping op in statement exprs. (cp_parser_postfix_open_square_expression): Add stride parsing for array sections. Use array section code to represent array refs if we have an array-shaping operator. (cp_parser_parenthesized_expression_list): Don't allow array-shaping op here. (cp_parser_cast_expression): Add array-shaping operator parsing. (cp_parser_lambda_expression): Don't allow array-shaping op in lambda body. (cp_parser_braced_list): Don't allow array-shaping op in braced list. (struct omp_dim): Add stride field. (cp_parser_var_list_no_open): Add stride/array shape support. (cp_parser_omp_target_update): Handle noncontiguous updates. * parser.h (cp_parser): Add omp_array_shaping_op_p and omp_has_array_shape_p fields. * pt.cc (tsubst): Add array-shape cast support. (tsubst_copy, tsubst_copy_and_build): Likewise. Add stride support for OMP_ARRAY_SECTION. (tsubst_omp_clause_decl): Add stride support for OMP_ARRAY_SECTION. * semantics.cc (handle_omp_array_sections_1): Add DISCONTIGUOUS parameter and stride support. (omp_array_section_low_bound): New function. (handle_omp_array_sections): Add DISCONTIGUOUS parameter and stride support. (finish_omp_clauses): Update calls to handle_omp_array_sections, and add noncontiguous array update support. (cp_build_omp_arrayshape_cast): New function. * typeck.cc (structural_comptypes): Add array-shape cast support. (build_omp_array_section): Add stride parameter. (check_for_casting_away_constness): Add OMP_ARRAYSHAPE_CAST_EXPR support. gcc/ * gimplify.cc (omp_group_last, omp_group_base): Add GOMP_MAP_TO_GRID, GOMP_MAP_FROM_GRID support. (gimplify_adjust_omp_clauses): Support new GOMP_MAP_GRID_DIM, GOMP_MAP_GRID_STRIDE mapping nodes. Don't crash on e.g. misuse of ADDR_EXPR in mapping clauses. * omp-general.cc (omp_parse_noncontiguous_array): New function. (omp_parse_access_method): Add noncontiguous array support. (omp_parse_structure_base): Add array-shaping support. (debug_omp_tokenized_addr): Add ACCESS_NONCONTIG_ARRAY, ACCESS_NONCONTIG_REF_TO_ARRAY token support. * omp-general.h (access_method_kinds): Add ACCESS_NONCONTIG_ARRAY and ACCESS_NONCONTIG_REF_TO_ARRAY access kinds. * omp-low.cc (omp_noncontig_descriptor_type): New function. (scan_sharing_clauses): Support noncontiguous array updates. (lower_omp_target): Likewise. * tree-pretty-print.cc (dump_omp_clause): Add GOMP_MAP_TO_GRID, GOMP_MAP_FROM_GRID, GOMP_MAP_GRID_DIM, GOMP_MAP_GRID_STRIDE map kinds. (dump_generic_node): Add stride support for OMP_ARRAY_SECTION. * tree.def (OMP_ARRAY_SECTION): Add stride argument. include/ * gomp-constants.h (gomp_map_kind): Add GOMP_MAP_TO_GRID, GOMP_MAP_FROM_GRID, GOMP_MAP_GRID_DIM, GOMP_MAP_GRID_STRIDE map kinds. gcc/testsuite/ * g++.dg/gomp/array-shaping-1.C: New test. * g++.dg/gomp/array-shaping-2.C: New test. * g++.dg/gomp/bad-array-shaping-1.C: New test. * g++.dg/gomp/bad-array-shaping-2.C: New test. * g++.dg/gomp/bad-array-shaping-3.C: New test. * g++.dg/gomp/bad-array-shaping-4.C: New test. * g++.dg/gomp/bad-array-shaping-5.C: New test. * g++.dg/gomp/bad-array-shaping-6.C: New test. * g++.dg/gomp/bad-array-shaping-7.C: New test. * g++.dg/gomp/bad-array-shaping-8.C: New test. libgomp/ * libgomp.h (omp_noncontig_array_desc): New struct. * target.c (omp_target_memcpy_rect_worker): Add stride array parameter. Forward declare. Add STRIDES parameter and strided update support. (gomp_update): Add noncontiguous (strided/shaped) update support. * testsuite/libgomp.c++/array-shaping-1.C: New test. * testsuite/libgomp.c++/array-shaping-2.C: New test. * testsuite/libgomp.c++/array-shaping-3.C: New test. * testsuite/libgomp.c++/array-shaping-4.C: New test. * testsuite/libgomp.c++/array-shaping-5.C: New test. * testsuite/libgomp.c++/array-shaping-6.C: New test. * testsuite/libgomp.c++/array-shaping-7.C: New test. * testsuite/libgomp.c++/array-shaping-8.C: New test. * testsuite/libgomp.c++/array-shaping-9.C: New test. * testsuite/libgomp.c++/array-shaping-10.C: New test. * testsuite/libgomp.c++/array-shaping-11.C: New test. * testsuite/libgomp.c++/array-shaping-12.C: New test. * testsuite/libgomp.c++/array-shaping-13.C: New test.
Diffstat (limited to 'gcc/c-family')
-rw-r--r--gcc/c-family/ChangeLog.omp16
-rw-r--r--gcc/c-family/c-common.h2
-rw-r--r--gcc/c-family/c-omp.cc206
-rw-r--r--gcc/c-family/c-pretty-print.cc5
4 files changed, 206 insertions, 23 deletions
diff --git a/gcc/c-family/ChangeLog.omp b/gcc/c-family/ChangeLog.omp
index f84f583fbdf..b2648980b28 100644
--- a/gcc/c-family/ChangeLog.omp
+++ b/gcc/c-family/ChangeLog.omp
@@ -1,5 +1,21 @@
2023-07-03 Julian Brown <julian@codesourcery.com>
+ * c-common.h (expand_array_base): Update prototype.
+ * c-omp.cc (c_omp_address_inspector::map_supported_p): Support
+ VIEW_CONVERT_EXPR and ADDR_EXPR codes.
+ (omp_expand_grid_dim): New function.
+ (omp_handle_noncontig_array): New function.
+ (c_omp_address_inspector:expand_array_base): Remove DECL_P parameter.
+ Support noncontiguous array updates.
+ (c_omp_address_inspector::expand_component_selector): Support
+ noncontiguous array updates.
+ (c_omp_address_inspector::expand_map_clause): Update calls to
+ expand_array_base.
+ * c-pretty-print.cc (c_pretty_printer::postfix_expression): Add
+ OMP_ARRAY_SECTION stride support.
+
+2023-07-03 Julian Brown <julian@codesourcery.com>
+
* c-common.h (expand_array_base, expand_component_selector,
expand_map_clause): Adjust member declarations.
* c-omp.cc (omp_expand_access_chain): Pass and return pointer to
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index 756358f3fd8..ea6c479cd62 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -1376,7 +1376,7 @@ public:
bool maybe_zero_length_array_section (tree);
tree * expand_array_base (tree *, vec<omp_addr_token *> &, tree, unsigned *,
- c_omp_region_type, bool);
+ c_omp_region_type);
tree * expand_component_selector (tree *, vec<omp_addr_token *> &, tree,
unsigned *);
tree * expand_map_clause (tree *, tree, vec<omp_addr_token *> &,
diff --git a/gcc/c-family/c-omp.cc b/gcc/c-family/c-omp.cc
index 17f3d71c655..9e307411f76 100644
--- a/gcc/c-family/c-omp.cc
+++ b/gcc/c-family/c-omp.cc
@@ -4042,7 +4042,9 @@ c_omp_address_inspector::map_supported_p ()
|| TREE_CODE (t) == POINTER_PLUS_EXPR
|| TREE_CODE (t) == NON_LVALUE_EXPR
|| TREE_CODE (t) == OMP_ARRAY_SECTION
- || TREE_CODE (t) == NOP_EXPR)
+ || TREE_CODE (t) == NOP_EXPR
+ || TREE_CODE (t) == VIEW_CONVERT_EXPR
+ || TREE_CODE (t) == ADDR_EXPR)
if (TREE_CODE (t) == COMPOUND_EXPR)
t = TREE_OPERAND (t, 1);
else
@@ -4192,21 +4194,95 @@ omp_expand_access_chain (tree *pc, tree expr,
return pc;
}
+static tree *
+omp_expand_grid_dim (location_t loc, tree *pc, tree decl)
+{
+ if (TREE_CODE (decl) == OMP_ARRAY_SECTION)
+ pc = omp_expand_grid_dim (loc, pc, TREE_OPERAND (decl, 0));
+ else
+ return pc;
+
+ tree c = *pc;
+ tree low_bound = TREE_OPERAND (decl, 1);
+ tree length = TREE_OPERAND (decl, 2);
+ tree stride = TREE_OPERAND (decl, 3);
+
+ tree cd = build_omp_clause (loc, OMP_CLAUSE_MAP);
+ OMP_CLAUSE_SET_MAP_KIND (cd, GOMP_MAP_GRID_DIM);
+ OMP_CLAUSE_DECL (cd) = unshare_expr (low_bound);
+ OMP_CLAUSE_SIZE (cd) = unshare_expr (length);
+
+ if (stride && !integer_onep (stride))
+ {
+ tree cs = build_omp_clause (loc, OMP_CLAUSE_MAP);
+ OMP_CLAUSE_SET_MAP_KIND (cs, GOMP_MAP_GRID_STRIDE);
+ OMP_CLAUSE_DECL (cs) = unshare_expr (stride);
+
+ OMP_CLAUSE_CHAIN (cs) = OMP_CLAUSE_CHAIN (c);
+ OMP_CLAUSE_CHAIN (cd) = cs;
+ OMP_CLAUSE_CHAIN (c) = cd;
+ pc = &OMP_CLAUSE_CHAIN (cd);
+ }
+ else
+ {
+ OMP_CLAUSE_CHAIN (cd) = OMP_CLAUSE_CHAIN (c);
+ OMP_CLAUSE_CHAIN (c) = cd;
+ pc = &OMP_CLAUSE_CHAIN (c);
+ }
+
+ return pc;
+}
+
+tree *
+omp_handle_noncontig_array (location_t loc, tree *pc, tree c, tree base)
+{
+ tree type;
+
+ if (POINTER_TYPE_P (TREE_TYPE (base)))
+ type = TREE_TYPE (TREE_TYPE (base));
+ else
+ type = strip_array_types (TREE_TYPE (base));
+
+ tree c_map = build_omp_clause (loc, OMP_CLAUSE_MAP);
+
+ OMP_CLAUSE_DECL (c_map) = unshare_expr (base);
+ /* Use the element size (or pointed-to type size) here. */
+ OMP_CLAUSE_SIZE (c_map) = TYPE_SIZE_UNIT (type);
+
+ switch (OMP_CLAUSE_CODE (c))
+ {
+ case OMP_CLAUSE_TO:
+ OMP_CLAUSE_SET_MAP_KIND (c_map, GOMP_MAP_TO_GRID);
+ break;
+ case OMP_CLAUSE_FROM:
+ OMP_CLAUSE_SET_MAP_KIND (c_map, GOMP_MAP_FROM_GRID);
+ break;
+ default:
+ gcc_unreachable ();
+ }
+
+ OMP_CLAUSE_CHAIN (c_map) = OMP_CLAUSE_CHAIN (c);
+
+ *pc = c_map;
+
+ return omp_expand_grid_dim (loc, pc, OMP_CLAUSE_DECL (c));
+}
+
/* Translate "array_base_decl access_method" to OMP mapping clauses. */
tree *
c_omp_address_inspector::expand_array_base (tree *pc,
vec<omp_addr_token *> &addr_tokens,
tree expr, unsigned *idx,
- c_omp_region_type ort,
- bool decl_p)
+ c_omp_region_type ort)
{
using namespace omp_addr_tokenizer;
tree c = *pc;
location_t loc = OMP_CLAUSE_LOCATION (c);
int i = *idx;
tree decl = addr_tokens[i + 1]->expr;
- bool declare_target_p = (decl_p
+ bool decl_p = DECL_P (decl);
+ bool declare_target_p = (DECL_P (decl)
&& is_global_var (decl)
&& lookup_attribute ("omp declare target",
DECL_ATTRIBUTES (decl)));
@@ -4218,6 +4294,7 @@ c_omp_address_inspector::expand_array_base (tree *pc,
unsigned consume_tokens = 2;
bool target = (ort & C_ORT_TARGET) != 0;
bool openmp = (ort & C_ORT_OMP) != 0;
+ unsigned acc = i + 1;
gcc_assert (i == 0);
@@ -4230,7 +4307,15 @@ c_omp_address_inspector::expand_array_base (tree *pc,
return pc;
}
- switch (addr_tokens[i + 1]->u.access_kind)
+ if (!map_p && chain_p)
+ {
+ /* See comment in c_omp_address_inspector::expand_component_selector. */
+ while (acc + 1 < addr_tokens.length ()
+ && addr_tokens[acc + 1]->type == ACCESS_METHOD)
+ acc++;
+ }
+
+ switch (addr_tokens[acc]->u.access_kind)
{
case ACCESS_DIRECT:
if (decl_p && !target)
@@ -4474,6 +4559,40 @@ c_omp_address_inspector::expand_array_base (tree *pc,
}
break;
+ case ACCESS_NONCONTIG_ARRAY:
+ {
+ gcc_assert (!map_p);
+
+ tree base = addr_tokens[acc]->expr;
+
+ if (decl_p)
+ c_common_mark_addressable_vec (base);
+
+ pc = omp_handle_noncontig_array (loc, pc, c, base);
+ consume_tokens = (acc + 1) - i;
+ chain_p = false;
+ }
+ break;
+
+ case ACCESS_NONCONTIG_REF_TO_ARRAY:
+ {
+ gcc_assert (!map_p);
+
+ if (decl_p)
+ c_common_mark_addressable_vec (addr_tokens[acc]->expr);
+
+ /* Or here. */
+ gcc_assert (!chain_p);
+
+ tree base = addr_tokens[i + 1]->expr;
+ base = convert_from_reference (base);
+
+ pc = omp_handle_noncontig_array (loc, pc, c, base);
+ consume_tokens = (acc + 1) - i;
+ chain_p = false;
+ }
+ break;
+
default:
*idx = i + consume_tokens;
return NULL;
@@ -4524,8 +4643,27 @@ c_omp_address_inspector::expand_component_selector (tree *pc,
tree c2 = NULL_TREE, c3 = NULL_TREE;
bool chain_p = omp_access_chain_p (addr_tokens, i + 1);
bool map_p = OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP;
+ unsigned acc = i + 1;
+
+ if (!map_p && chain_p)
+ {
+ /* We have a non-map clause (i.e. to/from for an "update" directive),
+ and we might have a noncontiguous array section at the end of a
+ chain of other accesses, e.g. pointer indirections like this:
+
+ struct_base_decl access_pointer access_pointer component_selector
+ access_pointer access_pointer access_noncontig_array
- switch (addr_tokens[i + 1]->u.access_kind)
+ We only need to process the last access in this case, so skip
+ over previous accesses. */
+
+ while (acc + 1 < addr_tokens.length ()
+ && addr_tokens[acc + 1]->type == ACCESS_METHOD)
+ acc++;
+ chain_p = false;
+ }
+
+ switch (addr_tokens[acc]->u.access_kind)
{
case ACCESS_DIRECT:
case ACCESS_INDEXED_ARRAY:
@@ -4535,7 +4673,7 @@ c_omp_address_inspector::expand_component_selector (tree *pc,
{
/* Copy the referenced object. Note that we also do this for !MAP_P
clauses. */
- tree obj = convert_from_reference (addr_tokens[i + 1]->expr);
+ tree obj = convert_from_reference (addr_tokens[acc]->expr);
OMP_CLAUSE_DECL (c) = obj;
OMP_CLAUSE_SIZE (c) = TYPE_SIZE_UNIT (TREE_TYPE (obj));
@@ -4544,7 +4682,7 @@ c_omp_address_inspector::expand_component_selector (tree *pc,
c2 = build_omp_clause (loc, OMP_CLAUSE_MAP);
OMP_CLAUSE_SET_MAP_KIND (c2, GOMP_MAP_ATTACH_DETACH);
- OMP_CLAUSE_DECL (c2) = addr_tokens[i + 1]->expr;
+ OMP_CLAUSE_DECL (c2) = addr_tokens[acc]->expr;
OMP_CLAUSE_SIZE (c2) = size_zero_node;
}
break;
@@ -4555,15 +4693,15 @@ c_omp_address_inspector::expand_component_selector (tree *pc,
break;
tree virtual_origin
- = convert_from_reference (addr_tokens[i + 1]->expr);
+ = convert_from_reference (addr_tokens[acc]->expr);
virtual_origin = build_fold_addr_expr (virtual_origin);
virtual_origin = fold_convert_loc (loc, ptrdiff_type_node,
virtual_origin);
- tree data_addr = omp_accessed_addr (addr_tokens, i + 1, expr);
+ tree data_addr = omp_accessed_addr (addr_tokens, acc, expr);
c2 = build_omp_clause (loc, OMP_CLAUSE_MAP);
OMP_CLAUSE_SET_MAP_KIND (c2, GOMP_MAP_ATTACH_DETACH);
- OMP_CLAUSE_DECL (c2) = addr_tokens[i + 1]->expr;
+ OMP_CLAUSE_DECL (c2) = addr_tokens[acc]->expr;
OMP_CLAUSE_SIZE (c2)
= fold_build2_loc (loc, MINUS_EXPR, ptrdiff_type_node,
fold_convert_loc (loc, ptrdiff_type_node,
@@ -4580,12 +4718,12 @@ c_omp_address_inspector::expand_component_selector (tree *pc,
tree virtual_origin
= fold_convert_loc (loc, ptrdiff_type_node,
- addr_tokens[i + 1]->expr);
- tree data_addr = omp_accessed_addr (addr_tokens, i + 1, expr);
+ addr_tokens[acc]->expr);
+ tree data_addr = omp_accessed_addr (addr_tokens, acc, expr);
c2 = build_omp_clause (loc, OMP_CLAUSE_MAP);
OMP_CLAUSE_SET_MAP_KIND (c2, GOMP_MAP_ATTACH_DETACH);
- OMP_CLAUSE_DECL (c2) = addr_tokens[i + 1]->expr;
+ OMP_CLAUSE_DECL (c2) = addr_tokens[acc]->expr;
OMP_CLAUSE_SIZE (c2)
= fold_build2_loc (loc, MINUS_EXPR, ptrdiff_type_node,
fold_convert_loc (loc, ptrdiff_type_node,
@@ -4600,10 +4738,10 @@ c_omp_address_inspector::expand_component_selector (tree *pc,
if (!map_p)
break;
- tree ptr = convert_from_reference (addr_tokens[i + 1]->expr);
+ tree ptr = convert_from_reference (addr_tokens[acc]->expr);
tree virtual_origin = fold_convert_loc (loc, ptrdiff_type_node,
ptr);
- tree data_addr = omp_accessed_addr (addr_tokens, i + 1, expr);
+ tree data_addr = omp_accessed_addr (addr_tokens, acc, expr);
/* Attach the pointer... */
c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP);
@@ -4618,13 +4756,38 @@ c_omp_address_inspector::expand_component_selector (tree *pc,
/* ...and also the reference. */
c3 = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP);
OMP_CLAUSE_SET_MAP_KIND (c3, GOMP_MAP_ATTACH_DETACH);
- OMP_CLAUSE_DECL (c3) = addr_tokens[i + 1]->expr;
+ OMP_CLAUSE_DECL (c3) = addr_tokens[acc]->expr;
OMP_CLAUSE_SIZE (c3) = size_zero_node;
}
break;
+ case ACCESS_NONCONTIG_ARRAY:
+ {
+ gcc_assert (!map_p);
+
+ /* We don't expect to see further accesses here. */
+ gcc_assert (!chain_p);
+
+ pc = omp_handle_noncontig_array (loc, pc, c, addr_tokens[acc]->expr);
+ }
+ break;
+
+ case ACCESS_NONCONTIG_REF_TO_ARRAY:
+ {
+ gcc_assert (!map_p);
+
+ /* Or here. */
+ gcc_assert (!chain_p);
+
+ tree base = addr_tokens[acc]->expr;
+ base = convert_from_reference (base);
+
+ pc = omp_handle_noncontig_array (loc, pc, c, base);
+ }
+ break;
+
default:
- *idx = i + 2;
+ *idx = acc + 1;
return NULL;
}
@@ -4642,8 +4805,7 @@ c_omp_address_inspector::expand_component_selector (tree *pc,
pc = &OMP_CLAUSE_CHAIN (c);
}
- i += 2;
- *idx = i;
+ *idx = acc + 1;
if (chain_p && map_p)
return omp_expand_access_chain (pc, expr, addr_tokens, idx);
@@ -4671,7 +4833,7 @@ c_omp_address_inspector::expand_map_clause (tree *pc, tree expr,
&& addr_tokens[i]->u.structure_base_kind == BASE_DECL
&& addr_tokens[i + 1]->type == ACCESS_METHOD)
{
- pc = expand_array_base (pc, addr_tokens, expr, &i, ort, true);
+ pc = expand_array_base (pc, addr_tokens, expr, &i, ort);
if (pc == NULL)
return NULL;
}
@@ -4680,7 +4842,7 @@ c_omp_address_inspector::expand_map_clause (tree *pc, tree expr,
&& addr_tokens[i]->u.structure_base_kind == BASE_ARBITRARY_EXPR
&& addr_tokens[i + 1]->type == ACCESS_METHOD)
{
- pc = expand_array_base (pc, addr_tokens, expr, &i, ort, false);
+ pc = expand_array_base (pc, addr_tokens, expr, &i, ort);
if (pc == NULL)
return NULL;
}
diff --git a/gcc/c-family/c-pretty-print.cc b/gcc/c-family/c-pretty-print.cc
index 225ac7ef285..fc99b951f98 100644
--- a/gcc/c-family/c-pretty-print.cc
+++ b/gcc/c-family/c-pretty-print.cc
@@ -1623,6 +1623,11 @@ c_pretty_printer::postfix_expression (tree e)
pp_colon (this);
if (TREE_OPERAND (e, 2))
expression (TREE_OPERAND (e, 2));
+ if (TREE_OPERAND (e, 3))
+ {
+ pp_colon (this);
+ expression (TREE_OPERAND (e, 3));
+ }
pp_c_right_bracket (this);
break;