Re: [PATCH 1/8] OpenMP: lvalue parsing for map/to/from clauses (C++)

2024-01-10 Thread Julian Brown
On Wed, 10 Jan 2024 10:14:41 +0100
Jakub Jelinek  wrote:

> On Fri, Jan 05, 2024 at 12:23:26PM +, Julian Brown wrote:
> > * g++.dg/gomp/bad-array-section-10.C: New test.  
> 
> This test FAILs in C++23/C++26 modes, just try
> make check-g++ GXX_TESTSUITE_STDS=98,11,14,17,20,23,26
> RUNTESTFLAGS=gomp.exp=bad-array-section-10.C While in C++20 comma in
> array references was deprecated, in C++23 we implement
> multidimensional arrays, so the diagnostics there is different. See
> https://wg21.link/p2036r3

Thanks -- I've pushed a patch to fix this.  The bad-array-section-11.C
test covered the C++23 case already, but I don't think normal testing
iterates the newer language standards, hence missing this.

Julian


Re: [PATCH 1/8] OpenMP: lvalue parsing for map/to/from clauses (C++)

2024-01-10 Thread Jakub Jelinek
On Fri, Jan 05, 2024 at 12:23:26PM +, Julian Brown wrote:
> * g++.dg/gomp/bad-array-section-10.C: New test.

This test FAILs in C++23/C++26 modes, just try
make check-g++ GXX_TESTSUITE_STDS=98,11,14,17,20,23,26 
RUNTESTFLAGS=gomp.exp=bad-array-section-10.C
While in C++20 comma in array references was deprecated, in C++23 we
implement multidimensional arrays, so the diagnostics there is different.
See https://wg21.link/p2036r3

Jakub



Re: [PATCH 1/8] OpenMP: lvalue parsing for map/to/from clauses (C++)

2024-01-09 Thread Thomas Schwinge
Hi Julian!

On 2024-01-07T16:04:37+0100, Tobias Burnus  wrote:
> Am 05.01.24 um 13:23 schrieb Julian Brown:
>> Here's a rebased/retested version [...]

> LGTM - [...]

Got pushed as commit r14-7033-g1413af02d62182bc1e19698aaa4dae406f8f13bf
"OpenMP: lvalue parsing for map/to/from clauses (C++)".

Some (hopefully minor) tuning in the test cases is necessary; for
example, for x86_64-pc-linux-gnu '-m32' testing, I see a few FAILs:

+PASS: g++.dg/gomp/array-section-1.C  -std=c++98  scan-tree-dump original 
"map\\(tofrom:arr1\\[1\\] [len: x != 0 ? [0-9]+ : [0-9]+\\]\\) 
map\\(firstprivate:arr1 \\[pointer assign, bias: [0-9]+\\]\\)"
+PASS: g++.dg/gomp/array-section-1.C  -std=c++98  scan-tree-dump original 
"map\\(tofrom:arr1\\[1\\] \\[len: x != 0 \\? [0-9]+ : [0-9]+\\]\\) 
map\\(firstprivate:arr1 \\[pointer assign, bias: [0-9]+\\]\\)"
+FAIL: g++.dg/gomp/array-section-1.C  -std=c++98  scan-tree-dump original 
"map\\(tofrom:arr1\\[SAVE_EXPR \\] \\[len: [0-9]+\\]\\) 
map\\(firstprivate:arr1 \\[pointer assign, bias: \\(long int\\) 
&arr1\\[SAVE_EXPR \\] - \\(long int\\) &arr1\\]\\)"
+FAIL: g++.dg/gomp/array-section-1.C  -std=c++98  scan-tree-dump original 
"map\\(tofrom:arr1\\[SAVE_EXPR \\] \\[len: [0-9]+\\]\\) 
map\\(firstprivate:arr1 \\[pointer assign, bias: \\(long int\\) 
&arr1\\[SAVE_EXPR \\] - \\(long int\\) &arr1\\]\\)"
+FAIL: g++.dg/gomp/array-section-1.C  -std=c++98  scan-tree-dump original 
"map\\(tofrom:arr1\\[SAVE_EXPR \\] \\[len: [0-9]+\\]\\) 
map\\(firstprivate:arr1 \\[pointer assign, bias: \\(long int\\) 
&arr1\\[SAVE_EXPR \\] - \\(long int\\) &arr1\\]\\)"
+FAIL: g++.dg/gomp/array-section-1.C  -std=c++98  scan-tree-dump original 
"map\\(tofrom:arr1\\[SAVE_EXPR \\] \\[len: [0-9]+\\]\\) 
map\\(firstprivate:arr1 \\[pointer assign, bias: \\(long int\\) 
&arr1\\[SAVE_EXPR \\] - \\(long int\\) &arr1\\]\\)"
+PASS: g++.dg/gomp/array-section-1.C  -std=c++98 (test for excess errors)

Etc.

+PASS: g++.dg/gomp/array-section-2.C  -std=c++98  scan-tree-dump original 
"map\\(tofrom:arr1\\[0\\] \\[len: \\(sizetype\\) y \\* [0-9]+\\]\\) 
map\\(firstprivate:arr1 \\[pointer assign, bias: 0\\]\\)"
+PASS: g++.dg/gomp/array-section-2.C  -std=c++98  scan-tree-dump original 
"map\\(tofrom:arr1\\[0\\] \\[len: \\(sizetype\\) y \\* [0-9]+\\]\\) 
map\\(firstprivate:arr1 \\[pointer assign, bias: 0\\]\\)"
+FAIL: g++.dg/gomp/array-section-2.C  -std=c++98  scan-tree-dump original 
"map\\(tofrom:arr1\\[SAVE_EXPR \\] \\[len: \\(40 - \\(sizetype\\) SAVE_EXPR 
\\) \\* [0-9]+\\]\\) map\\(firstprivate:arr1 \\[pointer assign, bias: 
\\(long int\\) &arr1\\[SAVE_EXPR \\] - \\(long int\\) &arr1\\]\\)"
+FAIL: g++.dg/gomp/array-section-2.C  -std=c++98  scan-tree-dump original 
"map\\(tofrom:arr1\\[SAVE_EXPR \\] \\[len: \\(40 - \\(sizetype\\) SAVE_EXPR 
\\) \\* [0-9]+\\]\\) map\\(firstprivate:arr1 \\[pointer assign, bias: 
\\(long int\\) &arr1\\[SAVE_EXPR \\] - \\(long int\\) &arr1\\]\\)"
+FAIL: g++.dg/gomp/array-section-2.C  -std=c++98  scan-tree-dump original 
"map\\(tofrom:arr1\\[SAVE_EXPR \\] \\[len: \\(sizetype\\) y \\* [0-9]+\\]\\) 
map\\(firstprivate:arr1 \\[pointer assign, bias: \\(long int\\) 
&arr1\\[SAVE_EXPR \\] - \\(long int\\) &arr1\\]\\)"
+FAIL: g++.dg/gomp/array-section-2.C  -std=c++98  scan-tree-dump original 
"map\\(tofrom:arr1\\[SAVE_EXPR \\] \\[len: \\(sizetype\\) y \\* [0-9]+\\]\\) 
map\\(firstprivate:arr1 \\[pointer assign, bias: \\(long int\\) 
&arr1\\[SAVE_EXPR \\] - \\(long int\\) &arr1\\]\\)"
+PASS: g++.dg/gomp/array-section-2.C  -std=c++98 (test for excess errors)

Etc.

+PASS: g++.dg/gomp/bad-array-section-4.C  -std=c++98  at line 15 (test for 
errors, line 14)
+PASS: g++.dg/gomp/bad-array-section-4.C  -std=c++98  at line 16 (test for 
errors, line 14)
+PASS: g++.dg/gomp/bad-array-section-4.C  -std=c++98  at line 17 (test for 
errors, line 14)
+PASS: g++.dg/gomp/bad-array-section-4.C  -std=c++98  at line 22 (test for 
warnings, line 21)
+PASS: g++.dg/gomp/bad-array-section-4.C  -std=c++98  at line 36 (test for 
errors, line 35)
+FAIL: g++.dg/gomp/bad-array-section-4.C  -std=c++98  at line 37 (test for 
warnings, line 35)
+PASS: g++.dg/gomp/bad-array-section-4.C  -std=c++98  at line 38 (test for 
errors, line 35)
+PASS: g++.dg/gomp/bad-array-section-4.C  -std=c++98  at line 39 (test for 
errors, line 35)
+PASS: g++.dg/gomp/bad-array-section-4.C  -std=c++98  at line 44 (test for 
warnings, line 43)
+PASS: g++.dg/gomp/bad-array-section-4.C  -std=c++98 (test for excess 
errors)

Etc.


Grüße
 Thomas
-
Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 
München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas 
Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht 
München, HRB 106955


Re: [PATCH 1/8] OpenMP: lvalue parsing for map/to/from clauses (C++)

2024-01-07 Thread Tobias Burnus

Am 05.01.24 um 13:23 schrieb Julian Brown:

On Wed, 20 Dec 2023 15:31:15 +0100
Tobias Burnus  wrote:
Here's a rebased/retested version which fixes those bits (I haven't
adjusted the libgomp.texi bit you noted yet, though).

How does this look now?




--- a/gcc/gimplify.cc
+++ b/gcc/gimplify.cc
@@ -13499,7 +13499,11 @@ gimplify_adjust_omp_clauses_1 (splay_tree_node n, void 
*data)
   if (TREE_CODE (dtype) == REFERENCE_TYPE)
dtype = TREE_TYPE (dtype);
   /* FIRSTPRIVATE_POINTER doesn't work well if we have a
-multiply-indirected pointer.  */
+multiply-indirected pointer.  If we have a reference to a pointer to
+a pointer, it's possible that this should really be
+GOMP_MAP_FIRSTPRIVATE_REFERENCE -- but that also doesn't work at the
+moment, so stick with this.  (See testcase
+baseptrs-4.C:ref2ptrptr_offset_decl_member_slice).  */


Looks as we should have a tracking PR about this; can you file one?

* * *


+  if (processing_template_decl)
+{
+  if (type_dependent_expression_p (array_expr)
+ || type_dependent_expression_p (index)
+ || type_dependent_expression_p (length))
+   return build_min_nt_loc (loc, OMP_ARRAY_SECTION, array_expr, index,
+length);
+}


I personally find it more readable if combined in a single 'if' condition.


+ /* Turn *foo into foo[0:1].  */
+ decl = TREE_OPERAND (decl, 0);
+ STRIP_NOPS (decl);
+
+ /* If we have "*foo" and
+- it's an indirection of a reference, "unconvert" it, i.e.
+  strip the indirection (to just "foo").
+- it's an indirection of a pointer, turn it into
+  "foo[0:1]".  */
+ if (!ref_p)
+   decl = grok_omp_array_section (loc, decl, integer_zero_node,
+  integer_one_node);


I would remove the first comment and remove the two succeeding lines 
below the second comment.




+ /* This code rewrites a parsed expression containing various tree
+codes used to represent array accesses into a more uniform nest of
+OMP_ARRAY_SECTION nodes before it is processed by
+semantics.cc:handle_omp_array_sections_1.  It might be more
+efficient to move this logic to that function instead, analysing
+the parsed expression directly rather than this preprocessed
+form.  */


Or to do this transformation in handle_omp_array_sections to get still a 
unified result in the middle end. I see advantages of all three 
solutions. (Doing this in parse.cc (as currently done) feels a bit odd, 
though.)


* * *


build_omp_array_section (location_t loc, tree array_expr, tree index,
+tree length)
+{
+  tree idxtype;
+
+  /* If we know the integer bounds, create an index type with exact
+ low/high (or zero/length) bounds.  Otherwise, create an incomplete
+ array type.  (This mostly only affects diagnostics.)  */
+  if (index != NULL_TREE
+  && length != NULL_TREE
+  && TREE_CODE (index) == INTEGER_CST
+  && TREE_CODE (length) == INTEGER_CST)
+{
+  tree low = fold_convert (sizetype, index);
+  tree high = fold_convert (sizetype, length);
+  high = size_binop (PLUS_EXPR, low, high);
+  high = size_binop (MINUS_EXPR, high, size_one_node);
+  idxtype = build_range_type (sizetype, low, high);
+}
+  else if ((index == NULL_TREE || integer_zerop (index))
+  && length != NULL_TREE
+  && TREE_CODE (length) == INTEGER_CST)
+idxtype = build_index_type (length);
+  else
+idxtype = NULL_TREE;
+
+  tree type = TREE_TYPE (array_expr);
+  gcc_assert (type);
+  type = non_reference (type);
+
+  tree sectype, eltype = TREE_TYPE (type);
+
+  /* It's not an array or pointer type.  Just reuse the type of the
+ original expression as the type of the array section (an error will be
+ raised anyway, later).  */
+  if (eltype == NULL_TREE)
+sectype = TREE_TYPE (array_expr);
+  else
+sectype = build_array_type (eltype, idxtype);
+
+  return build3_loc (loc, OMP_ARRAY_SECTION, sectype, array_expr, index,
+length);
+}


I wonder whether it would be more readable if one moves all the 
'idxtype' handling into the last 'else' branch.


* * *

LGTM - please file the PR and consider the readability items above.

Thanks,

Tobias




Re: [PATCH 1/8] OpenMP: lvalue parsing for map/to/from clauses (C++)

2023-12-20 Thread Tobias Burnus

On 05.09.23 21:28, Julian Brown wrote:

This patch supports "lvalue" parsing (or "locator list item type" parsing)
for several OpenMP clause types for C++, as required for OpenMP 5.0
and above.  It is based on the version committed to the og13 branch,
posted here:

   https://gcc.gnu.org/pipermail/gcc-patches/2023-June/623354.html

which in turn was based on the last version posted upstream:

   https://gcc.gnu.org/pipermail/gcc-patches/2022-December/609040.html

This version has mostly just been rebased.


I had a first pass at the patch and didn't spot anything (C++ code wise);
I have some build/rebase issues and one .texi comment that is trivial and
could also be handled together with the 2/8 patch (adding C support).

* * *

Another rebase is required because of:

1 out of 22 hunks FAILED -- saving rejects to file gcc/cp/parser.cc.rej
1 out of 4 hunks FAILED -- saving rejects to file gcc/cp/pt.cc.rej

but those patch-apply fails look trivial to fix.


And during build, I see:
gcc/cp/decl2.cc:643:20: error: ‘build_non_dependent_expr’ was not declared in 
this scope; did you mean ‘fold_non_dependent_expr’?

For details, see the two commits:
cd0e05b7ac3 c++: remove NON_DEPENDENT_EXPR, part 2
dad311874ac c++: remove NON_DEPENDENT_EXPR, part 1

* * *

When commenting those, even more build issues show up:

../../repos/gcc/gcc/cp/pt.cc:20493:20: error: ‘tsubst_copy’ was not declared in 
this scope; did you mean ‘tsubst_scope’?
20493 | tree op0 = tsubst_copy (TREE_OPERAND (t, 0), args, complain, 
in_decl);
  |^~~
  |tsubst_scope
In file included from ../../repos/gcc/gcc/cp/pt.cc:31:
../../repos/gcc/gcc/cp/pt.cc: In function ‘bool 
value_dependent_expression_p(tree)’:
../../repos/gcc/gcc/cp/pt.cc:28009:41: error: ‘t’ was not declared in this 
scope; did you mean ‘tm’?
28009 | tree op0 = RECUR (TREE_OPERAND (t, 0));
  | ^
../../repos/gcc/gcc/system.h:1178:61: note: in definition of macro ‘CONST_CAST2’
 1178 | #define CONST_CAST2(TOTYPE,FROMTYPE,X) (const_cast (X))
  | ^
../../repos/gcc/gcc/tree.h:1285:31: note: in expansion of macro 
‘TREE_OPERAND_CHECK’
 1285 | #define TREE_OPERAND(NODE, I) TREE_OPERAND_CHECK (NODE, I)
  |   ^~
../../repos/gcc/gcc/cp/pt.cc:28009:27: note: in expansion of macro 
‘TREE_OPERAND’
28009 | tree op0 = RECUR (TREE_OPERAND (t, 0));
  |   ^~~~
../../repos/gcc/gcc/cp/pt.cc:28009:20: error: ‘RECUR’ was not declared in this 
scope
28009 | tree op0 = RECUR (TREE_OPERAND (t, 0));
  |^
../../repos/gcc/gcc/cp/pt.cc:28012:11: error: ‘RETURN’ was not declared in this 
scope
28012 |   RETURN (error_mark_node);
  |   ^~

* * *

BTW: There is OpenMP specification Issue 2618 which is about code like "map(*p = 
10)" with the intent to disallow it.
That's in line with the current code which prints a 'sorry' for those.

* * *

libgomp.texi contains:

@item C/C++'s lvalue expressions in @code{to}, @code{from}
  and @code{map} clauses @tab N @tab

I think this can be set to 'P' + 'Only C++'; I think except for questionable 
code like '*p = 10'
the support is complete, isn't it? If no, 'Initial support for C++, only' could 
be a comment.

Alternatively, we can fold it into the next patch (which adds C support).

* * *


2023-09-05  Julian Brown

gcc/c-family/
  * c-common.h (c_omp_address_inspector): Remove static from get_origin
  and maybe_unconvert_ref methods.
  * c-omp.cc (c_omp_split_clauses): Support OMP_ARRAY_SECTION.
  (c_omp_address_inspector::map_supported_p): Handle OMP_ARRAY_SECTION.
  (c_omp_address_inspector::get_origin): Avoid dereferencing possibly
  NULL type when processing template decls.
  (c_omp_address_inspector::maybe_unconvert_ref): Likewise.

gcc/cp/
  * constexpr.cc (potential_consant_expression_1): Handle
  OMP_ARRAY_SECTION.
  * cp-tree.h (grok_omp_array_section, build_omp_array_section): Add
  prototypes.
  * decl2.cc (grok_omp_array_section): New function.
  * error.cc (dump_expr): Handle OMP_ARRAY_SECTION.
  * parser.cc (cp_parser_new): Initialize parser->omp_array_section_p.
  (cp_parser_statement_expr): Disallow array sections.
  (cp_parser_postfix_open_square_expression): Support OMP_ARRAY_SECTION
  parsing.
  (cp_parser_parenthesized_expression_list, cp_parser_lambda_expression,
  cp_parser_braced_list): Disallow array sections.
  (cp_parser_omp_var_list_no_open): Remove ALLOW_DEREF parameter, add
  MAP_LVALUE in its place.  Support generalised lvalue parsing for
  OpenMP map, to and from clauses.  Use OMP_ARRAY_SECTION
  code instead of TREE_LIST to represent OpenMP array sections.
  (cp_parser_omp_var_list): Remove ALLOW_DEREF parameter, add M