aboutsummaryrefslogtreecommitdiff
path: root/gcc/c/c-parser.cc
diff options
context:
space:
mode:
authorJulian Brown <julian@codesourcery.com>2025-04-24 15:32:14 +0000
committerSandra Loosemore <sloosemore@baylibre.com>2025-05-15 20:25:49 +0000
commit7fa6e7e1d94accd7ada57cf844dc0c8b9a403131 (patch)
tree797bf55a9976f230a2e662bfc40516277dbb9c93 /gcc/c/c-parser.cc
parent7431820c24b68001c614b26208be9c9f53c712b8 (diff)
downloadgcc-7fa6e7e1d94accd7ada57cf844dc0c8b9a403131.zip
gcc-7fa6e7e1d94accd7ada57cf844dc0c8b9a403131.tar.gz
gcc-7fa6e7e1d94accd7ada57cf844dc0c8b9a403131.tar.bz2
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-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): Support noncontiguous array updates. (c_omp_address_inspector::expand_component_selector): Support noncontiguous array updates. * 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/c-parser.cc')
-rw-r--r--gcc/c/c-parser.cc32
1 files changed, 19 insertions, 13 deletions
diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc
index 78a2f18..d72cd10 100644
--- a/gcc/c/c-parser.cc
+++ b/gcc/c/c-parser.cc
@@ -13633,7 +13633,7 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
len = c_parser_expression (parser).value;
expr.value = build_omp_array_section (op_loc, expr.value, idx,
- len);
+ len, NULL_TREE /* fixme */);
}
else
expr.value = build_array_ref (op_loc, expr.value, idx);
@@ -16339,11 +16339,11 @@ c_parser_oacc_wait_list (c_parser *parser, location_t clause_loc, tree list)
struct omp_dim
{
- tree low_bound, length;
+ tree low_bound, length, stride;
location_t loc;
bool no_colon;
- omp_dim (tree lb, tree len, location_t lo, bool nc)
- : low_bound (lb), length (len), loc (lo), no_colon (nc) {}
+ omp_dim (tree lb, tree len, tree str, location_t lo, bool nc)
+ : low_bound (lb), length (len), stride (str), loc (lo), no_colon (nc) {}
};
static tree
@@ -16472,7 +16472,9 @@ c_parser_omp_variable_list (c_parser *parser,
{
tree low_bound = TREE_OPERAND (decl, 1);
tree length = TREE_OPERAND (decl, 2);
- dims.safe_push (omp_dim (low_bound, length, loc, false));
+ tree stride = TREE_OPERAND (decl, 3);
+ dims.safe_push (omp_dim (low_bound, length, stride, loc,
+ false));
decl = TREE_OPERAND (decl, 0);
}
@@ -16488,21 +16490,22 @@ c_parser_omp_variable_list (c_parser *parser,
else if (TREE_CODE (decl) == INDIRECT_REF)
{
dims.safe_push (omp_dim (integer_zero_node,
- integer_one_node, loc, true));
+ integer_one_node, NULL_TREE, loc,
+ true));
decl = TREE_OPERAND (decl, 0);
}
else /* ARRAY_REF. */
{
tree index = TREE_OPERAND (decl, 1);
- dims.safe_push (omp_dim (index, integer_one_node, loc,
- true));
+ dims.safe_push (omp_dim (index, integer_one_node,
+ NULL_TREE, loc, true));
decl = TREE_OPERAND (decl, 0);
}
}
for (int i = dims.length () - 1; i >= 0; i--)
decl = build_omp_array_section (loc, decl, dims[i].low_bound,
- dims[i].length);
+ dims[i].length, dims[i].stride);
}
else if (TREE_CODE (decl) == INDIRECT_REF)
{
@@ -16511,7 +16514,7 @@ c_parser_omp_variable_list (c_parser *parser,
STRIP_NOPS (decl);
decl = build_omp_array_section (loc, decl, integer_zero_node,
- integer_one_node);
+ integer_one_node, NULL_TREE);
}
else if (TREE_CODE (decl) == ARRAY_REF)
{
@@ -16520,7 +16523,8 @@ c_parser_omp_variable_list (c_parser *parser,
decl = TREE_OPERAND (decl, 0);
STRIP_NOPS (decl);
- decl = build_omp_array_section (loc, decl, idx, integer_one_node);
+ decl = build_omp_array_section (loc, decl, idx, integer_one_node,
+ NULL_TREE);
}
else if (TREE_CODE (decl) == NON_LVALUE_EXPR
|| CONVERT_EXPR_P (decl))
@@ -16674,7 +16678,8 @@ c_parser_omp_variable_list (c_parser *parser,
break;
}
- dims.safe_push (omp_dim (low_bound, length, loc, no_colon));
+ dims.safe_push (omp_dim (low_bound, length, NULL_TREE, loc,
+ no_colon));
}
if (t != error_mark_node)
@@ -16698,7 +16703,8 @@ c_parser_omp_variable_list (c_parser *parser,
for (unsigned i = 0; i < dims.length (); i++)
t = build_omp_array_section (clause_loc, t,
dims[i].low_bound,
- dims[i].length);
+ dims[i].length,
+ dims[i].stride);
}
if ((kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)