On Fri, Nov 11, 2016 at 10:15 PM, David Malcolm <dmalc...@redhat.com> wrote: > Changed in this version: > > * Rather than running just one pass, run *all* passes, but start at > the given pass; support for "dg-do run" tests that execute the > resulting code. > * Updated test cases to new "compact" dump format; more test cases; > use "dg-do run" in various places. > * Lots of bugfixing > > Links to previous versions: > https://gcc.gnu.org/ml/gcc-patches/2016-10/msg00263.html > https://gcc.gnu.org/ml/gcc-patches/2016-10/msg00500.html
Does running the RTL passes right from the parser work with -fsyntax-only? Doing it like __GIMPLE has the advantage of not exposing "rest_of_compilation", etc.. I'm now handling __GIMPLE from within declspecs (the GIMPLE FE stuff has been committed), it would be nice to match the __RTL piece here. > gcc/ChangeLog: > * Makefile.in (OBJS): Add run-rtl-passes.o. > > 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): In the "GNU extensions" part of > the leading comment, add an alternate production for > "function-definition", along with new "rtl-body-specifier" and > "rtl-body-pass-specifier" productions. Handle "__RTL" by calling > c_parser_parse_rtl_body. Convert a timevar_push/pop pair > to an auto_timevar, to cope with early exit. > (c_parser_parse_rtl_body): New function. > > gcc/ChangeLog: > * cfg.c (free_original_copy_tables): Remove assertion > on original_copy_bb_pool. How can that trigger? > * 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. > * emit-rtl.c (unshare_all_rtl_again): Wrap set_used_decls call > in check for DECL_INITIAL. You should simply set DECL_INITIAL of your function decl (make_node (BLOCK);). There's too much code assuming that is not NULL (and I've fixed quite a bit of code during stage1 not doing that). > * final.c (rest_of_clean_state): Don't call delete_tree_ssa for > _RTL functions. > * function.h (struct function): Add field "native_RTL". I wonder if you could simply use ->curr_properties & PROP_rtl? (and set that property during parsing, of course) > * gimple-expr.c (gimple_has_body_p): Return false for __RTL > functions. > * 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". > (execute_one_pass): Implement skipping of passes for functions > with pass_startwith set. > * 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::int m_last_line): New field. > * read-rtl-function.c (function_reader::create_function): Only create > cfun if it doesn't already exist. Set "native_RTL" on cfun. Set > DECL_INITIAL. > (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 file. > * gcc.dg/rtl/aarch64/pr71779.c: New file. > * gcc.dg/rtl/rtl.exp: New file. > * gcc.dg/rtl/test.c: New file. > * gcc.dg/rtl/unknown-rtx-code.c: New file. > * gcc.dg/rtl/x86_64/dfinit.c: New file. > * gcc.dg/rtl/x86_64/different-structs.c: New file. > * gcc.dg/rtl/x86_64/final.c: New file. > * gcc.dg/rtl/x86_64/into-cfglayout.c: New file. > * gcc.dg/rtl/x86_64/ira.c: New file. > * gcc.dg/rtl/x86_64/pro_and_epilogue.c: New file. > * gcc.dg/rtl/x86_64/test-return-const.c.after-expand.c: New file. > * gcc.dg/rtl/x86_64/test-return-const.c.before-fwprop.c: New file. > * gcc.dg/rtl/x86_64/test-rtl.c: New file. > * gcc.dg/rtl/x86_64/test_1.h: New file. > * gcc.dg/rtl/x86_64/times-two.c.after-expand.c: New file. > * gcc.dg/rtl/x86_64/times-two.c.before-df.c: New file. > * gcc.dg/rtl/x86_64/vregs.c: New file. > --- > gcc/Makefile.in | 1 + > gcc/c-family/c-common.c | 1 + > gcc/c-family/c-common.h | 3 + > gcc/c/c-parser.c | 122 ++++++++++++++++++- > gcc/cfg.c | 1 - > gcc/cgraph.h | 4 + > gcc/cgraphunit.c | 41 ++++++- > gcc/emit-rtl.c | 3 +- > gcc/final.c | 3 +- > gcc/function.h | 9 ++ > gcc/gimple-expr.c | 2 +- > gcc/pass_manager.h | 6 + > gcc/passes.c | 47 ++++++++ > gcc/read-md.c | 35 +++++- > gcc/read-md.h | 7 ++ > gcc/read-rtl-function.c | 83 ++++++++++--- > gcc/read-rtl-function.h | 3 + > gcc/run-rtl-passes.c | 85 +++++++++++++ > gcc/run-rtl-passes.h | 25 ++++ > gcc/testsuite/gcc.dg/rtl/aarch64/asr_div1.c | 41 +++++++ > gcc/testsuite/gcc.dg/rtl/aarch64/pr71779.c | 50 ++++++++ > gcc/testsuite/gcc.dg/rtl/rtl.exp | 41 +++++++ > gcc/testsuite/gcc.dg/rtl/test.c | 31 +++++ > gcc/testsuite/gcc.dg/rtl/unknown-rtx-code.c | 8 ++ > gcc/testsuite/gcc.dg/rtl/x86_64/dfinit.c | 116 ++++++++++++++++++ > .../gcc.dg/rtl/x86_64/different-structs.c | 81 +++++++++++++ > gcc/testsuite/gcc.dg/rtl/x86_64/final.c | 133 > +++++++++++++++++++++ > gcc/testsuite/gcc.dg/rtl/x86_64/into-cfglayout.c | 117 ++++++++++++++++++ > gcc/testsuite/gcc.dg/rtl/x86_64/ira.c | 111 +++++++++++++++++ > gcc/testsuite/gcc.dg/rtl/x86_64/pro_and_epilogue.c | 110 +++++++++++++++++ > .../rtl/x86_64/test-return-const.c.after-expand.c | 39 ++++++ > .../rtl/x86_64/test-return-const.c.before-fwprop.c | 42 +++++++ > gcc/testsuite/gcc.dg/rtl/x86_64/test-rtl.c | 101 ++++++++++++++++ > gcc/testsuite/gcc.dg/rtl/x86_64/test_1.h | 16 +++ > .../gcc.dg/rtl/x86_64/times-two.c.after-expand.c | 70 +++++++++++ > .../gcc.dg/rtl/x86_64/times-two.c.before-df.c | 54 +++++++++ > gcc/testsuite/gcc.dg/rtl/x86_64/vregs.c | 112 +++++++++++++++++ > 37 files changed, 1727 insertions(+), 27 deletions(-) > create mode 100644 gcc/run-rtl-passes.c > create mode 100644 gcc/run-rtl-passes.h > create mode 100644 gcc/testsuite/gcc.dg/rtl/aarch64/asr_div1.c > create mode 100644 gcc/testsuite/gcc.dg/rtl/aarch64/pr71779.c > create mode 100644 gcc/testsuite/gcc.dg/rtl/rtl.exp > create mode 100644 gcc/testsuite/gcc.dg/rtl/test.c > create mode 100644 gcc/testsuite/gcc.dg/rtl/unknown-rtx-code.c > create mode 100644 gcc/testsuite/gcc.dg/rtl/x86_64/dfinit.c > create mode 100644 gcc/testsuite/gcc.dg/rtl/x86_64/different-structs.c > create mode 100644 gcc/testsuite/gcc.dg/rtl/x86_64/final.c > create mode 100644 gcc/testsuite/gcc.dg/rtl/x86_64/into-cfglayout.c > create mode 100644 gcc/testsuite/gcc.dg/rtl/x86_64/ira.c > create mode 100644 gcc/testsuite/gcc.dg/rtl/x86_64/pro_and_epilogue.c > create mode 100644 > gcc/testsuite/gcc.dg/rtl/x86_64/test-return-const.c.after-expand.c > create mode 100644 > gcc/testsuite/gcc.dg/rtl/x86_64/test-return-const.c.before-fwprop.c > create mode 100644 gcc/testsuite/gcc.dg/rtl/x86_64/test-rtl.c > create mode 100644 gcc/testsuite/gcc.dg/rtl/x86_64/test_1.h > create mode 100644 gcc/testsuite/gcc.dg/rtl/x86_64/times-two.c.after-expand.c > create mode 100644 gcc/testsuite/gcc.dg/rtl/x86_64/times-two.c.before-df.c > create mode 100644 gcc/testsuite/gcc.dg/rtl/x86_64/vregs.c > > diff --git a/gcc/Makefile.in b/gcc/Makefile.in > index 73d12dc..14ffb96 100644 > --- a/gcc/Makefile.in > +++ b/gcc/Makefile.in > @@ -1429,6 +1429,7 @@ OBJS = \ > rtlhash.o \ > rtlanal.o \ > rtlhooks.o \ > + run-rtl-passes.o \ > sbitmap.o \ > sched-deps.o \ > sched-ebb.o \ > diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c > index 307862b..573ca7a 100644 > --- a/gcc/c-family/c-common.c > +++ b/gcc/c-family/c-common.c > @@ -435,6 +435,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 547bab2..5e6882e 100644 > --- a/gcc/c-family/c-common.h > +++ b/gcc/c-family/c-common.h > @@ -118,6 +118,9 @@ enum rid > > 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 6bc42da..e6e86ec 100644 > --- a/gcc/c/c-parser.c > +++ b/gcc/c/c-parser.c > @@ -59,6 +59,8 @@ along with GCC; see the file COPYING3. If not see > #include "gimple-expr.h" > #include "context.h" > #include "gcc-rich-location.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. > @@ -1421,6 +1423,9 @@ 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, > + const char *start_with_pass); > + > /* Parse a translation unit (C90 6.7, C99 6.9). > > translation-unit: > @@ -1624,6 +1629,16 @@ static void c_finish_oacc_routine (struct > oacc_routine_data *, tree, bool); > declaration-specifiers declarator declaration-list[opt] > compound-statement > > + function-definition: > + declaration-specifiers rtl-body-specifier declarator > declaration-list[opt] > + compound-statement > + > + rtl-body-specifier: > + __RTL rtl-body-pass-specifier[opt] > + > + rtl-body-pass-specifier: > + ( string ) > + > attribute ; > > Objective-C: > @@ -1668,6 +1683,8 @@ 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; > + const char *start_with_pass = NULL; > > if (static_assert_ok > && c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT)) > @@ -1752,6 +1769,33 @@ c_parser_declaration_or_fndef (c_parser *parser, bool > fndef_ok, > c_parser_skip_to_end_of_block_or_statement (parser); > return; > } > + > + /* Handle GNU extension rtl-body-specifier by detecting "__RTL". */ > + if (c_parser_next_token_is_keyword (parser, RID_RTL)) > + { > + rtl_body_p = true; > + c_parser_consume_token (parser); > + > + /* Handle the optional rtl-body-pass-specifier: parens wrapping > + a string, giving a pass name. */ > + if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)) > + { > + c_parser_consume_token (parser); > + c_token *tok = c_parser_peek_token (parser); > + if (tok->type != CPP_STRING) > + { > + c_parser_error (parser, "expected string"); > + c_parser_skip_to_end_of_block_or_statement (parser); > + return; > + } > + gcc_assert (TREE_CODE (tok->value) == STRING_CST); > + start_with_pass = TREE_STRING_POINTER (tok->value); > + c_parser_consume_token (parser); > + > + c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"); > + } > + } > + > finish_declspecs (specs); > bool auto_type_p = specs->typespec_word == cts_auto_type; > if (c_parser_next_token_is (parser, CPP_SEMICOLON)) > @@ -2146,7 +2190,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 > @@ -2173,6 +2217,24 @@ c_parser_declaration_or_fndef (c_parser *parser, bool > fndef_ok, > c_finish_oacc_routine (oacc_routine_data, current_function_decl, > true); > DECL_STRUCT_FUNCTION (current_function_decl)->function_start_locus > = c_parser_peek_token (parser)->location; > + > + /* If we had an rtl-body-specifier, use the RTL parser now, > + consuming the function body. */ > + if (rtl_body_p) > + { > + c_parser_parse_rtl_body (parser, start_with_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; > + } > + > fnbody = c_parser_compound_statement (parser); > if (flag_cilkplus && contains_array_notation_expr (fnbody)) > fnbody = expand_array_notation_exprs (fnbody); > @@ -2195,7 +2257,6 @@ c_parser_declaration_or_fndef (c_parser *parser, bool > fndef_ok, > finish_function (); > } > > - timevar_pop (tv); > break; > } > } > @@ -18313,4 +18374,61 @@ 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. */ > + > +void > +c_parser_parse_rtl_body (c_parser *parser, const char *start_with_pass) > +{ > + if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>")) > + 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; > + 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)) > + return; > + > + /* If a pass name was provided for START_WITH_PASS, run the backend > + accordingly now, on the cfun created above. */ > + if (start_with_pass) > + run_rtl_passes (start_with_pass); > +} > + > #include "gt-c-c-parser.h" > diff --git a/gcc/cfg.c b/gcc/cfg.c > index 6604b02..26a68c1 100644 > --- a/gcc/cfg.c > +++ b/gcc/cfg.c > @@ -1083,7 +1083,6 @@ reset_original_copy_tables (void) > void > free_original_copy_tables (void) > { > - gcc_assert (original_copy_bb_pool); > delete bb_copy; > bb_copy = NULL; > delete bb_original; > diff --git a/gcc/cgraph.h b/gcc/cgraph.h > index cc730d2..79e33da 100644 > --- a/gcc/cgraph.h > +++ b/gcc/cgraph.h > @@ -328,6 +328,10 @@ public: > configury. This function is used just during symbol creation. */ > bool needed_p (void); > > + /* Return true if this symbol is a function from the C frontend specified > + directly in RTL form (with "__RTL"). */ > + bool native_rtl_p () const; > + > /* Return true when there are references to the node. */ > bool referred_to_p (bool include_self = true); > > diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c > index e315a77..956562e 100644 > --- a/gcc/cgraphunit.c > +++ b/gcc/cgraphunit.c > @@ -217,6 +217,19 @@ static void handle_alias_pairs (void); > /* Used for vtable lookup in thunk adjusting. */ > static GTY (()) tree vtable_entry_type; > > +/* Return true if this symbol is a function from the C frontend specified > + directly in RTL form (with "__RTL"). */ > + > +bool > +symtab_node::native_rtl_p () const > +{ > + if (TREE_CODE (decl) != FUNCTION_DECL) > + return false; > + if (!DECL_STRUCT_FUNCTION (decl)) > + return false; > + return DECL_STRUCT_FUNCTION (decl)->native_RTL; > +} > + > /* Determine if symbol declaration is needed. That is, visible to something > either outside this translation unit, something magic in the system > configury */ > @@ -225,8 +238,10 @@ symtab_node::needed_p (void) > { > /* Double check that no one output the function into assembly file > early. */ > - gcc_checking_assert (!DECL_ASSEMBLER_NAME_SET_P (decl) > - || !TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME > (decl))); > + if (!native_rtl_p ()) > + gcc_checking_assert > + (!DECL_ASSEMBLER_NAME_SET_P (decl) > + || !TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))); > > if (!definition) > return false; > @@ -435,6 +450,14 @@ cgraph_node::finalize_function (tree decl, bool > no_collect) > && !DECL_DISREGARD_INLINE_LIMITS (decl)) > node->force_output = 1; > > + /* __RTL functions were already output as soon as they were parsed (due > + to the large amount of global state in the backend). > + Mark such functions as "force_output" to reflect the fact that they > + will be in the asm file when considering the symbols they reference. > + The attempt to output them later on will bail out immediately. */ > + if (node->native_rtl_p ()) > + node->force_output = 1; > + > /* When not optimizing, also output the static functions. (see > PR24561), but don't do so for always_inline functions, functions > declared inline and nested functions. These were optimized out > @@ -568,6 +591,12 @@ cgraph_node::add_new_function (tree fndecl, bool lowered) > void > cgraph_node::analyze (void) > { > + if (native_rtl_p ()) > + { > + analyzed = true; > + return; > + } > + > tree decl = this->decl; > location_t saved_loc = input_location; > input_location = DECL_SOURCE_LOCATION (decl); > @@ -1226,7 +1255,8 @@ analyze_functions (bool first_time) > > gcc_assert (!cnode->definition || cnode->thunk.thunk_p > || cnode->alias > - || gimple_has_body_p (decl)); > + || gimple_has_body_p (decl) > + || cnode->native_rtl_p ()); > gcc_assert (cnode->analyzed == cnode->definition); > } > node->aux = NULL; > @@ -1965,6 +1995,11 @@ cgraph_node::expand (void) > /* We ought to not compile any inline clones. */ > gcc_assert (!global.inlined_to); > > + /* __RTL functions are compiled as soon as they are parsed, so don't > + do it again. */ > + if (native_rtl_p ()) > + return; > + > announce_function (decl); > process = 0; > gcc_assert (lowered); > diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c > index 179a91f..8039742 100644 > --- a/gcc/emit-rtl.c > +++ b/gcc/emit-rtl.c > @@ -2672,7 +2672,8 @@ unshare_all_rtl_again (rtx_insn *insn) > } > > /* Make sure that virtual stack slots are not shared. */ > - set_used_decls (DECL_INITIAL (cfun->decl)); > + if (DECL_INITIAL (cfun->decl)) > + set_used_decls (DECL_INITIAL (cfun->decl)); > > /* Make sure that virtual parameters are not shared. */ > for (decl = DECL_ARGUMENTS (cfun->decl); decl; decl = DECL_CHAIN (decl)) > diff --git a/gcc/final.c b/gcc/final.c > index 5709d0e..97e2e1a 100644 > --- a/gcc/final.c > +++ b/gcc/final.c > @@ -4701,7 +4701,8 @@ rest_of_clean_state (void) > > free_bb_for_insn (); > > - delete_tree_ssa (cfun); > + if (!cfun->native_RTL) > + delete_tree_ssa (cfun); > > /* We can reduce stack alignment on call site only when we are sure that > the function body just produced will be actually used in the final > diff --git a/gcc/function.h b/gcc/function.h > index 9fe479c..2263f30 100644 > --- a/gcc/function.h > +++ b/gcc/function.h > @@ -236,6 +236,9 @@ struct GTY(()) function { > /* The loops in this function. */ > struct loops *x_current_loops; > > + /* Filled by the GIMPLE FE, pass to start compilation with. */ > + const char *pass_startwith; > + > /* The stack usage of this function. */ > struct stack_usage *su; > > @@ -384,6 +387,12 @@ struct GTY(()) function { > > /* Set when the tail call has been identified. */ > unsigned int tail_call_marked : 1; > + > + /* Nonzero if the the current function was specified in RTL form using the > + C frontend's "__RTL" syntax. This initializes global RTL state, and so > + such functions must be compiled immediately, rather than under the > + control of the callgraph. */ > + unsigned int native_RTL : 1; > }; > > /* Add the decl D to the local_decls list of FUN. */ > diff --git a/gcc/gimple-expr.c b/gcc/gimple-expr.c > index de5cce1..3a06888 100644 > --- a/gcc/gimple-expr.c > +++ b/gcc/gimple-expr.c > @@ -323,7 +323,7 @@ bool > gimple_has_body_p (tree fndecl) > { > struct function *fn = DECL_STRUCT_FUNCTION (fndecl); > - return (gimple_body (fndecl) || (fn && fn->cfg)); > + return (gimple_body (fndecl) || (fn && fn->cfg && !fn->native_RTL)); > } > > /* Return a printable name for symbol DECL. */ > diff --git a/gcc/pass_manager.h b/gcc/pass_manager.h > index 464e25f..7278d97 100644 > --- a/gcc/pass_manager.h > +++ b/gcc/pass_manager.h > @@ -82,6 +82,12 @@ public: > > opt_pass *get_pass_by_name (const char *name); > > + opt_pass *get_rest_of_compilation () const > + { > + return pass_rest_of_compilation_1; > + } > + opt_pass *get_clean_slate () const { return pass_clean_state_1; } > + > public: > /* The root of the compilation pass tree, once constructed. */ > opt_pass *all_passes; > diff --git a/gcc/passes.c b/gcc/passes.c > index e78f9ed..54029f5 100644 > --- a/gcc/passes.c > +++ b/gcc/passes.c > @@ -59,6 +59,7 @@ along with GCC; see the file COPYING3. If not see > #include "cfgrtl.h" > #include "tree-ssa-live.h" /* For remove_unused_locals. */ > #include "tree-cfgcleanup.h" > +#include "insn-addr.h" /* for INSN_ADDRESSES_ALLOC. */ > > using namespace gcc; > > @@ -2313,6 +2314,52 @@ execute_one_pass (opt_pass *pass) > return false; > } > > + /* For skipping passes until startwith pass */ > + if (cfun > + && cfun->pass_startwith) > + { > + if (strcmp (pass->name, cfun->pass_startwith) == 0) > + { > + if (!quiet_flag) > + fprintf (stderr, "found starting pass: %s\n", > cfun->pass_startwith); > + cfun->pass_startwith = NULL; > + } > + else > + { > + /* Don't skip df init; later passes need it. */ > + if (strstr (pass->name, "dfinit") == NULL) > + { > + if (!quiet_flag) > + fprintf (stderr, "skipping pass: %s\n", pass->name); > + > + /* Pass "reload" sets the global "reload_completed", and many > + things depend on this (e.g. instructions in .md files). */ > + if (strcmp (pass->name, "reload") == 0) > + reload_completed = 1; > + > + /* The INSN_ADDRESSES vec is normally set up by > + shorten_branches; set it up for the benefit of passes that > + run after this. */ > + if (strcmp (pass->name, "shorten") == 0) > + INSN_ADDRESSES_ALLOC (get_max_uid ()); > + > + /* Update the cfg hooks as appropriate. */ > + if (strcmp (pass->name, "into_cfglayout") == 0) > + { > + cfg_layout_rtl_register_cfg_hooks (); > + cfun->curr_properties |= PROP_cfglayout; > + } > + if (strcmp (pass->name, "outof_cfglayout") == 0) > + { > + rtl_register_cfg_hooks (); > + cfun->curr_properties &= ~PROP_cfglayout; > + } > + > + return true; > + } > + } > + } > + > /* Pass execution event trigger: useful to identify passes being > executed. */ > invoke_plugin_callbacks (PLUGIN_PASS_EXECUTION, pass); > diff --git a/gcc/read-md.c b/gcc/read-md.c > index a8462a6..25bc3c4 100644 > --- a/gcc/read-md.c > +++ b/gcc/read-md.c > @@ -399,6 +399,16 @@ md_reader::read_char (void) > else > m_read_md_colno++; > > + /* If we're filtering lines, treat everything before the range of > + interest as a space, and as EOF for everything after. */ > + if (m_first_line && m_last_line) > + { > + if (m_read_md_lineno < m_first_line) > + return ' '; > + if (m_read_md_lineno > m_last_line) > + return EOF; > + } > + > return ch; > } > > @@ -981,7 +991,9 @@ md_reader::md_reader (bool compact) > m_read_md_lineno (0), > m_read_md_colno (0), > m_first_dir_md_include (NULL), > - m_last_dir_md_include_ptr (&m_first_dir_md_include) > + m_last_dir_md_include_ptr (&m_first_dir_md_include), > + m_first_line (0), > + m_last_line (0) > { > /* Set the global singleton pointer. */ > md_reader_ptr = this; > @@ -1284,6 +1296,27 @@ md_reader::read_md_files (int argc, const char **argv, > return !have_error; > } > > + > +/* Read FILENAME, filtering to just the given lines. */ > + > +bool > +md_reader::read_file_fragment (const char *filename, > + int first_line, > + int last_line) > +{ > + m_read_md_filename = filename; > + m_read_md_file = fopen (m_read_md_filename, "r"); > + if (m_read_md_file == 0) > + { > + perror (m_read_md_filename); > + return false; > + } > + m_first_line = first_line; > + m_last_line = last_line; > + handle_toplevel_file (); > + return !have_error; > +} > + > /* class noop_reader : public md_reader */ > > /* A dummy implementation which skips unknown directives. */ > diff --git a/gcc/read-md.h b/gcc/read-md.h > index 1be0f5a..06be3ec 100644 > --- a/gcc/read-md.h > +++ b/gcc/read-md.h > @@ -98,6 +98,9 @@ class md_reader > virtual ~md_reader (); > > bool read_md_files (int, const char **, bool (*) (const char *)); > + bool read_file_fragment (const char *filename, > + int first_line, > + int last_line); > > /* A hook that handles a single .md-file directive, up to but not > including the closing ')'. It takes two arguments: the file position > @@ -232,6 +235,10 @@ class md_reader > > /* A table of enum_type structures, hashed by name. */ > htab_t m_enum_types; > + > + /* If non-zero, filter the input to just this subset of lines. */ > + int m_first_line; > + int m_last_line; > }; > > /* Global singleton; constrast with rtx_reader_ptr below. */ > diff --git a/gcc/read-rtl-function.c b/gcc/read-rtl-function.c > index ff6c808..6c4b282 100644 > --- a/gcc/read-rtl-function.c > +++ b/gcc/read-rtl-function.c > @@ -489,23 +489,38 @@ function_reader::create_function () > else > rtl_register_cfg_hooks (); > > - /* Create cfun. */ > - tree fn_name = get_identifier (m_name ? m_name : "test_1"); > - tree int_type = integer_type_node; > - tree return_type = int_type; > - tree arg_types[3] = {int_type, int_type, int_type}; > - tree fn_type = build_function_type_array (return_type, 3, arg_types); > - tree fndecl = build_decl_stat (UNKNOWN_LOCATION, FUNCTION_DECL, fn_name, > - fn_type); > - tree resdecl = build_decl (UNKNOWN_LOCATION, RESULT_DECL, NULL_TREE, > - return_type); > - DECL_ARTIFICIAL (resdecl) = 1; > - DECL_IGNORED_P (resdecl) = 1; > - DECL_RESULT (fndecl) = resdecl; > - allocate_struct_function (fndecl, false); > - /* This sets cfun. */ > - > - current_function_decl = fndecl; > + /* When run from selftests or "rtl1", cfun is NULL. > + When run from "cc1" for a C function tagged with __RTL, cfun is the > + tagged function. */ > + if (!cfun) > + { > + tree fn_name = get_identifier (m_name ? m_name : "test_1"); > + tree int_type = integer_type_node; > + tree return_type = int_type; > + tree arg_types[3] = {int_type, int_type, int_type}; > + tree fn_type = build_function_type_array (return_type, 3, arg_types); > + tree fndecl = build_decl_stat (UNKNOWN_LOCATION, FUNCTION_DECL, > fn_name, > + fn_type); > + tree resdecl = build_decl (UNKNOWN_LOCATION, RESULT_DECL, NULL_TREE, > + return_type); > + DECL_ARTIFICIAL (resdecl) = 1; > + DECL_IGNORED_P (resdecl) = 1; > + DECL_RESULT (fndecl) = resdecl; > + allocate_struct_function (fndecl, false); > + /* This sets cfun. */ > + current_function_decl = fndecl; > + } > + > + gcc_assert (cfun); > + gcc_assert (current_function_decl); > + tree fndecl = current_function_decl; > + > + /* Mark this function as being specified as __RTL. */ > + cfun->native_RTL = 1; > + > + /* cc1 normally inits DECL_INITIAL (fndecl) to be error_mark_node. > + Ensure it is NULL_TREE. */ > + DECL_INITIAL (fndecl) = NULL_TREE; > > cfun->curr_properties = (PROP_cfg | PROP_rtl); > > @@ -1615,6 +1630,40 @@ read_rtl_function_body (int argc, const char **argv, > return true; > } > > +/* Run the RTL dump parser on the range of lines between START_LOC and > + END_LOC (including those lines). */ > + > +bool > +read_rtl_function_body_from_file_range (location_t start_loc, > + location_t end_loc) > +{ > + expanded_location exploc_start = expand_location (start_loc); > + expanded_location exploc_end = expand_location (end_loc); > + > + if (exploc_start.file != exploc_end.file) > + { > + error_at (end_loc, "start/end of RTL fragment are in different files"); > + return false; > + } > + if (exploc_start.line >= exploc_end.line) > + { > + error_at (end_loc, > + "start of RTL fragment must be on an earlier line than end"); > + return false; > + } > + > + initialize_rtl (); > + init_emit (); > + init_varasm_status (); > + > + function_reader reader (NULL); > + if (!reader.read_file_fragment (exploc_start.file, exploc_start.line, > + exploc_end.line - 1)) > + return false; > + > + return true; > +} > + > #if CHECKING_P > > namespace selftest { > diff --git a/gcc/read-rtl-function.h b/gcc/read-rtl-function.h > index 036fcce..d5d12ab 100644 > --- a/gcc/read-rtl-function.h > +++ b/gcc/read-rtl-function.h > @@ -33,4 +33,7 @@ extern bool read_rtl_function_body (int argc, const char > **argv, > bool (*parse_opt) (const char *), > function_reader_policy *policy); > > +extern bool read_rtl_function_body_from_file_range (location_t start_loc, > + location_t end_loc); > + > #endif /* GCC_READ_RTL_FUNCTION_H */ > diff --git a/gcc/run-rtl-passes.c b/gcc/run-rtl-passes.c > new file mode 100644 > index 0000000..2bca929 > --- /dev/null > +++ b/gcc/run-rtl-passes.c > @@ -0,0 +1,85 @@ > +/* run-rtl-passes.c - Run just one RTL pass > + Copyright (C) 2016 Free Software Foundation, Inc. > + > +This file is part of GCC. > + > +GCC is free software; you can redistribute it and/or modify it under > +the terms of the GNU General Public License as published by the Free > +Software Foundation; either version 3, or (at your option) any later > +version. > + > +GCC is distributed in the hope that it will be useful, but WITHOUT ANY > +WARRANTY; without even the implied warranty of MERCHANTABILITY or > +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License > +for more details. > + > +You should have received a copy of the GNU General Public License > +along with GCC; see the file COPYING3. If not see > +<http://www.gnu.org/licenses/>. */ > + > +#include "config.h" > +#include "system.h" > +#include "coretypes.h" > +#include "target.h" > +#include "tree.h" > +#include "gimple-expr.h" > +#include "diagnostic.h" > +#include "opts.h" > +#include "fold-const.h" > +#include "gimplify.h" > +#include "stor-layout.h" > +#include "debug.h" > +#include "convert.h" > +#include "langhooks.h" > +#include "langhooks-def.h" > +#include "common/common-target.h" > +#include "read-md.h" > +#include <mpfr.h> > +#include "rtl.h" > +#include "cfghooks.h" > +#include "stringpool.h" > +#include "function.h" > +#include "tree-cfg.h" > +#include "cfg.h" > +#include "basic-block.h" > +#include "cfgrtl.h" > +#include "memmodel.h" > +#include "emit-rtl.h" > +#include "cgraph.h" > +#include "tree-pass.h" > +#include "context.h" > +#include "pass_manager.h" > +#include "bitmap.h" > +#include "df.h" > +#include "regs.h" > +#include "insn-attr-common.h" /* for INSN_SCHEDULING. */ > +#include "insn-attr.h" /* for init_sched_attrs. */ > +#include "run-rtl-passes.h" > + > +/* Run the backend passes, starting at the given pass. */ > + > +void > +run_rtl_passes (const char *initial_pass_name) > +{ > + cfun->pass_startwith = initial_pass_name; > + max_regno = max_reg_num (); > + > + /* Pass "expand" noemally sets this up. */ > +#ifdef INSN_SCHEDULING > + init_sched_attrs (); > +#endif > + > + bitmap_obstack_initialize (NULL); > + bitmap_obstack_initialize (®_obstack); > + > + opt_pass *rest_of_compilation > + = g->get_passes ()->get_rest_of_compilation (); > + gcc_assert (rest_of_compilation); > + execute_pass_list (cfun, rest_of_compilation); > + > + opt_pass *clean_slate = g->get_passes ()->get_clean_slate (); > + gcc_assert (clean_slate); > + execute_pass_list (cfun, clean_slate); > + > + bitmap_obstack_release (®_obstack); > +} > diff --git a/gcc/run-rtl-passes.h b/gcc/run-rtl-passes.h > new file mode 100644 > index 0000000..14ea8ea > --- /dev/null > +++ b/gcc/run-rtl-passes.h > @@ -0,0 +1,25 @@ > +/* run-rtl-passes.h - Run a subset of the RTL passes > + Copyright (C) 2016 Free Software Foundation, Inc. > + > +This file is part of GCC. > + > +GCC is free software; you can redistribute it and/or modify it under > +the terms of the GNU General Public License as published by the Free > +Software Foundation; either version 3, or (at your option) any later > +version. > + > +GCC is distributed in the hope that it will be useful, but WITHOUT ANY > +WARRANTY; without even the implied warranty of MERCHANTABILITY or > +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License > +for more details. > + > +You should have received a copy of the GNU General Public License > +along with GCC; see the file COPYING3. If not see > +<http://www.gnu.org/licenses/>. */ > + > +#ifndef GCC_RUN_RTL_PASSES_H > +#define GCC_RUN_RTL_PASSES_H > + > +extern void run_rtl_passes (const char *initial_pass_name); > + > +#endif /* GCC_RUN_RTL_PASSES_H */ > diff --git a/gcc/testsuite/gcc.dg/rtl/aarch64/asr_div1.c > b/gcc/testsuite/gcc.dg/rtl/aarch64/asr_div1.c > new file mode 100644 > index 0000000..9123651 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/rtl/aarch64/asr_div1.c > @@ -0,0 +1,41 @@ > +/* { dg-do compile { target aarch64-*-* } } */ > +/* { dg-options "-mtune=cortex-a53 -fdump-rtl-combine -O2" } */ > + > +/* Taken from > + gcc/testsuite/gcc.dg/asr_div1.c -O2 -fdump-rtl-all -mtune=cortex-a53 > + for aarch64, hand editing to the new format. */ > + > +int __RTL("combine") f1 (int n) > +{ > +(function "f1" > + (param "n" > + (DECL_RTL (reg/v:SI %1 [ n ])) > + (DECL_RTL_INCOMING (reg:SI x0 [ n ])) > + ) ;; param "n" > + (insn-chain > + (block 2 > + (edge-from entry (flags "FALLTHRU")) > + (cnote 6 [bb 2] NOTE_INSN_BASIC_BLOCK) > + (cinsn 8 (set (reg:DI %2) > + (lshiftrt:DI (reg:DI %0) > + (const_int 32))) > + "../../src/gcc/testsuite/gcc.dg/asr_div1.c":14 > + (expr_list:REG_DEAD (reg:DI %0))) > + (cinsn 9 (set (reg:SI %1) > + (ashiftrt:SI (subreg:SI (reg:DI %2) 0) > + (const_int 3))) > + "../../src/gcc/testsuite/gcc.dg/asr_div1.c":14 > + (expr_list:REG_DEAD (reg:DI %2))) > + > + ;; Extra insn, to avoid all of the above from being deleted by DCE > + (insn 10 (use (reg/i:SI %1))) > + > + (edge-to exit (flags "FALLTHRU")) > + ) ;; block 2 > + ) ;; insn-chain > +) ;; function > +} > + > +/* Verify that insns 8 and 9 get combined into a shift of 35 (0x23) */ > +/* { dg-final { scan-rtl-dump "allowing combination of insns 8 and 9" > "combine" } } */ > +/* { dg-final { scan-rtl-dump "modifying insn i3 9: > r\[0-9\]+:SI#0=r\[0-9\]+:DI>>0x23" "combine" } } */ > diff --git a/gcc/testsuite/gcc.dg/rtl/aarch64/pr71779.c > b/gcc/testsuite/gcc.dg/rtl/aarch64/pr71779.c > new file mode 100644 > index 0000000..d318339 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/rtl/aarch64/pr71779.c > @@ -0,0 +1,50 @@ > +/* { dg-do compile { target aarch64-*-* } } */ > +/* { dg-options "-fdump-rtl-cse1" } */ > + > +/* Dump taken from comment 2 of PR 71779, of > + "...the relevant memory access coming out of expand" > + hand-edited to the compact dump format. */ > + > +int __RTL("cse1") test (int n) > +{ > +(function "fragment" > + (param "n" > + (DECL_RTL (reg/v:SI %1 [ n ])) > + (DECL_RTL_INCOMING (reg:SI x0 [ n ])) > + ) ;; param "n" > + (insn-chain > + (block 2 > + (edge-from entry (flags "FALLTHRU")) > + (cnote 6 [bb 2] NOTE_INSN_BASIC_BLOCK) > + > +;; MEM[(struct isl_obj *)&obj1] = &isl_obj_map_vtable; > +(insn 1045 (set (reg:SI %480) > + (high:SI (symbol_ref:SI ("isl_obj_map_vtable") > + [flags 0xc0] > + <var_decl 0x7fa0363ea240 isl_obj_map_vtable>))) > + y.c:12702) > +(insn 1046 (set (reg/f:SI %479) > + (lo_sum:SI (reg:SI %480) > + (symbol_ref:SI ("isl_obj_map_vtable") > + [flags 0xc0] > + <var_decl 0x7fa0363ea240 isl_obj_map_vtable>))) > + y.c:12702 > + (expr_list:REG_EQUAL (symbol_ref:SI ("isl_obj_map_vtable") > + [flags 0xc0] > + <var_decl 0x7fa0363ea240 isl_obj_map_vtable>))) > +(insn 1047 (set (reg:DI %481) > + (subreg:DI (reg/f:SI %479) 0)) y.c:12702) > +(insn 1048 (set (zero_extract:DI (reg/v:DI %191 [ obj1D.17368 ]) > + (const_int 32) > + (const_int 0)) > + (reg:DI %481)) y.c:12702) > +;; Extra insn, to avoid all of the above from being deleted by DCE > +(insn 1049 (set (mem:DI (reg:DI %191) [1 i+0 S4 A32]) > + (const_int 1))) > + (edge-to exit (flags "FALLTHRU")) > + ) ;; block 2 > + ) ;; insn-chain > +) ;; function > +} > + > +/* TODO: scan the dump. */ > diff --git a/gcc/testsuite/gcc.dg/rtl/rtl.exp > b/gcc/testsuite/gcc.dg/rtl/rtl.exp > new file mode 100644 > index 0000000..3c6648b > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/rtl/rtl.exp > @@ -0,0 +1,41 @@ > +# Copyright (C) 2016 Free Software Foundation, Inc. > + > +# This program is free software; you can redistribute it and/or modify > +# it under the terms of the GNU General Public License as published by > +# the Free Software Foundation; either version 3 of the License, or > +# (at your option) any later version. > +# > +# This program is distributed in the hope that it will be useful, > +# but WITHOUT ANY WARRANTY; without even the implied warranty of > +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > +# GNU General Public License for more details. > +# > +# You should have received a copy of the GNU General Public License > +# along with GCC; see the file COPYING3. If not see > +# <http://www.gnu.org/licenses/>. > + > +# GCC testsuite that uses the `dg.exp' driver. > + > +# Load support procs. > +load_lib gcc-dg.exp > + > +# If a testcase doesn't have special options, use these. > +global DEFAULT_RTLFLAGS > +if ![info exists DEFAULT_RTLFLAGS] then { > + set DEFAULT_RTLFLAGS "" > + # -fdump-tree-rtl-raw > +} > + > +# Initialize `dg'. > +dg-init > + > +# Gather a list of all tests. > +set tests [lsort [find $srcdir/$subdir *.c]] > + > +verbose "rtl.exp tests: $tests" 1 > + > +# Main loop. > +dg-runtest $tests "" $DEFAULT_RTLFLAGS > + > +# All done. > +dg-finish > diff --git a/gcc/testsuite/gcc.dg/rtl/test.c b/gcc/testsuite/gcc.dg/rtl/test.c > new file mode 100644 > index 0000000..ebb8aef > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/rtl/test.c > @@ -0,0 +1,31 @@ > +int test_1 (int i, int j, int k) > +{ > + if (i < j) > + return k + 4; > + else > + return -k; > +} > + > +/* Example showing: > + - data structure > + - loop > + - call to "abort". */ > + > +struct foo > +{ > + int count; > + float *data; > +}; > + > +float test_2 (struct foo *lhs, struct foo *rhs) > +{ > + float result = 0.0f; > + > + if (lhs->count != rhs->count) > + __builtin_abort (); > + > + for (int i = 0; i < lhs->count; i++) > + result += lhs->data[i] * rhs->data[i]; > + > + return result; > +} > diff --git a/gcc/testsuite/gcc.dg/rtl/unknown-rtx-code.c > b/gcc/testsuite/gcc.dg/rtl/unknown-rtx-code.c > new file mode 100644 > index 0000000..dd252f1 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/rtl/unknown-rtx-code.c > @@ -0,0 +1,8 @@ > +void __RTL test (void) > +{ > + (function "test" > + (insn-chain > + (not-a-valid-kind-of-insn 1 0 0) ;; { dg-error "unknown rtx code" } > + ) ;; insn-chain > + ) ;; function > +} > diff --git a/gcc/testsuite/gcc.dg/rtl/x86_64/dfinit.c > b/gcc/testsuite/gcc.dg/rtl/x86_64/dfinit.c > new file mode 100644 > index 0000000..f7b3e77 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/rtl/x86_64/dfinit.c > @@ -0,0 +1,116 @@ > +/* { dg-do run { target i?86-*-* x86_64-*-* } } */ > +/* { dg-options "-fdump-rtl-dfinit" } */ > + > +#include "test_1.h" > + > +/* Lightly-modified dump of test.c.261r.split1 for x86_64. */ > + > +int __RTL("no-opt dfinit") test_1 (int i, int j, int k) > +{ > +(function "test_1" > + (param "i" > + (DECL_RTL (mem/c:SI (plus:DI (reg/f:DI frame) > + (const_int -4)) [1 i+0 S4 A32])) > + (DECL_RTL_INCOMING (reg:SI di [ i ]))) > + (param "j" > + (DECL_RTL (mem/c:SI (plus:DI (reg/f:DI frame) > + (const_int -8)) [1 j+0 S4 A32])) > + (DECL_RTL_INCOMING (reg:SI si [ j ]))) > + (param "k" > + (DECL_RTL (mem/c:SI (plus:DI (reg/f:DI frame) > + (const_int -12)) [1 k+0 S4 A32])) > + (DECL_RTL_INCOMING (reg:SI dx [ k ]))) > + (insn-chain > + (cnote 1 NOTE_INSN_DELETED) > + (block 2 > + (edge-from entry (flags "FALLTHRU")) > + (cnote 6 [bb 2] NOTE_INSN_BASIC_BLOCK) > + (cinsn 2 (set (mem/c:SI (plus:DI (reg/f:DI frame) > + (const_int -4)) [1 i+0 S4 A32]) > + (reg:SI di [ i ])) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":2) > + (cinsn 3 (set (mem/c:SI (plus:DI (reg/f:DI frame) > + (const_int -8)) [1 j+0 S4 A32]) > + (reg:SI si [ j ])) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":2) > + (cinsn 4 (set (mem/c:SI (plus:DI (reg/f:DI frame) > + (const_int -12)) [1 k+0 S4 A32]) > + (reg:SI dx [ k ])) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":2) > + (cnote 5 NOTE_INSN_FUNCTION_BEG) > + (cinsn 8 (set (reg:SI %2) > + (mem/c:SI (plus:DI (reg/f:DI frame) > + (const_int -4)) [1 i+0 S4 A32])) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":3) > + (cinsn 9 (set (reg:CCGC flags) > + (compare:CCGC (reg:SI %2) > + (mem/c:SI (plus:DI (reg/f:DI frame) > + (const_int -8)) [1 j+0 S4 A32]))) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":3) > + (cjump_insn 10 (set (pc) > + (if_then_else (ge (reg:CCGC flags) > + (const_int 0)) > + (label_ref 16) > + (pc))) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":3) > + (edge-to 3 (flags "FALLTHRU")) > + (edge-to 4) > + ) ;; block 2 > + (block 3 > + (edge-from 2 (flags "FALLTHRU")) > + (cnote 11 [bb 3] NOTE_INSN_BASIC_BLOCK) > + (cinsn 12 (set (reg:SI %3) > + (mem/c:SI (plus:DI (reg/f:DI frame) > + (const_int -12)) [1 k+0 S4 A32])) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":4) > + (cinsn 13 (parallel [ > + (set (reg:SI %0 [ _1 ]) > + (plus:SI (reg:SI %3) > + (const_int 4))) > + (clobber (reg:CC flags)) > + ]) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":4 > + (expr_list:REG_EQUAL (plus:SI (mem/c:SI (plus:DI (reg/f:DI > frame) > + (const_int -12)) [1 k+0 S4 A32]) > + (const_int 4)))) > + (cjump_insn 29 (set (pc) > + (label_ref 20)) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":4) > + (edge-to 5) > + ) ;; block 3 > + (cbarrier 30) > + (block 4 > + (edge-from 2) > + (clabel 16 2) > + (cnote 17 [bb 4] NOTE_INSN_BASIC_BLOCK) > + (cinsn 18 (set (reg:SI %4) > + (mem/c:SI (plus:DI (reg/f:DI frame) > + (const_int -12)) [1 k+0 S4 A32])) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":6) > + (cinsn 19 (parallel [ > + (set (reg:SI %0 [ _1 ]) > + (neg:SI (reg:SI %4))) > + (clobber (reg:CC flags)) > + ]) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":6 > + (expr_list:REG_EQUAL (neg:SI (mem/c:SI (plus:DI (reg/f:DI > frame) > + (const_int -12)) [1 k+0 S4 A32])))) > + (edge-to 5 (flags "FALLTHRU")) > + ) ;; block 4 > + (block 5 > + (edge-from 4 (flags "FALLTHRU")) > + (edge-from 3) > + (clabel 20 3) > + (cnote 21 [bb 5] NOTE_INSN_BASIC_BLOCK) > + (cinsn 22 (set (reg:SI %1 [ <retval> ]) > + (reg:SI %0 [ _1 ]))) > + (cinsn 26 (set (reg/i:SI ax) > + (reg:SI %1 [ <retval> ])) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":7) > + (cinsn 27 (use (reg/i:SI ax)) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":7) > + (edge-to exit (flags "FALLTHRU")) > + ) ;; block 5 > + ) ;; insn-chain > + (crtl > + (return_rtx > + (reg/i:SI ax) > + ) ;; return_rtx > + ) ;; crtl > +) ;; function "test_1" > +} > + > +/* Verify that the dataflow information matches what cc1 would normally > + have generated. In particular, in earlier versions of the RTL > + frontend, the exit block use of reg 0 (ax) wasn't picked up > + on, due to not setting up crtl->return_rtx based on > + DECL_RESULT (fndecl). */ > +/* { dg-final { scan-rtl-dump ";; exit block uses.*0 .ax. 6 .bp. 7 .sp. 20 > .frame." "dfinit" } } */ > +/* { dg-final { scan-rtl-dump ";; regs ever live.*0 .ax. 1 .dx. 4 .si. 5 > .di. 17 .flags." "dfinit" } } */ > diff --git a/gcc/testsuite/gcc.dg/rtl/x86_64/different-structs.c > b/gcc/testsuite/gcc.dg/rtl/x86_64/different-structs.c > new file mode 100644 > index 0000000..8db1161 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/rtl/x86_64/different-structs.c > @@ -0,0 +1,81 @@ > +/* { dg-do compile { target x86_64-*-* } } */ > + > +extern double sqrt(double x); > + > +struct foo > +{ > + double x; > + double y; > +}; > + > +struct bar > +{ > + double x; > + double y; > +}; > + > +double __RTL test (struct foo *f, const struct bar *b) > +{ > +#if 0 > + /* Result of "expand" on this C code, compiled for x86_64 with -Os. */ > + f->x += b->x; > + f->y += b->y; > + return sqrt (f->x * f->x + f->y * f->y); > +#endif > +(function "test" > + (insn-chain > + (cnote 1 NOTE_INSN_DELETED) > + (block 2 > + (edge-from entry (flags "FALLTHRU")) > + (cnote 5 [bb 2] NOTE_INSN_BASIC_BLOCK) > + (cinsn 2 (set (reg/v/f:DI %10 [ f ]) > + (reg:DI di [ f ])) > "../../src/gcc/testsuite/gcc.dg/rtl/x86_64/different-structs.c":18) > + (cinsn 3 (set (reg/v/f:DI %11 [ b ]) > + (reg:DI si [ b ])) > "../../src/gcc/testsuite/gcc.dg/rtl/x86_64/different-structs.c":18) > + (cnote 4 NOTE_INSN_FUNCTION_BEG) > + (cinsn 7 (set (reg:DF %12) > + (mem:DF (reg/v/f:DI %10 [ f ]) [2 f_11(D)->x+0 S8 A64])) > "../../src/gcc/testsuite/gcc.dg/rtl/x86_64/different-structs.c":21) > + (cinsn 8 (set (reg:DF %2 [ _3 ]) > + (plus:DF (reg:DF %12) > + (mem:DF (reg/v/f:DI %11 [ b ]) [2 b_12(D)->x+0 S8 > A64]))) "../../src/gcc/testsuite/gcc.dg/rtl/x86_64/different-structs.c":21) > + (cinsn 9 (set (mem:DF (reg/v/f:DI %10 [ f ]) [2 f_11(D)->x+0 S8 A64]) > + (reg:DF %2 [ _3 ])) > "../../src/gcc/testsuite/gcc.dg/rtl/x86_64/different-structs.c":21) > + (cinsn 10 (set (reg:DF %13) > + (mem:DF (plus:DI (reg/v/f:DI %10 [ f ]) > + (const_int 8)) [2 f_11(D)->y+0 S8 A64])) > "../../src/gcc/testsuite/gcc.dg/rtl/x86_64/different-structs.c":22) > + (cinsn 11 (set (reg:DF %5 [ _6 ]) > + (plus:DF (reg:DF %13) > + (mem:DF (plus:DI (reg/v/f:DI %11 [ b ]) > + (const_int 8)) [2 b_12(D)->y+0 S8 A64]))) > "../../src/gcc/testsuite/gcc.dg/rtl/x86_64/different-structs.c":22) > + (cinsn 12 (set (mem:DF (plus:DI (reg/v/f:DI %10 [ f ]) > + (const_int 8)) [2 f_11(D)->y+0 S8 A64]) > + (reg:DF %5 [ _6 ])) > "../../src/gcc/testsuite/gcc.dg/rtl/x86_64/different-structs.c":22) > + (cinsn 13 (set (reg:DF %14) > + (mult:DF (reg:DF %2 [ _3 ]) > + (reg:DF %2 [ _3 ]))) > "../../src/gcc/testsuite/gcc.dg/rtl/x86_64/different-structs.c":23) > + (cinsn 14 (set (reg:DF %15) > + (mult:DF (reg:DF %5 [ _6 ]) > + (reg:DF %5 [ _6 ]))) > "../../src/gcc/testsuite/gcc.dg/rtl/x86_64/different-structs.c":23) > + (cinsn 15 (set (reg:DF %16) > + (plus:DF (reg:DF %14) > + (reg:DF %15))) > "../../src/gcc/testsuite/gcc.dg/rtl/x86_64/different-structs.c":23) > + (cinsn 16 (set (reg:DF xmm0) > + (reg:DF %16)) > "../../src/gcc/testsuite/gcc.dg/rtl/x86_64/different-structs.c":23) > + (ccall_insn/j 17 (set (reg:DF xmm0) > + (call (mem:QI (symbol_ref:DI ("sqrt") [flags 0x41] > <function_decl 0x7fa24e331d00 sqrt>) [0 __builtin_sqrt S1 A8]) > + (const_int 0))) > "../../src/gcc/testsuite/gcc.dg/rtl/x86_64/different-structs.c":23 > + (expr_list:REG_CALL_DECL (symbol_ref:DI ("sqrt") [flags > 0x41] <function_decl 0x7fa24e331d00 sqrt>) > + (expr_list:REG_EH_REGION (const_int 0))) > + (expr_list:DF (use (reg:DF xmm0)))) > + (edge-to exit (flags "ABNORMAL | SIBCALL")) > + ) ;; block 2 > + (cbarrier 18) > + ) ;; insn-chain > + (crtl > + (return_rtx > + (reg/i:DF xmm0) > + ) ;; return_rtx > + ) ;; crtl > +) ;; function "test" > + > +} > diff --git a/gcc/testsuite/gcc.dg/rtl/x86_64/final.c > b/gcc/testsuite/gcc.dg/rtl/x86_64/final.c > new file mode 100644 > index 0000000..d10deb0 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/rtl/x86_64/final.c > @@ -0,0 +1,133 @@ > +/* { dg-do compile { target i?86-*-* x86_64-*-* } } */ > +/* { dg-options "-fdump-rtl-final" } */ > + > +/* Lightly-modified dump of test.c.304r.dwarf2 for x86_64 target, > + with various NOTE_INSN_CFI deleted by hand for now. */ > + > +int __RTL("final") test_1 (int i, int j, int k) > +{ > +(function "test_1" > + (param "i" > + (DECL_RTL (mem/c:SI (plus:DI (reg/f:DI frame) > + (const_int -4)) [1 i+0 S4 A32])) > + (DECL_RTL_INCOMING (reg:SI di [ i ]))) > + (param "j" > + (DECL_RTL (mem/c:SI (plus:DI (reg/f:DI frame) > + (const_int -8)) [1 j+0 S4 A32])) > + (DECL_RTL_INCOMING (reg:SI si [ j ]))) > + (param "k" > + (DECL_RTL (mem/c:SI (plus:DI (reg/f:DI frame) > + (const_int -12)) [1 k+0 S4 A32])) > + (DECL_RTL_INCOMING (reg:SI dx [ k ]))) > + (insn-chain > + (cnote 1 NOTE_INSN_DELETED) > + (block 2 > + (edge-from entry (flags "FALLTHRU")) > + (cnote 6 [bb 2] NOTE_INSN_BASIC_BLOCK) > + (cinsn/f 32 (set (mem:DI (pre_dec:DI (reg/f:DI sp)) [0 S8 A8]) > + (reg/f:DI bp)) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":2) > + (cinsn/f 33 (set (reg/f:DI bp) > + (reg/f:DI sp)) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":2) > + (cinsn 34 (set (mem/v:BLK (0|scratch:DI) [0 A8]) > + (unspec:BLK [ > + (mem/v:BLK (reuse_rtx 0) [0 A8]) > + ] UNSPEC_MEMORY_BLOCKAGE)) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":2) > + (cnote 35 NOTE_INSN_PROLOGUE_END) > + (cinsn 2 (set (mem/c:SI (plus:DI (reg/f:DI bp) > + (const_int -4)) [1 i+0 S4 A32]) > + (reg:SI di [ i ])) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":2) > + (cinsn 3 (set (mem/c:SI (plus:DI (reg/f:DI bp) > + (const_int -8)) [1 j+0 S4 A32]) > + (reg:SI si [ j ])) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":2) > + (cinsn 4 (set (mem/c:SI (plus:DI (reg/f:DI bp) > + (const_int -12)) [1 k+0 S4 A32]) > + (reg:SI dx [ k ])) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":2) > + (cnote 5 NOTE_INSN_FUNCTION_BEG) > + (cinsn 8 (set (reg:SI ax [89]) > + (mem/c:SI (plus:DI (reg/f:DI bp) > + (const_int -4)) [1 i+0 S4 A32])) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":3) > + (cinsn 9 (set (reg:CCGC flags) > + (compare:CCGC (reg:SI ax [89]) > + (mem/c:SI (plus:DI (reg/f:DI bp) > + (const_int -8)) [1 j+0 S4 A32]))) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":3) > + (cjump_insn 10 (set (pc) > + (if_then_else (ge (reg:CCGC flags) > + (const_int 0)) > + (label_ref 16) > + (pc))) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":3) > + (edge-to 3 (flags "FALLTHRU")) > + (edge-to 4) > + ) ;; block 2 > + (block 3 > + (edge-from 2 (flags "FALLTHRU")) > + (cnote 11 [bb 3] NOTE_INSN_BASIC_BLOCK) > + (cinsn 12 (set (reg:SI ax [90]) > + (mem/c:SI (plus:DI (reg/f:DI bp) > + (const_int -12)) [1 k+0 S4 A32])) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":4) > + (cinsn 13 (parallel [ > + (set (reg:SI ax [orig:87 _1 ] [87]) > + (plus:SI (reg:SI ax [90]) > + (const_int 4))) > + (clobber (reg:CC flags)) > + ]) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":4 > + (expr_list:REG_EQUAL (plus:SI (mem/c:SI (plus:DI (reg/f:DI > frame) > + (const_int -12)) [1 k+0 S4 A32]) > + (const_int 4)))) > + (cjump_insn 29 (set (pc) > + (label_ref 20)) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":4) > + (edge-to 5) > + ) ;; block 3 > + (cbarrier 30) > + (block 4 > + (edge-from 2) > + (clabel 16 2) > + (cnote 17 [bb 4] NOTE_INSN_BASIC_BLOCK) > + (cinsn 18 (set (reg:SI ax [91]) > + (mem/c:SI (plus:DI (reg/f:DI bp) > + (const_int -12)) [1 k+0 S4 A32])) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":6) > + (cinsn 19 (parallel [ > + (set (reg:SI ax [orig:87 _1 ] [87]) > + (neg:SI (reg:SI ax [91]))) > + (clobber (reg:CC flags)) > + ]) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":6 > + (expr_list:REG_EQUAL (neg:SI (mem/c:SI (plus:DI (reg/f:DI > frame) > + (const_int -12)) [1 k+0 S4 A32])))) > + (edge-to 5 (flags "FALLTHRU")) > + ) ;; block 4 > + (block 5 > + (edge-from 4 (flags "FALLTHRU")) > + (edge-from 3) > + (clabel 20 3) > + (cnote 21 [bb 5] NOTE_INSN_BASIC_BLOCK) > + (cinsn 27 (use (reg/i:SI ax)) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":7) > + (cnote 36 NOTE_INSN_EPILOGUE_BEG) > + (cinsn 37 (set (mem/v:BLK (1|scratch:DI) [0 A8]) > + (unspec:BLK [ > + (mem/v:BLK (reuse_rtx 1) [0 A8]) > + ] UNSPEC_MEMORY_BLOCKAGE)) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":7) > + (cinsn/f 38 (set (reg/f:DI bp) > + (mem:DI (post_inc:DI (reg/f:DI sp)) [0 S8 A8])) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":7 > + (expr_list:REG_CFA_DEF_CFA (plus:DI (reg/f:DI sp) > + (const_int 8)))) > + (cjump_insn 39 (simple_return) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":7) > + (edge-to exit) > + ) ;; block 5 > + (cbarrier 40) > + (cnote 31 NOTE_INSN_DELETED) > + ) ;; insn-chain > + (crtl > + (return_rtx > + (reg/i:SI ax) > + ) ;; return_rtx > + ) ;; crtl > +) ;; function "test_1" > +} > + > +/* Verify that asm was emitted. */ > +/* { dg-final { scan-assembler "test_1:" } } */ > +/* { dg-final { scan-assembler ".cfi_startproc" } } */ > +/* { dg-final { scan-assembler ".cfi_endproc" } } */ > + > +/* Verify that the "simple_return" was recognized. > + FIXME: this assumes i386.md. */ > +/* { dg-final { scan-assembler "ret" } } */ > diff --git a/gcc/testsuite/gcc.dg/rtl/x86_64/into-cfglayout.c > b/gcc/testsuite/gcc.dg/rtl/x86_64/into-cfglayout.c > new file mode 100644 > index 0000000..d080956 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/rtl/x86_64/into-cfglayout.c > @@ -0,0 +1,117 @@ > +/* { dg-do run { target i?86-*-* x86_64-*-* } } */ > +/* { dg-options "-fdump-rtl-into_cfglayout" } */ > + > +/* Lightly-modified dump of test.c.226r.vregs for x86_64. */ > + > +#include "test_1.h" > + > +int __RTL("into_cfglayout") test_1 (int i, int j, int k) > +{ > +(function "test_1" > + (param "i" > + (DECL_RTL (mem/c:SI (plus:DI (reg/f:DI frame) > + (const_int -4)) [1 i+0 S4 A32])) > + (DECL_RTL_INCOMING (reg:SI di [ i ]))) > + (param "j" > + (DECL_RTL (mem/c:SI (plus:DI (reg/f:DI frame) > + (const_int -8)) [1 j+0 S4 A32])) > + (DECL_RTL_INCOMING (reg:SI si [ j ]))) > + (param "k" > + (DECL_RTL (mem/c:SI (plus:DI (reg/f:DI frame) > + (const_int -12)) [1 k+0 S4 A32])) > + (DECL_RTL_INCOMING (reg:SI dx [ k ]))) > + (insn-chain > + (cnote 1 NOTE_INSN_DELETED) > + (block 2 > + (edge-from entry (flags "FALLTHRU")) > + (cnote 6 [bb 2] NOTE_INSN_BASIC_BLOCK) > + (cinsn 2 (set (mem/c:SI (plus:DI (reg/f:DI frame) > + (const_int -4)) [1 i+0 S4 A32]) > + (reg:SI di [ i ])) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":2) > + (cinsn 3 (set (mem/c:SI (plus:DI (reg/f:DI frame) > + (const_int -8)) [1 j+0 S4 A32]) > + (reg:SI si [ j ])) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":2) > + (cinsn 4 (set (mem/c:SI (plus:DI (reg/f:DI frame) > + (const_int -12)) [1 k+0 S4 A32]) > + (reg:SI dx [ k ])) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":2) > + (cnote 5 NOTE_INSN_FUNCTION_BEG) > + (cinsn 8 (set (reg:SI %2) > + (mem/c:SI (plus:DI (reg/f:DI frame) > + (const_int -4)) [1 i+0 S4 A32])) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":3) > + (cinsn 9 (set (reg:CCGC flags) > + (compare:CCGC (reg:SI %2) > + (mem/c:SI (plus:DI (reg/f:DI frame) > + (const_int -8)) [1 j+0 S4 A32]))) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":3) > + (cjump_insn 10 (set (pc) > + (if_then_else (ge (reg:CCGC flags) > + (const_int 0)) > + (label_ref 16) > + (pc))) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":3) > + (edge-to 4 (flags "FALLTHRU")) > + (edge-to 5) > + ) ;; block 2 > + (block 4 > + (edge-from 2 (flags "FALLTHRU")) > + (cnote 11 [bb 4] NOTE_INSN_BASIC_BLOCK) > + (cinsn 12 (set (reg:SI %3) > + (mem/c:SI (plus:DI (reg/f:DI frame) > + (const_int -12)) [1 k+0 S4 A32])) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":4) > + (cinsn 13 (parallel [ > + (set (reg:SI %0 [ _1 ]) > + (plus:SI (reg:SI %3) > + (const_int 4))) > + (clobber (reg:CC flags)) > + ]) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":4 > + (expr_list:REG_EQUAL (plus:SI (mem/c:SI (plus:DI (reg/f:DI > frame) > + (const_int -12)) [1 k+0 S4 A32]) > + (const_int 4)))) > + (cjump_insn 14 (set (pc) > + (label_ref 20)) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":4) > + (edge-to 6) > + ) ;; block 4 > + (cbarrier 15) > + (block 5 > + (edge-from 2) > + (clabel 16 2) > + (cnote 17 [bb 5] NOTE_INSN_BASIC_BLOCK) > + (cinsn 18 (set (reg:SI %4) > + (mem/c:SI (plus:DI (reg/f:DI frame) > + (const_int -12)) [1 k+0 S4 A32])) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":6) > + (cinsn 19 (parallel [ > + (set (reg:SI %0 [ _1 ]) > + (neg:SI (reg:SI %4))) > + (clobber (reg:CC flags)) > + ]) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":6 > + (expr_list:REG_EQUAL (neg:SI (mem/c:SI (plus:DI (reg/f:DI > frame) > + (const_int -12)) [1 k+0 S4 A32])))) > + (edge-to 6 (flags "FALLTHRU")) > + ) ;; block 5 > + (block 6 > + (edge-from 4) > + (edge-from 5 (flags "FALLTHRU")) > + (clabel 20 3) > + (cnote 21 [bb 6] NOTE_INSN_BASIC_BLOCK) > + (cinsn 22 (set (reg:SI %1 [ <retval> ]) > + (reg:SI %0 [ _1 ]))) > + (cinsn 26 (set (reg/i:SI ax) > + (reg:SI %1 [ <retval> ])) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":7) > + (cinsn 27 (use (reg/i:SI ax)) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":7) > + (edge-to exit (flags "FALLTHRU")) > + ) ;; block 6 > + ) ;; insn-chain > + (crtl > + (return_rtx > + (reg/i:SI ax) > + ) ;; return_rtx > + ) ;; crtl > +) ;; function "test_1" > +} > + > +/* The conversion to cfglayout should eliminate unconditional jump > + instructions... */ > +/* { dg-final { scan-rtl-dump "Removing jump 14." "into_cfglayout" } } */ > +/* { dg-final { scan-rtl-dump-not "jump_insn 14" "into_cfglayout" } } */ > +/* { dg-final { scan-rtl-dump-not "barrier" "into_cfglayout" } } */ > + > +/* ...but conditional jumps should be preserved. */ > +/* { dg-final { scan-rtl-dump "jump_insn 10" "into_cfglayout" } } */ > diff --git a/gcc/testsuite/gcc.dg/rtl/x86_64/ira.c > b/gcc/testsuite/gcc.dg/rtl/x86_64/ira.c > new file mode 100644 > index 0000000..3f729cd > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/rtl/x86_64/ira.c > @@ -0,0 +1,111 @@ > +/* { dg-do run { target i?86-*-* x86_64-*-* } } */ > +/* { dg-options "-fdump-rtl-ira" } */ > + > +/* Lightly-modified dump of test.c.265r.asmcons for x86_64. */ > + > +#include "test_1.h" > + > +int __RTL ("ira") test_1 (int i, int j, int k) > +{ > +(function "test_1" > + (param "i" > + (DECL_RTL (mem/c:SI (plus:DI (reg/f:DI frame) > + (const_int -4)) [1 i+0 S4 A32])) > + (DECL_RTL_INCOMING (reg:SI di [ i ]))) > + (param "j" > + (DECL_RTL (mem/c:SI (plus:DI (reg/f:DI frame) > + (const_int -8)) [1 j+0 S4 A32])) > + (DECL_RTL_INCOMING (reg:SI si [ j ]))) > + (param "k" > + (DECL_RTL (mem/c:SI (plus:DI (reg/f:DI frame) > + (const_int -12)) [1 k+0 S4 A32])) > + (DECL_RTL_INCOMING (reg:SI dx [ k ]))) > + (insn-chain > + (cnote 1 NOTE_INSN_DELETED) > + (block 2 > + (edge-from entry (flags "FALLTHRU")) > + (cnote 6 [bb 2] NOTE_INSN_BASIC_BLOCK) > + (cinsn 2 (set (mem/c:SI (plus:DI (reg/f:DI frame) > + (const_int -4)) [1 i+0 S4 A32]) > + (reg:SI di [ i ])) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":2) > + (cinsn 3 (set (mem/c:SI (plus:DI (reg/f:DI frame) > + (const_int -8)) [1 j+0 S4 A32]) > + (reg:SI si [ j ])) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":2) > + (cinsn 4 (set (mem/c:SI (plus:DI (reg/f:DI frame) > + (const_int -12)) [1 k+0 S4 A32]) > + (reg:SI dx [ k ])) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":2) > + (cnote 5 NOTE_INSN_FUNCTION_BEG) > + (cinsn 8 (set (reg:SI %2) > + (mem/c:SI (plus:DI (reg/f:DI frame) > + (const_int -4)) [1 i+0 S4 A32])) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":3) > + (cinsn 9 (set (reg:CCGC flags) > + (compare:CCGC (reg:SI %2) > + (mem/c:SI (plus:DI (reg/f:DI frame) > + (const_int -8)) [1 j+0 S4 A32]))) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":3) > + (cjump_insn 10 (set (pc) > + (if_then_else (ge (reg:CCGC flags) > + (const_int 0)) > + (label_ref 16) > + (pc))) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":3) > + (edge-to 3 (flags "FALLTHRU")) > + (edge-to 4) > + ) ;; block 2 > + (block 3 > + (edge-from 2 (flags "FALLTHRU")) > + (cnote 11 [bb 3] NOTE_INSN_BASIC_BLOCK) > + (cinsn 12 (set (reg:SI %3) > + (mem/c:SI (plus:DI (reg/f:DI frame) > + (const_int -12)) [1 k+0 S4 A32])) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":4) > + (cinsn 13 (parallel [ > + (set (reg:SI %0 [ _1 ]) > + (plus:SI (reg:SI %3) > + (const_int 4))) > + (clobber (reg:CC flags)) > + ]) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":4 > + (expr_list:REG_EQUAL (plus:SI (mem/c:SI (plus:DI (reg/f:DI > frame) > + (const_int -12)) [1 k+0 S4 A32]) > + (const_int 4)))) > + (cjump_insn 29 (set (pc) > + (label_ref 20)) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":4) > + (edge-to 5) > + ) ;; block 3 > + (cbarrier 30) > + (block 4 > + (edge-from 2) > + (clabel 16 2) > + (cnote 17 [bb 4] NOTE_INSN_BASIC_BLOCK) > + (cinsn 18 (set (reg:SI %4) > + (mem/c:SI (plus:DI (reg/f:DI frame) > + (const_int -12)) [1 k+0 S4 A32])) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":6) > + (cinsn 19 (parallel [ > + (set (reg:SI %0 [ _1 ]) > + (neg:SI (reg:SI %4))) > + (clobber (reg:CC flags)) > + ]) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":6 > + (expr_list:REG_EQUAL (neg:SI (mem/c:SI (plus:DI (reg/f:DI > frame) > + (const_int -12)) [1 k+0 S4 A32])))) > + (edge-to 5 (flags "FALLTHRU")) > + ) ;; block 4 > + (block 5 > + (edge-from 4 (flags "FALLTHRU")) > + (edge-from 3) > + (clabel 20 3) > + (cnote 21 [bb 5] NOTE_INSN_BASIC_BLOCK) > + (cinsn 22 (set (reg:SI %1 [ <retval> ]) > + (reg:SI %0 [ _1 ]))) > + (cinsn 26 (set (reg/i:SI ax) > + (reg:SI %1 [ <retval> ])) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":7) > + (cinsn 27 (use (reg/i:SI ax)) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":7) > + (edge-to exit (flags "FALLTHRU")) > + ) ;; block 5 > + ) ;; insn-chain > + (crtl > + (return_rtx > + (reg/i:SI ax) > + ) ;; return_rtx > + ) ;; crtl > +) ;; function "test_1" > +} > + > +/* Verify that IRA was run. */ > +/* { dg-final { scan-rtl-dump "Building IRA IR" "ira" } } */ > diff --git a/gcc/testsuite/gcc.dg/rtl/x86_64/pro_and_epilogue.c > b/gcc/testsuite/gcc.dg/rtl/x86_64/pro_and_epilogue.c > new file mode 100644 > index 0000000..712faf0 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/rtl/x86_64/pro_and_epilogue.c > @@ -0,0 +1,110 @@ > +/* { dg-do compile { target i?86-*-* x86_64-*-* } } */ > +/* { dg-options "-fdump-rtl-pro_and_epilogue" } */ > + > +/* Lightly-modified dump of test.c.274r.split2 for x86_64. */ > + > +int __RTL("pro_and_epilogue") test_1 (int i, int j, int k) > +{ > +(function "test_1" > + (param "i" > + (DECL_RTL (mem/c:SI (plus:DI (reg/f:DI frame) > + (const_int -4)) [1 i+0 S4 A32])) > + (DECL_RTL_INCOMING (reg:SI di [ i ]))) > + (param "j" > + (DECL_RTL (mem/c:SI (plus:DI (reg/f:DI frame) > + (const_int -8)) [1 j+0 S4 A32])) > + (DECL_RTL_INCOMING (reg:SI si [ j ]))) > + (param "k" > + (DECL_RTL (mem/c:SI (plus:DI (reg/f:DI frame) > + (const_int -12)) [1 k+0 S4 A32])) > + (DECL_RTL_INCOMING (reg:SI dx [ k ]))) > + (insn-chain > + (cnote 1 NOTE_INSN_DELETED) > + (block 2 > + (edge-from entry (flags "FALLTHRU")) > + (cnote 6 [bb 2] NOTE_INSN_BASIC_BLOCK) > + (cinsn 2 (set (mem/c:SI (plus:DI (reg/f:DI bp) > + (const_int -4)) [1 i+0 S4 A32]) > + (reg:SI di [ i ])) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":2) > + (cinsn 3 (set (mem/c:SI (plus:DI (reg/f:DI bp) > + (const_int -8)) [1 j+0 S4 A32]) > + (reg:SI si [ j ])) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":2) > + (cinsn 4 (set (mem/c:SI (plus:DI (reg/f:DI bp) > + (const_int -12)) [1 k+0 S4 A32]) > + (reg:SI dx [ k ])) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":2) > + (cnote 5 NOTE_INSN_FUNCTION_BEG) > + (cinsn 8 (set (reg:SI ax [89]) > + (mem/c:SI (plus:DI (reg/f:DI bp) > + (const_int -4)) [1 i+0 S4 A32])) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":3) > + (cinsn 9 (set (reg:CCGC flags) > + (compare:CCGC (reg:SI ax [89]) > + (mem/c:SI (plus:DI (reg/f:DI bp) > + (const_int -8)) [1 j+0 S4 A32]))) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":3) > + (cjump_insn 10 (set (pc) > + (if_then_else (ge (reg:CCGC flags) > + (const_int 0)) > + (label_ref 16) > + (pc))) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":3) > + (edge-to 3 (flags "FALLTHRU")) > + (edge-to 4) > + ) ;; block 2 > + (block 3 > + (edge-from 2 (flags "FALLTHRU")) > + (cnote 11 [bb 3] NOTE_INSN_BASIC_BLOCK) > + (cinsn 12 (set (reg:SI ax [90]) > + (mem/c:SI (plus:DI (reg/f:DI bp) > + (const_int -12)) [1 k+0 S4 A32])) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":4) > + (cinsn 13 (parallel [ > + (set (reg:SI ax [orig:87 _1 ] [87]) > + (plus:SI (reg:SI ax [90]) > + (const_int 4))) > + (clobber (reg:CC flags)) > + ]) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":4 > + (expr_list:REG_EQUAL (plus:SI (mem/c:SI (plus:DI (reg/f:DI > frame) > + (const_int -12)) [1 k+0 S4 A32]) > + (const_int 4)))) > + (cjump_insn 29 (set (pc) > + (label_ref 20)) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":4) > + (edge-to 5) > + ) ;; block 3 > + (cbarrier 30) > + (block 4 > + (edge-from 2) > + (clabel 16 2) > + (cnote 17 [bb 4] NOTE_INSN_BASIC_BLOCK) > + (cinsn 18 (set (reg:SI ax [91]) > + (mem/c:SI (plus:DI (reg/f:DI bp) > + (const_int -12)) [1 k+0 S4 A32])) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":6) > + (cinsn 19 (parallel [ > + (set (reg:SI ax [orig:87 _1 ] [87]) > + (neg:SI (reg:SI ax [91]))) > + (clobber (reg:CC flags)) > + ]) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":6 > + (expr_list:REG_EQUAL (neg:SI (mem/c:SI (plus:DI (reg/f:DI > frame) > + (const_int -12)) [1 k+0 S4 A32])))) > + (edge-to 5 (flags "FALLTHRU")) > + ) ;; block 4 > + (block 5 > + (edge-from 4 (flags "FALLTHRU")) > + (edge-from 3) > + (clabel 20 3) > + (cnote 21 [bb 5] NOTE_INSN_BASIC_BLOCK) > + (cinsn 27 (use (reg/i:SI ax)) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":7) > + (edge-to exit (flags "FALLTHRU")) > + ) ;; block 5 > + (cnote 31 NOTE_INSN_DELETED) > + ) ;; insn-chain > + (crtl > + (return_rtx > + (reg/i:SI ax) > + ) ;; return_rtx > + ) ;; crtl > +) ;; function "test_1" > +} > + > +/* Verify that the prologue and epilogue were added. */ > +/* { dg-final { scan-rtl-dump-times "NOTE_INSN_PROLOGUE_END" 1 > "pro_and_epilogue" } } */ > + > +/* We expect a jump_insn to "simple_return". */ > +/* { dg-final { scan-rtl-dump-times "simple_return" 2 "pro_and_epilogue" } } > */ > + > diff --git > a/gcc/testsuite/gcc.dg/rtl/x86_64/test-return-const.c.after-expand.c > b/gcc/testsuite/gcc.dg/rtl/x86_64/test-return-const.c.after-expand.c > new file mode 100644 > index 0000000..bb431ee > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/rtl/x86_64/test-return-const.c.after-expand.c > @@ -0,0 +1,39 @@ > +/* { dg-do run { target x86_64-*-* } } */ > + > +extern void abort (void); > + > +int __RTL("vregs") test_returning_constant (void) > +{ > + /* C code: > + return 42; */ > +(function "test_returning_constant" > + (insn-chain > + (cnote 1 NOTE_INSN_DELETED) > + (block 2 > + (edge-from entry (flags "FALLTHRU")) > + (cnote 3 [bb 2] NOTE_INSN_BASIC_BLOCK) > + (cnote 2 NOTE_INSN_FUNCTION_BEG) > + (cinsn 5 (set (reg:SI %0 [ _1 ]) > + (const_int 42)) "../../src/test-return-const.c":3) > + (cinsn 8 (set (reg:SI %1 [ <retval> ]) > + (reg:SI %0 [ _1 ])) "../../src/test-return-const.c":3) > + (cinsn 12 (set (reg/i:SI ax) > + (reg:SI %1 [ <retval> ])) > "../../src/test-return-const.c":4) > + (cinsn 13 (use (reg/i:SI ax)) "../../src/test-return-const.c":4) > + (edge-to exit (flags "FALLTHRU")) > + ) ;; block 2 > + ) ;; insn-chain > + (crtl > + (return_rtx > + (reg/i:SI ax) > + ) ;; return_rtx > + ) ;; crtl > +) ;; function "test_returning_constant" > +} > + > +int main (void) > +{ > + if (test_returning_constant () != 42) > + abort (); > + return 0; > +} > diff --git > a/gcc/testsuite/gcc.dg/rtl/x86_64/test-return-const.c.before-fwprop.c > b/gcc/testsuite/gcc.dg/rtl/x86_64/test-return-const.c.before-fwprop.c > new file mode 100644 > index 0000000..4ae5418 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/rtl/x86_64/test-return-const.c.before-fwprop.c > @@ -0,0 +1,42 @@ > +/* { dg-do run { target x86_64-*-* } } */ > +/* { dg-options "-fdump-rtl-fwprop1 -O2" } */ > + > +extern void abort (void); > + > +int __RTL ("fwprop1") test_returning_constant (void) > +{ > + /* C code: > + return 42; */ > +(function "test_returning_constant" > + (insn-chain > + (block 2 > + (edge-from entry (flags "FALLTHRU")) > + (cnote 3 [bb 2] NOTE_INSN_BASIC_BLOCK) > + (cnote 2 NOTE_INSN_FUNCTION_BEG) > + (cinsn 5 (set (reg:SI %0 [ <retval> ]) > + (const_int 42)) "../../src/test-return-const.c":3) > + (cinsn 9 (set (reg/i:SI ax) > + (const_int 42)) "../../src/test-return-const.c":4 > + (expr_list:REG_DEAD (reg:SI %0 [ <retval> ]))) > + (cinsn 10 (use (reg/i:SI ax)) "../../src/test-return-const.c":4) > + (edge-to exit (flags "FALLTHRU")) > + ) ;; block 2 > + ) ;; insn-chain > + (crtl > + (return_rtx > + (reg/i:SI ax) > + ) ;; return_rtx > + ) ;; crtl > +) ;; function "test_returning_constant" > +} > + > +/* Verify that insn 5 is eliminated. */ > +/* { dg-final { scan-rtl-dump "deferring deletion of insn with uid = 5" > "fwprop1" } } */ > +/* { dg-final { scan-rtl-dump "Deleted 1 trivially dead insns" "fwprop1" } } > */ > + > +int main (void) > +{ > + if (test_returning_constant () != 42) > + abort (); > + return 0; > +} > diff --git a/gcc/testsuite/gcc.dg/rtl/x86_64/test-rtl.c > b/gcc/testsuite/gcc.dg/rtl/x86_64/test-rtl.c > new file mode 100644 > index 0000000..b4d1e6d > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/rtl/x86_64/test-rtl.c > @@ -0,0 +1,101 @@ > +/* { dg-do compile { target i?86-*-* x86_64-*-* } } */ > + > +/* Test of embedding RTL dump in a C function, tagged with "__RTL". > + > + This is a dump of test.c from immediately after "expand", for x86_64. */ > + > +int __RTL test_1 (int i, int j, int k) > +{ > + /* > + if (i < j) > + return k + 4; > + else > + return -k; > + */ > +(function "test_1" > + (insn-chain > + (cnote 1 NOTE_INSN_DELETED) > + (block 2 > + (edge-from entry (flags "FALLTHRU")) > + (cnote 6 [bb 2] NOTE_INSN_BASIC_BLOCK) > + (cinsn 2 (set (mem/c:SI (plus:DI (reg/f:DI virtual-stack-vars) > + (const_int -4)) [1 i+0 S4 A32]) > + (reg:SI di [ i ])) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":2) > + (cinsn 3 (set (mem/c:SI (plus:DI (reg/f:DI virtual-stack-vars) > + (const_int -8)) [1 j+0 S4 A32]) > + (reg:SI si [ j ])) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":2) > + (cinsn 4 (set (mem/c:SI (plus:DI (reg/f:DI virtual-stack-vars) > + (const_int -12)) [1 k+0 S4 A32]) > + (reg:SI dx [ k ])) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":2) > + (cnote 5 NOTE_INSN_FUNCTION_BEG) > + (cinsn 8 (set (reg:SI %2) > + (mem/c:SI (plus:DI (reg/f:DI virtual-stack-vars) > + (const_int -4)) [1 i+0 S4 A32])) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":3) > + (cinsn 9 (set (reg:CCGC flags) > + (compare:CCGC (reg:SI %2) > + (mem/c:SI (plus:DI (reg/f:DI virtual-stack-vars) > + (const_int -8)) [1 j+0 S4 A32]))) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":3) > + (cjump_insn 10 (set (pc) > + (if_then_else (ge (reg:CCGC flags) > + (const_int 0)) > + (label_ref 16) > + (pc))) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":3) > + (edge-to 4 (flags "FALLTHRU")) > + (edge-to 5) > + ) ;; block 2 > + (block 4 > + (edge-from 2 (flags "FALLTHRU")) > + (cnote 11 [bb 4] NOTE_INSN_BASIC_BLOCK) > + (cinsn 12 (set (reg:SI %3) > + (mem/c:SI (plus:DI (reg/f:DI virtual-stack-vars) > + (const_int -12)) [1 k+0 S4 A32])) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":4) > + (cinsn 13 (parallel [ > + (set (reg:SI %0 [ _1 ]) > + (plus:SI (reg:SI %3) > + (const_int 4))) > + (clobber (reg:CC flags)) > + ]) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":4 > + (expr_list:REG_EQUAL (plus:SI (mem/c:SI (plus:DI (reg/f:DI > virtual-stack-vars) > + (const_int -12)) [1 k+0 S4 A32]) > + (const_int 4)))) > + (cjump_insn 14 (set (pc) > + (label_ref 20)) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":4) > + (edge-to 6) > + ) ;; block 4 > + (cbarrier 15) > + (block 5 > + (edge-from 2) > + (clabel 16 2) > + (cnote 17 [bb 5] NOTE_INSN_BASIC_BLOCK) > + (cinsn 18 (set (reg:SI %4) > + (mem/c:SI (plus:DI (reg/f:DI virtual-stack-vars) > + (const_int -12)) [1 k+0 S4 A32])) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":6) > + (cinsn 19 (parallel [ > + (set (reg:SI %0 [ _1 ]) > + (neg:SI (reg:SI %4))) > + (clobber (reg:CC flags)) > + ]) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":6 > + (expr_list:REG_EQUAL (neg:SI (mem/c:SI (plus:DI (reg/f:DI > virtual-stack-vars) > + (const_int -12)) [1 k+0 S4 A32])))) > + (edge-to 6 (flags "FALLTHRU")) > + ) ;; block 5 > + (block 6 > + (edge-from 4) > + (edge-from 5 (flags "FALLTHRU")) > + (clabel 20 3) > + (cnote 21 [bb 6] NOTE_INSN_BASIC_BLOCK) > + (cinsn 22 (set (reg:SI %1 [ <retval> ]) > + (reg:SI %0 [ _1 ]))) > + (cinsn 26 (set (reg/i:SI ax) > + (reg:SI %1 [ <retval> ])) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":7) > + (cinsn 27 (use (reg/i:SI ax)) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":7) > + (edge-to exit (flags "FALLTHRU")) > + ) ;; block 6 > + ) ;; insn-chain > + (crtl > + (return_rtx > + (reg/i:SI ax) > + ) ;; return_rtx > + ) ;; crtl > +) ;; function "test_1" > +} > diff --git a/gcc/testsuite/gcc.dg/rtl/x86_64/test_1.h > b/gcc/testsuite/gcc.dg/rtl/x86_64/test_1.h > new file mode 100644 > index 0000000..a783ea8 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/rtl/x86_64/test_1.h > @@ -0,0 +1,16 @@ > +/* Shared test code for the various __RTL tests of test_1 that > + start at different passes. */ > + > +extern void abort (void); > +extern int test_1 (int i, int j, int k); > + > +int main (void) > +{ > + if (test_1 (0, 0, 3) != -3) > + abort (); > + > + if (test_1 (0, 1, 3) != 7) > + abort (); > + > + return 0; > +} > diff --git a/gcc/testsuite/gcc.dg/rtl/x86_64/times-two.c.after-expand.c > b/gcc/testsuite/gcc.dg/rtl/x86_64/times-two.c.after-expand.c > new file mode 100644 > index 0000000..f6bd45f > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/rtl/x86_64/times-two.c.after-expand.c > @@ -0,0 +1,70 @@ > +/* { dg-do run { target i?86-*-* x86_64-*-* } } */ > + > +extern void abort (void); > + > +int __RTL ("vregs") times_two (int i) > +{ > + /* C function: > + return i * 2; */ > +(function "times_two" > + (param "i" > + (DECL_RTL (mem/c:SI (plus:DI (reg/f:DI virtual-stack-vars) > + (const_int -4)) [1 i+0 S4 A32])) > + (DECL_RTL_INCOMING (reg:SI di [ i ])) > + ) ;; param "i" > + (insn-chain > + (cnote 1 NOTE_INSN_DELETED) > + (block 2 > + (edge-from entry (flags "FALLTHRU")) > + (cnote 4 [bb 2] NOTE_INSN_BASIC_BLOCK) > + (cinsn 2 (set (mem/c:SI (plus:DI (reg/f:DI virtual-stack-vars) > + (const_int -4)) [1 i+0 S4 A32]) > + (reg:SI di [ i ])) "../../src/times-two.c":2 > + (nil)) > + (cnote 3 NOTE_INSN_FUNCTION_BEG) > + (cinsn 6 (set (reg:SI %2) > + (mem/c:SI (plus:DI (reg/f:DI virtual-stack-vars) > + (const_int -4)) [1 i+0 S4 A32])) > "../../src/times-two.c":3 > + (nil)) > + (cinsn 7 (parallel [ > + (set (reg:SI %0 [ _2 ]) > + (ashift:SI (reg:SI %2) > + (const_int 1))) > + (clobber (reg:CC flags)) > + ]) "../../src/times-two.c":3 > + (expr_list:REG_EQUAL (ashift:SI (mem/c:SI (plus:DI > (reg/f:DI virtual-stack-vars) > + (const_int -4)) [1 i+0 S4 A32]) > + (const_int 1)) > + (nil))) > + (cinsn 10 (set (reg:SI %1 [ <retval> ]) > + (reg:SI %0 [ _2 ])) "../../src/times-two.c":3 > + (nil)) > + (cinsn 14 (set (reg/i:SI ax) > + (reg:SI %1 [ <retval> ])) "../../src/times-two.c":4 > + (nil)) > + (cinsn 15 (use (reg/i:SI ax)) "../../src/times-two.c":4 > + (nil)) > + (edge-to exit (flags "FALLTHRU")) > + ) ;; block 2 > + ) ;; insn-chain > + (crtl > + (return_rtx > + (reg/i:SI ax) > + ) ;; return_rtx > + ) ;; crtl > +) ;; function "times_two" > +} > + > +int main (void) > +{ > + if (times_two (0) != 0) > + abort (); > + > + if (times_two (1) != 2) > + abort (); > + > + if (times_two (100) != 200) > + abort (); > + > + return 0; > +} > diff --git a/gcc/testsuite/gcc.dg/rtl/x86_64/times-two.c.before-df.c > b/gcc/testsuite/gcc.dg/rtl/x86_64/times-two.c.before-df.c > new file mode 100644 > index 0000000..5cb4a71 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/rtl/x86_64/times-two.c.before-df.c > @@ -0,0 +1,54 @@ > +/* { dg-do compile { target x86_64-*-* } } */ > +/* { dg-options "-fdump-rtl-dfinit" } */ > + > +int __RTL ("rtl-dfinit") times_two (int i) > +{ > + /* C function: > + return i * 2; */ > +(function "times_two" > + (insn-chain > + (cnote 1 NOTE_INSN_DELETED) > + (block 2 > + (edge-from entry (flags "FALLTHRU")) > + (cnote 4 [bb 2] NOTE_INSN_BASIC_BLOCK) > + (cinsn 2 (set (mem/c:SI (plus:DI (reg/f:DI frame) > + (const_int -4)) [1 i+0 S4 A32]) > + (reg:SI di [ i ])) "../../src/times-two.c":2) > + (cnote 3 NOTE_INSN_FUNCTION_BEG) > + (cinsn 6 (set (reg:SI %2) > + (mem/c:SI (plus:DI (reg/f:DI frame) > + (const_int -4)) [1 i+0 S4 A32])) > "../../src/times-two.c":3) > + (cinsn 7 (parallel [ > + (set (reg:SI %0 [ _2 ]) > + (ashift:SI (reg:SI %2) > + (const_int 1))) > + (clobber (reg:CC flags)) > + ]) "../../src/times-two.c":3 > + (expr_list:REG_EQUAL (ashift:SI (mem/c:SI (plus:DI > (reg/f:DI frame) > + (const_int -4)) [1 i+0 S4 A32]) > + (const_int 1)))) > + (cinsn 10 (set (reg:SI %1 [ <retval> ]) > + (reg:SI %0 [ _2 ])) "../../src/times-two.c":3) > + (cinsn 14 (set (reg/i:SI ax) > + (reg:SI %1 [ <retval> ])) "../../src/times-two.c":4) > + (cinsn 15 (use (reg/i:SI ax)) "../../src/times-two.c":4) > + (edge-to exit (flags "FALLTHRU")) > + ) ;; block 2 > + ) ;; insn-chain > + (crtl > + (return_rtx > + (reg/i:SI ax) > + ) ;; return_rtx > + ) ;; crtl > +) ;; function "times_two" > +} > + > +/* Verify that the dataflow information matches what cc1 would have > + generated. In particular, in earlier versions of the RTL > + frontend, the exit block use of reg 0 (ax) wasn't picked up > + on, due to not setting up crtl->return_rtx based on > + DECL_RESULT (fndecl). */ > + > +/* { dg-final { scan-rtl-dump ";; exit block uses.*0 .ax. 6 .bp. 7 .sp. 20 > .frame." "dfinit" } } */ > + > +/* { dg-final { scan-rtl-dump ";; regs ever live.*0 .ax. 5 .di. 17 .flags." > "dfinit" } } */ > diff --git a/gcc/testsuite/gcc.dg/rtl/x86_64/vregs.c > b/gcc/testsuite/gcc.dg/rtl/x86_64/vregs.c > new file mode 100644 > index 0000000..24d141f > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/rtl/x86_64/vregs.c > @@ -0,0 +1,112 @@ > +/* { dg-do run { target i?86-*-* x86_64-*-* } } */ > +/* { dg-options "-fdump-rtl-vregs" } */ > + > +/* Lightly-modified dump of test.c.225r.expand for x86_64. */ > + > +#include "test_1.h" > + > +int __RTL("vregs") test_1 (int i, int j, int k) > +{ > +(function "test_1" > + (param "i" > + (DECL_RTL (mem/c:SI (plus:DI (reg/f:DI frame) > + (const_int -4)) [1 i+0 S4 A32])) > + (DECL_RTL_INCOMING (reg:SI di [ i ]))) > + (param "j" > + (DECL_RTL (mem/c:SI (plus:DI (reg/f:DI frame) > + (const_int -8)) [1 j+0 S4 A32])) > + (DECL_RTL_INCOMING (reg:SI si [ j ]))) > + (param "k" > + (DECL_RTL (mem/c:SI (plus:DI (reg/f:DI frame) > + (const_int -12)) [1 k+0 S4 A32])) > + (DECL_RTL_INCOMING (reg:SI dx [ k ]))) > + (insn-chain > + (cnote 1 NOTE_INSN_DELETED) > + (block 2 > + (edge-from entry (flags "FALLTHRU")) > + (cnote 6 [bb 2] NOTE_INSN_BASIC_BLOCK) > + (cinsn 2 (set (mem/c:SI (plus:DI (reg/f:DI virtual-stack-vars) > + (const_int -4)) [1 i+0 S4 A32]) > + (reg:SI di [ i ])) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":2) > + (cinsn 3 (set (mem/c:SI (plus:DI (reg/f:DI virtual-stack-vars) > + (const_int -8)) [1 j+0 S4 A32]) > + (reg:SI si [ j ])) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":2) > + (cinsn 4 (set (mem/c:SI (plus:DI (reg/f:DI virtual-stack-vars) > + (const_int -12)) [1 k+0 S4 A32]) > + (reg:SI dx [ k ])) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":2) > + (cnote 5 NOTE_INSN_FUNCTION_BEG) > + (cinsn 8 (set (reg:SI %2) > + (mem/c:SI (plus:DI (reg/f:DI virtual-stack-vars) > + (const_int -4)) [1 i+0 S4 A32])) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":3) > + (cinsn 9 (set (reg:CCGC flags) > + (compare:CCGC (reg:SI %2) > + (mem/c:SI (plus:DI (reg/f:DI virtual-stack-vars) > + (const_int -8)) [1 j+0 S4 A32]))) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":3) > + (cjump_insn 10 (set (pc) > + (if_then_else (ge (reg:CCGC flags) > + (const_int 0)) > + (label_ref 16) > + (pc))) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":3) > + (edge-to 4 (flags "FALLTHRU")) > + (edge-to 5) > + ) ;; block 2 > + (block 4 > + (edge-from 2 (flags "FALLTHRU")) > + (cnote 11 [bb 4] NOTE_INSN_BASIC_BLOCK) > + (cinsn 12 (set (reg:SI %3) > + (mem/c:SI (plus:DI (reg/f:DI virtual-stack-vars) > + (const_int -12)) [1 k+0 S4 A32])) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":4) > + (cinsn 13 (parallel [ > + (set (reg:SI %0 [ _1 ]) > + (plus:SI (reg:SI %3) > + (const_int 4))) > + (clobber (reg:CC flags)) > + ]) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":4 > + (expr_list:REG_EQUAL (plus:SI (mem/c:SI (plus:DI (reg/f:DI > virtual-stack-vars) > + (const_int -12)) [1 k+0 S4 A32]) > + (const_int 4)))) > + (cjump_insn 14 (set (pc) > + (label_ref 20)) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":4) > + (edge-to 6) > + ) ;; block 4 > + (cbarrier 15) > + (block 5 > + (edge-from 2) > + (clabel 16 2) > + (cnote 17 [bb 5] NOTE_INSN_BASIC_BLOCK) > + (cinsn 18 (set (reg:SI %4) > + (mem/c:SI (plus:DI (reg/f:DI virtual-stack-vars) > + (const_int -12)) [1 k+0 S4 A32])) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":6) > + (cinsn 19 (parallel [ > + (set (reg:SI %0 [ _1 ]) > + (neg:SI (reg:SI %4))) > + (clobber (reg:CC flags)) > + ]) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":6 > + (expr_list:REG_EQUAL (neg:SI (mem/c:SI (plus:DI (reg/f:DI > virtual-stack-vars) > + (const_int -12)) [1 k+0 S4 A32])))) > + (edge-to 6 (flags "FALLTHRU")) > + ) ;; block 5 > + (block 6 > + (edge-from 4) > + (edge-from 5 (flags "FALLTHRU")) > + (clabel 20 3) > + (cnote 21 [bb 6] NOTE_INSN_BASIC_BLOCK) > + (cinsn 22 (set (reg:SI %1 [ <retval> ]) > + (reg:SI %0 [ _1 ]))) > + (cinsn 26 (set (reg/i:SI ax) > + (reg:SI %1 [ <retval> ])) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":7) > + (cinsn 27 (use (reg/i:SI ax)) > "../../src/gcc/testsuite/gcc.dg/rtl/test.c":7) > + (edge-to exit (flags "FALLTHRU")) > + ) ;; block 6 > + ) ;; insn-chain > + (crtl > + (return_rtx > + (reg/i:SI ax) > + ) ;; return_rtx > + ) ;; crtl > +) ;; function "test_1" > +} > + > +/* The 9 instances of "virtual-stack-vars" should now all be "frame". */ > +/* { dg-final { scan-rtl-dump-times "frame" 9 "vregs" } } */ > +/* { dg-final { scan-rtl-dump-not "virtual-stack-vars" "vregs" } } */ > -- > 1.8.5.3 >