[CCing Prasad since this may be useful for his gimple FE work, by replacing "rtl" with "gimple" in the patch]
On Mon, 2016-05-09 at 11:44 +0200, Richard Biener wrote: > On Wed, May 4, 2016 at 10:49 PM, David Malcolm <dmalc...@redhat.com> > wrote: > > This patch kit introduces an RTL frontend, for the purpose > > of unit testing: primarly for unit testing of RTL passes, and > > possibly for unit testing of .md files. > > > > It's very much a work-in-progress; I'm posting it now to get > > feedback. [...snip...] > > * The RTL frontend doesn't have any knowledge of the name of the > > function, > > of parameters, types, locals, globals, etc. It creates a single > > function. > > The function is currently hardcoded to have this signature: > > > > int test_1 (int, int, int); > > > > since there's no syntax for specify otherwise, and we need to > > provide > > a FUNCTION_DECL tree when building a function object (by calling > > allocate_struct_function). > > > > * Similarly, there are no types beyond the built-in ones; all > > expressions > > are treated as being of type int. I suspect that this approach > > will be too simplistic when it comes to e.g. aliasing. > > To address this and the previous issue I suggest to implement the RTL > FE > similar to how I proposed the GIMPLE FE - piggy-back on the C FE and > thus > allow > > int __RTL foo (int a, int b) // gets you function decl and param > decls > { > (insn ...) > ... > > } > > int main() > { > if (foo (1) != 0) > abort (); > } > > That would also allow dg-do run testcases and not rely solely on > scanning > RTL dumps. The following is an attempt at implementing this, by adding a new "__RTL" keyword, and detecting it in the C frontend, switching to a custom parser for the function body. Does this look like the kind of thing you had in mind for the RTL and gimple "frontends"? Wiring this up to the existing RTL parser might be awkward: the existing RTL parser in read-md.c etc works at the level of characters (read_char and unread_char from a FILE *), whereas the C frontend is in terms of tokens. I have a patch that ports the RTL parser to using libcpp for location-tracking, and another that updates it to use libcpp for diagnostics. This adds more dependency on a build-time libcpp to the gen* tools. Both patches are currently messy. Potentially I could build on them and attempt to update the RTL parser further, to use libcpp's tokenizer. Does that general approach sound sane? In particular: - is it sane to eliminate errors.c in favor of building diagnostics*.c for the build machine as well as the host machine? - is it sane to rewrite the read-md.c/read-rtl.c code to a token-based approach, using libcpp? Alternatively, the shorter term approach would be to kludge in reading from a FILE * in read-md.c based on where the C parser has got to, with a hybrid of the two approaches (character-based vs token-based). Thoughts? Thanks Dave [...snip...] 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 (c_parser_declaration_or_fndef): Handle "__RTL" before a function name by calling c_parser_parse_rtl_body rather than c_parser_compound_statement. (c_parser_parse_rtl_body): New function. --- gcc/c-family/c-common.c | 1 + gcc/c-family/c-common.h | 3 +++ gcc/c/c-parser.c | 41 +++++++++++++++++++++++++++++++++++++++-- 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index d45bf1b..109bfeb 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -511,6 +511,7 @@ const struct c_common_resword c_common_reswords[] = { "__underlying_type", RID_UNDERLYING_TYPE, D_CXXONLY }, { "__volatile", RID_VOLATILE, 0 }, { "__volatile__", RID_VOLATILE, 0 }, + { "__RTL", RID_RTL, 0 }, { "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 1714284..7e5ff42 100644 --- a/gcc/c-family/c-common.h +++ b/gcc/c-family/c-common.h @@ -104,6 +104,9 @@ enum rid RID_DFLOAT32, RID_DFLOAT64, RID_DFLOAT128, RID_FRACT, RID_ACCUM, RID_AUTO_TYPE, RID_BUILTIN_CALL_WITH_STATIC_CHAIN, + /* "__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 701ab45..bf98d0a 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -1397,6 +1397,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); + /* Parse a translation unit (C90 6.7, C99 6.9). translation-unit: @@ -1638,6 +1640,7 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, tree all_prefix_attrs; bool diagnosed_no_specs = false; location_t here = c_parser_peek_token (parser)->location; + bool rtl_body_p = false; if (static_assert_ok && c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT)) @@ -1687,6 +1690,17 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, c_parser_skip_to_end_of_block_or_statement (parser); return; } + + if (c_parser_next_token_is (parser, CPP_KEYWORD)) + { + c_token *kw_token = c_parser_peek_token (parser); + if (kw_token->keyword == RID_RTL) + { + rtl_body_p = true; + c_parser_consume_token (parser); + } + } + finish_declspecs (specs); bool auto_type_p = specs->typespec_word == cts_auto_type; if (c_parser_next_token_is (parser, CPP_SEMICOLON)) @@ -2074,7 +2088,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 @@ -2102,6 +2116,13 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, oacc_routine_clauses, false, first, true); DECL_STRUCT_FUNCTION (current_function_decl)->function_start_locus = c_parser_peek_token (parser)->location; + if (rtl_body_p) + { + c_parser_parse_rtl_body (parser); + finish_function (); + return; + } + fnbody = c_parser_compound_statement (parser); if (flag_cilkplus && contains_array_notation_expr (fnbody)) fnbody = expand_array_notation_exprs (fnbody); @@ -2124,7 +2145,6 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, finish_function (); } - timevar_pop (tv); break; } } @@ -18055,4 +18075,21 @@ 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". */ + +void +c_parser_parse_rtl_body (c_parser *parser) +{ + if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>")) + return; + + location_t start_loc = c_parser_peek_token (parser)->location; + inform (start_loc, "start of RTL"); + + while (c_parser_next_token_is_not (parser, CPP_CLOSE_BRACE)) + c_parser_consume_token (parser); + + c_parser_consume_token (parser); +} + #include "gt-c-c-parser.h" -- 1.8.5.3