This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


On Fri, Nov 11, 2016 at 10:15 PM, David Malcolm <dmalcolm@redhat.com> wrote:
> Changed in this version:
>
> * Rather than running just one pass, run *all* passes, but start at
>   the given pass; support for "dg-do run" tests that execute the
>   resulting code.
> * Updated test cases to new "compact" dump format; more test cases;
>   use "dg-do run" in various places.
> * Lots of bugfixing
>
> Links to previous versions:
>   https://gcc.gnu.org/ml/gcc-patches/2016-10/msg00263.html
>   https://gcc.gnu.org/ml/gcc-patches/2016-10/msg00500.html

Does running the RTL passes right from the parser work with -fsyntax-only?
Doing it like __GIMPLE has the advantage of not exposing
"rest_of_compilation", etc..

I'm now handling __GIMPLE from within declspecs (the GIMPLE FE stuff
has been committed), it would be nice to match the __RTL piece here.

> gcc/ChangeLog:
>         * Makefile.in (OBJS): Add run-rtl-passes.o.
>
> gcc/c-family/ChangeLog:
>         * c-common.c (c_common_reswords): Add "__RTL".
>         * c-common.h (enum rid): Add RID_RTL.
>
> gcc/c/ChangeLog:
>         * c-parser.c: Include "read-rtl-function.h" and
>         "run-rtl-passes.h".
>         (c_parser_declaration_or_fndef): In the "GNU extensions" part of
>         the leading comment, add an alternate production for
>         "function-definition", along with new "rtl-body-specifier" and
>         "rtl-body-pass-specifier" productions.  Handle "__RTL" by calling
>         c_parser_parse_rtl_body.  Convert a timevar_push/pop pair
>         to an auto_timevar, to cope with early exit.
>         (c_parser_parse_rtl_body): New function.
>
> gcc/ChangeLog:
>         * cfg.c (free_original_copy_tables): Remove assertion
>         on original_copy_bb_pool.

How can that trigger?

>         * cgraph.h (symtab_node::native_rtl_p): New decl.
>         * cgraphunit.c (symtab_node::native_rtl_p): New function.
>         (symtab_node::needed_p): Don't assert for early assembly output
>         for __RTL functions.
>         (cgraph_node::finalize_function): Set "force_output" for __RTL
>         functions.
>         (cgraph_node::analyze): Bail out early for __RTL functions.
>         (analyze_functions): Update assertion to support __RTL functions.
>         (cgraph_node::expand): Bail out early for __RTL functions.
>         * emit-rtl.c (unshare_all_rtl_again): Wrap set_used_decls call
>         in check for DECL_INITIAL.

You should simply set DECL_INITIAL of your function decl (make_node (BLOCK);).
There's too much code assuming that is not NULL (and I've fixed quite a bit of
code during stage1 not doing that).

>         * final.c (rest_of_clean_state): Don't call delete_tree_ssa for
>         _RTL functions.
>         * function.h (struct function): Add field "native_RTL".

I wonder if you could simply use ->curr_properties & PROP_rtl?  (and set that
property during parsing, of course)

>         * gimple-expr.c (gimple_has_body_p): Return false for __RTL
>         functions.
>         * pass_manager.h (gcc::pass_manager::get_rest_of_compilation): New
>         accessor.
>         (gcc::pass_manager::get_clean_slate): New accessor.
>         * passes.c: Include "insn-addr.h".
>         (execute_one_pass): Implement skipping of passes for functions
>         with pass_startwith set.
>         * read-md.c (md_reader::read_char): Support filtering
>         the input to a subset of line numbers.
>         (md_reader::md_reader): Initialize fields
>         m_first_line and m_last_line.
>         (md_reader::read_file_fragment): New function.
>         * read-md.h (md_reader::read_file_fragment): New decl.
>         (md_reader::m_first_line): New field.
>         (md_reader::int m_last_line): New field.
>         * read-rtl-function.c (function_reader::create_function): Only create
>         cfun if it doesn't already exist.  Set "native_RTL" on cfun.  Set
>         DECL_INITIAL.
>         (read_rtl_function_body_from_file_range): New function.
>         * read-rtl-function.h (read_rtl_function_body_from_file_range):
>         New decl.
>         * run-rtl-passes.c: New file.
>         * run-rtl-passes.h: New file.
>
> gcc/testsuite/ChangeLog:
>         * gcc.dg/rtl/aarch64/asr_div1.c: New file.
>         * gcc.dg/rtl/aarch64/pr71779.c: New file.
>         * gcc.dg/rtl/rtl.exp: New file.
>         * gcc.dg/rtl/test.c: New file.
>         * gcc.dg/rtl/unknown-rtx-code.c: New file.
>         * gcc.dg/rtl/x86_64/dfinit.c: New file.
>         * gcc.dg/rtl/x86_64/different-structs.c: New file.
>         * gcc.dg/rtl/x86_64/final.c: New file.
>         * gcc.dg/rtl/x86_64/into-cfglayout.c: New file.
>         * gcc.dg/rtl/x86_64/ira.c: New file.
>         * gcc.dg/rtl/x86_64/pro_and_epilogue.c: New file.
>         * gcc.dg/rtl/x86_64/test-return-const.c.after-expand.c: New file.
>         * gcc.dg/rtl/x86_64/test-return-const.c.before-fwprop.c: New file.
>         * gcc.dg/rtl/x86_64/test-rtl.c: New file.
>         * gcc.dg/rtl/x86_64/test_1.h: New file.
>         * gcc.dg/rtl/x86_64/times-two.c.after-expand.c: New file.
>         * gcc.dg/rtl/x86_64/times-two.c.before-df.c: New file.
>         * gcc.dg/rtl/x86_64/vregs.c: New file.
> ---
>  gcc/Makefile.in                                    |   1 +
>  gcc/c-family/c-common.c                            |   1 +
>  gcc/c-family/c-common.h                            |   3 +
>  gcc/c/c-parser.c                                   | 122 ++++++++++++++++++-
>  gcc/cfg.c                                          |   1 -
>  gcc/cgraph.h                                       |   4 +
>  gcc/cgraphunit.c                                   |  41 ++++++-
>  gcc/emit-rtl.c                                     |   3 +-
>  gcc/final.c                                        |   3 +-
>  gcc/function.h                                     |   9 ++
>  gcc/gimple-expr.c                                  |   2 +-
>  gcc/pass_manager.h                                 |   6 +
>  gcc/passes.c                                       |  47 ++++++++
>  gcc/read-md.c                                      |  35 +++++-
>  gcc/read-md.h                                      |   7 ++
>  gcc/read-rtl-function.c                            |  83 ++++++++++---
>  gcc/read-rtl-function.h                            |   3 +
>  gcc/run-rtl-passes.c                               |  85 +++++++++++++
>  gcc/run-rtl-passes.h                               |  25 ++++
>  gcc/testsuite/gcc.dg/rtl/aarch64/asr_div1.c        |  41 +++++++
>  gcc/testsuite/gcc.dg/rtl/aarch64/pr71779.c         |  50 ++++++++
>  gcc/testsuite/gcc.dg/rtl/rtl.exp                   |  41 +++++++
>  gcc/testsuite/gcc.dg/rtl/test.c                    |  31 +++++
>  gcc/testsuite/gcc.dg/rtl/unknown-rtx-code.c        |   8 ++
>  gcc/testsuite/gcc.dg/rtl/x86_64/dfinit.c           | 116 ++++++++++++++++++
>  .../gcc.dg/rtl/x86_64/different-structs.c          |  81 +++++++++++++
>  gcc/testsuite/gcc.dg/rtl/x86_64/final.c            | 133 +++++++++++++++++++++
>  gcc/testsuite/gcc.dg/rtl/x86_64/into-cfglayout.c   | 117 ++++++++++++++++++
>  gcc/testsuite/gcc.dg/rtl/x86_64/ira.c              | 111 +++++++++++++++++
>  gcc/testsuite/gcc.dg/rtl/x86_64/pro_and_epilogue.c | 110 +++++++++++++++++
>  .../rtl/x86_64/test-return-const.c.after-expand.c  |  39 ++++++
>  .../rtl/x86_64/test-return-const.c.before-fwprop.c |  42 +++++++
>  gcc/testsuite/gcc.dg/rtl/x86_64/test-rtl.c         | 101 ++++++++++++++++
>  gcc/testsuite/gcc.dg/rtl/x86_64/test_1.h           |  16 +++
>  .../gcc.dg/rtl/x86_64/times-two.c.after-expand.c   |  70 +++++++++++
>  .../gcc.dg/rtl/x86_64/times-two.c.before-df.c      |  54 +++++++++
>  gcc/testsuite/gcc.dg/rtl/x86_64/vregs.c            | 112 +++++++++++++++++
>  37 files changed, 1727 insertions(+), 27 deletions(-)
>  create mode 100644 gcc/run-rtl-passes.c
>  create mode 100644 gcc/run-rtl-passes.h
>  create mode 100644 gcc/testsuite/gcc.dg/rtl/aarch64/asr_div1.c
>  create mode 100644 gcc/testsuite/gcc.dg/rtl/aarch64/pr71779.c
>  create mode 100644 gcc/testsuite/gcc.dg/rtl/rtl.exp
>  create mode 100644 gcc/testsuite/gcc.dg/rtl/test.c
>  create mode 100644 gcc/testsuite/gcc.dg/rtl/unknown-rtx-code.c
>  create mode 100644 gcc/testsuite/gcc.dg/rtl/x86_64/dfinit.c
>  create mode 100644 gcc/testsuite/gcc.dg/rtl/x86_64/different-structs.c
>  create mode 100644 gcc/testsuite/gcc.dg/rtl/x86_64/final.c
>  create mode 100644 gcc/testsuite/gcc.dg/rtl/x86_64/into-cfglayout.c
>  create mode 100644 gcc/testsuite/gcc.dg/rtl/x86_64/ira.c
>  create mode 100644 gcc/testsuite/gcc.dg/rtl/x86_64/pro_and_epilogue.c
>  create mode 100644 gcc/testsuite/gcc.dg/rtl/x86_64/test-return-const.c.after-expand.c
>  create mode 100644 gcc/testsuite/gcc.dg/rtl/x86_64/test-return-const.c.before-fwprop.c
>  create mode 100644 gcc/testsuite/gcc.dg/rtl/x86_64/test-rtl.c
>  create mode 100644 gcc/testsuite/gcc.dg/rtl/x86_64/test_1.h
>  create mode 100644 gcc/testsuite/gcc.dg/rtl/x86_64/times-two.c.after-expand.c
>  create mode 100644 gcc/testsuite/gcc.dg/rtl/x86_64/times-two.c.before-df.c
>  create mode 100644 gcc/testsuite/gcc.dg/rtl/x86_64/vregs.c
>
> diff --git a/gcc/Makefile.in b/gcc/Makefile.in
> index 73d12dc..14ffb96 100644
> --- a/gcc/Makefile.in
> +++ b/gcc/Makefile.in
> @@ -1429,6 +1429,7 @@ OBJS = \
>         rtlhash.o \
>         rtlanal.o \
>         rtlhooks.o \
> +       run-rtl-passes.o \
>         sbitmap.o \
>         sched-deps.o \
>         sched-ebb.o \
> diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
> index 307862b..573ca7a 100644
> --- a/gcc/c-family/c-common.c
> +++ b/gcc/c-family/c-common.c
> @@ -435,6 +435,7 @@ const struct c_common_resword c_common_reswords[] =
>    { "__underlying_type", RID_UNDERLYING_TYPE, D_CXXONLY },
>    { "__volatile",      RID_VOLATILE,   0 },
>    { "__volatile__",    RID_VOLATILE,   0 },
> +  { "__RTL",           RID_RTL,        0 },
>    { "alignas",         RID_ALIGNAS,    D_CXXONLY | D_CXX11 | D_CXXWARN },
>    { "alignof",         RID_ALIGNOF,    D_CXXONLY | D_CXX11 | D_CXXWARN },
>    { "asm",             RID_ASM,        D_ASM },
> diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
> index 547bab2..5e6882e 100644
> --- a/gcc/c-family/c-common.h
> +++ b/gcc/c-family/c-common.h
> @@ -118,6 +118,9 @@ enum rid
>
>    RID_FRACT, RID_ACCUM, RID_AUTO_TYPE, RID_BUILTIN_CALL_WITH_STATIC_CHAIN,
>
> +  /* "__RTL", for the RTL-parsing extension to the C frontend.  */
> +  RID_RTL,
> +
>    /* C11 */
>    RID_ALIGNAS, RID_GENERIC,
>
> diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
> index 6bc42da..e6e86ec 100644
> --- a/gcc/c/c-parser.c
> +++ b/gcc/c/c-parser.c
> @@ -59,6 +59,8 @@ along with GCC; see the file COPYING3.  If not see
>  #include "gimple-expr.h"
>  #include "context.h"
>  #include "gcc-rich-location.h"
> +#include "read-rtl-function.h"
> +#include "run-rtl-passes.h"
>
>  /* We need to walk over decls with incomplete struct/union/enum types
>     after parsing the whole translation unit.
> @@ -1421,6 +1423,9 @@ static tree c_parser_array_notation (location_t, c_parser *, tree, tree);
>  static tree c_parser_cilk_clause_vectorlength (c_parser *, tree, bool);
>  static void c_parser_cilk_grainsize (c_parser *, bool *);
>
> +static void c_parser_parse_rtl_body (c_parser *parser,
> +                                    const char *start_with_pass);
> +
>  /* Parse a translation unit (C90 6.7, C99 6.9).
>
>     translation-unit:
> @@ -1624,6 +1629,16 @@ static void c_finish_oacc_routine (struct oacc_routine_data *, tree, bool);
>       declaration-specifiers declarator declaration-list[opt]
>         compound-statement
>
> +   function-definition:
> +     declaration-specifiers rtl-body-specifier declarator declaration-list[opt]
> +       compound-statement
> +
> +   rtl-body-specifier:
> +     __RTL rtl-body-pass-specifier[opt]
> +
> +   rtl-body-pass-specifier:
> +     ( string )
> +
>     attribute ;
>
>     Objective-C:
> @@ -1668,6 +1683,8 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
>    tree all_prefix_attrs;
>    bool diagnosed_no_specs = false;
>    location_t here = c_parser_peek_token (parser)->location;
> +  bool rtl_body_p = false;
> +  const char *start_with_pass = NULL;
>
>    if (static_assert_ok
>        && c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
> @@ -1752,6 +1769,33 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
>        c_parser_skip_to_end_of_block_or_statement (parser);
>        return;
>      }
> +
> +  /* Handle GNU extension rtl-body-specifier by detecting "__RTL".  */
> +  if (c_parser_next_token_is_keyword (parser, RID_RTL))
> +    {
> +      rtl_body_p = true;
> +      c_parser_consume_token (parser);
> +
> +      /* Handle the optional rtl-body-pass-specifier: parens wrapping
> +        a string, giving a pass name.  */
> +      if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
> +       {
> +         c_parser_consume_token (parser);
> +         c_token *tok = c_parser_peek_token (parser);
> +         if (tok->type != CPP_STRING)
> +           {
> +             c_parser_error (parser, "expected string");
> +             c_parser_skip_to_end_of_block_or_statement (parser);
> +             return;
> +           }
> +         gcc_assert (TREE_CODE (tok->value) == STRING_CST);
> +         start_with_pass = TREE_STRING_POINTER (tok->value);
> +         c_parser_consume_token (parser);
> +
> +         c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>");
> +       }
> +    }
> +
>    finish_declspecs (specs);
>    bool auto_type_p = specs->typespec_word == cts_auto_type;
>    if (c_parser_next_token_is (parser, CPP_SEMICOLON))
> @@ -2146,7 +2190,7 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
>          tv = TV_PARSE_INLINE;
>        else
>          tv = TV_PARSE_FUNC;
> -      timevar_push (tv);
> +      auto_timevar at (g_timer, tv);
>
>        /* Parse old-style parameter declarations.  ??? Attributes are
>          not allowed to start declaration specifiers here because of a
> @@ -2173,6 +2217,24 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
>         c_finish_oacc_routine (oacc_routine_data, current_function_decl, true);
>        DECL_STRUCT_FUNCTION (current_function_decl)->function_start_locus
>         = c_parser_peek_token (parser)->location;
> +
> +      /* If we had an rtl-body-specifier, use the RTL parser now,
> +        consuming the function body.  */
> +      if (rtl_body_p)
> +       {
> +         c_parser_parse_rtl_body (parser, start_with_pass);
> +
> +         /* Normally, store_parm_decls sets next_is_function_body,
> +            anticipating a function body.  We need a push_scope/pop_scope
> +            pair to flush out this state, or subsequent function parsing
> +            will go wrong.  */
> +         push_scope ();
> +         pop_scope ();
> +
> +         finish_function ();
> +         return;
> +       }
> +
>        fnbody = c_parser_compound_statement (parser);
>        if (flag_cilkplus && contains_array_notation_expr (fnbody))
>         fnbody = expand_array_notation_exprs (fnbody);
> @@ -2195,7 +2257,6 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
>           finish_function ();
>         }
>
> -      timevar_pop (tv);
>        break;
>      }
>  }
> @@ -18313,4 +18374,61 @@ c_parser_array_notation (location_t loc, c_parser *parser, tree initial_index,
>    return value_tree;
>  }
>
> +/* Parse the body of a function declaration marked with "__RTL".
> +
> +   The RTL parser works on the level of characters read from a
> +   FILE *, whereas c_parser works at the level of tokens.
> +   Square this circle by consuming all of the tokens up to and
> +   including the closing brace, recording the start/end of the RTL
> +   fragment, and reopening the file and re-reading the relevant
> +   lines within the RTL parser.
> +
> +   This requires the opening and closing braces of the C function
> +   to be on separate lines from the RTL they wrap.  */
> +
> +void
> +c_parser_parse_rtl_body (c_parser *parser, const char *start_with_pass)
> +{
> +  if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
> +    return;
> +
> +  location_t start_loc = c_parser_peek_token (parser)->location;
> +
> +  /* Consume all tokens, up to the closing brace, handling
> +     matching pairs of braces in the rtl dump.  */
> +  int num_open_braces = 1;
> +  while (1)
> +    {
> +      switch (c_parser_peek_token (parser)->type)
> +       {
> +       case CPP_OPEN_BRACE:
> +         num_open_braces++;
> +         break;
> +       case CPP_CLOSE_BRACE:
> +         if (--num_open_braces == 0)
> +           goto found_closing_brace;
> +         break;
> +       default:
> +         break;
> +       }
> +      c_parser_consume_token (parser);
> +    }
> +
> + found_closing_brace:
> +  /* At the closing brace; record its location.  */
> +  location_t end_loc = c_parser_peek_token (parser)->location;
> +
> +  /* Consume the closing brace.  */
> +  c_parser_consume_token (parser);
> +
> +  /* Invoke the RTL parser.  */
> +  if (!read_rtl_function_body_from_file_range (start_loc, end_loc))
> +    return;
> +
> + /*  If a pass name was provided for START_WITH_PASS, run the backend
> +     accordingly now, on the cfun created above.  */
> +  if (start_with_pass)
> +    run_rtl_passes (start_with_pass);
> +}
> +
>  #include "gt-c-c-parser.h"
> diff --git a/gcc/cfg.c b/gcc/cfg.c
> index 6604b02..26a68c1 100644
> --- a/gcc/cfg.c
> +++ b/gcc/cfg.c
> @@ -1083,7 +1083,6 @@ reset_original_copy_tables (void)
>  void
>  free_original_copy_tables (void)
>  {
> -  gcc_assert (original_copy_bb_pool);
>    delete bb_copy;
>    bb_copy = NULL;
>    delete bb_original;
> diff --git a/gcc/cgraph.h b/gcc/cgraph.h
> index cc730d2..79e33da 100644
> --- a/gcc/cgraph.h
> +++ b/gcc/cgraph.h
> @@ -328,6 +328,10 @@ public:
>       configury. This function is used just during symbol creation.  */
>    bool needed_p (void);
>
> +  /* Return true if this symbol is a function from the C frontend specified
> +     directly in RTL form (with "__RTL").  */
> +  bool native_rtl_p () const;
> +
>    /* Return true when there are references to the node.  */
>    bool referred_to_p (bool include_self = true);
>
> diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
> index e315a77..956562e 100644
> --- a/gcc/cgraphunit.c
> +++ b/gcc/cgraphunit.c
> @@ -217,6 +217,19 @@ static void handle_alias_pairs (void);
>  /* Used for vtable lookup in thunk adjusting.  */
>  static GTY (()) tree vtable_entry_type;
>
> +/* Return true if this symbol is a function from the C frontend specified
> +   directly in RTL form (with "__RTL").  */
> +
> +bool
> +symtab_node::native_rtl_p () const
> +{
> +  if (TREE_CODE (decl) != FUNCTION_DECL)
> +    return false;
> +  if (!DECL_STRUCT_FUNCTION (decl))
> +    return false;
> +  return DECL_STRUCT_FUNCTION (decl)->native_RTL;
> +}
> +
>  /* Determine if symbol declaration is needed.  That is, visible to something
>     either outside this translation unit, something magic in the system
>     configury */
> @@ -225,8 +238,10 @@ symtab_node::needed_p (void)
>  {
>    /* Double check that no one output the function into assembly file
>       early.  */
> -  gcc_checking_assert (!DECL_ASSEMBLER_NAME_SET_P (decl)
> -                      || !TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)));
> +  if (!native_rtl_p ())
> +      gcc_checking_assert
> +       (!DECL_ASSEMBLER_NAME_SET_P (decl)
> +        || !TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)));
>
>    if (!definition)
>      return false;
> @@ -435,6 +450,14 @@ cgraph_node::finalize_function (tree decl, bool no_collect)
>        && !DECL_DISREGARD_INLINE_LIMITS (decl))
>      node->force_output = 1;
>
> +  /* __RTL functions were already output as soon as they were parsed (due
> +     to the large amount of global state in the backend).
> +     Mark such functions as "force_output" to reflect the fact that they
> +     will be in the asm file when considering the symbols they reference.
> +     The attempt to output them later on will bail out immediately.  */
> +  if (node->native_rtl_p ())
> +    node->force_output = 1;
> +
>    /* When not optimizing, also output the static functions. (see
>       PR24561), but don't do so for always_inline functions, functions
>       declared inline and nested functions.  These were optimized out
> @@ -568,6 +591,12 @@ cgraph_node::add_new_function (tree fndecl, bool lowered)
>  void
>  cgraph_node::analyze (void)
>  {
> +  if (native_rtl_p ())
> +    {
> +      analyzed = true;
> +      return;
> +    }
> +
>    tree decl = this->decl;
>    location_t saved_loc = input_location;
>    input_location = DECL_SOURCE_LOCATION (decl);
> @@ -1226,7 +1255,8 @@ analyze_functions (bool first_time)
>
>           gcc_assert (!cnode->definition || cnode->thunk.thunk_p
>                       || cnode->alias
> -                     || gimple_has_body_p (decl));
> +                     || gimple_has_body_p (decl)
> +                     || cnode->native_rtl_p ());
>           gcc_assert (cnode->analyzed == cnode->definition);
>         }
>        node->aux = NULL;
> @@ -1965,6 +1995,11 @@ cgraph_node::expand (void)
>    /* We ought to not compile any inline clones.  */
>    gcc_assert (!global.inlined_to);
>
> +  /* __RTL functions are compiled as soon as they are parsed, so don't
> +     do it again.  */
> +  if (native_rtl_p ())
> +    return;
> +
>    announce_function (decl);
>    process = 0;
>    gcc_assert (lowered);
> diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
> index 179a91f..8039742 100644
> --- a/gcc/emit-rtl.c
> +++ b/gcc/emit-rtl.c
> @@ -2672,7 +2672,8 @@ unshare_all_rtl_again (rtx_insn *insn)
>        }
>
>    /* Make sure that virtual stack slots are not shared.  */
> -  set_used_decls (DECL_INITIAL (cfun->decl));
> +  if (DECL_INITIAL (cfun->decl))
> +    set_used_decls (DECL_INITIAL (cfun->decl));
>
>    /* Make sure that virtual parameters are not shared.  */
>    for (decl = DECL_ARGUMENTS (cfun->decl); decl; decl = DECL_CHAIN (decl))
> diff --git a/gcc/final.c b/gcc/final.c
> index 5709d0e..97e2e1a 100644
> --- a/gcc/final.c
> +++ b/gcc/final.c
> @@ -4701,7 +4701,8 @@ rest_of_clean_state (void)
>
>    free_bb_for_insn ();
>
> -  delete_tree_ssa (cfun);
> +  if (!cfun->native_RTL)
> +    delete_tree_ssa (cfun);
>
>    /* We can reduce stack alignment on call site only when we are sure that
>       the function body just produced will be actually used in the final
> diff --git a/gcc/function.h b/gcc/function.h
> index 9fe479c..2263f30 100644
> --- a/gcc/function.h
> +++ b/gcc/function.h
> @@ -236,6 +236,9 @@ struct GTY(()) function {
>    /* The loops in this function.  */
>    struct loops *x_current_loops;
>
> +  /* Filled by the GIMPLE FE, pass to start compilation with.  */
> +  const char *pass_startwith;
> +
>    /* The stack usage of this function.  */
>    struct stack_usage *su;
>
> @@ -384,6 +387,12 @@ struct GTY(()) function {
>
>    /* Set when the tail call has been identified.  */
>    unsigned int tail_call_marked : 1;
> +
> +  /* Nonzero if the the current function was specified in RTL form using the
> +     C frontend's "__RTL" syntax.  This initializes global RTL state, and so
> +     such functions must be compiled immediately, rather than under the
> +     control of the callgraph.  */
> +  unsigned int native_RTL : 1;
>  };
>
>  /* Add the decl D to the local_decls list of FUN.  */
> diff --git a/gcc/gimple-expr.c b/gcc/gimple-expr.c
> index de5cce1..3a06888 100644
> --- a/gcc/gimple-expr.c
> +++ b/gcc/gimple-expr.c
> @@ -323,7 +323,7 @@ bool
>  gimple_has_body_p (tree fndecl)
>  {
>    struct function *fn = DECL_STRUCT_FUNCTION (fndecl);
> -  return (gimple_body (fndecl) || (fn && fn->cfg));
> +  return (gimple_body (fndecl) || (fn && fn->cfg && !fn->native_RTL));
>  }
>
>  /* Return a printable name for symbol DECL.  */
> diff --git a/gcc/pass_manager.h b/gcc/pass_manager.h
> index 464e25f..7278d97 100644
> --- a/gcc/pass_manager.h
> +++ b/gcc/pass_manager.h
> @@ -82,6 +82,12 @@ public:
>
>    opt_pass *get_pass_by_name (const char *name);
>
> +  opt_pass *get_rest_of_compilation () const
> +  {
> +    return pass_rest_of_compilation_1;
> +  }
> +  opt_pass *get_clean_slate () const { return pass_clean_state_1; }
> +
>  public:
>    /* The root of the compilation pass tree, once constructed.  */
>    opt_pass *all_passes;
> diff --git a/gcc/passes.c b/gcc/passes.c
> index e78f9ed..54029f5 100644
> --- a/gcc/passes.c
> +++ b/gcc/passes.c
> @@ -59,6 +59,7 @@ along with GCC; see the file COPYING3.  If not see
>  #include "cfgrtl.h"
>  #include "tree-ssa-live.h"  /* For remove_unused_locals.  */
>  #include "tree-cfgcleanup.h"
> +#include "insn-addr.h" /* for INSN_ADDRESSES_ALLOC.  */
>
>  using namespace gcc;
>
> @@ -2313,6 +2314,52 @@ execute_one_pass (opt_pass *pass)
>        return false;
>      }
>
> +  /* For skipping passes until startwith pass */
> +  if (cfun
> +      && cfun->pass_startwith)
> +    {
> +      if (strcmp (pass->name, cfun->pass_startwith) == 0)
> +       {
> +         if (!quiet_flag)
> +           fprintf (stderr, "found starting pass: %s\n", cfun->pass_startwith);
> +         cfun->pass_startwith = NULL;
> +       }
> +      else
> +       {
> +         /* Don't skip df init; later passes need it.  */
> +         if (strstr (pass->name, "dfinit") == NULL)
> +           {
> +             if (!quiet_flag)
> +               fprintf (stderr, "skipping pass: %s\n", pass->name);
> +
> +             /* Pass "reload" sets the global "reload_completed", and many
> +                things depend on this (e.g. instructions in .md files).  */
> +             if (strcmp (pass->name, "reload") == 0)
> +               reload_completed = 1;
> +
> +             /* The INSN_ADDRESSES vec is normally set up by
> +                shorten_branches; set it up for the benefit of passes that
> +                run after this.  */
> +             if (strcmp (pass->name, "shorten") == 0)
> +               INSN_ADDRESSES_ALLOC (get_max_uid ());
> +
> +             /* Update the cfg hooks as appropriate.  */
> +             if (strcmp (pass->name, "into_cfglayout") == 0)
> +               {
> +                 cfg_layout_rtl_register_cfg_hooks ();
> +                 cfun->curr_properties |= PROP_cfglayout;
> +               }
> +             if (strcmp (pass->name, "outof_cfglayout") == 0)
> +               {
> +                 rtl_register_cfg_hooks ();
> +                 cfun->curr_properties &= ~PROP_cfglayout;
> +               }
> +
> +             return true;
> +           }
> +       }
> +    }
> +
>    /* Pass execution event trigger: useful to identify passes being
>       executed.  */
>    invoke_plugin_callbacks (PLUGIN_PASS_EXECUTION, pass);
> diff --git a/gcc/read-md.c b/gcc/read-md.c
> index a8462a6..25bc3c4 100644
> --- a/gcc/read-md.c
> +++ b/gcc/read-md.c
> @@ -399,6 +399,16 @@ md_reader::read_char (void)
>    else
>      m_read_md_colno++;
>
> +  /* If we're filtering lines, treat everything before the range of
> +     interest as a space, and as EOF for everything after.  */
> +  if (m_first_line && m_last_line)
> +    {
> +      if (m_read_md_lineno < m_first_line)
> +       return ' ';
> +      if (m_read_md_lineno > m_last_line)
> +       return EOF;
> +    }
> +
>    return ch;
>  }
>
> @@ -981,7 +991,9 @@ md_reader::md_reader (bool compact)
>    m_read_md_lineno (0),
>    m_read_md_colno (0),
>    m_first_dir_md_include (NULL),
> -  m_last_dir_md_include_ptr (&m_first_dir_md_include)
> +  m_last_dir_md_include_ptr (&m_first_dir_md_include),
> +  m_first_line (0),
> +  m_last_line (0)
>  {
>    /* Set the global singleton pointer.  */
>    md_reader_ptr = this;
> @@ -1284,6 +1296,27 @@ md_reader::read_md_files (int argc, const char **argv,
>    return !have_error;
>  }
>
> +
> +/* Read FILENAME, filtering to just the given lines.  */
> +
> +bool
> +md_reader::read_file_fragment (const char *filename,
> +                              int first_line,
> +                              int last_line)
> +{
> +  m_read_md_filename = filename;
> +  m_read_md_file = fopen (m_read_md_filename, "r");
> +  if (m_read_md_file == 0)
> +    {
> +      perror (m_read_md_filename);
> +      return false;
> +    }
> +  m_first_line = first_line;
> +  m_last_line = last_line;
> +  handle_toplevel_file ();
> +  return !have_error;
> +}
> +
>  /* class noop_reader : public md_reader */
>
>  /* A dummy implementation which skips unknown directives.  */
> diff --git a/gcc/read-md.h b/gcc/read-md.h
> index 1be0f5a..06be3ec 100644
> --- a/gcc/read-md.h
> +++ b/gcc/read-md.h
> @@ -98,6 +98,9 @@ class md_reader
>    virtual ~md_reader ();
>
>    bool read_md_files (int, const char **, bool (*) (const char *));
> +  bool read_file_fragment (const char *filename,
> +                          int first_line,
> +                          int last_line);
>
>    /* A hook that handles a single .md-file directive, up to but not
>       including the closing ')'.  It takes two arguments: the file position
> @@ -232,6 +235,10 @@ class md_reader
>
>    /* A table of enum_type structures, hashed by name.  */
>    htab_t m_enum_types;
> +
> +  /* If non-zero, filter the input to just this subset of lines.  */
> +  int m_first_line;
> +  int m_last_line;
>  };
>
>  /* Global singleton; constrast with rtx_reader_ptr below.  */
> diff --git a/gcc/read-rtl-function.c b/gcc/read-rtl-function.c
> index ff6c808..6c4b282 100644
> --- a/gcc/read-rtl-function.c
> +++ b/gcc/read-rtl-function.c
> @@ -489,23 +489,38 @@ function_reader::create_function ()
>    else
>      rtl_register_cfg_hooks ();
>
> -  /* Create cfun.  */
> -  tree fn_name = get_identifier (m_name ? m_name : "test_1");
> -  tree int_type = integer_type_node;
> -  tree return_type = int_type;
> -  tree arg_types[3] = {int_type, int_type, int_type};
> -  tree fn_type = build_function_type_array (return_type, 3, arg_types);
> -  tree fndecl = build_decl_stat (UNKNOWN_LOCATION, FUNCTION_DECL, fn_name,
> -                                fn_type);
> -  tree resdecl = build_decl (UNKNOWN_LOCATION, RESULT_DECL, NULL_TREE,
> -                            return_type);
> -  DECL_ARTIFICIAL (resdecl) = 1;
> -  DECL_IGNORED_P (resdecl) = 1;
> -  DECL_RESULT (fndecl) = resdecl;
> -  allocate_struct_function (fndecl, false);
> -  /* This sets cfun.  */
> -
> -  current_function_decl = fndecl;
> +  /* When run from selftests or "rtl1", cfun is NULL.
> +     When run from "cc1" for a C function tagged with __RTL, cfun is the
> +     tagged function.  */
> +  if (!cfun)
> +    {
> +      tree fn_name = get_identifier (m_name ? m_name : "test_1");
> +      tree int_type = integer_type_node;
> +      tree return_type = int_type;
> +      tree arg_types[3] = {int_type, int_type, int_type};
> +      tree fn_type = build_function_type_array (return_type, 3, arg_types);
> +      tree fndecl = build_decl_stat (UNKNOWN_LOCATION, FUNCTION_DECL, fn_name,
> +                                    fn_type);
> +      tree resdecl = build_decl (UNKNOWN_LOCATION, RESULT_DECL, NULL_TREE,
> +                                return_type);
> +      DECL_ARTIFICIAL (resdecl) = 1;
> +      DECL_IGNORED_P (resdecl) = 1;
> +      DECL_RESULT (fndecl) = resdecl;
> +      allocate_struct_function (fndecl, false);
> +      /* This sets cfun.  */
> +      current_function_decl = fndecl;
> +    }
> +
> +  gcc_assert (cfun);
> +  gcc_assert (current_function_decl);
> +  tree fndecl = current_function_decl;
> +
> +  /* Mark this function as being specified as __RTL.  */
> +  cfun->native_RTL = 1;
> +
> +  /* cc1 normally inits DECL_INITIAL (fndecl) to be error_mark_node.
> +     Ensure it is NULL_TREE.  */
> +  DECL_INITIAL (fndecl) = NULL_TREE;
>
>    cfun->curr_properties = (PROP_cfg | PROP_rtl);
>
> @@ -1615,6 +1630,40 @@ read_rtl_function_body (int argc, const char **argv,
>    return true;
>  }
>
> +/* Run the RTL dump parser on the range of lines between START_LOC and
> +   END_LOC (including those lines).  */
> +
> +bool
> +read_rtl_function_body_from_file_range (location_t start_loc,
> +                                       location_t end_loc)
> +{
> +  expanded_location exploc_start = expand_location (start_loc);
> +  expanded_location exploc_end = expand_location (end_loc);
> +
> +  if (exploc_start.file != exploc_end.file)
> +    {
> +      error_at (end_loc, "start/end of RTL fragment are in different files");
> +      return false;
> +    }
> +  if (exploc_start.line >= exploc_end.line)
> +    {
> +      error_at (end_loc,
> +               "start of RTL fragment must be on an earlier line than end");
> +      return false;
> +    }
> +
> +  initialize_rtl ();
> +  init_emit ();
> +  init_varasm_status ();
> +
> +  function_reader reader (NULL);
> +  if (!reader.read_file_fragment (exploc_start.file, exploc_start.line,
> +                                 exploc_end.line - 1))
> +    return false;
> +
> +  return true;
> +}
> +
>  #if CHECKING_P
>
>  namespace selftest {
> diff --git a/gcc/read-rtl-function.h b/gcc/read-rtl-function.h
> index 036fcce..d5d12ab 100644
> --- a/gcc/read-rtl-function.h
> +++ b/gcc/read-rtl-function.h
> @@ -33,4 +33,7 @@ extern bool read_rtl_function_body (int argc, const char **argv,
>                                     bool (*parse_opt) (const char *),
>                                     function_reader_policy *policy);
>
> +extern bool read_rtl_function_body_from_file_range (location_t start_loc,
> +                                                   location_t end_loc);
> +
>  #endif /* GCC_READ_RTL_FUNCTION_H */
> diff --git a/gcc/run-rtl-passes.c b/gcc/run-rtl-passes.c
> new file mode 100644
> index 0000000..2bca929
> --- /dev/null
> +++ b/gcc/run-rtl-passes.c
> @@ -0,0 +1,85 @@
> +/* run-rtl-passes.c - Run just one RTL pass
> +   Copyright (C) 2016 Free Software Foundation, Inc.
> +
> +This file is part of GCC.
> +
> +GCC is free software; you can redistribute it and/or modify it under
> +the terms of the GNU General Public License as published by the Free
> +Software Foundation; either version 3, or (at your option) any later
> +version.
> +
> +GCC is distributed in the hope that it will be useful, but WITHOUT ANY
> +WARRANTY; without even the implied warranty of MERCHANTABILITY or
> +FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
> +for more details.
> +
> +You should have received a copy of the GNU General Public License
> +along with GCC; see the file COPYING3.  If not see
> +<http://www.gnu.org/licenses/>.  */
> +
> +#include "config.h"
> +#include "system.h"
> +#include "coretypes.h"
> +#include "target.h"
> +#include "tree.h"
> +#include "gimple-expr.h"
> +#include "diagnostic.h"
> +#include "opts.h"
> +#include "fold-const.h"
> +#include "gimplify.h"
> +#include "stor-layout.h"
> +#include "debug.h"
> +#include "convert.h"
> +#include "langhooks.h"
> +#include "langhooks-def.h"
> +#include "common/common-target.h"
> +#include "read-md.h"
> +#include <mpfr.h>
> +#include "rtl.h"
> +#include "cfghooks.h"
> +#include "stringpool.h"
> +#include "function.h"
> +#include "tree-cfg.h"
> +#include "cfg.h"
> +#include "basic-block.h"
> +#include "cfgrtl.h"
> +#include "memmodel.h"
> +#include "emit-rtl.h"
> +#include "cgraph.h"
> +#include "tree-pass.h"
> +#include "context.h"
> +#include "pass_manager.h"
> +#include "bitmap.h"
> +#include "df.h"
> +#include "regs.h"
> +#include "insn-attr-common.h" /* for INSN_SCHEDULING.  */
> +#include "insn-attr.h" /* for init_sched_attrs.  */
> +#include "run-rtl-passes.h"
> +
> +/* Run the backend passes, starting at the given pass.  */
> +
> +void
> +run_rtl_passes (const char *initial_pass_name)
> +{
> +  cfun->pass_startwith = initial_pass_name;
> +  max_regno = max_reg_num ();
> +
> +  /* Pass "expand" noemally sets this up.  */
> +#ifdef INSN_SCHEDULING
> +  init_sched_attrs ();
> +#endif
> +
> +  bitmap_obstack_initialize (NULL);
> +  bitmap_obstack_initialize (&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
>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]