diff mbox

[9/9] Add "__RTL" to cc1 (v4)

Message ID 1478898935-46932-10-git-send-email-dmalcolm@redhat.com
State New
Headers show

Commit Message

David Malcolm Nov. 11, 2016, 9:15 p.m. UTC
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

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.
	* 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.
	* final.c (rest_of_clean_state): Don't call delete_tree_ssa for
	_RTL functions.
	* function.h (struct function): Add field "native_RTL".
	* 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

Comments

Richard Biener Nov. 14, 2016, 3:14 p.m. UTC | #1
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 (&reg_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 (&reg_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
>
David Malcolm Nov. 15, 2016, 9:07 p.m. UTC | #2
On Mon, 2016-11-14 at 16:14 +0100, Richard Biener wrote:
> 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?

It depends what you mean by "work".  If I run it with -fsyntax-only,
then pass_rest_of_compilation::gate returns false, and none of the RTL
passes are run.  Is this behavior correct?

> Doing it like __GIMPLE has the advantage of not exposing
> "rest_of_compilation", etc..

The gimple part of the compiler supports having multiple functions in
memory at once, and then compiling them in arbitrary order based on
decisions made by the callgraph.

By contrast, the RTL part of the compiler is full of singleton state:
things like crtl (aka x_rtl), the state of emit-rtl.c,
"reload_completed", etc etc.

To try to limit the scope of the project, for the RTL frontend work I'm
merely attempting to restore the singleton RTL state from a dump,
rather than to support having per function stashes of RTL state.

Hence the rest of compilation gets invoked directly from the frontend
for the __RTL case, since it will get overwritten if there's a second
__RTL function in the source file (which sounds like an idea for a test
case; I'll attempt such a test case).

I hope this is a reasonable approach.  If not, I suppose I can attempt
to bundle it up into some kind of RTL function state, but that seems
like significant scope creep.

> 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.

(Congratulations on getting the GIMPLE FE stuff in)

I'm not sure I understand you here - do you want me to rewrite the
__RTL parsing to match the __GIMPLE piece, or the other way around?
If the former, presumably I should reuse (and rename)
c_parser_gimple_pass_list?


> > 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?

It happens when running pass_outof_cfg_layout_mode::execute; seen with
gcc.dg/rtl/x86_64/test-return-const.c.before-fwprop.c.

The input file is a dump taken in cfg_layout mode (although in this
case it's a trivial 3-basic-block CFG, but ideally there would be cases
with non-trivial control flow); it has "fwprop1" as its starting pass.

Running without -quiet shows:

skipping pass: *rest_of_compilation
skipping pass: vregs
skipping pass: into_cfglayout
skipping pass: jump
skipping pass: subreg1
skipping pass: cse1
found starting pass: fwprop1

i.e. it skips the into_cfglayout (amongst others), to start with
fwprop1.

In theory skipping a pass ought to be a no-op, assuming that we're
faithfully reconstructing all RTL state.  However, RTL state management
is fiddly, so the patch introduces some logic in passes.c to do some
things when skipping a pass; in particular, it has:

	      /* 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;
		}

so that even when skipping "into_cfglayout", the CFG hooks are at least
correct.

The assertion fires when running outof_cfglayout later on (rather than
skipping it); the assertion:

  gcc_assert (original_copy_bb_pool);

assumes that into_cfglayout was actually run, rather than just the
simple "skipping" version of it.

> >         * 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).

Thanks; fixed.

> >         * 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)

I tried to doing that; it mostly works, but this assertion fails:

237	symtab_node::needed_p (void)
238	{
239	  /* Double check that no one output the function into assembly file
240	     early.  */
241	  if (!native_rtl_p ())
242	      gcc_checking_assert
243		(!DECL_ASSEMBLER_NAME_SET_P (decl)
244		 || !TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)));

[I added the "if (!native_rtl_p ())" guard in the patch]

The issue here is that when this is run, the __RTL function has been
compiled and cleaned up, and the curr_properties & PROP_rtl has been
cleared:

  (gdb) p decl->function_decl->f->curr_properties
  $7 = 0

I could set the flag again after running the passes; on doing so, the
test suite successfully runs.

Would you prefer I use curr_properties & PROP_rtl for this?

[...snip...]

Thanks
Dave
Richard Biener Nov. 16, 2016, 1:24 p.m. UTC | #3
On Tue, Nov 15, 2016 at 10:07 PM, David Malcolm <dmalcolm@redhat.com> wrote:
> On Mon, 2016-11-14 at 16:14 +0100, Richard Biener wrote:
>> 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?
>
> It depends what you mean by "work".  If I run it with -fsyntax-only,
> then pass_rest_of_compilation::gate returns false, and none of the RTL
> passes are run.  Is this behavior correct?

Yes.

>> Doing it like __GIMPLE has the advantage of not exposing
>> "rest_of_compilation", etc..
>
> The gimple part of the compiler supports having multiple functions in
> memory at once, and then compiling them in arbitrary order based on
> decisions made by the callgraph.
>
> By contrast, the RTL part of the compiler is full of singleton state:
> things like crtl (aka x_rtl), the state of emit-rtl.c,
> "reload_completed", etc etc.

Ah, of course - I forgot that...

> To try to limit the scope of the project, for the RTL frontend work I'm
> merely attempting to restore the singleton RTL state from a dump,
> rather than to support having per function stashes of RTL state.
>
> Hence the rest of compilation gets invoked directly from the frontend
> for the __RTL case, since it will get overwritten if there's a second
> __RTL function in the source file (which sounds like an idea for a test
> case; I'll attempt such a test case).
>
> I hope this is a reasonable approach.  If not, I suppose I can attempt
> to bundle it up into some kind of RTL function state, but that seems
> like significant scope creep.

Yeah, I think it's a good approach for now.

>> 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.
>
> (Congratulations on getting the GIMPLE FE stuff in)
>
> I'm not sure I understand you here - do you want me to rewrite the
> __RTL parsing to match the __GIMPLE piece, or the other way around?
> If the former, presumably I should reuse (and rename)
> c_parser_gimple_pass_list?

Handle __RTL like __GIMPLE, thus as declspec.  Of course ultimatively
Joseph has the last word 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?
>
> It happens when running pass_outof_cfg_layout_mode::execute; seen with
> gcc.dg/rtl/x86_64/test-return-const.c.before-fwprop.c.
>
> The input file is a dump taken in cfg_layout mode (although in this
> case it's a trivial 3-basic-block CFG, but ideally there would be cases
> with non-trivial control flow); it has "fwprop1" as its starting pass.
>
> Running without -quiet shows:
>
> skipping pass: *rest_of_compilation
> skipping pass: vregs
> skipping pass: into_cfglayout
> skipping pass: jump
> skipping pass: subreg1
> skipping pass: cse1
> found starting pass: fwprop1
>
> i.e. it skips the into_cfglayout (amongst others), to start with
> fwprop1.
>
> In theory skipping a pass ought to be a no-op, assuming that we're
> faithfully reconstructing all RTL state.  However, RTL state management
> is fiddly, so the patch introduces some logic in passes.c to do some
> things when skipping a pass; in particular, it has:
>
>               /* 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;
>                 }
>
> so that even when skipping "into_cfglayout", the CFG hooks are at least
> correct.

I suppose the pass manager could handle the hook switching based on
a (RTL) pass setting/clearing PROP_cfglayout.  Or all passes needing
cfglayout would need to set prop_required accordingly and thus
the into/outouf cfglayout passes would be implicit.

> The assertion fires when running outof_cfglayout later on (rather than
> skipping it); the assertion:
>
>   gcc_assert (original_copy_bb_pool);
>
> assumes that into_cfglayout was actually run, rather than just the
> simple "skipping" version of it.

Ah, I see cfg_layout_initialize calls initialize_original_copy_tables ()
for whatever reason and they are kept initialized until out-of-cfglayout...

GIMPLE passes do init/free them all the time.  I think a better
fix would be to add a original_copy_tables_initialized () function
and guard the free_original_copy_tables call with that (keeping
the assertion that they run in pairs).

>> >         * 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).
>
> Thanks; fixed.
>
>> >         * 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)
>
> I tried to doing that; it mostly works, but this assertion fails:
>
> 237     symtab_node::needed_p (void)
> 238     {
> 239       /* Double check that no one output the function into assembly file
> 240          early.  */
> 241       if (!native_rtl_p ())
> 242           gcc_checking_assert
> 243             (!DECL_ASSEMBLER_NAME_SET_P (decl)
> 244              || !TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)));
>
> [I added the "if (!native_rtl_p ())" guard in the patch]
>
> The issue here is that when this is run, the __RTL function has been
> compiled and cleaned up, and the curr_properties & PROP_rtl has been
> cleared:
>
>   (gdb) p decl->function_decl->f->curr_properties
>   $7 = 0
>
> I could set the flag again after running the passes; on doing so, the
> test suite successfully runs.

Hmm, so if you are finished with the function you should set
symtab_node->analyzed
to false I think (it signals it's now merely an "extern" symbol and no
longer has a body).
Or set body_removed.  Maybe just ask Honza what to do ...

Richard.

> Would you prefer I use curr_properties & PROP_rtl for this?

> [...snip...]
>
> Thanks
> Dave
diff mbox

Patch

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 (&reg_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 (&reg_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" } }  */