Re: [Patch] OpenMP (C only): omp allocate - extend parsing support, improve diagnostic (was: [Patch] OpenMP (C only): omp allocate - handle stack vars, improve diagnostic)
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)
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)
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)
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)
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; } +