diff options
author | Julian Brown <julian@codesourcery.com> | 2023-03-01 14:22:25 +0000 |
---|---|---|
committer | Julian Brown <julian@codesourcery.com> | 2023-07-03 21:40:59 +0000 |
commit | 6336f8eaeb26af8729592754c01ffba0c5ece32b (patch) | |
tree | 70de864e8f7a333a65669d597d900111f4f06f0c /gcc/c-family | |
parent | 5d491f7ae2f99d60d70f6bb2dff5db11ba1328a4 (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.omp | 16 | ||||
-rw-r--r-- | gcc/c-family/c-common.h | 2 | ||||
-rw-r--r-- | gcc/c-family/c-omp.cc | 206 | ||||
-rw-r--r-- | gcc/c-family/c-pretty-print.cc | 5 |
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; |