diff options
author | David Malcolm <dmalcolm@redhat.com> | 2017-01-24 17:07:36 +0000 |
---|---|---|
committer | David Malcolm <dmalcolm@gcc.gnu.org> | 2017-01-24 17:07:36 +0000 |
commit | c2e843276310bfa2eb0fa40c6b54f530ac207a4f (patch) | |
tree | 3de19fa9c6316e31a6092997031d1600b7d4bfcc /gcc/c/c-parser.c | |
parent | 82b239054da5fcae11d01a055c277258cd73f235 (diff) | |
download | gcc-c2e843276310bfa2eb0fa40c6b54f530ac207a4f.zip gcc-c2e843276310bfa2eb0fa40c6b54f530ac207a4f.tar.gz gcc-c2e843276310bfa2eb0fa40c6b54f530ac207a4f.tar.bz2 |
Add "__RTL" to cc1
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:
* cfg.c (original_copy_tables_initialized_p): New function.
* cfg.h (original_copy_tables_initialized_p): New decl.
* cfgrtl.c (relink_block_chain): Guard the call to
free_original_copy_tables with a call to
original_copy_tables_initialized_p.
* cgraph.h (symtab_node::native_rtl_p): New decl.
* cgraphunit.c (symtab_node::native_rtl_p): New function.
(symtab_node::needed_p): Don't assert for early assembly output
for __RTL functions.
(cgraph_node::finalize_function): Set "force_output" for __RTL
functions.
(cgraph_node::analyze): Bail out early for __RTL functions.
(analyze_functions): Update assertion to support __RTL functions.
(cgraph_node::expand): Bail out early for __RTL functions.
* final.c (rest_of_clean_state): Don't call delete_tree_ssa for
__RTL functions.
* function.h (struct function): Update comment for field
"pass_startwith".
* gimple-expr.c: Include "tree-pass.h".
(gimple_has_body_p): Return false for __RTL functions.
* Makefile.in (OBJS): Add run-rtl-passes.o.
* pass_manager.h (gcc::pass_manager::get_rest_of_compilation): New
accessor.
(gcc::pass_manager::get_clean_slate): New accessor.
* passes.c: Include "insn-addr.h".
(should_skip_pass_p): Add logging. Update logic for running
"expand" to be compatible with both __GIMPLE and __RTL. Guard
property-provider override so it is only done for gimple passes.
Don't skip dfinit.
(skip_pass): New function.
(execute_one_pass): Call skip_pass when skipping passes.
* read-md.c (md_reader::read_char): Support filtering
the input to a subset of line numbers.
(md_reader::md_reader): Initialize fields
m_first_line and m_last_line.
(md_reader::read_file_fragment): New function.
* read-md.h (md_reader::read_file_fragment): New decl.
(md_reader::m_first_line): New field.
(md_reader::m_last_line): New field.
* read-rtl-function.c (function_reader::create_function): Only
create cfun if it doesn't already exist. Set PROP_rtl on cfun's
curr_properties. Set DECL_INITIAL to a dummy block.
(read_rtl_function_body_from_file_range): New function.
* read-rtl-function.h (read_rtl_function_body_from_file_range):
New decl.
* run-rtl-passes.c: New file.
* run-rtl-passes.h: New file.
gcc/testsuite/ChangeLog:
* gcc.dg/rtl/aarch64/asr_div1.c: New test case.
* gcc.dg/rtl/aarch64/pr71779.c: New test case.
* gcc.dg/rtl/rtl.exp: New file.
* gcc.dg/rtl/test.c: New file.
* gcc.dg/rtl/truncated-rtl-file.c: New test case.
* gcc.dg/rtl/unknown-rtx-code.c: New test case.
* gcc.dg/rtl/x86_64/dfinit.c: New test case.
* gcc.dg/rtl/x86_64/different-structs.c: New test case.
* gcc.dg/rtl/x86_64/final.c: New test case.
* gcc.dg/rtl/x86_64/into-cfglayout.c: New test case.
* gcc.dg/rtl/x86_64/ira.c: New test case.
* gcc.dg/rtl/x86_64/pro_and_epilogue.c: New test case.
* gcc.dg/rtl/x86_64/test-multiple-fns.c: New test case.
* gcc.dg/rtl/x86_64/test-return-const.c.after-expand.c: New test case.
* gcc.dg/rtl/x86_64/test-return-const.c.before-fwprop.c: New test case.
* gcc.dg/rtl/x86_64/test-rtl.c: New test case.
* gcc.dg/rtl/x86_64/test_1.h: New file.
* gcc.dg/rtl/x86_64/times-two.c.after-expand.c: New test case.
* gcc.dg/rtl/x86_64/times-two.c.before-df.c: New test case.
* gcc.dg/rtl/x86_64/times-two.h: New file.
* gcc.dg/rtl/x86_64/vregs.c: New test case.
From-SVN: r244878
Diffstat (limited to 'gcc/c/c-parser.c')
-rw-r--r-- | gcc/c/c-parser.c | 109 |
1 files changed, 104 insertions, 5 deletions
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index a3504d3..5c152ab 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 @@ -2045,7 +2053,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 @@ -2077,12 +2085,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); @@ -2113,7 +2137,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; } } @@ -2605,7 +2628,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; @@ -18296,4 +18325,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" |