aboutsummaryrefslogtreecommitdiff
path: root/gcc/c/c-parser.c
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2017-01-24 17:07:36 +0000
committerDavid Malcolm <dmalcolm@gcc.gnu.org>2017-01-24 17:07:36 +0000
commitc2e843276310bfa2eb0fa40c6b54f530ac207a4f (patch)
tree3de19fa9c6316e31a6092997031d1600b7d4bfcc /gcc/c/c-parser.c
parent82b239054da5fcae11d01a055c277258cd73f235 (diff)
downloadgcc-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.c109
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"