Re: [Patch] OpenMP (C only): omp allocate - extend parsing support, improve diagnostic (was: [Patch] OpenMP (C only): omp allocate - handle stack vars, improve diagnostic)

2023-09-11 Thread Jakub Jelinek via Gcc-patches
On Mon, Sep 11, 2023 at 03:21:54PM +0200, Tobias Burnus wrote:
> +  if (TREE_STATIC (var))
> + {
> +   if (allocator == NULL_TREE && allocator_loc == UNKNOWN_LOCATION)
> + error_at (loc, "% clause required for "
> +"static variable %qD", var);
> +   else if (allocator
> +&& (tree_int_cst_sgn (allocator) != 1
> +|| tree_to_shwi (allocator) > 8))

Has anything checked that in this case allocator is actually INTEGER_CST
which fits into shwi?  Otherwise tree_to_shwi will ICE.
Consider say allocator argument of
329857234985743598347598437598347594835743895743wb
or (((unsigned __int128) 0x123456789abcdef0) << 64)
Either tree_fits_shwi_p (allocator) check would do it, or perhaps
else if (allocator
 && TREE_CODE (allocator) == INTEGER_CST
 && wi::to_widest (allocator) > 0
 && wi::to_widest (allocator) <= 8)
?

> +  if (allocator
> +   && TREE_CODE (allocator) == VAR_DECL
> +   && c_check_in_current_scope (var))
> + {
> +   if (linemap_location_before_p (line_table, DECL_SOURCE_LOCATION (var),
> +  DECL_SOURCE_LOCATION (allocator)))
> + {
> +   error_at (OMP_CLAUSE_LOCATION (nl),
> + "allocator variable %qD must be declared before %qD",
> + allocator, var);
> +   inform (DECL_SOURCE_LOCATION (allocator),
> +   "allocator declared here");
> +   inform (DECL_SOURCE_LOCATION (var), "declared here");
> + }
> +   else
> +{
> +  gcc_assert (cur_stmt_list
> +  && TREE_CODE (cur_stmt_list) == STATEMENT_LIST);
> +  tree_stmt_iterator l = tsi_last (cur_stmt_list);
> +  while (!tsi_end_p (l))
> +{
> +  if (linemap_location_before_p (line_table, EXPR_LOCATION (*l),
> + DECL_SOURCE_LOCATION (var)))
> +break;
> +  if (TREE_CODE (*l) == MODIFY_EXPR
> +  && TREE_OPERAND (*l, 0) == allocator)
> +{
> +  error_at (EXPR_LOCATION (*l),
> +"allocator variable %qD, used in the "
> +"% directive for %qD, must not be "
> +"modified between declaration of %qD and its "
> +"% directive",
> +allocator, var, var);
> +  inform (DECL_SOURCE_LOCATION (var), "declared here");
> +  inform (OMP_CLAUSE_LOCATION (nl), "used here");
> +  break;
> +   }
> + --l;
> +  }
> +}

BTW, it doesn't necessarily have to be just the simple case which you catch
here, namely that allocator is a VAR_DECL defined after var in current
scope.
One can have an expression which uses those other vars, say
  int v;
  int a = 1;
  int b[n]; // VLA
  b[a] = 5;
  #pragma omp allocate (v) allocator (foo (a, [a]))
where foo would be some function which returns omp_allocator_handle_t.
Or it could be e.g. lambda declared later, etc.
I bet we can't catch everything, but perhaps e.g. doing the first
diagnostics from within walk_tree might be better.

Jakub



Re: [Patch] OpenMP (C only): omp allocate - extend parsing support, improve diagnostic (was: [Patch] OpenMP (C only): omp allocate - handle stack vars, improve diagnostic)

2023-09-11 Thread Tobias Burnus

Hi,

thanks for the comments and for the line-number thing. (I wanted to
re-check it myself but then totally forgot about it.)

Attached is the updated patch, fixing the line-number comparison, the
C++ addition to the enum decl in two of the testcases, and adding
"allocator" to the one inform (both to the code and to one testcase).

Tobias
-
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
OpenMP (C only): omp allocate - extend parsing support, improve diagnostic

The 'allocate' directive can be used for both stack and static variables.
While the parser in C and C++ was pre-existing, it missed several
diagnostics, which this commit adds - for now only for C.

While the "sorry, unimplemented" for static variables is still issues
during parsing, the sorry for stack variables is now issued in the
middle end, preparing for the actual implementation. (Again: only for C.)

gcc/c/ChangeLog:

	* c-parser.cc (c_parser_omp_construct): Move call to
	c_parser_omp_allocate to ...
	(c_parser_pragma): ... here.
	(c_parser_omp_allocate): Avoid ICE is allocator could not be
	parsed; set 'omp allocate' attribute for stack/automatic variables
	and only reject static variables; add several additional
	restriction checks.
	* c-tree.h (c_mark_decl_jump_unsafe_in_current_scope): New prototype.
	* c-decl.cc (decl_jump_unsafe): Return true for omp-allocated decls.
	(c_mark_decl_jump_unsafe_in_current_scope): New.
	(warn_about_goto, c_check_switch_jump_warnings): Add error for
	omp-allocated decls.

gcc/ChangeLog:

	* gimplify.cc (gimplify_bind_expr): Check for
	insertion after variable cleanup.  Convert 'omp allocate'
	var-decl attribute to GOMP_alloc/GOMP_free calls.

gcc/testsuite/ChangeLog:

	* c-c++-common/gomp/allocate-5.c: Fix testcase; make some
	dg-messages for 'sorry' as c++, only.
	* c-c++-common/gomp/directive-1.c: Make a 'sorry' c++ only.
	* c-c++-common/gomp/allocate-9.c: New test.
	* c-c++-common/gomp/allocate-11.c: New test.
	* c-c++-common/gomp/allocate-12.c: New test.
	* c-c++-common/gomp/allocate-14.c: New test.
	* c-c++-common/gomp/allocate-15.c: New test.

 gcc/c/c-decl.cc   |  26 ++
 gcc/c/c-parser.cc | 115 +++---
 gcc/c/c-tree.h|   1 +
 gcc/gimplify.cc   |  40 +
 gcc/testsuite/c-c++-common/gomp/allocate-11.c |  40 +
 gcc/testsuite/c-c++-common/gomp/allocate-12.c |  49 +++
 gcc/testsuite/c-c++-common/gomp/allocate-14.c |  26 ++
 gcc/testsuite/c-c++-common/gomp/allocate-15.c |  28 +++
 gcc/testsuite/c-c++-common/gomp/allocate-5.c  |  60 +++---
 gcc/testsuite/c-c++-common/gomp/allocate-9.c  |  99 ++
 gcc/testsuite/c-c++-common/gomp/directive-1.c |   2 +-
 11 files changed, 444 insertions(+), 42 deletions(-)

diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index 649c5ae66c2..5822faf01b4 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -681,6 +681,11 @@ decl_jump_unsafe (tree decl)
   if (VAR_P (decl) && C_DECL_COMPOUND_LITERAL_P (decl))
 return false;
 
+  if (flag_openmp
+  && VAR_P (decl)
+  && lookup_attribute ("omp allocate", DECL_ATTRIBUTES (decl)))
+return true;
+
   /* Always warn about crossing variably modified types.  */
   if ((VAR_P (decl) || TREE_CODE (decl) == TYPE_DECL)
   && c_type_variably_modified_p (TREE_TYPE (decl)))
@@ -724,6 +729,15 @@ c_print_identifier (FILE *file, tree node, int indent)
   c_binding_oracle = save;
 }
 
+/* Establish that the scope contains declarations that are sensitive to
+   jumps that cross a binding.  Together with decl_jump_unsafe, this is
+   used to diagnose such jumps.  */
+void
+c_mark_decl_jump_unsafe_in_current_scope ()
+{
+  current_scope->has_jump_unsafe_decl = 1;
+}
+
 /* Establish a binding between NAME, an IDENTIFIER_NODE, and DECL,
which may be any of several kinds of DECL or TYPE or error_mark_node,
in the scope SCOPE.  */
@@ -3974,6 +3988,9 @@ warn_about_goto (location_t goto_loc, tree label, tree decl)
   if (c_type_variably_modified_p (TREE_TYPE (decl)))
 error_at (goto_loc,
 	  "jump into scope of identifier with variably modified type");
+  else if (flag_openmp
+	   && lookup_attribute ("omp allocate", DECL_ATTRIBUTES (decl)))
+error_at (goto_loc, "jump skips OpenMP % allocation");
   else
 if (!warning_at (goto_loc, OPT_Wjump_misses_init,
 		 "jump skips variable initialization"))
@@ -4253,6 +4270,15 @@ c_check_switch_jump_warnings (struct c_spot_bindings *switch_bindings,
 			 "variably modified type"));
 		  emitted = true;
 		}
+	  else if (flag_openmp
+		   && lookup_attribute ("omp allocate",
+	DECL_ATTRIBUTES (b->decl)))
+		{
+		  saw_error = true;
+		  error_at 

Re: [Patch] OpenMP (C only): omp allocate - extend parsing support, improve diagnostic (was: [Patch] OpenMP (C only): omp allocate - handle stack vars, improve diagnostic)

2023-09-11 Thread David Malcolm via Gcc-patches
On Mon, 2023-09-11 at 13:54 +0200, Jakub Jelinek wrote:
> Hi!
> 
> One question to David below, CCed.
> 
> On Mon, Sep 11, 2023 at 01:44:07PM +0200, Tobias Burnus wrote:

[...]

> 
> > +
> > + if (DECL_SOURCE_LOCATION (allocator) >
> > DECL_SOURCE_LOCATION (var))
> > +   {
> > + error_at (OMP_CLAUSE_LOCATION (nl),
> > +   "allocator variable %qD must be declared
> > before %qD",
> > +   allocator, var);
> > + inform (DECL_SOURCE_LOCATION (allocator), "declared
> > here");
> > + inform (DECL_SOURCE_LOCATION (var), "declared here");
> 
> I think this will be confusing to users when the inform is the same
> in both
> cases.  I'd use "allocator declared here" in the first case.
> 
> And, am really not sure if one can just simply compare location_t
> like that.
> Isn't there some function which determines what source location is
> before
> another one?  David?

Indeed, the numerical ordering of location_t values doesn't fully
correspond to declaration order.

Please use
  linemap_compare_locations
or
  linemap_location_before_p

> 
> > +    if (EXPR_LOCATION (*l) < DECL_SOURCE_LOCATION
> > (var))
> > +  break;
> 
> Likewise.
> 


Dave
> 


Re: [Patch] OpenMP (C only): omp allocate - extend parsing support, improve diagnostic (was: [Patch] OpenMP (C only): omp allocate - handle stack vars, improve diagnostic)

2023-09-11 Thread Jakub Jelinek via Gcc-patches
Hi!

One question to David below, CCed.

On Mon, Sep 11, 2023 at 01:44:07PM +0200, Tobias Burnus wrote:
> --- a/gcc/c/c-decl.cc
> +++ b/gcc/c/c-decl.cc
> @@ -681,6 +681,11 @@ decl_jump_unsafe (tree decl)
>if (VAR_P (decl) && C_DECL_COMPOUND_LITERAL_P (decl))
>  return false;
>  
> +  if (flag_openmp
> +  && VAR_P (decl)
> +  && lookup_attribute ("omp allocate", DECL_ATTRIBUTES (decl)))
> +return true;
> +
>/* Always warn about crossing variably modified types.  */
>if ((VAR_P (decl) || TREE_CODE (decl) == TYPE_DECL)
>&& c_type_variably_modified_p (TREE_TYPE (decl)))
> @@ -724,6 +729,12 @@ c_print_identifier (FILE *file, tree node, int indent)
>c_binding_oracle = save;
>  }
>  

I think we want a function comment here.

> +void
> +c_mark_decl_jump_unsafe_in_current_scope ()
> +{
> +  current_scope->has_jump_unsafe_decl = 1;
> +}
> +
> +   if (DECL_SOURCE_LOCATION (allocator) > DECL_SOURCE_LOCATION (var))
> + {
> +   error_at (OMP_CLAUSE_LOCATION (nl),
> + "allocator variable %qD must be declared before %qD",
> + allocator, var);
> +   inform (DECL_SOURCE_LOCATION (allocator), "declared here");
> +   inform (DECL_SOURCE_LOCATION (var), "declared here");

I think this will be confusing to users when the inform is the same in both
cases.  I'd use "allocator declared here" in the first case.

And, am really not sure if one can just simply compare location_t like that.
Isn't there some function which determines what source location is before
another one?  David?

> +  if (EXPR_LOCATION (*l) < DECL_SOURCE_LOCATION (var))
> +break;

Likewise.

> --- /dev/null
> +++ b/gcc/testsuite/c-c++-common/gomp/allocate-12.c
> @@ -0,0 +1,46 @@
> +/* TODO: enable for C++ once implemented. */
> +/* { dg-do compile { target c } } */
> +
> +typedef enum omp_allocator_handle_t

I think all the c-c++-common tests declaring
omp_allocator_handle_t should have
#if __cplusplus >= 201103L
: __UINTPTR_TYPE__
#endif
here (even if they are just { target c } for now, we'd certainly
forget to adjust them).


Jakub



[Patch] OpenMP (C only): omp allocate - extend parsing support, improve diagnostic (was: [Patch] OpenMP (C only): omp allocate - handle stack vars, improve diagnostic)

2023-09-11 Thread Tobias Burnus

The patch adds more check and fixes some minor FE bits, but it now has a
'sorry' for automatic/stack variables in the middle end.

I think it is useful by itself as it completes the C FE part and adds
diagnostic, even if the actual code generation is disabled.

Comments, remarks, suggestions?

The actual code generation works fine (see previous patch) but it fails
with OpenMP privatization and mapping; I have locally an incomplete WIP
patch to fix this. But until it works, the 'sorry' makes more sense.
Besides solving that issue, C++ needs to be updated to be on par with C
and my (not yet posted) Fortran patch also needs some changes for the C
and ME changes.

Tobias
-
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
OpenMP (C only): omp allocate - extend parsing support, improve diagnostic

The 'allocate' directive can be used for both stack and static variables.
While the parser in C and C++ was pre-existing, it missed several
diagnostics, which this commit adds - for now only for C.

While the "sorry, unimplemented" for static variables is still issues
during parsing, the sorry for stack variables is now issued in the
middle end, preparing for the actual implementation. (Again: only for C.)

gcc/c/ChangeLog:

	* c-parser.cc (c_parser_omp_construct): Move call to
	c_parser_omp_allocate to ...
	(c_parser_pragma): ... here.
	(c_parser_omp_allocate): Avoid ICE is allocator could not be
	parsed; set 'omp allocate' attribute for stack/automatic variables
	and only reject static variables; add several additional
	restriction checks.
	* c-tree.h (c_mark_decl_jump_unsafe_in_current_scope): New prototype.
	* c-decl.cc (decl_jump_unsafe): Return true for omp-allocated decls.
	(c_mark_decl_jump_unsafe_in_current_scope): New.
	(warn_about_goto, c_check_switch_jump_warnings): Add error for
	omp-allocated decls.

gcc/ChangeLog:

	* gimplify.cc (gimplify_bind_expr): Check for
	insertion after variable cleanup.  Convert 'omp allocate'
	var-decl attribute to GOMP_alloc/GOMP_free calls.

gcc/testsuite/ChangeLog:

	* c-c++-common/gomp/allocate-5.c: Fix testcase; make some
	dg-messages for 'sorry' as c++, only.
	* c-c++-common/gomp/directive-1.c: Make a 'sorry' c++ only.
	* c-c++-common/gomp/allocate-9.c: New test.
	* c-c++-common/gomp/allocate-11.c: New test.
	* c-c++-common/gomp/allocate-12.c: New test.
	* c-c++-common/gomp/allocate-14.c: New test.
	* c-c++-common/gomp/allocate-15.c: New test.

 gcc/c/c-decl.cc   |  23 ++
 gcc/c/c-parser.cc | 112 +++---
 gcc/c/c-tree.h|   1 +
 gcc/gimplify.cc   |  40 +
 gcc/testsuite/c-c++-common/gomp/allocate-11.c |  40 +
 gcc/testsuite/c-c++-common/gomp/allocate-12.c |  46 +++
 gcc/testsuite/c-c++-common/gomp/allocate-14.c |  26 ++
 gcc/testsuite/c-c++-common/gomp/allocate-15.c |  28 +++
 gcc/testsuite/c-c++-common/gomp/allocate-5.c  |  60 +++---
 gcc/testsuite/c-c++-common/gomp/allocate-9.c  |  96 ++
 gcc/testsuite/c-c++-common/gomp/directive-1.c |   2 +-
 11 files changed, 432 insertions(+), 42 deletions(-)

diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index 649c5ae66c2..05fdb9240ae 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -681,6 +681,11 @@ decl_jump_unsafe (tree decl)
   if (VAR_P (decl) && C_DECL_COMPOUND_LITERAL_P (decl))
 return false;
 
+  if (flag_openmp
+  && VAR_P (decl)
+  && lookup_attribute ("omp allocate", DECL_ATTRIBUTES (decl)))
+return true;
+
   /* Always warn about crossing variably modified types.  */
   if ((VAR_P (decl) || TREE_CODE (decl) == TYPE_DECL)
   && c_type_variably_modified_p (TREE_TYPE (decl)))
@@ -724,6 +729,12 @@ c_print_identifier (FILE *file, tree node, int indent)
   c_binding_oracle = save;
 }
 
+void
+c_mark_decl_jump_unsafe_in_current_scope ()
+{
+  current_scope->has_jump_unsafe_decl = 1;
+}
+
 /* Establish a binding between NAME, an IDENTIFIER_NODE, and DECL,
which may be any of several kinds of DECL or TYPE or error_mark_node,
in the scope SCOPE.  */
@@ -3974,6 +3985,9 @@ warn_about_goto (location_t goto_loc, tree label, tree decl)
   if (c_type_variably_modified_p (TREE_TYPE (decl)))
 error_at (goto_loc,
 	  "jump into scope of identifier with variably modified type");
+  else if (flag_openmp
+	   && lookup_attribute ("omp allocate", DECL_ATTRIBUTES (decl)))
+error_at (goto_loc, "jump skips OpenMP % allocation");
   else
 if (!warning_at (goto_loc, OPT_Wjump_misses_init,
 		 "jump skips variable initialization"))
@@ -4253,6 +4267,15 @@ c_check_switch_jump_warnings (struct c_spot_bindings *switch_bindings,
 			 "variably modified type"));
 		  emitted = true;
 		}
+