This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH 9/9] Add "__RTL" to cc1 (v4)
On Fri, Nov 11, 2016 at 10:15 PM, David Malcolm <dmalcolm@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
>