From patchwork Tue Jan 10 02:38:15 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Malcolm X-Patchwork-Id: 713044 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org 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 3tyFhV6tXbz9sCM for ; Tue, 10 Jan 2017 13:04:42 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="Jfvg58cU"; dkim-atps=neutral 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:cc:subject:date:message-id:in-reply-to:references; q=dns; s= default; b=V/so7qfxsZThjN41Bqpx0YvaSCqBW3pwUqFC1SBDaXM1mC8ROaPnh aV9nrBW09jW3AEI2AUelVu/B/D3JveJ0v8sA3gH6vuuD0f/nwImcisNF9mCmamV7 fZQEqci9czLAMES0yLo6Y0cu0EjIm2glVlpP29wc1mh7R9liWVCPZY= 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:cc:subject:date:message-id:in-reply-to:references; s= default; bh=WFUDfKSiD5NoxX92k3CSGwQzyjQ=; b=Jfvg58cUjiRQpGQw4OK7 a/bSSq5VhAHeLHqOWTgpbbPY0ApAlgaicLuBVrG0TQ4w6cYvTcLhb4zmdK44wTGz e3/mtc3N6bRAF/yxRi+ivVPUn+Aq8NzpUyrwrOB23+T9fqK3VOuPJd0coCOgugSB iKZUBonBadFwVQy9GwQiz38= Received: (qmail 89588 invoked by alias); 10 Jan 2017 02:04:13 -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 88981 invoked by uid 89); 10 Jan 2017 02:04:13 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-5.1 required=5.0 tests=BAYES_00, RP_MATCHES_RCVD, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=circle, greatest, 6.9, GIMPLE X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 10 Jan 2017 02:04:11 +0000 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id D8ED537E64 for ; Tue, 10 Jan 2017 02:04:10 +0000 (UTC) Received: from c64.redhat.com (vpn-232-109.phx2.redhat.com [10.3.232.109]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id v0A248Y9022051; Mon, 9 Jan 2017 21:04:10 -0500 From: David Malcolm To: gcc-patches@gcc.gnu.org Cc: David Malcolm Subject: [PATCH 9a] Add "__RTL" to C frontend Date: Mon, 9 Jan 2017 21:38:15 -0500 Message-Id: <1484015904-32671-2-git-send-email-dmalcolm@redhat.com> In-Reply-To: <1484015904-32671-1-git-send-email-dmalcolm@redhat.com> References: <1484015904-32671-1-git-send-email-dmalcolm@redhat.com> X-IsSubscribed: yes This part of the patch adds the ability to tag a function with "__RTL", analogous to the "__GIMPLE" tag. gcc/c-family/ChangeLog: * c-common.c (c_common_reswords): Add "__RTL". * c-common.h (enum rid): Add RID_RTL. gcc/c/ChangeLog: * c-parser.c: Include "read-rtl-function.h" and "run-rtl-passes.h". (c_parser_declaration_or_fndef): Rename "gimple-pass-list" in grammar to gimple-or-rtl-pass-list. Add rtl-function-definition production. Update for renaming of field "gimple_pass" to "gimple_or_rtl_pass". If __RTL was seen, call c_parser_parse_rtl_body. Convert a timevar_push/pop pair to an auto_timevar, to cope with early exit. (c_parser_declspecs): Update RID_GIMPLE handling for renaming of field "gimple_pass" to "gimple_or_rtl_pass", and for renaming of c_parser_gimple_pass_list to c_parser_gimple_or_rtl_pass_list. Handle RID_RTL. (c_parser_parse_rtl_body): New function. * c-tree.h (enum c_declspec_word): Add cdw_rtl. (struct c_declspecs): Rename field "gimple_pass" to "gimple_or_rtl_pass". Add field "rtl_p". * gimple-parser.c (c_parser_gimple_pass_list): Rename to... (c_parser_gimple_or_rtl_pass_list): ...this, updating accordingly. * gimple-parser.h (c_parser_gimple_pass_list): Rename to... (c_parser_gimple_or_rtl_pass_list): ...this. gcc/ChangeLog: * function.h (struct function): Update comment for field "pass_startwith". --- gcc/c-family/c-common.c | 1 + gcc/c-family/c-common.h | 3 ++ gcc/c/c-parser.c | 109 +++++++++++++++++++++++++++++++++++++++++++++--- gcc/c/c-tree.h | 7 +++- gcc/c/gimple-parser.c | 8 ++-- gcc/c/gimple-parser.h | 2 +- gcc/function.h | 2 +- 7 files changed, 119 insertions(+), 13 deletions(-) diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index 15ead18..62b762b 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -437,6 +437,7 @@ const struct c_common_resword c_common_reswords[] = { "__volatile__", RID_VOLATILE, 0 }, { "__GIMPLE", RID_GIMPLE, D_CONLY }, { "__PHI", RID_PHI, D_CONLY }, + { "__RTL", RID_RTL, D_CONLY }, { "alignas", RID_ALIGNAS, D_CXXONLY | D_CXX11 | D_CXXWARN }, { "alignof", RID_ALIGNOF, D_CXXONLY | D_CXX11 | D_CXXWARN }, { "asm", RID_ASM, D_ASM }, diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h index b838869..fc2ce87 100644 --- a/gcc/c-family/c-common.h +++ b/gcc/c-family/c-common.h @@ -124,6 +124,9 @@ enum rid /* "__PHI", for parsing PHI function in GIMPLE FE. */ RID_PHI, + /* "__RTL", for the RTL-parsing extension to the C frontend. */ + RID_RTL, + /* C11 */ RID_ALIGNAS, RID_GENERIC, diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index 6d443da..bcfae86 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -62,6 +62,8 @@ along with GCC; see the file COPYING3. If not see #include "gcc-rich-location.h" #include "c-parser.h" #include "gimple-parser.h" +#include "read-rtl-function.h" +#include "run-rtl-passes.h" /* We need to walk over decls with incomplete struct/union/enum types after parsing the whole translation unit. @@ -1311,6 +1313,8 @@ static tree c_parser_array_notation (location_t, c_parser *, tree, tree); static tree c_parser_cilk_clause_vectorlength (c_parser *, tree, bool); static void c_parser_cilk_grainsize (c_parser *, bool *); +static void c_parser_parse_rtl_body (c_parser *parser, char *start_with_pass); + /* Parse a translation unit (C90 6.7, C99 6.9). translation-unit: @@ -1547,7 +1551,11 @@ static void c_finish_oacc_routine (struct oacc_routine_data *, tree, bool); GIMPLE: gimple-function-definition: - declaration-specifiers[opt] __GIMPLE (gimple-pass-list) declarator + declaration-specifiers[opt] __GIMPLE (gimple-or-rtl-pass-list) declarator + declaration-list[opt] compound-statement + + rtl-function-definition: + declaration-specifiers[opt] __RTL (gimple-or-rtl-pass-list) declarator declaration-list[opt] compound-statement */ static void @@ -2043,7 +2051,7 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, tv = TV_PARSE_INLINE; else tv = TV_PARSE_FUNC; - timevar_push (tv); + auto_timevar at (g_timer, tv); /* Parse old-style parameter declarations. ??? Attributes are not allowed to start declaration specifiers here because of a @@ -2075,12 +2083,28 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, function body as GIMPLE. */ if (specs->gimple_p) { - cfun->pass_startwith = specs->gimple_pass; + cfun->pass_startwith = specs->gimple_or_rtl_pass; bool saved = in_late_binary_op; in_late_binary_op = true; c_parser_parse_gimple_body (parser); in_late_binary_op = saved; } + /* Similarly, if it was marked with __RTL, use the RTL parser now, + consuming the function body. */ + else if (specs->rtl_p) + { + c_parser_parse_rtl_body (parser, specs->gimple_or_rtl_pass); + + /* Normally, store_parm_decls sets next_is_function_body, + anticipating a function body. We need a push_scope/pop_scope + pair to flush out this state, or subsequent function parsing + will go wrong. */ + push_scope (); + pop_scope (); + + finish_function (); + return; + } else { fnbody = c_parser_compound_statement (parser); @@ -2111,7 +2135,6 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, if (specs->gimple_p) DECL_SAVED_TREE (fndecl) = NULL_TREE; - timevar_pop (tv); break; } } @@ -2603,7 +2626,13 @@ c_parser_declspecs (c_parser *parser, struct c_declspecs *specs, c_parser_consume_token (parser); specs->gimple_p = true; specs->locations[cdw_gimple] = loc; - specs->gimple_pass = c_parser_gimple_pass_list (parser); + specs->gimple_or_rtl_pass = c_parser_gimple_or_rtl_pass_list (parser); + break; + case RID_RTL: + c_parser_consume_token (parser); + specs->rtl_p = true; + specs->locations[cdw_rtl] = loc; + specs->gimple_or_rtl_pass = c_parser_gimple_or_rtl_pass_list (parser); break; default: goto out; @@ -18281,4 +18310,74 @@ c_parser_array_notation (location_t loc, c_parser *parser, tree initial_index, return value_tree; } +/* Parse the body of a function declaration marked with "__RTL". + + The RTL parser works on the level of characters read from a + FILE *, whereas c_parser works at the level of tokens. + Square this circle by consuming all of the tokens up to and + including the closing brace, recording the start/end of the RTL + fragment, and reopening the file and re-reading the relevant + lines within the RTL parser. + + This requires the opening and closing braces of the C function + to be on separate lines from the RTL they wrap. + + Take ownership of START_WITH_PASS, if non-NULL. */ + +void +c_parser_parse_rtl_body (c_parser *parser, char *start_with_pass) +{ + if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>")) + { + free (start_with_pass); + return; + } + + location_t start_loc = c_parser_peek_token (parser)->location; + + /* Consume all tokens, up to the closing brace, handling + matching pairs of braces in the rtl dump. */ + int num_open_braces = 1; + while (1) + { + switch (c_parser_peek_token (parser)->type) + { + case CPP_OPEN_BRACE: + num_open_braces++; + break; + case CPP_CLOSE_BRACE: + if (--num_open_braces == 0) + goto found_closing_brace; + break; + case CPP_EOF: + error_at (start_loc, "no closing brace"); + free (start_with_pass); + return; + default: + break; + } + c_parser_consume_token (parser); + } + + found_closing_brace: + /* At the closing brace; record its location. */ + location_t end_loc = c_parser_peek_token (parser)->location; + + /* Consume the closing brace. */ + c_parser_consume_token (parser); + + /* Invoke the RTL parser. */ + if (!read_rtl_function_body_from_file_range (start_loc, end_loc)) + { + free (start_with_pass); + return; + } + + /* If a pass name was provided for START_WITH_PASS, run the backend + accordingly now, on the cfun created above, transferring + ownership of START_WITH_PASS. */ + if (start_with_pass) + run_rtl_passes (start_with_pass); +} + #include "gt-c-c-parser.h" diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h index 2604884..39cd3a6 100644 --- a/gcc/c/c-tree.h +++ b/gcc/c/c-tree.h @@ -268,6 +268,7 @@ enum c_declspec_word { cdw_alignas, cdw_address_space, cdw_gimple, + cdw_rtl, cdw_number_of_elements /* This one must always be the last enumerator. */ }; @@ -291,8 +292,8 @@ struct c_declspecs { NULL; attributes (possibly from multiple lists) will be passed separately. */ tree attrs; - /* The pass to start compiling a __GIMPLE function with. */ - char *gimple_pass; + /* The pass to start compiling a __GIMPLE or __RTL function with. */ + char *gimple_or_rtl_pass; /* The base-2 log of the greatest alignment required by an _Alignas specifier, in bytes, or -1 if no such specifiers with nonzero alignment. */ @@ -367,6 +368,8 @@ struct c_declspecs { BOOL_BITFIELD alignas_p : 1; /* Whether any __GIMPLE specifier was specified. */ BOOL_BITFIELD gimple_p : 1; + /* Whether any __RTL specifier was specified. */ + BOOL_BITFIELD rtl_p : 1; /* The address space that the declaration belongs to. */ addr_space_t address_space; }; diff --git a/gcc/c/gimple-parser.c b/gcc/c/gimple-parser.c index 291bbf6..e68905c 100644 --- a/gcc/c/gimple-parser.c +++ b/gcc/c/gimple-parser.c @@ -1008,18 +1008,18 @@ c_parser_gimple_label (c_parser *parser, gimple_seq *seq) return; } -/* Parse gimple pass list. +/* Parse gimple/RTL pass list. - gimple-pass-list: + gimple-or-rtl-pass-list: startwith("pass-name") */ char * -c_parser_gimple_pass_list (c_parser *parser) +c_parser_gimple_or_rtl_pass_list (c_parser *parser) { char *pass = NULL; - /* Accept __GIMPLE. */ + /* Accept __GIMPLE/__RTL. */ if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN)) return NULL; c_parser_consume_token (parser); diff --git a/gcc/c/gimple-parser.h b/gcc/c/gimple-parser.h index fd36ce1..85cf13a 100644 --- a/gcc/c/gimple-parser.h +++ b/gcc/c/gimple-parser.h @@ -22,6 +22,6 @@ along with GCC; see the file COPYING3. If not see /* Gimple parsing functions. */ extern void c_parser_parse_gimple_body (c_parser *); -extern char *c_parser_gimple_pass_list (c_parser *); +extern char *c_parser_gimple_or_rtl_pass_list (c_parser *); #endif diff --git a/gcc/function.h b/gcc/function.h index fb3cbbc..ec5a9a3 100644 --- a/gcc/function.h +++ b/gcc/function.h @@ -236,7 +236,7 @@ struct GTY(()) function { /* The loops in this function. */ struct loops *x_current_loops; - /* Filled by the GIMPLE FE, pass to start compilation with. */ + /* Filled by the GIMPLE and RTL FEs, pass to start compilation with. */ char *pass_startwith; /* The stack usage of this function. */