From: David Malcolm <dmalcolm@redhat.com>
To: Richard Biener <richard.guenther@gmail.com>,
Jan Hubicka <hubicka@ucw.cz>
Cc: GCC Patches <gcc-patches@gcc.gnu.org>,
David Malcolm <dmalcolm@redhat.com>
Subject: [PATCH] Add "__RTL" to cc1 (v5)
Date: Fri, 18 Nov 2016 21:02:00 -0000 [thread overview]
Message-ID: <1479504842-45080-1-git-send-email-dmalcolm@redhat.com> (raw)
In-Reply-To: <CAFiYyc2e4ScGVBO852S_hyeWAK7Ln5OOkPsJxduUf3aRdpoiRQ@mail.gmail.com>
On Wed, 2016-11-16 at 14:24 +0100, Richard Biener wrote:
> On Tue, Nov 15, 2016 at 10:07 PM, David Malcolm <dmalcolm@redhat.com>
> wrote:
> > On Mon, 2016-11-14 at 16:14 +0100, Richard Biener wrote:
> > > On Fri, Nov 11, 2016 at 10:15 PM, David Malcolm <
> > > dmalcolm@redhat.com>
> > > wrote:
> > > > Changed in this version:
> > > >
> > > > * Rather than running just one pass, run *all* passes, but
> > > > start at
> > > > the given pass; support for "dg-do run" tests that execute
> > > > the
> > > > resulting code.
> > > > * Updated test cases to new "compact" dump format; more test
> > > > cases;
> > > > use "dg-do run" in various places.
> > > > * Lots of bugfixing
> > > >
> > > > Links to previous versions:
> > > > https://gcc.gnu.org/ml/gcc-patches/2016-10/msg00263.html
> > > > https://gcc.gnu.org/ml/gcc-patches/2016-10/msg00500.html
> >
> > > Does running the RTL passes right from the parser work with
> > > -fsyntax
> > > -only?
> >
> > It depends what you mean by "work". If I run it with -fsyntax
> > -only,
> > then pass_rest_of_compilation::gate returns false, and none of the
> > RTL
> > passes are run. Is this behavior correct?
>
> Yes.
Thanks.
> > > Doing it like __GIMPLE has the advantage of not exposing
> > > "rest_of_compilation", etc..
> >
> > The gimple part of the compiler supports having multiple functions
> > in
> > memory at once, and then compiling them in arbitrary order based on
> > decisions made by the callgraph.
> >
> > By contrast, the RTL part of the compiler is full of singleton
> > state:
> > things like crtl (aka x_rtl), the state of emit-rtl.c,
> > "reload_completed", etc etc.
>
> Ah, of course - I forgot that...
>
> > To try to limit the scope of the project, for the RTL frontend work
> > I'm
> > merely attempting to restore the singleton RTL state from a dump,
> > rather than to support having per function stashes of RTL state.
> >
> > Hence the rest of compilation gets invoked directly from the
> > frontend
> > for the __RTL case, since it will get overwritten if there's a
> > second
> > __RTL function in the source file (which sounds like an idea for a
> > test
> > case; I'll attempt such a test case).
> >
> > I hope this is a reasonable approach. If not, I suppose I can
> > attempt
> > to bundle it up into some kind of RTL function state, but that
> > seems
> > like significant scope creep.
>
> Yeah, I think it's a good approach for now.
OK.
> > > I'm now handling __GIMPLE from within declspecs (the GIMPLE FE
> > > stuff
> > > has been committed), it would be nice to match the __RTL piece
> > > here.
> >
> > (Congratulations on getting the GIMPLE FE stuff in)
> >
> > I'm not sure I understand you here - do you want me to rewrite the
> > __RTL parsing to match the __GIMPLE piece, or the other way around?
> > If the former, presumably I should reuse (and rename)
> > c_parser_gimple_pass_list?
>
> Handle __RTL like __GIMPLE, thus as declspec. Of course ultimatively
> Joseph has the last word here.
I've updated the patch to do so.
> >
> > > > gcc/ChangeLog:
> > > > * Makefile.in (OBJS): Add run-rtl-passes.o.
> > > >
> > > > gcc/c-family/ChangeLog:
> > > > * c-common.c (c_common_reswords): Add "__RTL".
> > > > * c-common.h (enum rid): Add RID_RTL.
> > > >
> > > > gcc/c/ChangeLog:
> > > > * c-parser.c: Include "read-rtl-function.h" and
> > > > "run-rtl-passes.h".
> > > > (c_parser_declaration_or_fndef): In the "GNU
> > > > extensions"
> > > > part of
> > > > the leading comment, add an alternate production for
> > > > "function-definition", along with new "rtl-body
> > > > -specifier"
> > > > and
> > > > "rtl-body-pass-specifier" productions. Handle "__RTL"
> > > > by
> > > > calling
> > > > c_parser_parse_rtl_body. Convert a timevar_push/pop
> > > > pair
> > > > to an auto_timevar, to cope with early exit.
> > > > (c_parser_parse_rtl_body): New function.
> > > >
> > > > gcc/ChangeLog:
> > > > * cfg.c (free_original_copy_tables): Remove assertion
> > > > on original_copy_bb_pool.
> > >
> > > How can that trigger?
> >
> > It happens when running pass_outof_cfg_layout_mode::execute; seen
> > with
> > gcc.dg/rtl/x86_64/test-return-const.c.before-fwprop.c.
> >
> > The input file is a dump taken in cfg_layout mode (although in this
> > case it's a trivial 3-basic-block CFG, but ideally there would be
> > cases
> > with non-trivial control flow); it has "fwprop1" as its starting
> > pass.
> >
> > Running without -quiet shows:
> >
> > skipping pass: *rest_of_compilation
> > skipping pass: vregs
> > skipping pass: into_cfglayout
> > skipping pass: jump
> > skipping pass: subreg1
> > skipping pass: cse1
> > found starting pass: fwprop1
> >
> > i.e. it skips the into_cfglayout (amongst others), to start with
> > fwprop1.
> >
> > In theory skipping a pass ought to be a no-op, assuming that we're
> > faithfully reconstructing all RTL state. However, RTL state
> > management
> > is fiddly, so the patch introduces some logic in passes.c to do
> > some
> > things when skipping a pass; in particular, it has:
> >
> > /* Update the cfg hooks as appropriate. */
> > if (strcmp (pass->name, "into_cfglayout") == 0)
> > {
> > cfg_layout_rtl_register_cfg_hooks ();
> > cfun->curr_properties |= PROP_cfglayout;
> > }
> > if (strcmp (pass->name, "outof_cfglayout") == 0)
> > {
> > rtl_register_cfg_hooks ();
> > cfun->curr_properties &= ~PROP_cfglayout;
> > }
> >
> > so that even when skipping "into_cfglayout", the CFG hooks are at
> > least
> > correct.
>
> I suppose the pass manager could handle the hook switching based on
> a (RTL) pass setting/clearing PROP_cfglayout. Or all passes needing
> cfglayout would need to set prop_required accordingly and thus
> the into/outouf cfglayout passes would be implicit.
(I haven't attempted to touch the pass properties in this version of
the patch).
> > The assertion fires when running outof_cfglayout later on (rather
> > than
> > skipping it); the assertion:
> >
> > gcc_assert (original_copy_bb_pool);
> >
> > assumes that into_cfglayout was actually run, rather than just the
> > simple "skipping" version of it.
>
> Ah, I see cfg_layout_initialize calls initialize_original_copy_tables
> ()
> for whatever reason and they are kept initialized until out-of
> -cfglayout...
>
> GIMPLE passes do init/free them all the time. I think a better
> fix would be to add a original_copy_tables_initialized () function
> and guard the free_original_copy_tables call with that (keeping
> the assertion that they run in pairs).
Done.
> > > > * cgraph.h (symtab_node::native_rtl_p): New decl.
> > > > * cgraphunit.c (symtab_node::native_rtl_p): New
> > > > function.
> > > > (symtab_node::needed_p): Don't assert for early
> > > > assembly
> > > > output
> > > > for __RTL functions.
> > > > (cgraph_node::finalize_function): Set "force_output"
> > > > for
> > > > __RTL
> > > > functions.
> > > > (cgraph_node::analyze): Bail out early for __RTL
> > > > functions.
> > > > (analyze_functions): Update assertion to support __RTL
> > > > functions.
> > > > (cgraph_node::expand): Bail out early for __RTL
> > > > functions.
> > > > * emit-rtl.c (unshare_all_rtl_again): Wrap
> > > > set_used_decls
> > > > call
> > > > in check for DECL_INITIAL.
> > >
> > > You should simply set DECL_INITIAL of your function decl
> > > (make_node
> > > (BLOCK);).
> > > There's too much code assuming that is not NULL (and I've fixed
> > > quite
> > > a bit of
> > > code during stage1 not doing that).
> >
> > Thanks; fixed.
> >
> > > > * final.c (rest_of_clean_state): Don't call
> > > > delete_tree_ssa
> > > > for
> > > > _RTL functions.
> > > > * function.h (struct function): Add field "native_RTL".
> > >
> > > I wonder if you could simply use ->curr_properties & PROP_rtl?
> > > (and
> > > set that
> > > property during parsing, of course)
> >
> > I tried to doing that; it mostly works, but this assertion fails:
> >
> > 237 symtab_node::needed_p (void)
> > 238 {
> > 239 /* Double check that no one output the function into
> > assembly file
> > 240 early. */
> > 241 if (!native_rtl_p ())
> > 242 gcc_checking_assert
> > 243 (!DECL_ASSEMBLER_NAME_SET_P (decl)
> > 244 || !TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME
> > (decl)));
> >
> > [I added the "if (!native_rtl_p ())" guard in the patch]
> >
> > The issue here is that when this is run, the __RTL function has
> > been
> > compiled and cleaned up, and the curr_properties & PROP_rtl has
> > been
> > cleared:
> >
> > (gdb) p decl->function_decl->f->curr_properties
> > $7 = 0
> >
> > I could set the flag again after running the passes; on doing so,
> > the
> > test suite successfully runs.
>
> Hmm, so if you are finished with the function you should set
> symtab_node->analyzed
> to false I think (it signals it's now merely an "extern" symbol and
> no
> longer has a body).
> Or set body_removed. Maybe just ask Honza what to do ...
I looked at these fields, but I think I prefer the approach of
simply setting the PROP_rtl flag again; the other fields seem to
have specific meanings that don't apply here.
> Richard.
>
> > Would you prefer I use curr_properties & PROP_rtl for this?
>
> > [...snip...]
> >
> > Thanks
> > Dave
Updated patch follows.
Changed in v5:
- rebased from r242065 to r242392. In particular, this
brings in the gimple FE. I rewrote the "startwith" pass-skipping
mechanism to work with both __GIMPLE and __RTL.
- rewrote the "__RTL" parser so that it shares code with the
"__GIMPLE" parser, within c_parser_declspecs.
Updated all the test cases to use the 'startwith' syntax.
The gimple FE has a "flag_gimple" to enable __GIMPLE; should
I add an equivalent for __RTL?
- eliminated the new "native_RTL" field, instead just using
curr_properties & PROP_rtl.
- added original_copy_tables_initialized_p and reinstate:
gcc_assert (original_copy_bb_pool);
within free_original_copy_tables.
- added a test of multiple __RTL-marked functions within one test
case.
Successfully bootstrapped®rtested on x86_64-pc-linux-gnu as
part of the patch kit.
OK for trunk? (most of the rest of the kit also still needs
review, fwiw).
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): Rename "gimple-pass-list" in
grammar to gimple-or-rtl-pass-list. Add rtl-function-definition
production. Update for renaming of field "gimple_pass" to
"gimple_or_rtl_pass". If __RTL was seen, call
c_parser_parse_rtl_body. Convert a timevar_push/pop pair
to an auto_timevar, to cope with early exit.
(c_parser_declspecs): Update RID_GIMPLE handling for renaming of
field "gimple_pass" to "gimple_or_rtl_pass", and for renaming of
c_parser_gimple_pass_list to c_parser_gimple_or_rtl_pass_list.
Handle RID_RTL.
(c_parser_parse_rtl_body): New function.
* c-tree.h (enum c_declspec_word): Add cdw_rtl.
(struct c_declspecs): Rename field "gimple_pass" to
"gimple_or_rtl_pass". Add field "rtl_p".
* gimple-parser.c (c_parser_gimple_pass_list): Rename to...
(c_parser_gimple_or_rtl_pass_list): ...this, updating accordingly.
* gimple-parser.h (c_parser_gimple_pass_list): Rename to...
(c_parser_gimple_or_rtl_pass_list): ...this.
gcc/ChangeLog:
* cfg.c (original_copy_tables_initialized_p): New function.
* cfg.h (original_copy_tables_initialized_p): New decl.
* cfgrtl.c (relink_block_chain): Guard the call to
free_original_copy_tables with a call to
original_copy_tables_initialized_p.
* cgraph.h (symtab_node::native_rtl_p): New decl.
* cgraphunit.c (symtab_node::native_rtl_p): New function.
(symtab_node::needed_p): Don't assert for early assembly output
for __RTL functions.
(cgraph_node::finalize_function): Set "force_output" for __RTL
functions.
(cgraph_node::analyze): Bail out early for __RTL functions.
(analyze_functions): Update assertion to support __RTL functions.
(cgraph_node::expand): Bail out early for __RTL functions.
* final.c (rest_of_clean_state): Don't call delete_tree_ssa for
_RTL functions.
* gimple-expr.c: Include "tree-pass.h".
(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): Split out logic for skipping passes into...
(determine_pass_name_match): ...this new function, ...
(should_skip_pass_p): ...and this new function, adding logging
and special-casing dfinit.
(skip_pass): New function.
* 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 PROP_rtl on cfun's
curr_properties. Set DECL_INITIAL to a dummy block.
(read_rtl_function_body_from_file_range): New function.
* read-rtl-function.h (read_rtl_function_body_from_file_range):
New decl.
* run-rtl-passes.c: New file.
* run-rtl-passes.h: New file.
gcc/testsuite/ChangeLog:
* gcc.dg/rtl/aarch64/asr_div1.c: New 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-multiple-fns.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 | 105 +++++++++++++++-
gcc/c/c-tree.h | 7 +-
gcc/c/gimple-parser.c | 8 +-
gcc/c/gimple-parser.h | 2 +-
gcc/cfg.c | 9 ++
gcc/cfg.h | 1 +
gcc/cfgrtl.c | 3 +-
gcc/cgraph.h | 4 +
gcc/cgraphunit.c | 41 ++++++-
gcc/final.c | 3 +-
gcc/function.h | 2 +-
gcc/gimple-expr.c | 3 +-
gcc/pass_manager.h | 6 +
gcc/passes.c | 130 ++++++++++++++++----
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 | 88 ++++++++++++++
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 +++++++++++++++++
.../gcc.dg/rtl/x86_64/test-multiple-fns.c | 105 ++++++++++++++++
.../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 +++++++++++++++++
42 files changed, 1885 insertions(+), 63 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-multiple-fns.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 2997c83..7ba3539 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -437,6 +437,7 @@ const struct c_common_resword c_common_reswords[] =
{ "__volatile__", RID_VOLATILE, 0 },
{ "__GIMPLE", RID_GIMPLE, D_CONLY },
{ "__PHI", RID_PHI, D_CONLY },
+ { "__RTL", RID_RTL, D_CONLY },
{ "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 241b345..89a5f6f 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -124,6 +124,9 @@ enum rid
/* "__PHI", for parsing PHI function in GIMPLE FE. */
RID_PHI,
+ /* "__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 00fe731..d645d29 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -61,6 +61,8 @@ along with GCC; see the file COPYING3. If not see
#include "gcc-rich-location.h"
#include "c-parser.h"
#include "gimple-parser.h"
+#include "read-rtl-function.h"
+#include "run-rtl-passes.h"
/* We need to walk over decls with incomplete struct/union/enum types
after parsing the whole translation unit.
@@ -1310,6 +1312,8 @@ static tree c_parser_array_notation (location_t, c_parser *, tree, tree);
static tree c_parser_cilk_clause_vectorlength (c_parser *, tree, bool);
static void c_parser_cilk_grainsize (c_parser *, bool *);
+static void c_parser_parse_rtl_body (c_parser *parser, char *start_with_pass);
+
/* Parse a translation unit (C90 6.7, C99 6.9).
translation-unit:
@@ -1546,7 +1550,11 @@ static void c_finish_oacc_routine (struct oacc_routine_data *, tree, bool);
GIMPLE:
gimple-function-definition:
- declaration-specifiers[opt] __GIMPLE (gimple-pass-list) declarator
+ declaration-specifiers[opt] __GIMPLE (gimple-or-rtl-pass-list) declarator
+ declaration-list[opt] compound-statement
+
+ rtl-function-definition:
+ declaration-specifiers[opt] __RTL (gimple-or-rtl-pass-list) declarator
declaration-list[opt] compound-statement */
static void
@@ -2042,7 +2050,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
@@ -2074,12 +2082,28 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
function body as GIMPLE. */
if (specs->gimple_p)
{
- cfun->pass_startwith = specs->gimple_pass;
+ cfun->pass_startwith = specs->gimple_or_rtl_pass;
bool saved = in_late_binary_op;
in_late_binary_op = true;
c_parser_parse_gimple_body (parser);
in_late_binary_op = saved;
}
+ /* Similarly, if it was marked with __RTL, use the RTL parser now,
+ consuming the function body. */
+ else if (specs->rtl_p)
+ {
+ c_parser_parse_rtl_body (parser, specs->gimple_or_rtl_pass);
+
+ /* Normally, store_parm_decls sets next_is_function_body,
+ anticipating a function body. We need a push_scope/pop_scope
+ pair to flush out this state, or subsequent function parsing
+ will go wrong. */
+ push_scope ();
+ pop_scope ();
+
+ finish_function ();
+ return;
+ }
else
{
fnbody = c_parser_compound_statement (parser);
@@ -2110,7 +2134,6 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
if (specs->gimple_p)
DECL_SAVED_TREE (fndecl) = NULL_TREE;
- timevar_pop (tv);
break;
}
}
@@ -2602,7 +2625,13 @@ c_parser_declspecs (c_parser *parser, struct c_declspecs *specs,
c_parser_consume_token (parser);
specs->gimple_p = true;
specs->locations[cdw_gimple] = loc;
- specs->gimple_pass = c_parser_gimple_pass_list (parser);
+ specs->gimple_or_rtl_pass = c_parser_gimple_or_rtl_pass_list (parser);
+ break;
+ case RID_RTL:
+ c_parser_consume_token (parser);
+ specs->rtl_p = true;
+ specs->locations[cdw_rtl] = loc;
+ specs->gimple_or_rtl_pass = c_parser_gimple_or_rtl_pass_list (parser);
break;
default:
goto out;
@@ -18258,4 +18287,70 @@ c_parser_array_notation (location_t loc, c_parser *parser, tree initial_index,
return value_tree;
}
+/* Parse the body of a function declaration marked with "__RTL".
+
+ The RTL parser works on the level of characters read from a
+ FILE *, whereas c_parser works at the level of tokens.
+ Square this circle by consuming all of the tokens up to and
+ including the closing brace, recording the start/end of the RTL
+ fragment, and reopening the file and re-reading the relevant
+ lines within the RTL parser.
+
+ This requires the opening and closing braces of the C function
+ to be on separate lines from the RTL they wrap.
+
+ Take ownership of START_WITH_PASS, if non-NULL. */
+
+void
+c_parser_parse_rtl_body (c_parser *parser, char *start_with_pass)
+{
+ if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
+ {
+ free (start_with_pass);
+ return;
+ }
+
+ location_t start_loc = c_parser_peek_token (parser)->location;
+
+ /* Consume all tokens, up to the closing brace, handling
+ matching pairs of braces in the rtl dump. */
+ int num_open_braces = 1;
+ while (1)
+ {
+ switch (c_parser_peek_token (parser)->type)
+ {
+ case CPP_OPEN_BRACE:
+ num_open_braces++;
+ break;
+ case CPP_CLOSE_BRACE:
+ if (--num_open_braces == 0)
+ goto found_closing_brace;
+ break;
+ default:
+ break;
+ }
+ c_parser_consume_token (parser);
+ }
+
+ found_closing_brace:
+ /* At the closing brace; record its location. */
+ location_t end_loc = c_parser_peek_token (parser)->location;
+
+ /* Consume the closing brace. */
+ c_parser_consume_token (parser);
+
+ /* Invoke the RTL parser. */
+ if (!read_rtl_function_body_from_file_range (start_loc, end_loc))
+ {
+ free (start_with_pass);
+ return;
+ }
+
+ /* If a pass name was provided for START_WITH_PASS, run the backend
+ accordingly now, on the cfun created above, transferring
+ ownership of START_WITH_PASS. */
+ if (start_with_pass)
+ run_rtl_passes (start_with_pass);
+}
+
#include "gt-c-c-parser.h"
diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h
index a8cf353..94821d8 100644
--- a/gcc/c/c-tree.h
+++ b/gcc/c/c-tree.h
@@ -268,6 +268,7 @@ enum c_declspec_word {
cdw_alignas,
cdw_address_space,
cdw_gimple,
+ cdw_rtl,
cdw_number_of_elements /* This one must always be the last
enumerator. */
};
@@ -291,8 +292,8 @@ struct c_declspecs {
NULL; attributes (possibly from multiple lists) will be passed
separately. */
tree attrs;
- /* The pass to start compiling a __GIMPLE function with. */
- char *gimple_pass;
+ /* The pass to start compiling a __GIMPLE or __RTL function with. */
+ char *gimple_or_rtl_pass;
/* The base-2 log of the greatest alignment required by an _Alignas
specifier, in bytes, or -1 if no such specifiers with nonzero
alignment. */
@@ -367,6 +368,8 @@ struct c_declspecs {
BOOL_BITFIELD alignas_p : 1;
/* Whether any __GIMPLE specifier was specified. */
BOOL_BITFIELD gimple_p : 1;
+ /* Whether any __RTL specifier was specified. */
+ BOOL_BITFIELD rtl_p : 1;
/* The address space that the declaration belongs to. */
addr_space_t address_space;
};
diff --git a/gcc/c/gimple-parser.c b/gcc/c/gimple-parser.c
index 9b6af13..f5b2c44 100644
--- a/gcc/c/gimple-parser.c
+++ b/gcc/c/gimple-parser.c
@@ -1000,18 +1000,18 @@ c_parser_gimple_label (c_parser *parser, gimple_seq *seq)
return;
}
-/* Parse gimple pass list.
+/* Parse gimple/RTL pass list.
- gimple-pass-list:
+ gimple-or-rtl-pass-list:
startwith("pass-name")
*/
char *
-c_parser_gimple_pass_list (c_parser *parser)
+c_parser_gimple_or_rtl_pass_list (c_parser *parser)
{
char *pass = NULL;
- /* Accept __GIMPLE. */
+ /* Accept __GIMPLE/__RTL. */
if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
return NULL;
c_parser_consume_token (parser);
diff --git a/gcc/c/gimple-parser.h b/gcc/c/gimple-parser.h
index f72b626..e3ab019 100644
--- a/gcc/c/gimple-parser.h
+++ b/gcc/c/gimple-parser.h
@@ -22,6 +22,6 @@ along with GCC; see the file COPYING3. If not see
/* Gimple parsing functions. */
extern void c_parser_parse_gimple_body (c_parser *);
-extern char *c_parser_gimple_pass_list (c_parser *);
+extern char *c_parser_gimple_or_rtl_pass_list (c_parser *);
#endif
diff --git a/gcc/cfg.c b/gcc/cfg.c
index 6604b02..1ca6592 100644
--- a/gcc/cfg.c
+++ b/gcc/cfg.c
@@ -1094,6 +1094,15 @@ free_original_copy_tables (void)
original_copy_bb_pool = NULL;
}
+/* Return true iff we have had a call to initialize_original_copy_tables
+ without a corresponding call to free_original_copy_tables. */
+
+bool
+original_copy_tables_initialized_p (void)
+{
+ return original_copy_bb_pool != NULL;
+}
+
/* Removes the value associated with OBJ from table TAB. */
static void
diff --git a/gcc/cfg.h b/gcc/cfg.h
index ad935e3..df1480f 100644
--- a/gcc/cfg.h
+++ b/gcc/cfg.h
@@ -110,6 +110,7 @@ extern void scale_bbs_frequencies_gcov_type (basic_block *, int, gcov_type,
extern void initialize_original_copy_tables (void);
extern void reset_original_copy_tables (void);
extern void free_original_copy_tables (void);
+extern bool original_copy_tables_initialized_p (void);
extern void set_bb_original (basic_block, basic_block);
extern basic_block get_bb_original (basic_block);
extern void set_bb_copy (basic_block, basic_block);
diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c
index d2719db..de53295 100644
--- a/gcc/cfgrtl.c
+++ b/gcc/cfgrtl.c
@@ -3647,7 +3647,8 @@ relink_block_chain (bool stay_in_cfglayout_mode)
/* Maybe reset the original copy tables, they are not valid anymore
when we renumber the basic blocks in compact_blocks. If we are
are going out of cfglayout mode, don't re-allocate the tables. */
- free_original_copy_tables ();
+ if (original_copy_tables_initialized_p ())
+ free_original_copy_tables ();
if (stay_in_cfglayout_mode)
initialize_original_copy_tables ();
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..aae7b2a 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)->curr_properties & PROP_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/final.c b/gcc/final.c
index 5709d0e..c1afc57 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->gimple_df)
+ 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 cabffb9..19c26c8 100644
--- a/gcc/function.h
+++ b/gcc/function.h
@@ -236,7 +236,7 @@ struct GTY(()) function {
/* The loops in this function. */
struct loops *x_current_loops;
- /* Filled by the GIMPLE FE, pass to start compilation with. */
+ /* Filled by the GIMPLE and RTL FEs, pass to start compilation with. */
char *pass_startwith;
/* The stack usage of this function. */
diff --git a/gcc/gimple-expr.c b/gcc/gimple-expr.c
index de5cce1..e60c607 100644
--- a/gcc/gimple-expr.c
+++ b/gcc/gimple-expr.c
@@ -34,6 +34,7 @@ along with GCC; see the file COPYING3. If not see
#include "demangle.h"
#include "hash-set.h"
#include "rtl.h"
+#include "tree-pass.h"
/* ----- Type related ----- */
@@ -323,7 +324,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->curr_properties & PROP_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 51d0d84..5086868 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;
@@ -2273,6 +2274,106 @@ override_gate_status (opt_pass *pass, tree func, bool gate_status)
return gate_status;
}
+/* Determine if PASS_NAME matches CRITERION.
+ Not a pure predicate, since it can update CRITERION, to support
+ matching the Nth invocation of a pass.
+ Subroutine of should_skip_pass_p. */
+
+static bool
+determine_pass_name_match (const char *pass_name, char *criterion)
+{
+ size_t namelen = strlen (pass_name);
+ if (!strncmp (pass_name, criterion, namelen))
+ {
+ /* The following supports starting with the Nth invocation
+ of a pass (where N does not necessarily is equal to the
+ dump file suffix). */
+ if (criterion[namelen] == '\0'
+ || (criterion[namelen] == '1'
+ && criterion[namelen + 1] == '\0'))
+ return true;
+ else
+ {
+ if (criterion[namelen + 1] == '\0')
+ --criterion[namelen];
+ return false;
+ }
+ }
+ else
+ return false;
+}
+
+/* For skipping passes until "startwith" pass.
+ Return true iff PASS should be skipped.
+ Clear cfun->pass_startwith when encountering the "startwith" pass,
+ so that all subsequent passes are run. */
+
+static bool
+should_skip_pass_p (opt_pass *pass)
+{
+ if (!cfun)
+ return false;
+ if (!cfun->pass_startwith)
+ return false;
+
+ /* We can't skip the lowering phase yet -- ideally we'd
+ drive that phase fully via properties. */
+ if (pass->type == GIMPLE_PASS
+ && !(cfun->curr_properties & PROP_ssa))
+ {
+ if (!quiet_flag)
+ fprintf (stderr, "running pass anyway: %s\n", pass->name);
+ return false;
+ }
+
+ if (determine_pass_name_match (pass->name, cfun->pass_startwith))
+ {
+ if (!quiet_flag)
+ fprintf (stderr, "found starting pass: %s\n", pass->name);
+ cfun->pass_startwith = NULL;
+ return false;
+ }
+
+ /* Don't skip df init; later RTL passes need it. */
+ if (strstr (pass->name, "dfinit") != NULL)
+ return false;
+
+ if (!quiet_flag)
+ fprintf (stderr, "skipping pass: %s\n", pass->name);
+ return true;
+}
+
+/* Skip the given pass, for handling passes before "startwith"
+ in __GIMPLE and__RTL-marked functions.
+ In theory, this ought to be a no-op, but some of the RTL passes
+ need additional processing here. */
+
+static void
+skip_pass (opt_pass *pass)
+{
+ /* 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;
+ }
+}
/* Execute PASS. */
@@ -2313,33 +2414,10 @@ execute_one_pass (opt_pass *pass)
return false;
}
- /* For skipping passes until startwith pass */
- if (cfun
- && cfun->pass_startwith
- /* But we can't skip the lowering phase yet -- ideally we'd
- drive that phase fully via properties. */
- && (cfun->curr_properties & PROP_ssa))
+ if (should_skip_pass_p (pass))
{
- size_t namelen = strlen (pass->name);
- if (! strncmp (pass->name, cfun->pass_startwith, namelen))
- {
- /* The following supports starting with the Nth invocation
- of a pass (where N does not necessarily is equal to the
- dump file suffix). */
- if (cfun->pass_startwith[namelen] == '\0'
- || (cfun->pass_startwith[namelen] == '1'
- && cfun->pass_startwith[namelen + 1] == '\0'))
- cfun->pass_startwith = NULL;
- else
- {
- if (cfun->pass_startwith[namelen + 1] != '\0')
- return true;
- --cfun->pass_startwith[namelen];
- return true;
- }
- }
- else
- return true;
+ skip_pass (pass);
+ return true;
}
/* Pass execution event trigger: useful to identify passes being
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 3e19433..d051506 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->curr_properties |= PROP_rtl;
+
+ /* cc1 normally inits DECL_INITIAL (fndecl) to be error_mark_node.
+ Create a dummy block for it. */
+ DECL_INITIAL (fndecl) = make_node (BLOCK);
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..eefbad4
--- /dev/null
+++ b/gcc/run-rtl-passes.c
@@ -0,0 +1,88 @@
+/* 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.
+ Take ownership of INITIAL_PASS_NAME. */
+
+void
+run_rtl_passes (char *initial_pass_name)
+{
+ cfun->pass_startwith = initial_pass_name;
+ max_regno = max_reg_num ();
+
+ /* Pass "expand" normally sets this up. */
+#ifdef INSN_SCHEDULING
+ init_sched_attrs ();
+#endif
+
+ bitmap_obstack_initialize (NULL);
+ bitmap_obstack_initialize (®_obstack);
+
+ opt_pass *rest_of_compilation
+ = g->get_passes ()->get_rest_of_compilation ();
+ gcc_assert (rest_of_compilation);
+ execute_pass_list (cfun, rest_of_compilation);
+
+ opt_pass *clean_slate = g->get_passes ()->get_clean_slate ();
+ gcc_assert (clean_slate);
+ execute_pass_list (cfun, clean_slate);
+
+ bitmap_obstack_release (®_obstack);
+
+ cfun->curr_properties |= PROP_rtl;
+}
diff --git a/gcc/run-rtl-passes.h b/gcc/run-rtl-passes.h
new file mode 100644
index 0000000..aa035c5
--- /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 (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..bc39a70
--- /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 (startwith ("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..91ae937
--- /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 (startwith ("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..8701c1d
--- /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 (startwith ("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..1b8ea09
--- /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 (startwith ("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..ab92004
--- /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 (startwith ("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..d23cca4
--- /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 (startwith ("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..4ba3d6e
--- /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 (startwith ("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-multiple-fns.c b/gcc/testsuite/gcc.dg/rtl/x86_64/test-multiple-fns.c
new file mode 100644
index 0000000..ac0ebe4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/rtl/x86_64/test-multiple-fns.c
@@ -0,0 +1,105 @@
+/* { dg-do run { target x86_64-*-* } } */
+
+/* Verify that we can have multiple __RTL functions in one test case.
+ Each of these __RTL functions returns a const, dumped immediately after
+ expand. */
+
+extern void abort (void);
+
+int __RTL (startwith ("vregs")) test_return_42 (void)
+{
+ /* C code:
+ return 42; */
+(function "test_return_42"
+ (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_return_42"
+}
+
+int __RTL (startwith ("vregs")) test_return_43 (void)
+{
+ /* C code:
+ return 43; */
+(function "test_return_43"
+ (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 43)) "../../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_return_43"
+}
+
+int __RTL (startwith ("vregs")) test_return_44 (void)
+{
+ /* C code:
+ return 44; */
+(function "test_return_44"
+ (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 44)) "../../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_return_44"
+}
+
+int main (void)
+{
+ if (test_return_42 () != 42)
+ abort ();
+ if (test_return_43 () != 43)
+ abort ();
+ if (test_return_44 () != 44)
+ abort ();
+ return 0;
+}
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..8753809
--- /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 (startwith ("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..603caa3
--- /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 (startwith ("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..f6eb1c9
--- /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 (startwith ("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..1321eaf
--- /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 (startwith ("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..50d90dc
--- /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 (startwith ("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
next prev parent reply other threads:[~2016-11-18 21:02 UTC|newest]
Thread overview: 78+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-11-11 20:44 [PATCH 0/9] RTL frontend v4 David Malcolm
2016-11-11 20:43 ` [PATCH 3/9] Introduce emit_status::ensure_regno_capacity David Malcolm
2016-11-14 14:17 ` Bernd Schmidt
2016-11-14 14:31 ` David Malcolm
2016-11-23 20:12 ` Jeff Law
2016-11-11 20:43 ` [PATCH 2/9] (approved) Introduce rtl_data::init_stack_alignment David Malcolm
2016-11-23 20:09 ` Jeff Law
2016-11-11 20:44 ` [PATCH 8/9] Introduce class function_reader (v4) David Malcolm
2016-11-23 20:15 ` Bernd Schmidt
2016-11-23 20:46 ` David Malcolm
2016-12-01 14:40 ` Bernd Schmidt
2016-12-01 21:43 ` David Malcolm
2016-12-02 1:27 ` [PATCH 8a/9] Introduce class function_reader (v6) David Malcolm
2016-12-02 1:27 ` [PATCH 8d/9] Add x86_64-specific selftests for RTL function reader David Malcolm
2016-12-19 16:43 ` [PATCH] Add x86_64-specific selftests for RTL function reader (v2) David Malcolm
2017-01-03 16:47 ` PING " David Malcolm
2017-01-05 9:43 ` Uros Bizjak
2016-12-02 1:27 ` [PATCH 8c/9] Add aarch64-specific selftests for RTL function reader David Malcolm
2016-12-06 17:22 ` James Greenhalgh
2016-12-06 19:38 ` David Malcolm
2016-12-07 9:30 ` James Greenhalgh
2016-12-02 1:27 ` [PATCH 8b/9] Add target-independent selftests of " David Malcolm
2016-12-02 15:06 ` Bernd Schmidt
2016-12-05 5:55 ` Jeff Law
2016-12-02 1:28 ` [PATCH 9/9] Add "__RTL" to cc1 (v6) David Malcolm
2016-12-02 14:41 ` [PATCH 8a/9] Introduce class function_reader (v6) Bernd Schmidt
2016-12-02 18:12 ` [PATCH 8a/9] Introduce class function_reader (v7) David Malcolm
2016-12-02 18:58 ` Bernd Schmidt
2016-12-08 2:29 ` [PATCH] Avoid double unread_char (c) in patch 8a of RTL frontend David Malcolm
2016-12-08 15:16 ` Bernd Schmidt
2016-12-08 20:06 ` [PATCH] Fix bug in MEM parsing in patches 8a/8b David Malcolm
2016-12-08 20:08 ` Bernd Schmidt
2016-12-09 1:29 ` [PATCH] Prevent use of MEM_* attr accessor macros as lvalues David Malcolm
2016-12-09 1:32 ` Bernd Schmidt
2016-12-19 22:15 ` [PATCH] Fix bug in MEM parsing in patches 8a/8b Jeff Law
2016-12-19 23:02 ` David Malcolm
2016-12-02 15:28 ` [PATCH 8/9] Introduce class function_reader (v4) Bernd Schmidt
2016-12-02 19:51 ` [PATCH] Add ASSERT_RTX_PTR_EQ David Malcolm
2016-12-06 12:09 ` Bernd Schmidt
2016-11-11 20:44 ` [PATCH 5/9] Introduce selftest::locate_file (v4) David Malcolm
2016-12-01 13:29 ` Bernd Schmidt
2016-12-02 1:20 ` David Malcolm
2016-12-08 21:47 ` David Malcolm
2016-12-09 1:48 ` Bernd Schmidt
2016-12-09 19:32 ` PR target/78213 revisited (was Re: [PATCH 5/9] Introduce selftest::locate_file (v4)) David Malcolm
2016-12-14 14:04 ` Bernd Schmidt
2016-12-15 2:14 ` [committed] Introduce selftest::locate_file (v5) David Malcolm
2021-08-17 7:00 ` Thomas Schwinge
2021-08-17 9:00 ` Richard Biener
2021-08-18 23:56 ` H.J. Lu
2021-08-19 7:01 ` Thomas Schwinge
2016-11-11 20:44 ` [PATCH 9/9] Add "__RTL" to cc1 (v4) David Malcolm
2016-11-14 15:14 ` Richard Biener
2016-11-15 21:07 ` David Malcolm
2016-11-16 13:24 ` Richard Biener
2016-11-18 21:02 ` David Malcolm [this message]
2016-11-18 22:14 ` [PATCH] Add "__RTL" to cc1 (v5) Joseph Myers
2016-11-18 22:46 ` [PATCH] Handle EOF in c_parser_parse_rtl_body David Malcolm
2016-11-11 20:44 ` [PATCH 6/9] Split class rtx_reader into md_reader vs rtx_reader David Malcolm
2016-11-22 21:26 ` Richard Sandiford
2016-11-11 20:44 ` [PATCH 1/9] print_rtx: implement support for reuse IDs (v2) David Malcolm
2016-12-01 23:05 ` Jeff Law
2016-12-02 1:37 ` David Malcolm
2016-12-02 15:28 ` Bernd Schmidt
2016-11-11 20:44 ` [PATCH 7/9] Add RTL-error-handling to host David Malcolm
2016-11-22 21:29 ` Richard Sandiford
2016-11-28 13:47 ` Bernd Schmidt
2016-11-29 17:20 ` David Malcolm
2016-11-29 17:23 ` Bernd Schmidt
2016-11-29 18:53 ` David Malcolm
2016-11-29 21:13 ` Bernd Schmidt
2016-11-30 16:18 ` Bernd Schmidt
2016-11-30 19:51 ` [PATCH] Minimal reimplementation of errors.c within read-md.c David Malcolm
2016-12-01 12:40 ` Bernd Schmidt
2016-12-02 22:34 ` [PATCH] Even more minimal " David Malcolm
2016-12-06 12:11 ` Bernd Schmidt
2016-11-11 20:44 ` [PATCH 4/9] (approved) Add some functions for use by the RTL frontend David Malcolm
2016-11-23 20:11 ` Jeff Law
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1479504842-45080-1-git-send-email-dmalcolm@redhat.com \
--to=dmalcolm@redhat.com \
--cc=gcc-patches@gcc.gnu.org \
--cc=hubicka@ucw.cz \
--cc=richard.guenther@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).