Message ID | 871seaofij.fsf@linaro.org |
---|---|
State | New |
Headers | show |
Series | Gimple FE support for internal functions | expand |
On Thu, May 17, 2018 at 10:27 AM Richard Sandiford < richard.sandiford@linaro.org> wrote: > This patch gets the gimple FE to parse calls to internal functions. > The only non-obvious thing was how the functions should be written > to avoid clashes with real function names. One option would be to > go the magic number of underscores route, but we already do that for > built-in functions, and it would be good to keep them visually > distinct. In the end I borrowed the local/internal label convention > from asm and used: > x = .SQRT (y); > I don't think even C++ has found a meaning for a leading dot yet. Heh, clever idea! > Tested on aarch64-linux-gnu (with and without SVE), aarch64_be-elf > and x86_64-linux-gnu. OK to install? OK and thanks for doing this! Richard. > Richard > 2018-05-17 Richard Sandiford <richard.sandiford@linaro.org> > gcc/ > * internal-fn.h (lookup_internal_fn): Declare > * internal-fn.c (lookup_internal_fn): New function. > * gimple.c (gimple_build_call_from_tree): Handle calls to > internal functions. > * gimple-pretty-print.c (dump_gimple_call): Print "." before > internal function names. > * tree-pretty-print.c (dump_generic_node): Likewise. > * tree-ssa-scopedtables.c (expr_hash_elt::print): Likewise. > gcc/c/ > * gimple-parser.c: Include internal-fn.h. > (c_parser_gimple_statement): Treat a leading CPP_DOT as a call. > (c_parser_gimple_call_internal): New function. > (c_parser_gimple_postfix_expression): Use it to handle CPP_DOT. > Fix typos in comment. > gcc/testsuite/ > * gcc.dg/gimplefe-28.c: New test. > * gcc.dg/asan/use-after-scope-9.c: Adjust expected output for > internal function calls. > * gcc.dg/goacc/loop-processing-1.c: Likewise. > Index: gcc/internal-fn.h > =================================================================== > --- gcc/internal-fn.h 2018-05-16 12:48:59.194282896 +0100 > +++ gcc/internal-fn.h 2018-05-17 09:17:58.757608747 +0100 > @@ -107,6 +107,8 @@ internal_fn_name (enum internal_fn fn) > return internal_fn_name_array[(int) fn]; > } > +extern internal_fn lookup_internal_fn (const char *); > + > /* Return the ECF_* flags for function FN. */ > extern const int internal_fn_flags_array[]; > Index: gcc/internal-fn.c > =================================================================== > --- gcc/internal-fn.c 2018-05-16 12:48:59.410941892 +0100 > +++ gcc/internal-fn.c 2018-05-17 09:22:49.808912358 +0100 > @@ -64,6 +64,26 @@ #define DEF_INTERNAL_FN(CODE, FLAGS, FNS > 0 > }; > +/* Return the internal function called NAME, or IFN_LAST if there's > + no such function. */ > + > +internal_fn > +lookup_internal_fn (const char *name) > +{ > + typedef hash_map<nofree_string_hash, internal_fn> name_to_fn_map_type; > + static name_to_fn_map_type *name_to_fn_map; > + > + if (!name_to_fn_map) > + { > + name_to_fn_map = new name_to_fn_map_type (IFN_LAST); > + for (unsigned int i = 0; i < IFN_LAST; ++i) > + name_to_fn_map->put (internal_fn_name (internal_fn (i)), > + internal_fn (i)); > + } > + internal_fn *entry = name_to_fn_map->get (name); > + return entry ? *entry : IFN_LAST; > +} > + > /* Fnspec of each internal function, indexed by function number. */ > const_tree internal_fn_fnspec_array[IFN_LAST + 1]; > Index: gcc/gimple.c > =================================================================== > --- gcc/gimple.c 2018-05-16 12:48:59.410941892 +0100 > +++ gcc/gimple.c 2018-05-17 09:22:49.808912358 +0100 > @@ -350,12 +350,19 @@ gimple_build_call_from_tree (tree t, tre > { > unsigned i, nargs; > gcall *call; > - tree fndecl = get_callee_fndecl (t); > gcc_assert (TREE_CODE (t) == CALL_EXPR); > nargs = call_expr_nargs (t); > - call = gimple_build_call_1 (fndecl ? fndecl : CALL_EXPR_FN (t), nargs); > + > + tree fndecl = NULL_TREE; > + if (CALL_EXPR_FN (t) == NULL_TREE) > + call = gimple_build_call_internal_1 (CALL_EXPR_IFN (t), nargs); > + else > + { > + fndecl = get_callee_fndecl (t); > + call = gimple_build_call_1 (fndecl ? fndecl : CALL_EXPR_FN (t), nargs); > + } > for (i = 0; i < nargs; i++) > gimple_call_set_arg (call, i, CALL_EXPR_ARG (t, i)); > Index: gcc/gimple-pretty-print.c > =================================================================== > --- gcc/gimple-pretty-print.c 2018-05-16 12:48:59.410941892 +0100 > +++ gcc/gimple-pretty-print.c 2018-05-17 09:22:49.808912358 +0100 > @@ -874,7 +874,7 @@ dump_gimple_call (pretty_printer *buffer > if (flags & TDF_RAW) > { > if (gimple_call_internal_p (gs)) > - dump_gimple_fmt (buffer, spc, flags, "%G <%s, %T", gs, > + dump_gimple_fmt (buffer, spc, flags, "%G <.%s, %T", gs, > internal_fn_name (gimple_call_internal_fn (gs)), lhs); > else > dump_gimple_fmt (buffer, spc, flags, "%G <%T, %T", gs, fn, lhs); > @@ -898,7 +898,10 @@ dump_gimple_call (pretty_printer *buffer > pp_space (buffer); > } > if (gimple_call_internal_p (gs)) > - pp_string (buffer, internal_fn_name (gimple_call_internal_fn (gs))); > + { > + pp_dot (buffer); > + pp_string (buffer, internal_fn_name (gimple_call_internal_fn (gs))); > + } > else > print_call_name (buffer, fn, flags); > pp_string (buffer, " ("); > Index: gcc/tree-pretty-print.c > =================================================================== > --- gcc/tree-pretty-print.c 2018-05-16 12:48:59.410941892 +0100 > +++ gcc/tree-pretty-print.c 2018-05-17 09:22:49.808912358 +0100 > @@ -2262,7 +2262,10 @@ dump_generic_node (pretty_printer *pp, t > if (CALL_EXPR_FN (node) != NULL_TREE) > print_call_name (pp, CALL_EXPR_FN (node), flags); > else > - pp_string (pp, internal_fn_name (CALL_EXPR_IFN (node))); > + { > + pp_dot (pp); > + pp_string (pp, internal_fn_name (CALL_EXPR_IFN (node))); > + } > /* Print parameters. */ > pp_space (pp); > Index: gcc/tree-ssa-scopedtables.c > =================================================================== > --- gcc/tree-ssa-scopedtables.c 2018-02-08 13:34:20.649280969 +0000 > +++ gcc/tree-ssa-scopedtables.c 2018-05-17 09:17:58.758608713 +0100 > @@ -906,8 +906,8 @@ expr_hash_elt::print (FILE *stream) > fn_from = m_expr.ops.call.fn_from; > if (gimple_call_internal_p (fn_from)) > - fputs (internal_fn_name (gimple_call_internal_fn (fn_from)), > - stream); > + fprintf (stream, ".%s", > + internal_fn_name (gimple_call_internal_fn (fn_from))); > else > print_generic_expr (stream, gimple_call_fn (fn_from)); > fprintf (stream, " ("); > Index: gcc/c/gimple-parser.c > =================================================================== > --- gcc/c/gimple-parser.c 2018-05-16 12:48:59.410941892 +0100 > +++ gcc/c/gimple-parser.c 2018-05-17 09:22:49.808912358 +0100 > @@ -53,6 +53,7 @@ Software Foundation; either version 3, o > #include "tree-ssanames.h" > #include "gimple-ssa.h" > #include "tree-dfa.h" > +#include "internal-fn.h" > /* Gimple parsing functions. */ > @@ -400,9 +401,10 @@ c_parser_gimple_statement (c_parser *par > } > /* GIMPLE call with lhs. */ > - if (c_parser_next_token_is (parser, CPP_NAME) > - && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN > - && lookup_name (c_parser_peek_token (parser)->value)) > + if (c_parser_next_token_is (parser, CPP_DOT) > + || (c_parser_next_token_is (parser, CPP_NAME) > + && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN > + && lookup_name (c_parser_peek_token (parser)->value))) > { > rhs = c_parser_gimple_unary_expression (parser); > if (rhs.value != error_mark_node) > @@ -726,14 +728,57 @@ c_parser_parse_ssa_name (c_parser *parse > return name; > } > +/* Parse a gimple call to an internal function. > + > + gimple-call-internal: > + . identifier ( gimple-argument-expression-list[opt] ) */ > + > +static struct c_expr > +c_parser_gimple_call_internal (c_parser *parser) > +{ > + struct c_expr expr; > + expr.set_error (); > + > + gcc_assert (c_parser_next_token_is (parser, CPP_DOT)); > + c_parser_consume_token (parser); > + location_t loc = c_parser_peek_token (parser)->location; > + if (!c_parser_next_token_is (parser, CPP_NAME) > + || c_parser_peek_token (parser)->id_kind != C_ID_ID) > + { > + c_parser_error (parser, "expecting internal function name"); > + return expr; > + } > + tree id = c_parser_peek_token (parser)->value; > + internal_fn ifn = lookup_internal_fn (IDENTIFIER_POINTER (id)); > + c_parser_consume_token (parser); > + if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) > + { > + auto_vec<tree> exprlist; > + if (!c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) > + c_parser_gimple_expr_list (parser, &exprlist); > + c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); > + if (ifn == IFN_LAST) > + error_at (loc, "unknown internal function %qE", id); > + else > + { > + expr.value = build_call_expr_internal_loc_array > + (loc, ifn, void_type_node, exprlist.length (), > + exprlist.address ()); > + expr.original_code = ERROR_MARK; > + expr.original_type = NULL; > + } > + } > + return expr; > +} > + > /* Parse gimple postfix expression. > gimple-postfix-expression: > gimple-primary-expression > - gimple-primary-xpression [ gimple-primary-expression ] > + gimple-primary-expression [ gimple-primary-expression ] > gimple-primary-expression ( gimple-argument-expression-list[opt] ) > - postfix-expression . identifier > - postfix-expression -> identifier > + gimple-postfix-expression . identifier > + gimple-postfix-expression -> identifier > gimple-argument-expression-list: > gimple-unary-expression > @@ -743,6 +788,7 @@ c_parser_parse_ssa_name (c_parser *parse > identifier > constant > string-literal > + gimple-call-internal > */ > @@ -779,6 +825,9 @@ c_parser_gimple_postfix_expression (c_pa > expr.original_code = STRING_CST; > c_parser_consume_token (parser); > break; > + case CPP_DOT: > + expr = c_parser_gimple_call_internal (parser); > + break; > case CPP_NAME: > if (c_parser_peek_token (parser)->id_kind == C_ID_ID) > { > Index: gcc/testsuite/gcc.dg/gimplefe-28.c > =================================================================== > --- /dev/null 2018-04-20 16:19:46.369131350 +0100 > +++ gcc/testsuite/gcc.dg/gimplefe-28.c 2018-05-17 09:17:58.757608747 +0100 > @@ -0,0 +1,16 @@ > +/* { dg-do compile { target sqrt_insn } } */ > +/* { dg-options "-fgimple -O2" } */ > + > +double __GIMPLE > +f1 (double x) > +{ > + double res; > + res = .SQRT (x); > + return res; > +} > + > +void __GIMPLE > +f2 (double x) > +{ > + .SQRT (x); // Dead code > +} > Index: gcc/testsuite/gcc.dg/asan/use-after-scope-9.c > =================================================================== > --- gcc/testsuite/gcc.dg/asan/use-after-scope-9.c 2017-02-23 19:54:08.000000000 +0000 > +++ gcc/testsuite/gcc.dg/asan/use-after-scope-9.c 2018-05-17 09:17:58.757608747 +0100 > @@ -17,7 +17,7 @@ main (int argc, char **argv) > return *ptr; > } > -// { dg-final { scan-tree-dump-times "= ASAN_POISON \\(\\)" 1 "asan1" } } > +// { dg-final { scan-tree-dump-times {= \.ASAN_POISON \(\)} 1 "asan1" } } > // { dg-output "ERROR: AddressSanitizer: stack-use-after-scope on address.*(\n|\r\n|\r)" } > // { dg-output "READ of size .*" } > // { dg-output ".*'a' <== Memory access at offset \[0-9\]* is inside this variable.*" } > Index: gcc/testsuite/gcc.dg/goacc/loop-processing-1.c > =================================================================== > --- gcc/testsuite/gcc.dg/goacc/loop-processing-1.c 2017-02-23 19:54:08.000000000 +0000 > +++ gcc/testsuite/gcc.dg/goacc/loop-processing-1.c 2018-05-17 09:17:58.757608747 +0100 > @@ -15,4 +15,4 @@ void vector_1 (int *ary, int size) > } > } > -/* { dg-final { scan-tree-dump {OpenACC loops.*Loop 0\(0\).*Loop 24\(1\).*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_HEAD_MARK, 0, 1, 36\);.*Head-0:.*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_HEAD_MARK, 0, 1, 36\);.*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_FORK, \.data_dep\.[0-9_]+, 0\);.*Tail-0:.*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_TAIL_MARK, \.data_dep\.[0-9_]+, 1\);.*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_JOIN, \.data_dep\.[0-9_]+, 0\);.*Loop 6\(6\).*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_HEAD_MARK, 0, 2, 6\);.*Head-0:.*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_HEAD_MARK, 0, 2, 6\);.*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_FORK, \.data_dep\.[0-9_]+, 1\);.*Head-1:.*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_HEAD_MARK, \.data_dep\.[0-9_]+, 1\);.*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_FORK, \.data_dep\.[0-9_]+, 2\);.*Tail-1:.*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_TAIL_MARK, \.data_dep\.[0-9_]+, 2\);.*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_JOIN, \.data_dep\.[0-9_]+, 2\);.*Tail-0:.*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_TAIL_MARK, \.data_dep\.[0-9_]+, 1\);.*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_JOIN, \.data_dep\.[0-9_]+, 1\);} "oaccdevlow" } } */ > +/* { dg-final { scan-tree-dump {OpenACC loops.*Loop 0\(0\).*Loop 24\(1\).*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_HEAD_MARK, 0, 1, 36\);.*Head-0:.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_HEAD_MARK, 0, 1, 36\);.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_FORK, \.data_dep\.[0-9_]+, 0\);.*Tail-0:.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_TAIL_MARK, \.data_dep\.[0-9_]+, 1\);.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_JOIN, \.data_dep\.[0-9_]+, 0\);.*Loop 6\(6\).*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_HEAD_MARK, 0, 2, 6\);.*Head-0:.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_HEAD_MARK, 0, 2, 6\);.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_FORK, \.data_dep\.[0-9_]+, 1\);.*Head-1:.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_HEAD_MARK, \.data_dep\.[0-9_]+, 1\);.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_FORK, \.data_dep\.[0-9_]+, 2\);.*Tail-1:.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_TAIL_MARK, \.data_dep\.[0-9_]+, 2\);.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_JOIN, \.data_dep\.[0-9_]+, 2\);.*Tail-0:.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_TAIL_MARK, \.data_dep\.[0-9_]+, 1\);.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_JOIN, \.data_dep\.[0-9_]+, 1\);} "oaccdevlow" } } */
On 17 May 2018 at 10:25, Richard Sandiford <richard.sandiford@linaro.org> wrote: > This patch gets the gimple FE to parse calls to internal functions. > The only non-obvious thing was how the functions should be written > to avoid clashes with real function names. One option would be to > go the magic number of underscores route, but we already do that for > built-in functions, and it would be good to keep them visually > distinct. In the end I borrowed the local/internal label convention > from asm and used: > > x = .SQRT (y); > > I don't think even C++ has found a meaning for a leading dot yet. > > Tested on aarch64-linux-gnu (with and without SVE), aarch64_be-elf > and x86_64-linux-gnu. OK to install? > > Richard > > > 2018-05-17 Richard Sandiford <richard.sandiford@linaro.org> > > gcc/ > * internal-fn.h (lookup_internal_fn): Declare > * internal-fn.c (lookup_internal_fn): New function. > * gimple.c (gimple_build_call_from_tree): Handle calls to > internal functions. > * gimple-pretty-print.c (dump_gimple_call): Print "." before > internal function names. > * tree-pretty-print.c (dump_generic_node): Likewise. > * tree-ssa-scopedtables.c (expr_hash_elt::print): Likewise. > > gcc/c/ > * gimple-parser.c: Include internal-fn.h. > (c_parser_gimple_statement): Treat a leading CPP_DOT as a call. > (c_parser_gimple_call_internal): New function. > (c_parser_gimple_postfix_expression): Use it to handle CPP_DOT. > Fix typos in comment. > > gcc/testsuite/ > * gcc.dg/gimplefe-28.c: New test. Hi Richard, I've noticed that this new test fails on arm-none-linux-gnueabi and arm-none-eabi: during RTL pass: expand /gcc/testsuite/gcc.dg/gimplefe-28.c: In function 'f1': /gcc/testsuite/gcc.dg/gimplefe-28.c:5:1: internal compiler error: in maybe_gen_insn, at optabs.c:7240 0xa9157a maybe_gen_insn(insn_code, unsigned int, expand_operand*) /gcc/optabs.c:7240 0xa91658 maybe_expand_insn(insn_code, unsigned int, expand_operand*) /gcc/optabs.c:7284 0xa91688 expand_insn(insn_code, unsigned int, expand_operand*) /gcc/optabs.c:7315 0x94242d expand_direct_optab_fn /gcc/internal-fn.c:2918 0x6c5d14 expand_call_stmt /gcc/cfgexpand.c:2598 0x6c6fd4 expand_gimple_stmt_1 /gcc/cfgexpand.c:3644 0x6c6fd4 expand_gimple_stmt /gcc/cfgexpand.c:3810 0x6c7ab4 expand_gimple_tailcall /gcc/cfgexpand.c:3856 0x6c9183 expand_gimple_basic_block /gcc/cfgexpand.c:5816 0x6cbf26 execute /gcc/cfgexpand.c:6445 It passes on arm-none-linux-gnueabihf and armeb-none-linux-gnueabihf. Christophe > * gcc.dg/asan/use-after-scope-9.c: Adjust expected output for > internal function calls. > * gcc.dg/goacc/loop-processing-1.c: Likewise. > > Index: gcc/internal-fn.h > =================================================================== > --- gcc/internal-fn.h 2018-05-16 12:48:59.194282896 +0100 > +++ gcc/internal-fn.h 2018-05-17 09:17:58.757608747 +0100 > @@ -107,6 +107,8 @@ internal_fn_name (enum internal_fn fn) > return internal_fn_name_array[(int) fn]; > } > > +extern internal_fn lookup_internal_fn (const char *); > + > /* Return the ECF_* flags for function FN. */ > > extern const int internal_fn_flags_array[]; > Index: gcc/internal-fn.c > =================================================================== > --- gcc/internal-fn.c 2018-05-16 12:48:59.410941892 +0100 > +++ gcc/internal-fn.c 2018-05-17 09:22:49.808912358 +0100 > @@ -64,6 +64,26 @@ #define DEF_INTERNAL_FN(CODE, FLAGS, FNS > 0 > }; > > +/* Return the internal function called NAME, or IFN_LAST if there's > + no such function. */ > + > +internal_fn > +lookup_internal_fn (const char *name) > +{ > + typedef hash_map<nofree_string_hash, internal_fn> name_to_fn_map_type; > + static name_to_fn_map_type *name_to_fn_map; > + > + if (!name_to_fn_map) > + { > + name_to_fn_map = new name_to_fn_map_type (IFN_LAST); > + for (unsigned int i = 0; i < IFN_LAST; ++i) > + name_to_fn_map->put (internal_fn_name (internal_fn (i)), > + internal_fn (i)); > + } > + internal_fn *entry = name_to_fn_map->get (name); > + return entry ? *entry : IFN_LAST; > +} > + > /* Fnspec of each internal function, indexed by function number. */ > const_tree internal_fn_fnspec_array[IFN_LAST + 1]; > > Index: gcc/gimple.c > =================================================================== > --- gcc/gimple.c 2018-05-16 12:48:59.410941892 +0100 > +++ gcc/gimple.c 2018-05-17 09:22:49.808912358 +0100 > @@ -350,12 +350,19 @@ gimple_build_call_from_tree (tree t, tre > { > unsigned i, nargs; > gcall *call; > - tree fndecl = get_callee_fndecl (t); > > gcc_assert (TREE_CODE (t) == CALL_EXPR); > > nargs = call_expr_nargs (t); > - call = gimple_build_call_1 (fndecl ? fndecl : CALL_EXPR_FN (t), nargs); > + > + tree fndecl = NULL_TREE; > + if (CALL_EXPR_FN (t) == NULL_TREE) > + call = gimple_build_call_internal_1 (CALL_EXPR_IFN (t), nargs); > + else > + { > + fndecl = get_callee_fndecl (t); > + call = gimple_build_call_1 (fndecl ? fndecl : CALL_EXPR_FN (t), nargs); > + } > > for (i = 0; i < nargs; i++) > gimple_call_set_arg (call, i, CALL_EXPR_ARG (t, i)); > Index: gcc/gimple-pretty-print.c > =================================================================== > --- gcc/gimple-pretty-print.c 2018-05-16 12:48:59.410941892 +0100 > +++ gcc/gimple-pretty-print.c 2018-05-17 09:22:49.808912358 +0100 > @@ -874,7 +874,7 @@ dump_gimple_call (pretty_printer *buffer > if (flags & TDF_RAW) > { > if (gimple_call_internal_p (gs)) > - dump_gimple_fmt (buffer, spc, flags, "%G <%s, %T", gs, > + dump_gimple_fmt (buffer, spc, flags, "%G <.%s, %T", gs, > internal_fn_name (gimple_call_internal_fn (gs)), lhs); > else > dump_gimple_fmt (buffer, spc, flags, "%G <%T, %T", gs, fn, lhs); > @@ -898,7 +898,10 @@ dump_gimple_call (pretty_printer *buffer > pp_space (buffer); > } > if (gimple_call_internal_p (gs)) > - pp_string (buffer, internal_fn_name (gimple_call_internal_fn (gs))); > + { > + pp_dot (buffer); > + pp_string (buffer, internal_fn_name (gimple_call_internal_fn (gs))); > + } > else > print_call_name (buffer, fn, flags); > pp_string (buffer, " ("); > Index: gcc/tree-pretty-print.c > =================================================================== > --- gcc/tree-pretty-print.c 2018-05-16 12:48:59.410941892 +0100 > +++ gcc/tree-pretty-print.c 2018-05-17 09:22:49.808912358 +0100 > @@ -2262,7 +2262,10 @@ dump_generic_node (pretty_printer *pp, t > if (CALL_EXPR_FN (node) != NULL_TREE) > print_call_name (pp, CALL_EXPR_FN (node), flags); > else > - pp_string (pp, internal_fn_name (CALL_EXPR_IFN (node))); > + { > + pp_dot (pp); > + pp_string (pp, internal_fn_name (CALL_EXPR_IFN (node))); > + } > > /* Print parameters. */ > pp_space (pp); > Index: gcc/tree-ssa-scopedtables.c > =================================================================== > --- gcc/tree-ssa-scopedtables.c 2018-02-08 13:34:20.649280969 +0000 > +++ gcc/tree-ssa-scopedtables.c 2018-05-17 09:17:58.758608713 +0100 > @@ -906,8 +906,8 @@ expr_hash_elt::print (FILE *stream) > > fn_from = m_expr.ops.call.fn_from; > if (gimple_call_internal_p (fn_from)) > - fputs (internal_fn_name (gimple_call_internal_fn (fn_from)), > - stream); > + fprintf (stream, ".%s", > + internal_fn_name (gimple_call_internal_fn (fn_from))); > else > print_generic_expr (stream, gimple_call_fn (fn_from)); > fprintf (stream, " ("); > Index: gcc/c/gimple-parser.c > =================================================================== > --- gcc/c/gimple-parser.c 2018-05-16 12:48:59.410941892 +0100 > +++ gcc/c/gimple-parser.c 2018-05-17 09:22:49.808912358 +0100 > @@ -53,6 +53,7 @@ Software Foundation; either version 3, o > #include "tree-ssanames.h" > #include "gimple-ssa.h" > #include "tree-dfa.h" > +#include "internal-fn.h" > > > /* Gimple parsing functions. */ > @@ -400,9 +401,10 @@ c_parser_gimple_statement (c_parser *par > } > > /* GIMPLE call with lhs. */ > - if (c_parser_next_token_is (parser, CPP_NAME) > - && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN > - && lookup_name (c_parser_peek_token (parser)->value)) > + if (c_parser_next_token_is (parser, CPP_DOT) > + || (c_parser_next_token_is (parser, CPP_NAME) > + && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN > + && lookup_name (c_parser_peek_token (parser)->value))) > { > rhs = c_parser_gimple_unary_expression (parser); > if (rhs.value != error_mark_node) > @@ -726,14 +728,57 @@ c_parser_parse_ssa_name (c_parser *parse > return name; > } > > +/* Parse a gimple call to an internal function. > + > + gimple-call-internal: > + . identifier ( gimple-argument-expression-list[opt] ) */ > + > +static struct c_expr > +c_parser_gimple_call_internal (c_parser *parser) > +{ > + struct c_expr expr; > + expr.set_error (); > + > + gcc_assert (c_parser_next_token_is (parser, CPP_DOT)); > + c_parser_consume_token (parser); > + location_t loc = c_parser_peek_token (parser)->location; > + if (!c_parser_next_token_is (parser, CPP_NAME) > + || c_parser_peek_token (parser)->id_kind != C_ID_ID) > + { > + c_parser_error (parser, "expecting internal function name"); > + return expr; > + } > + tree id = c_parser_peek_token (parser)->value; > + internal_fn ifn = lookup_internal_fn (IDENTIFIER_POINTER (id)); > + c_parser_consume_token (parser); > + if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) > + { > + auto_vec<tree> exprlist; > + if (!c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) > + c_parser_gimple_expr_list (parser, &exprlist); > + c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); > + if (ifn == IFN_LAST) > + error_at (loc, "unknown internal function %qE", id); > + else > + { > + expr.value = build_call_expr_internal_loc_array > + (loc, ifn, void_type_node, exprlist.length (), > + exprlist.address ()); > + expr.original_code = ERROR_MARK; > + expr.original_type = NULL; > + } > + } > + return expr; > +} > + > /* Parse gimple postfix expression. > > gimple-postfix-expression: > gimple-primary-expression > - gimple-primary-xpression [ gimple-primary-expression ] > + gimple-primary-expression [ gimple-primary-expression ] > gimple-primary-expression ( gimple-argument-expression-list[opt] ) > - postfix-expression . identifier > - postfix-expression -> identifier > + gimple-postfix-expression . identifier > + gimple-postfix-expression -> identifier > > gimple-argument-expression-list: > gimple-unary-expression > @@ -743,6 +788,7 @@ c_parser_parse_ssa_name (c_parser *parse > identifier > constant > string-literal > + gimple-call-internal > > */ > > @@ -779,6 +825,9 @@ c_parser_gimple_postfix_expression (c_pa > expr.original_code = STRING_CST; > c_parser_consume_token (parser); > break; > + case CPP_DOT: > + expr = c_parser_gimple_call_internal (parser); > + break; > case CPP_NAME: > if (c_parser_peek_token (parser)->id_kind == C_ID_ID) > { > Index: gcc/testsuite/gcc.dg/gimplefe-28.c > =================================================================== > --- /dev/null 2018-04-20 16:19:46.369131350 +0100 > +++ gcc/testsuite/gcc.dg/gimplefe-28.c 2018-05-17 09:17:58.757608747 +0100 > @@ -0,0 +1,16 @@ > +/* { dg-do compile { target sqrt_insn } } */ > +/* { dg-options "-fgimple -O2" } */ > + > +double __GIMPLE > +f1 (double x) > +{ > + double res; > + res = .SQRT (x); > + return res; > +} > + > +void __GIMPLE > +f2 (double x) > +{ > + .SQRT (x); // Dead code > +} > Index: gcc/testsuite/gcc.dg/asan/use-after-scope-9.c > =================================================================== > --- gcc/testsuite/gcc.dg/asan/use-after-scope-9.c 2017-02-23 19:54:08.000000000 +0000 > +++ gcc/testsuite/gcc.dg/asan/use-after-scope-9.c 2018-05-17 09:17:58.757608747 +0100 > @@ -17,7 +17,7 @@ main (int argc, char **argv) > return *ptr; > } > > -// { dg-final { scan-tree-dump-times "= ASAN_POISON \\(\\)" 1 "asan1" } } > +// { dg-final { scan-tree-dump-times {= \.ASAN_POISON \(\)} 1 "asan1" } } > // { dg-output "ERROR: AddressSanitizer: stack-use-after-scope on address.*(\n|\r\n|\r)" } > // { dg-output "READ of size .*" } > // { dg-output ".*'a' <== Memory access at offset \[0-9\]* is inside this variable.*" } > Index: gcc/testsuite/gcc.dg/goacc/loop-processing-1.c > =================================================================== > --- gcc/testsuite/gcc.dg/goacc/loop-processing-1.c 2017-02-23 19:54:08.000000000 +0000 > +++ gcc/testsuite/gcc.dg/goacc/loop-processing-1.c 2018-05-17 09:17:58.757608747 +0100 > @@ -15,4 +15,4 @@ void vector_1 (int *ary, int size) > } > } > > -/* { dg-final { scan-tree-dump {OpenACC loops.*Loop 0\(0\).*Loop 24\(1\).*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_HEAD_MARK, 0, 1, 36\);.*Head-0:.*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_HEAD_MARK, 0, 1, 36\);.*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_FORK, \.data_dep\.[0-9_]+, 0\);.*Tail-0:.*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_TAIL_MARK, \.data_dep\.[0-9_]+, 1\);.*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_JOIN, \.data_dep\.[0-9_]+, 0\);.*Loop 6\(6\).*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_HEAD_MARK, 0, 2, 6\);.*Head-0:.*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_HEAD_MARK, 0, 2, 6\);.*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_FORK, \.data_dep\.[0-9_]+, 1\);.*Head-1:.*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_HEAD_MARK, \.data_dep\.[0-9_]+, 1\);.*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_FORK, \.data_dep\.[0-9_]+, 2\);.*Tail-1:.*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_TAIL_MARK, \.data_dep\.[0-9_]+, 2\);.*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_JOIN, \.data_dep\.[0-9_]+, 2\);.*Tail-0:.*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_TAIL_MARK, \.data_dep\.[0-9_]+, 1\);.*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_JOIN, \.data_dep\.[0-9_]+, 1\);} "oaccdevlow" } } */ > +/* { dg-final { scan-tree-dump {OpenACC loops.*Loop 0\(0\).*Loop 24\(1\).*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_HEAD_MARK, 0, 1, 36\);.*Head-0:.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_HEAD_MARK, 0, 1, 36\);.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_FORK, \.data_dep\.[0-9_]+, 0\);.*Tail-0:.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_TAIL_MARK, \.data_dep\.[0-9_]+, 1\);.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_JOIN, \.data_dep\.[0-9_]+, 0\);.*Loop 6\(6\).*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_HEAD_MARK, 0, 2, 6\);.*Head-0:.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_HEAD_MARK, 0, 2, 6\);.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_FORK, \.data_dep\.[0-9_]+, 1\);.*Head-1:.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_HEAD_MARK, \.data_dep\.[0-9_]+, 1\);.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_FORK, \.data_dep\.[0-9_]+, 2\);.*Tail-1:.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_TAIL_MARK, \.data_dep\.[0-9_]+, 2\);.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_JOIN, \.data_dep\.[0-9_]+, 2\);.*Tail-0:.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_TAIL_MARK, \.data_dep\.[0-9_]+, 1\);.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_JOIN, \.data_dep\.[0-9_]+, 1\);} "oaccdevlow" } } */
Index: gcc/internal-fn.h =================================================================== --- gcc/internal-fn.h 2018-05-16 12:48:59.194282896 +0100 +++ gcc/internal-fn.h 2018-05-17 09:17:58.757608747 +0100 @@ -107,6 +107,8 @@ internal_fn_name (enum internal_fn fn) return internal_fn_name_array[(int) fn]; } +extern internal_fn lookup_internal_fn (const char *); + /* Return the ECF_* flags for function FN. */ extern const int internal_fn_flags_array[]; Index: gcc/internal-fn.c =================================================================== --- gcc/internal-fn.c 2018-05-16 12:48:59.410941892 +0100 +++ gcc/internal-fn.c 2018-05-17 09:22:49.808912358 +0100 @@ -64,6 +64,26 @@ #define DEF_INTERNAL_FN(CODE, FLAGS, FNS 0 }; +/* Return the internal function called NAME, or IFN_LAST if there's + no such function. */ + +internal_fn +lookup_internal_fn (const char *name) +{ + typedef hash_map<nofree_string_hash, internal_fn> name_to_fn_map_type; + static name_to_fn_map_type *name_to_fn_map; + + if (!name_to_fn_map) + { + name_to_fn_map = new name_to_fn_map_type (IFN_LAST); + for (unsigned int i = 0; i < IFN_LAST; ++i) + name_to_fn_map->put (internal_fn_name (internal_fn (i)), + internal_fn (i)); + } + internal_fn *entry = name_to_fn_map->get (name); + return entry ? *entry : IFN_LAST; +} + /* Fnspec of each internal function, indexed by function number. */ const_tree internal_fn_fnspec_array[IFN_LAST + 1]; Index: gcc/gimple.c =================================================================== --- gcc/gimple.c 2018-05-16 12:48:59.410941892 +0100 +++ gcc/gimple.c 2018-05-17 09:22:49.808912358 +0100 @@ -350,12 +350,19 @@ gimple_build_call_from_tree (tree t, tre { unsigned i, nargs; gcall *call; - tree fndecl = get_callee_fndecl (t); gcc_assert (TREE_CODE (t) == CALL_EXPR); nargs = call_expr_nargs (t); - call = gimple_build_call_1 (fndecl ? fndecl : CALL_EXPR_FN (t), nargs); + + tree fndecl = NULL_TREE; + if (CALL_EXPR_FN (t) == NULL_TREE) + call = gimple_build_call_internal_1 (CALL_EXPR_IFN (t), nargs); + else + { + fndecl = get_callee_fndecl (t); + call = gimple_build_call_1 (fndecl ? fndecl : CALL_EXPR_FN (t), nargs); + } for (i = 0; i < nargs; i++) gimple_call_set_arg (call, i, CALL_EXPR_ARG (t, i)); Index: gcc/gimple-pretty-print.c =================================================================== --- gcc/gimple-pretty-print.c 2018-05-16 12:48:59.410941892 +0100 +++ gcc/gimple-pretty-print.c 2018-05-17 09:22:49.808912358 +0100 @@ -874,7 +874,7 @@ dump_gimple_call (pretty_printer *buffer if (flags & TDF_RAW) { if (gimple_call_internal_p (gs)) - dump_gimple_fmt (buffer, spc, flags, "%G <%s, %T", gs, + dump_gimple_fmt (buffer, spc, flags, "%G <.%s, %T", gs, internal_fn_name (gimple_call_internal_fn (gs)), lhs); else dump_gimple_fmt (buffer, spc, flags, "%G <%T, %T", gs, fn, lhs); @@ -898,7 +898,10 @@ dump_gimple_call (pretty_printer *buffer pp_space (buffer); } if (gimple_call_internal_p (gs)) - pp_string (buffer, internal_fn_name (gimple_call_internal_fn (gs))); + { + pp_dot (buffer); + pp_string (buffer, internal_fn_name (gimple_call_internal_fn (gs))); + } else print_call_name (buffer, fn, flags); pp_string (buffer, " ("); Index: gcc/tree-pretty-print.c =================================================================== --- gcc/tree-pretty-print.c 2018-05-16 12:48:59.410941892 +0100 +++ gcc/tree-pretty-print.c 2018-05-17 09:22:49.808912358 +0100 @@ -2262,7 +2262,10 @@ dump_generic_node (pretty_printer *pp, t if (CALL_EXPR_FN (node) != NULL_TREE) print_call_name (pp, CALL_EXPR_FN (node), flags); else - pp_string (pp, internal_fn_name (CALL_EXPR_IFN (node))); + { + pp_dot (pp); + pp_string (pp, internal_fn_name (CALL_EXPR_IFN (node))); + } /* Print parameters. */ pp_space (pp); Index: gcc/tree-ssa-scopedtables.c =================================================================== --- gcc/tree-ssa-scopedtables.c 2018-02-08 13:34:20.649280969 +0000 +++ gcc/tree-ssa-scopedtables.c 2018-05-17 09:17:58.758608713 +0100 @@ -906,8 +906,8 @@ expr_hash_elt::print (FILE *stream) fn_from = m_expr.ops.call.fn_from; if (gimple_call_internal_p (fn_from)) - fputs (internal_fn_name (gimple_call_internal_fn (fn_from)), - stream); + fprintf (stream, ".%s", + internal_fn_name (gimple_call_internal_fn (fn_from))); else print_generic_expr (stream, gimple_call_fn (fn_from)); fprintf (stream, " ("); Index: gcc/c/gimple-parser.c =================================================================== --- gcc/c/gimple-parser.c 2018-05-16 12:48:59.410941892 +0100 +++ gcc/c/gimple-parser.c 2018-05-17 09:22:49.808912358 +0100 @@ -53,6 +53,7 @@ Software Foundation; either version 3, o #include "tree-ssanames.h" #include "gimple-ssa.h" #include "tree-dfa.h" +#include "internal-fn.h" /* Gimple parsing functions. */ @@ -400,9 +401,10 @@ c_parser_gimple_statement (c_parser *par } /* GIMPLE call with lhs. */ - if (c_parser_next_token_is (parser, CPP_NAME) - && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN - && lookup_name (c_parser_peek_token (parser)->value)) + if (c_parser_next_token_is (parser, CPP_DOT) + || (c_parser_next_token_is (parser, CPP_NAME) + && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN + && lookup_name (c_parser_peek_token (parser)->value))) { rhs = c_parser_gimple_unary_expression (parser); if (rhs.value != error_mark_node) @@ -726,14 +728,57 @@ c_parser_parse_ssa_name (c_parser *parse return name; } +/* Parse a gimple call to an internal function. + + gimple-call-internal: + . identifier ( gimple-argument-expression-list[opt] ) */ + +static struct c_expr +c_parser_gimple_call_internal (c_parser *parser) +{ + struct c_expr expr; + expr.set_error (); + + gcc_assert (c_parser_next_token_is (parser, CPP_DOT)); + c_parser_consume_token (parser); + location_t loc = c_parser_peek_token (parser)->location; + if (!c_parser_next_token_is (parser, CPP_NAME) + || c_parser_peek_token (parser)->id_kind != C_ID_ID) + { + c_parser_error (parser, "expecting internal function name"); + return expr; + } + tree id = c_parser_peek_token (parser)->value; + internal_fn ifn = lookup_internal_fn (IDENTIFIER_POINTER (id)); + c_parser_consume_token (parser); + if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) + { + auto_vec<tree> exprlist; + if (!c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) + c_parser_gimple_expr_list (parser, &exprlist); + c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); + if (ifn == IFN_LAST) + error_at (loc, "unknown internal function %qE", id); + else + { + expr.value = build_call_expr_internal_loc_array + (loc, ifn, void_type_node, exprlist.length (), + exprlist.address ()); + expr.original_code = ERROR_MARK; + expr.original_type = NULL; + } + } + return expr; +} + /* Parse gimple postfix expression. gimple-postfix-expression: gimple-primary-expression - gimple-primary-xpression [ gimple-primary-expression ] + gimple-primary-expression [ gimple-primary-expression ] gimple-primary-expression ( gimple-argument-expression-list[opt] ) - postfix-expression . identifier - postfix-expression -> identifier + gimple-postfix-expression . identifier + gimple-postfix-expression -> identifier gimple-argument-expression-list: gimple-unary-expression @@ -743,6 +788,7 @@ c_parser_parse_ssa_name (c_parser *parse identifier constant string-literal + gimple-call-internal */ @@ -779,6 +825,9 @@ c_parser_gimple_postfix_expression (c_pa expr.original_code = STRING_CST; c_parser_consume_token (parser); break; + case CPP_DOT: + expr = c_parser_gimple_call_internal (parser); + break; case CPP_NAME: if (c_parser_peek_token (parser)->id_kind == C_ID_ID) { Index: gcc/testsuite/gcc.dg/gimplefe-28.c =================================================================== --- /dev/null 2018-04-20 16:19:46.369131350 +0100 +++ gcc/testsuite/gcc.dg/gimplefe-28.c 2018-05-17 09:17:58.757608747 +0100 @@ -0,0 +1,16 @@ +/* { dg-do compile { target sqrt_insn } } */ +/* { dg-options "-fgimple -O2" } */ + +double __GIMPLE +f1 (double x) +{ + double res; + res = .SQRT (x); + return res; +} + +void __GIMPLE +f2 (double x) +{ + .SQRT (x); // Dead code +} Index: gcc/testsuite/gcc.dg/asan/use-after-scope-9.c =================================================================== --- gcc/testsuite/gcc.dg/asan/use-after-scope-9.c 2017-02-23 19:54:08.000000000 +0000 +++ gcc/testsuite/gcc.dg/asan/use-after-scope-9.c 2018-05-17 09:17:58.757608747 +0100 @@ -17,7 +17,7 @@ main (int argc, char **argv) return *ptr; } -// { dg-final { scan-tree-dump-times "= ASAN_POISON \\(\\)" 1 "asan1" } } +// { dg-final { scan-tree-dump-times {= \.ASAN_POISON \(\)} 1 "asan1" } } // { dg-output "ERROR: AddressSanitizer: stack-use-after-scope on address.*(\n|\r\n|\r)" } // { dg-output "READ of size .*" } // { dg-output ".*'a' <== Memory access at offset \[0-9\]* is inside this variable.*" } Index: gcc/testsuite/gcc.dg/goacc/loop-processing-1.c =================================================================== --- gcc/testsuite/gcc.dg/goacc/loop-processing-1.c 2017-02-23 19:54:08.000000000 +0000 +++ gcc/testsuite/gcc.dg/goacc/loop-processing-1.c 2018-05-17 09:17:58.757608747 +0100 @@ -15,4 +15,4 @@ void vector_1 (int *ary, int size) } } -/* { dg-final { scan-tree-dump {OpenACC loops.*Loop 0\(0\).*Loop 24\(1\).*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_HEAD_MARK, 0, 1, 36\);.*Head-0:.*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_HEAD_MARK, 0, 1, 36\);.*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_FORK, \.data_dep\.[0-9_]+, 0\);.*Tail-0:.*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_TAIL_MARK, \.data_dep\.[0-9_]+, 1\);.*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_JOIN, \.data_dep\.[0-9_]+, 0\);.*Loop 6\(6\).*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_HEAD_MARK, 0, 2, 6\);.*Head-0:.*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_HEAD_MARK, 0, 2, 6\);.*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_FORK, \.data_dep\.[0-9_]+, 1\);.*Head-1:.*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_HEAD_MARK, \.data_dep\.[0-9_]+, 1\);.*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_FORK, \.data_dep\.[0-9_]+, 2\);.*Tail-1:.*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_TAIL_MARK, \.data_dep\.[0-9_]+, 2\);.*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_JOIN, \.data_dep\.[0-9_]+, 2\);.*Tail-0:.*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_TAIL_MARK, \.data_dep\.[0-9_]+, 1\);.*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_JOIN, \.data_dep\.[0-9_]+, 1\);} "oaccdevlow" } } */ +/* { dg-final { scan-tree-dump {OpenACC loops.*Loop 0\(0\).*Loop 24\(1\).*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_HEAD_MARK, 0, 1, 36\);.*Head-0:.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_HEAD_MARK, 0, 1, 36\);.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_FORK, \.data_dep\.[0-9_]+, 0\);.*Tail-0:.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_TAIL_MARK, \.data_dep\.[0-9_]+, 1\);.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_JOIN, \.data_dep\.[0-9_]+, 0\);.*Loop 6\(6\).*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_HEAD_MARK, 0, 2, 6\);.*Head-0:.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_HEAD_MARK, 0, 2, 6\);.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_FORK, \.data_dep\.[0-9_]+, 1\);.*Head-1:.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_HEAD_MARK, \.data_dep\.[0-9_]+, 1\);.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_FORK, \.data_dep\.[0-9_]+, 2\);.*Tail-1:.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_TAIL_MARK, \.data_dep\.[0-9_]+, 2\);.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_JOIN, \.data_dep\.[0-9_]+, 2\);.*Tail-0:.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_TAIL_MARK, \.data_dep\.[0-9_]+, 1\);.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_JOIN, \.data_dep\.[0-9_]+, 1\);} "oaccdevlow" } } */