From patchwork Thu May 17 08:25:24 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Sandiford X-Patchwork-Id: 915185 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-477806-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="x3OK20TM"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40mktj0r6rz9s3x for ; Thu, 17 May 2018 18:27:07 +1000 (AEST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:subject:date:message-id:mime-version:content-type :content-transfer-encoding; q=dns; s=default; b=LHkz3n04pSx4wQzY XDCPm1wESNrsET4wVGYUmyMN9jqh0UiD3RA/FfrwoU1OwUVcCLCo4JuIEigne2CR EqUTE49sTaaJkuvNissnIYuLwqS2tlOJAPSaeWwU+ktMlGl7rd4/tUZOZOUj1Xab R/i6gknvJERCDCaw7MR099fM3rg= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:subject:date:message-id:mime-version:content-type :content-transfer-encoding; s=default; bh=oKnJRW9t4Zhi8jbPbLCOnI nT1Uc=; b=x3OK20TMqHjWjeSDLckLqMmj7u5D5cHKIS6hK/AGuMOIwnm7grVIap A7c40ShPzgTzyIssuuHiQt2YuYjLrc/IWy4Apls857cXezOvfeK4vZ5lAaUn5za/ G2ov3RsVouNnKRRDS1PuKAmnL7cvykOVIBVkTY0CBf+Ax6Kf7ZCaw= Received: (qmail 120113 invoked by alias); 17 May 2018 08:25:34 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 120001 invoked by uid 89); 17 May 2018 08:25:33 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-10.8 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=UNIQUE, READ, route, *a X-HELO: mail-wm0-f49.google.com Received: from mail-wm0-f49.google.com (HELO mail-wm0-f49.google.com) (74.125.82.49) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 17 May 2018 08:25:29 +0000 Received: by mail-wm0-f49.google.com with SMTP id t11-v6so6934058wmt.0 for ; Thu, 17 May 2018 01:25:28 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:mail-followup-to:subject:date:message-id :user-agent:mime-version:content-transfer-encoding; bh=ggfNvBMdVUlXTaETc6/o2PQgxZ3SssR2arg5vYY9lyQ=; b=lBh7cj/VFXfPzsyCKnXpYqzJ7nTPfulVwJFjpkkXuJP55dWk3Vfmx6VxF6sbrg8OZ7 EggvhJdUCFgyOJvRRwISqefgvUziaL/EdAs62WFWfAVTJFvHv7Y6jjHF6jkAYBOBDMGb /Pid2rNfv2nevwH+HKbh6v693l3G3SexvviOPwuk1tQCkaTJcvrozyo4Yz2bSJbKXYJ3 pH/ZQzKSoI0f9HvIeaxb5Etuytry31+nMQNxxX2S4WjJPpcD8mOOz1ZibLWskSIWkHK1 DwG7NLgeymaeWpu3n9HrQJNqwgE70FJfm2TUC9jHDdXrirPTUcUaF+FpuXXx655SGHk4 yaag== X-Gm-Message-State: ALKqPwfQeAoPfLBhXv47/wYoDSpu4xky5DrEQgfce8v3thpEiEqSc+0O qbahePZ2vmsIbYp8XTAwMzy+ZEpRQn4= X-Google-Smtp-Source: AB8JxZpf+0bAjI4jHA3pn1e85yy9wWuH8AULzGSg2Ai3nKMIN/K7kyJ+Usc5TlIsABsayYJcdmHFBA== X-Received: by 2002:a1c:8350:: with SMTP id f77-v6mr1008890wmd.1.1526545526213; Thu, 17 May 2018 01:25:26 -0700 (PDT) Received: from localhost ([217.140.96.141]) by smtp.gmail.com with ESMTPSA id u20-v6sm4507746wru.33.2018.05.17.01.25.25 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 17 May 2018 01:25:25 -0700 (PDT) From: Richard Sandiford To: gcc-patches@gcc.gnu.org Mail-Followup-To: gcc-patches@gcc.gnu.org, richard.sandiford@linaro.org Subject: Gimple FE support for internal functions Date: Thu, 17 May 2018 09:25:24 +0100 Message-ID: <871seaofij.fsf@linaro.org> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.3 (gnu/linux) MIME-Version: 1.0 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 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 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 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" } } */