Hi, this patch properly handles OpenACC 'wait' clauses without arguments, making it an equivalent of "wait all". (current trunk basically discards and ignores such argument-less wait clauses) This adds additional handling in the pack/unpack of the wait argument across the compiler/libgomp interface, but is done in a matter that doesn't affect binary compatibility.
This patch was part of the OpenACC async re-work that was done on the gomp4 branch (later merged to OG7/OG8), see [1]. I'm separating this part out and submitting it first because it's logically independent. [1] https://gcc.gnu.org/ml/gcc-patches/2017-06/msg01842.html Re-tested with offloading to ensure no regressions, is this okay for trunk? Thanks, Chung-Lin 2018-08-30 Chung-Lin Tang <clt...@codesourcery.com> gcc/c/ * c-parser.c (c_parser_oacc_clause_wait): Add representation of wait clause without argument as 'wait (GOMP_ASYNC_NOVAL)', adjust comments. gcc/cp/ * parser.c (cp_parser_oacc_clause_wait): Add representation of wait clause without argument as 'wait (GOMP_ASYNC_NOVAL)', adjust comments. gcc/fortran/ * trans-openmp.c (gfc_trans_omp_clauses_1): Add representation of wait clause without argument as 'wait (GOMP_ASYNC_NOVAL)'. gcc/ * omp-low.c (expand_omp_target): Add middle-end support for handling OMP_CLAUSE_WAIT clause with a GOMP_ASYNC_NOVAL(-1) as the argument. include/ * gomp-constants.h (GOMP_LAUNCH_OP_MASK): Define. (GOMP_LAUNCH_PACK): Add bitwise-and of GOMP_LAUNCH_OP_MASK. (GOMP_LAUNCH_OP): Likewise. libgomp/ * oacc-parallel.c (GOACC_parallel_keyed): Interpret launch op as signed 16-bit field, adjust num_waits handling. (GOACC_enter_exit_data): Adjust num_waits handling. (GOACC_update): Adjust num_waits handling.
Index: gcc/c/c-parser.c =================================================================== --- gcc/c/c-parser.c (revision 263981) +++ gcc/c/c-parser.c (working copy) @@ -12719,7 +12719,7 @@ c_parser_oacc_clause_tile (c_parser *parser, tree } /* OpenACC: - wait ( int-expr-list ) */ + wait [( int-expr-list )] */ static tree c_parser_oacc_clause_wait (c_parser *parser, tree list) @@ -12728,7 +12728,15 @@ c_parser_oacc_clause_wait (c_parser *parser, tree if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN) list = c_parser_oacc_wait_list (parser, clause_loc, list); + else + { + tree c = build_omp_clause (clause_loc, OMP_CLAUSE_WAIT); + OMP_CLAUSE_DECL (c) = build_int_cst (integer_type_node, GOMP_ASYNC_NOVAL); + OMP_CLAUSE_CHAIN (c) = list; + list = c; + } + return list; } Index: gcc/cp/parser.c =================================================================== --- gcc/cp/parser.c (revision 263981) +++ gcc/cp/parser.c (working copy) @@ -32137,7 +32137,7 @@ cp_parser_oacc_wait_list (cp_parser *parser, locat } /* OpenACC: - wait ( int-expr-list ) */ + wait [( int-expr-list )] */ static tree cp_parser_oacc_clause_wait (cp_parser *parser, tree list) @@ -32144,10 +32144,16 @@ cp_parser_oacc_clause_wait (cp_parser *parser, tre { location_t location = cp_lexer_peek_token (parser->lexer)->location; - if (cp_lexer_peek_token (parser->lexer)->type != CPP_OPEN_PAREN) - return list; + if (cp_lexer_peek_token (parser->lexer)->type == CPP_OPEN_PAREN) + list = cp_parser_oacc_wait_list (parser, location, list); + else + { + tree c = build_omp_clause (location, OMP_CLAUSE_WAIT); - list = cp_parser_oacc_wait_list (parser, location, list); + OMP_CLAUSE_DECL (c) = build_int_cst (integer_type_node, GOMP_ASYNC_NOVAL); + OMP_CLAUSE_CHAIN (c) = list; + list = c; + } return list; } Index: gcc/fortran/trans-openmp.c =================================================================== --- gcc/fortran/trans-openmp.c (revision 263981) +++ gcc/fortran/trans-openmp.c (working copy) @@ -2922,6 +2922,13 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp omp_clauses = c; } } + else if (clauses->wait) + { + c = build_omp_clause (where.lb->location, OMP_CLAUSE_WAIT); + OMP_CLAUSE_DECL (c) = build_int_cst (integer_type_node, GOMP_ASYNC_NOVAL); + OMP_CLAUSE_CHAIN (c) = omp_clauses; + omp_clauses = c; + } if (clauses->num_gangs_expr) { tree num_gangs_var Index: gcc/omp-expand.c =================================================================== --- gcc/omp-expand.c (revision 263981) +++ gcc/omp-expand.c (working copy) @@ -7381,16 +7381,32 @@ expand_omp_target (struct omp_region *region) /* ... push a placeholder. */ args.safe_push (integer_zero_node); + bool noval_seen = false; + tree noval = build_int_cst (integer_type_node, GOMP_ASYNC_NOVAL); + for (; c; c = OMP_CLAUSE_CHAIN (c)) if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_WAIT) { + tree wait_expr = OMP_CLAUSE_WAIT_EXPR (c); + + if (TREE_CODE (wait_expr) == INTEGER_CST + && tree_int_cst_compare (wait_expr, noval) == 0) + { + noval_seen = true; + continue; + } + args.safe_push (fold_convert_loc (OMP_CLAUSE_LOCATION (c), - integer_type_node, - OMP_CLAUSE_WAIT_EXPR (c))); + integer_type_node, wait_expr)); num_waits++; } - if (!tagging || num_waits) + if (noval_seen && num_waits == 0) + args[t_wait_idx] = + (tagging + ? oacc_launch_pack (GOMP_LAUNCH_WAIT, NULL_TREE, GOMP_ASYNC_NOVAL) + : noval); + else if (!tagging || num_waits) { tree len; Index: include/gomp-constants.h =================================================================== --- include/gomp-constants.h (revision 263981) +++ include/gomp-constants.h (working copy) @@ -221,13 +221,14 @@ enum gomp_map_kind #define GOMP_LAUNCH_CODE_SHIFT 28 #define GOMP_LAUNCH_DEVICE_SHIFT 16 #define GOMP_LAUNCH_OP_SHIFT 0 +#define GOMP_LAUNCH_OP_MASK 0xffff #define GOMP_LAUNCH_PACK(CODE,DEVICE,OP) \ (((CODE) << GOMP_LAUNCH_CODE_SHIFT) \ | ((DEVICE) << GOMP_LAUNCH_DEVICE_SHIFT) \ - | ((OP) << GOMP_LAUNCH_OP_SHIFT)) + | (((OP) & GOMP_LAUNCH_OP_MASK) << GOMP_LAUNCH_OP_SHIFT)) #define GOMP_LAUNCH_CODE(X) (((X) >> GOMP_LAUNCH_CODE_SHIFT) & 0xf) #define GOMP_LAUNCH_DEVICE(X) (((X) >> GOMP_LAUNCH_DEVICE_SHIFT) & 0xfff) -#define GOMP_LAUNCH_OP(X) (((X) >> GOMP_LAUNCH_OP_SHIFT) & 0xffff) +#define GOMP_LAUNCH_OP(X) (((X) >> GOMP_LAUNCH_OP_SHIFT) & GOMP_LAUNCH_OP_MASK) #define GOMP_LAUNCH_OP_MAX 0xffff /* Bitmask to apply in order to find out the intended device of a target Index: libgomp/oacc-parallel.c =================================================================== --- libgomp/oacc-parallel.c (revision 263981) +++ libgomp/oacc-parallel.c (working copy) @@ -194,10 +194,14 @@ GOACC_parallel_keyed (int device, void (*fn) (void case GOMP_LAUNCH_WAIT: { - unsigned num_waits = GOMP_LAUNCH_OP (tag); + /* Be careful to cast the op field as a signed 16-bit, and + sign-extend to full integer. */ + int num_waits = ((signed short) GOMP_LAUNCH_OP (tag)); - if (num_waits) + if (num_waits > 0) goacc_wait (async, num_waits, &ap); + else if (num_waits == acc_async_noval) + acc_wait_all_async (async); break; } @@ -351,7 +355,7 @@ GOACC_enter_exit_data (int device, size_t mapnum, || host_fallback) return; - if (num_waits) + if (num_waits > 0) { va_list ap; @@ -359,6 +363,8 @@ GOACC_enter_exit_data (int device, size_t mapnum, goacc_wait (async, num_waits, &ap); va_end (ap); } + else if (num_waits == acc_async_noval) + acc_wait_all_async (async); /* Determine whether "finalize" semantics apply to all mappings of this OpenACC directive. */ @@ -542,7 +548,7 @@ GOACC_update (int device, size_t mapnum, || host_fallback) return; - if (num_waits) + if (num_waits > 0) { va_list ap; @@ -550,6 +556,8 @@ GOACC_update (int device, size_t mapnum, goacc_wait (async, num_waits, &ap); va_end (ap); } + else if (num_waits == acc_async_noval) + acc_wait_all_async (async); acc_dev->openacc.async_set_async_func (async);