public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH 9a] Add "__RTL" to C frontend
  2017-01-10  2:04 [PATCH 9/9] Add "__RTL" to cc1 (v8) David Malcolm
                   ` (6 preceding siblings ...)
  2017-01-10  2:04 ` [PATCH 9e] Update "startwith" logic for pass-skipping to handle __RTL functions David Malcolm
@ 2017-01-10  2:04 ` David Malcolm
  2017-01-10 22:57   ` Joseph Myers
  2017-01-10  2:04 ` [PATCH 9f] Add a way for the C frontend to compile __RTL-tagged functions David Malcolm
  2017-01-10  2:04 ` [PATCH 9j] testsuite: add x86_64-specific files David Malcolm
  9 siblings, 1 reply; 44+ messages in thread
From: David Malcolm @ 2017-01-10  2:04 UTC (permalink / raw)
  To: gcc-patches; +Cc: David Malcolm

This part of the patch adds the ability to tag a function with
"__RTL", analogous to the "__GIMPLE" tag.

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:
	* function.h (struct function): Update comment for field
	"pass_startwith".
---
 gcc/c-family/c-common.c |   1 +
 gcc/c-family/c-common.h |   3 ++
 gcc/c/c-parser.c        | 109 +++++++++++++++++++++++++++++++++++++++++++++---
 gcc/c/c-tree.h          |   7 +++-
 gcc/c/gimple-parser.c   |   8 ++--
 gcc/c/gimple-parser.h   |   2 +-
 gcc/function.h          |   2 +-
 7 files changed, 119 insertions(+), 13 deletions(-)

diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 15ead18..62b762b 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 b838869..fc2ce87 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 6d443da..bcfae86 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -62,6 +62,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.
@@ -1311,6 +1313,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:
@@ -1547,7 +1551,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
@@ -2043,7 +2051,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
@@ -2075,12 +2083,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);
@@ -2111,7 +2135,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;
     }
 }
@@ -2603,7 +2626,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;
@@ -18281,4 +18310,74 @@ 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;
+	case CPP_EOF:
+	  error_at (start_loc, "no closing brace");
+	  free (start_with_pass);
+	  return;
+	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 2604884..39cd3a6 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 291bbf6..e68905c 100644
--- a/gcc/c/gimple-parser.c
+++ b/gcc/c/gimple-parser.c
@@ -1008,18 +1008,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 fd36ce1..85cf13a 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/function.h b/gcc/function.h
index fb3cbbc..ec5a9a3 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.  */
-- 
1.8.5.3

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [PATCH 9j] testsuite: add x86_64-specific files
  2017-01-10  2:04 [PATCH 9/9] Add "__RTL" to cc1 (v8) David Malcolm
                   ` (8 preceding siblings ...)
  2017-01-10  2:04 ` [PATCH 9f] Add a way for the C frontend to compile __RTL-tagged functions David Malcolm
@ 2017-01-10  2:04 ` David Malcolm
  2017-01-16 21:59   ` Jeff Law
  9 siblings, 1 reply; 44+ messages in thread
From: David Malcolm @ 2017-01-10  2:04 UTC (permalink / raw)
  To: gcc-patches; +Cc: David Malcolm

A collection of test cases, capturing the state of various
functions at various places within the pass list, and verifying
that we can restart at various passes.

gcc/testsuite/ChangeLog:
	* gcc.dg/rtl/x86_64/dfinit.c: New test case.
	* gcc.dg/rtl/x86_64/different-structs.c: New test case.
	* gcc.dg/rtl/x86_64/final.c: New test case.
	* gcc.dg/rtl/x86_64/into-cfglayout.c: New test case.
	* gcc.dg/rtl/x86_64/ira.c: New test case.
	* gcc.dg/rtl/x86_64/pro_and_epilogue.c: New test case.
	* gcc.dg/rtl/x86_64/test-multiple-fns.c: New test case.
	* gcc.dg/rtl/x86_64/test-return-const.c.after-expand.c: New test case.
	* gcc.dg/rtl/x86_64/test-return-const.c.before-fwprop.c: New test case.
	* gcc.dg/rtl/x86_64/test-rtl.c: New test case.
	* gcc.dg/rtl/x86_64/test_1.h: New file.
	* gcc.dg/rtl/x86_64/times-two.c.after-expand.c: New test case.
	* gcc.dg/rtl/x86_64/times-two.c.before-df.c: New test case.
	* gcc.dg/rtl/x86_64/times-two.h: New file.
	* gcc.dg/rtl/x86_64/vregs.c: New test case.
---
 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/times-two.h        |  22 ++++
 gcc/testsuite/gcc.dg/rtl/x86_64/vregs.c            | 112 +++++++++++++++++
 15 files changed, 1229 insertions(+)
 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/times-two.h
 create mode 100644 gcc/testsuite/gcc.dg/rtl/x86_64/vregs.c

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..3425b97
--- /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..90efaa7
--- /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..ff84c68
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/rtl/x86_64/final.c
@@ -0,0 +1,133 @@
+/* { dg-do compile { target 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..4a82e80
--- /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..a86a846
--- /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..dff4a1b
--- /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..6c1202d
--- /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..d83029e
--- /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..4496868
--- /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..a922c62
--- /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..45f4961
--- /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/times-two.h b/gcc/testsuite/gcc.dg/rtl/x86_64/times-two.h
new file mode 100644
index 0000000..3b89cb9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/rtl/x86_64/times-two.h
@@ -0,0 +1,22 @@
+/* Shared test code for the various __RTL tests of times_two that
+   start at different passes.  */
+
+extern void abort (void);
+int times_two (int i);
+
+int main (void)
+{
+  if (times_two (0) != 0)
+    abort ();
+
+  if (times_two (1) != 2)
+    abort ();
+
+  if (times_two (100) != 200)
+    abort ();
+
+  if (times_two (-20) != -40)
+    abort ();
+
+  return 0;
+}
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..0a3b57a
--- /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

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [PATCH 9h] testsuite: add platform-independent files
  2017-01-10  2:04 [PATCH 9/9] Add "__RTL" to cc1 (v8) David Malcolm
  2017-01-10  2:04 ` [PATCH 9d] Don't call delete_tree_ssa for __RTL functions David Malcolm
@ 2017-01-10  2:04 ` David Malcolm
  2017-01-16 21:56   ` Jeff Law
  2017-01-10  2:04 ` [PATCH 9c] callgraph: handle __RTL functions David Malcolm
                   ` (7 subsequent siblings)
  9 siblings, 1 reply; 44+ messages in thread
From: David Malcolm @ 2017-01-10  2:04 UTC (permalink / raw)
  To: gcc-patches; +Cc: David Malcolm

This patch adds:
  - an rtl.exp (to make it easy to run just the tests
for __RTL-tagged functions)
  - a test.c source file I used when generating the various RTL
dumps (for reference)
  - a couple of tests of __RTL parser errors

gcc/testsuite/ChangeLog:
	* gcc.dg/rtl/rtl.exp: New file.
	* gcc.dg/rtl/test.c: New file.
	* gcc.dg/rtl/truncated-rtl-file.c: New test case.
	* gcc.dg/rtl/unknown-rtx-code.c: New test case.
---
 gcc/testsuite/gcc.dg/rtl/rtl.exp              | 41 +++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/rtl/test.c               | 31 ++++++++++++++++++++
 gcc/testsuite/gcc.dg/rtl/truncated-rtl-file.c |  2 ++
 gcc/testsuite/gcc.dg/rtl/unknown-rtx-code.c   |  8 ++++++
 4 files changed, 82 insertions(+)
 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/truncated-rtl-file.c
 create mode 100644 gcc/testsuite/gcc.dg/rtl/unknown-rtx-code.c

diff --git a/gcc/testsuite/gcc.dg/rtl/rtl.exp b/gcc/testsuite/gcc.dg/rtl/rtl.exp
new file mode 100644
index 0000000..70a6d8b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/rtl/rtl.exp
@@ -0,0 +1,41 @@
+#   Copyright (C) 2016-2017 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/truncated-rtl-file.c b/gcc/testsuite/gcc.dg/rtl/truncated-rtl-file.c
new file mode 100644
index 0000000..4dd8214
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/rtl/truncated-rtl-file.c
@@ -0,0 +1,2 @@
+void __RTL test (void)
+{ /* { dg-error "no closing brace" } */
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
+}
-- 
1.8.5.3

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [PATCH 9/9] Add "__RTL" to cc1 (v8)
@ 2017-01-10  2:04 David Malcolm
  2017-01-10  2:04 ` [PATCH 9d] Don't call delete_tree_ssa for __RTL functions David Malcolm
                   ` (9 more replies)
  0 siblings, 10 replies; 44+ messages in thread
From: David Malcolm @ 2017-01-10  2:04 UTC (permalink / raw)
  To: gcc-patches; +Cc: David Malcolm

This is a slightly updated version of the patch sent here:

  "[PATCH] Add "__RTL" to cc1 (v7)"
    https://gcc.gnu.org/ml/gcc-patches/2016-12/msg01662.html

but split up into smaller parts to (I hope) make review
easier.

Other changes in v8:
 - fix copyright years in new files
 - split out changes to passes.c; fixups to pass skipping

The set of patches wires up the RTL-reading code into cc1 for
functions tagged with "__RTL" in an analogous manner to those
tagged with "__GIMPLE", and adds a collection of testcases using
this functionality.

One difference from the GIMPLE frontend is that, due to the
pervasive singleton state throughout the RTL code, we can't have
more than one RTL function in memory at once.  Hence as soon as
we're done parsing an __RTL-tagged function we have to run the
rest of the passes on it, and emit asm for it, rather than having
the callgraph control this.

Successfully bootstrapped&regrtested on x86_64-pc-linux-gnu;
v7 was successfully built for 191 target configurations.

David Malcolm (10):
  Add "__RTL" to C frontend
  Don't assume that copy tables were initialized
  callgraph: handle __RTL functions
  Don't call delete_tree_ssa for __RTL functions
  Update "startwith" logic for pass-skipping to handle __RTL functions
  Add a way for the C frontend to compile __RTL-tagged functions
  Extend .md and RTL parsing to support being wired up to cc1
  testsuite: add platform-independent files
  testsuite: add aarch64-specific files
  testsuite: add x86_64-specific files

 gcc/Makefile.in                                    |   1 +
 gcc/c-family/c-common.c                            |   1 +
 gcc/c-family/c-common.h                            |   3 +
 gcc/c/c-parser.c                                   | 109 ++++++++++++++++-
 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                                       |  65 ++++++++--
 gcc/read-md.c                                      |  34 +++++-
 gcc/read-md.h                                      |   7 ++
 gcc/read-rtl-function.c                            |  83 ++++++++++---
 gcc/read-rtl-function.h                            |   3 +
 gcc/run-rtl-passes.c                               |  66 ++++++++++
 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/truncated-rtl-file.c      |   2 +
 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/times-two.h        |  22 ++++
 gcc/testsuite/gcc.dg/rtl/x86_64/vregs.c            | 112 +++++++++++++++++
 44 files changed, 1844 insertions(+), 44 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/truncated-rtl-file.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/times-two.h
 create mode 100644 gcc/testsuite/gcc.dg/rtl/x86_64/vregs.c

-- 
1.8.5.3

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [PATCH 9e] Update "startwith" logic for pass-skipping to handle __RTL functions
  2017-01-10  2:04 [PATCH 9/9] Add "__RTL" to cc1 (v8) David Malcolm
                   ` (5 preceding siblings ...)
  2017-01-10  2:04 ` [PATCH 9i] testsuite: add aarch64-specific files David Malcolm
@ 2017-01-10  2:04 ` David Malcolm
  2017-01-16 21:42   ` Jeff Law
  2017-01-10  2:04 ` [PATCH 9a] Add "__RTL" to C frontend David Malcolm
                   ` (2 subsequent siblings)
  9 siblings, 1 reply; 44+ messages in thread
From: David Malcolm @ 2017-01-10  2:04 UTC (permalink / raw)
  To: gcc-patches; +Cc: David Malcolm

gcc/ChangeLog:
	* passes.c: Include "insn-addr.h".
	(should_skip_pass_p): Add logging.  Update logic for running
	"expand" to be compatible with both __GIMPLE and __RTL.  Guard
	property-provider override so it is only done for gimple passes.
	Don't skip dfinit.
	(skip_pass): New function.
	(execute_one_pass): Call skip_pass when skipping passes.
---
 gcc/passes.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 58 insertions(+), 7 deletions(-)

diff --git a/gcc/passes.c b/gcc/passes.c
index 31262ed..6954d1e 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;
 
@@ -2315,26 +2316,73 @@ should_skip_pass_p (opt_pass *pass)
   if (!cfun->pass_startwith)
     return false;
 
-  /* We can't skip the lowering phase yet -- ideally we'd
-     drive that phase fully via properties.  */
-  if (!(cfun->curr_properties & PROP_ssa))
-    return false;
+ /* For __GIMPLE functions, we have to at least start when we leave
+     SSA.  */
+  if (pass->properties_destroyed & PROP_ssa)
+    {
+      if (!quiet_flag)
+	fprintf (stderr, "starting anyway when leaving SSA: %s\n", pass->name);
+      cfun->pass_startwith = NULL;
+      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;
     }
 
-  /* And also run any property provider.  */
-  if (pass->properties_provided != 0)
+  /* Run any property provider.  */
+  if (pass->type == GIMPLE_PASS
+      && pass->properties_provided != 0)
     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);
+
   /* If we get here, then we have a "startwith" that we haven't seen yet;
      skip the pass.  */
   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. */
 
 bool
@@ -2375,7 +2423,10 @@ execute_one_pass (opt_pass *pass)
     }
 
   if (should_skip_pass_p (pass))
-    return true;
+    {
+      skip_pass (pass);
+      return true;
+    }
 
   /* Pass execution event trigger: useful to identify passes being
      executed.  */
-- 
1.8.5.3

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [PATCH 9i] testsuite: add aarch64-specific files
  2017-01-10  2:04 [PATCH 9/9] Add "__RTL" to cc1 (v8) David Malcolm
                   ` (4 preceding siblings ...)
  2017-01-10  2:04 ` [PATCH 9g] Extend .md and RTL parsing to support being wired up to cc1 David Malcolm
@ 2017-01-10  2:04 ` David Malcolm
  2017-01-16 22:00   ` Jeff Law
  2017-01-10  2:04 ` [PATCH 9e] Update "startwith" logic for pass-skipping to handle __RTL functions David Malcolm
                   ` (3 subsequent siblings)
  9 siblings, 1 reply; 44+ messages in thread
From: David Malcolm @ 2017-01-10  2:04 UTC (permalink / raw)
  To: gcc-patches; +Cc: David Malcolm

gcc/testsuite/ChangeLog:
	* gcc.dg/rtl/aarch64/asr_div1.c: New test case.
	* gcc.dg/rtl/aarch64/pr71779.c: New test case.
---
 gcc/testsuite/gcc.dg/rtl/aarch64/asr_div1.c | 41 +++++++++++++++++++++++
 gcc/testsuite/gcc.dg/rtl/aarch64/pr71779.c  | 50 +++++++++++++++++++++++++++++
 2 files changed, 91 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/rtl/aarch64/asr_div1.c
 create mode 100644 gcc/testsuite/gcc.dg/rtl/aarch64/pr71779.c

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..a95c8c7
--- /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..9174abb
--- /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.  */
-- 
1.8.5.3

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [PATCH 9g] Extend .md and RTL parsing to support being wired up to cc1
  2017-01-10  2:04 [PATCH 9/9] Add "__RTL" to cc1 (v8) David Malcolm
                   ` (3 preceding siblings ...)
  2017-01-10  2:04 ` [PATCH 9b] Don't assume that copy tables were initialized David Malcolm
@ 2017-01-10  2:04 ` David Malcolm
  2017-01-16 22:04   ` Jeff Law
  2017-01-10  2:04 ` [PATCH 9i] testsuite: add aarch64-specific files David Malcolm
                   ` (4 subsequent siblings)
  9 siblings, 1 reply; 44+ messages in thread
From: David Malcolm @ 2017-01-10  2:04 UTC (permalink / raw)
  To: gcc-patches; +Cc: David Malcolm

gcc/ChangeLog:
	* 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::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.
---
 gcc/read-md.c           | 34 +++++++++++++++++++-
 gcc/read-md.h           |  7 +++++
 gcc/read-rtl-function.c | 83 +++++++++++++++++++++++++++++++++++++++----------
 gcc/read-rtl-function.h |  3 ++
 4 files changed, 109 insertions(+), 18 deletions(-)

diff --git a/gcc/read-md.c b/gcc/read-md.c
index ac28944..4036afa 100644
--- a/gcc/read-md.c
+++ b/gcc/read-md.c
@@ -411,6 +411,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;
 }
 
@@ -991,7 +1001,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;
@@ -1314,6 +1326,26 @@ md_reader::read_file (const char *filename)
   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 4fcbcb4..fea7011 100644
--- a/gcc/read-md.h
+++ b/gcc/read-md.h
@@ -111,6 +111,9 @@ class md_reader
 
   bool read_md_files (int, const char **, bool (*) (const char *));
   bool read_file (const char *filename);
+  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
@@ -245,6 +248,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 c5cb3f7..f27e174 100644
--- a/gcc/read-rtl-function.c
+++ b/gcc/read-rtl-function.c
@@ -475,23 +475,38 @@ function_reader::create_function ()
   /* We start in cfgrtl mode, rather than cfglayout mode.  */
   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);
 
@@ -1583,6 +1598,40 @@ read_rtl_function_body (const char *path)
   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;
+  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 45ada84..10ceab8 100644
--- a/gcc/read-rtl-function.h
+++ b/gcc/read-rtl-function.h
@@ -22,4 +22,7 @@ along with GCC; see the file COPYING3.  If not see
 
 extern bool read_rtl_function_body (const char *path);
 
+extern bool read_rtl_function_body_from_file_range (location_t start_loc,
+						    location_t end_loc);
+
 #endif /* GCC_READ_RTL_FUNCTION_H */
-- 
1.8.5.3

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [PATCH 9b] Don't assume that copy tables were initialized
  2017-01-10  2:04 [PATCH 9/9] Add "__RTL" to cc1 (v8) David Malcolm
                   ` (2 preceding siblings ...)
  2017-01-10  2:04 ` [PATCH 9c] callgraph: handle __RTL functions David Malcolm
@ 2017-01-10  2:04 ` David Malcolm
  2017-01-10 13:37   ` Richard Biener
  2017-01-10  2:04 ` [PATCH 9g] Extend .md and RTL parsing to support being wired up to cc1 David Malcolm
                   ` (5 subsequent siblings)
  9 siblings, 1 reply; 44+ messages in thread
From: David Malcolm @ 2017-01-10  2:04 UTC (permalink / raw)
  To: gcc-patches; +Cc: David Malcolm

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.
---
 gcc/cfg.c    | 9 +++++++++
 gcc/cfg.h    | 1 +
 gcc/cfgrtl.c | 3 ++-
 3 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/gcc/cfg.c b/gcc/cfg.c
index 97cc755..f30b680 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 d421d3b..b44f1e1 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 7604346..b3b1146 100644
--- a/gcc/cfgrtl.c
+++ b/gcc/cfgrtl.c
@@ -3646,7 +3646,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 ();
 
-- 
1.8.5.3

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [PATCH 9f] Add a way for the C frontend to compile __RTL-tagged functions
  2017-01-10  2:04 [PATCH 9/9] Add "__RTL" to cc1 (v8) David Malcolm
                   ` (7 preceding siblings ...)
  2017-01-10  2:04 ` [PATCH 9a] Add "__RTL" to C frontend David Malcolm
@ 2017-01-10  2:04 ` David Malcolm
  2017-01-16 21:55   ` Jeff Law
  2017-01-10  2:04 ` [PATCH 9j] testsuite: add x86_64-specific files David Malcolm
  9 siblings, 1 reply; 44+ messages in thread
From: David Malcolm @ 2017-01-10  2:04 UTC (permalink / raw)
  To: gcc-patches; +Cc: David Malcolm

The backend is full of singleton state, so we have to compile
__RTL-functions as soon as we parse them.  This means that the
C frontend needs to invoke the backed.

This patch adds the support needed.

Normally this would be a no-no, and including rtl headers is
blocked by this within system.h:

 /* Front ends should never have to include middle-end headers.  Enforce
    this by poisoning the header double-include protection defines.  */
 #ifdef IN_GCC_FRONTEND
 #pragma GCC poison GCC_RTL_H GCC_EXCEPT_H GCC_EXPR_H
 #endif

Hence the patch puts the decl into a new header (run-rtl-passes.h)
that's accessible to the C frontend without exposing any RTL
internals.  (If adding a header for just this decl is overkill, is
there a better place to put the decl?)

gcc/ChangeLog:
	* Makefile.in (OBJS): Add run-rtl-passes.o.
	* pass_manager.h (gcc::pass_manager::get_rest_of_compilation): New
	accessor.
	(gcc::pass_manager::get_clean_slate): New accessor.
	* run-rtl-passes.c: New file.
	* run-rtl-passes.h: New file.
---
 gcc/Makefile.in      |  1 +
 gcc/pass_manager.h   |  6 +++++
 gcc/run-rtl-passes.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 gcc/run-rtl-passes.h | 25 ++++++++++++++++++++
 4 files changed, 98 insertions(+)
 create mode 100644 gcc/run-rtl-passes.c
 create mode 100644 gcc/run-rtl-passes.h

diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 3d9532b..3ad53ad 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1442,6 +1442,7 @@ OBJS = \
 	rtlhash.o \
 	rtlanal.o \
 	rtlhooks.o \
+	run-rtl-passes.o \
 	sbitmap.o \
 	sched-deps.o \
 	sched-ebb.o \
diff --git a/gcc/pass_manager.h b/gcc/pass_manager.h
index 4d15407..ae97cd4 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/run-rtl-passes.c b/gcc/run-rtl-passes.c
new file mode 100644
index 0000000..e1ac4bd
--- /dev/null
+++ b/gcc/run-rtl-passes.c
@@ -0,0 +1,66 @@
+/* run-rtl-passes.c - Run RTL passes directly from frontend
+   Copyright (C) 2016-2017 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 "rtl.h"
+#include "function.h"
+#include "basic-block.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 (&reg_obstack);
+
+  opt_pass *rest_of_compilation
+    = g->get_passes ()->get_rest_of_compilation ();
+  gcc_assert (rest_of_compilation);
+  execute_pass_list (cfun, rest_of_compilation);
+
+  opt_pass *clean_slate = g->get_passes ()->get_clean_slate ();
+  gcc_assert (clean_slate);
+  execute_pass_list (cfun, clean_slate);
+
+  bitmap_obstack_release (&reg_obstack);
+
+  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..1390303
--- /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-2017 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 */
-- 
1.8.5.3

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [PATCH 9d] Don't call delete_tree_ssa for __RTL functions
  2017-01-10  2:04 [PATCH 9/9] Add "__RTL" to cc1 (v8) David Malcolm
@ 2017-01-10  2:04 ` David Malcolm
  2017-01-10 13:42   ` Richard Biener
  2017-01-16 21:14   ` Jeff Law
  2017-01-10  2:04 ` [PATCH 9h] testsuite: add platform-independent files David Malcolm
                   ` (8 subsequent siblings)
  9 siblings, 2 replies; 44+ messages in thread
From: David Malcolm @ 2017-01-10  2:04 UTC (permalink / raw)
  To: gcc-patches; +Cc: David Malcolm

gcc/ChangeLog:
	* final.c (rest_of_clean_state): Don't call delete_tree_ssa for
	__RTL functions.
---
 gcc/final.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/gcc/final.c b/gcc/final.c
index 8a4c9f8..2483381 100644
--- a/gcc/final.c
+++ b/gcc/final.c
@@ -4699,7 +4699,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
-- 
1.8.5.3

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [PATCH 9c] callgraph: handle __RTL functions
  2017-01-10  2:04 [PATCH 9/9] Add "__RTL" to cc1 (v8) David Malcolm
  2017-01-10  2:04 ` [PATCH 9d] Don't call delete_tree_ssa for __RTL functions David Malcolm
  2017-01-10  2:04 ` [PATCH 9h] testsuite: add platform-independent files David Malcolm
@ 2017-01-10  2:04 ` David Malcolm
  2017-01-16 21:25   ` Jeff Law
  2017-01-10  2:04 ` [PATCH 9b] Don't assume that copy tables were initialized David Malcolm
                   ` (6 subsequent siblings)
  9 siblings, 1 reply; 44+ messages in thread
From: David Malcolm @ 2017-01-10  2:04 UTC (permalink / raw)
  To: gcc-patches; +Cc: David Malcolm

The RTL backend code is full of singleton state, so we have to handle
functions as soon as we parse them.  This requires various special-casing
in the callgraph code.

gcc/ChangeLog:
	* 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.
	* gimple-expr.c: Include "tree-pass.h".
	(gimple_has_body_p): Return false for __RTL functions.
---
 gcc/cgraph.h      |  4 ++++
 gcc/cgraphunit.c  | 41 ++++++++++++++++++++++++++++++++++++++---
 gcc/gimple-expr.c |  3 ++-
 3 files changed, 44 insertions(+), 4 deletions(-)

diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index db2915c..edaae51 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 81a3ae9..ed699e1 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/gimple-expr.c b/gcc/gimple-expr.c
index b435b99..2ee87c2 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.  */
-- 
1.8.5.3

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 9b] Don't assume that copy tables were initialized
  2017-01-10  2:04 ` [PATCH 9b] Don't assume that copy tables were initialized David Malcolm
@ 2017-01-10 13:37   ` Richard Biener
  0 siblings, 0 replies; 44+ messages in thread
From: Richard Biener @ 2017-01-10 13:37 UTC (permalink / raw)
  To: David Malcolm; +Cc: GCC Patches

On Tue, Jan 10, 2017 at 3:38 AM, David Malcolm <dmalcolm@redhat.com> wrote:
> 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.

Ok.

Richard.

> ---
>  gcc/cfg.c    | 9 +++++++++
>  gcc/cfg.h    | 1 +
>  gcc/cfgrtl.c | 3 ++-
>  3 files changed, 12 insertions(+), 1 deletion(-)
>
> diff --git a/gcc/cfg.c b/gcc/cfg.c
> index 97cc755..f30b680 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 d421d3b..b44f1e1 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 7604346..b3b1146 100644
> --- a/gcc/cfgrtl.c
> +++ b/gcc/cfgrtl.c
> @@ -3646,7 +3646,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 ();
>
> --
> 1.8.5.3
>

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 9d] Don't call delete_tree_ssa for __RTL functions
  2017-01-10  2:04 ` [PATCH 9d] Don't call delete_tree_ssa for __RTL functions David Malcolm
@ 2017-01-10 13:42   ` Richard Biener
  2017-01-16 21:15     ` Jeff Law
  2017-01-16 21:14   ` Jeff Law
  1 sibling, 1 reply; 44+ messages in thread
From: Richard Biener @ 2017-01-10 13:42 UTC (permalink / raw)
  To: David Malcolm; +Cc: GCC Patches

On Tue, Jan 10, 2017 at 3:38 AM, David Malcolm <dmalcolm@redhat.com> wrote:
> gcc/ChangeLog:
>         * final.c (rest_of_clean_state): Don't call delete_tree_ssa for
>         __RTL functions.

Heh, so you are lucky that nothing looks at this.  MEM_EXPRs can
contain SSA names
these days (for points-to info), but I suppose you don't parse
MEM_EXPRs fully yet.

I'm somewhat inclined to tell you calling init_tree_ssa () for __RTL
functions...

Richard.

> ---
>  gcc/final.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/gcc/final.c b/gcc/final.c
> index 8a4c9f8..2483381 100644
> --- a/gcc/final.c
> +++ b/gcc/final.c
> @@ -4699,7 +4699,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
> --
> 1.8.5.3
>

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 9a] Add "__RTL" to C frontend
  2017-01-10  2:04 ` [PATCH 9a] Add "__RTL" to C frontend David Malcolm
@ 2017-01-10 22:57   ` Joseph Myers
  0 siblings, 0 replies; 44+ messages in thread
From: Joseph Myers @ 2017-01-10 22:57 UTC (permalink / raw)
  To: David Malcolm; +Cc: gcc-patches

On Mon, 9 Jan 2017, David Malcolm wrote:

> This part of the patch adds the ability to tag a function with
> "__RTL", analogous to the "__GIMPLE" tag.
> 
> 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:
> 	* function.h (struct function): Update comment for field
> 	"pass_startwith".

OK.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 9d] Don't call delete_tree_ssa for __RTL functions
  2017-01-10  2:04 ` [PATCH 9d] Don't call delete_tree_ssa for __RTL functions David Malcolm
  2017-01-10 13:42   ` Richard Biener
@ 2017-01-16 21:14   ` Jeff Law
  1 sibling, 0 replies; 44+ messages in thread
From: Jeff Law @ 2017-01-16 21:14 UTC (permalink / raw)
  To: David Malcolm, gcc-patches

On 01/09/2017 07:38 PM, David Malcolm wrote:
> gcc/ChangeLog:
> 	* final.c (rest_of_clean_state): Don't call delete_tree_ssa for
> 	__RTL functions.
OK.   And just for the record, these patches were submitted prior to 
stage1 close.  I'm hesitant to go forward with them unless the set as a 
whole can easily be seen to not affect the existing front-end.

jeff

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 9d] Don't call delete_tree_ssa for __RTL functions
  2017-01-10 13:42   ` Richard Biener
@ 2017-01-16 21:15     ` Jeff Law
  0 siblings, 0 replies; 44+ messages in thread
From: Jeff Law @ 2017-01-16 21:15 UTC (permalink / raw)
  To: Richard Biener, David Malcolm; +Cc: GCC Patches

On 01/10/2017 06:42 AM, Richard Biener wrote:
> On Tue, Jan 10, 2017 at 3:38 AM, David Malcolm <dmalcolm@redhat.com> wrote:
>> gcc/ChangeLog:
>>         * final.c (rest_of_clean_state): Don't call delete_tree_ssa for
>>         __RTL functions.
>
> Heh, so you are lucky that nothing looks at this.  MEM_EXPRs can
> contain SSA names
> these days (for points-to info), but I suppose you don't parse
> MEM_EXPRs fully yet.
>
> I'm somewhat inclined to tell you calling init_tree_ssa () for __RTL
> functions...
Perhaps, but I suspect it'll just open up another can-o-worms WRT state 
that needs to be initialized.

Jeff

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 9c] callgraph: handle __RTL functions
  2017-01-10  2:04 ` [PATCH 9c] callgraph: handle __RTL functions David Malcolm
@ 2017-01-16 21:25   ` Jeff Law
  2017-01-17  9:21     ` Richard Biener
  0 siblings, 1 reply; 44+ messages in thread
From: Jeff Law @ 2017-01-16 21:25 UTC (permalink / raw)
  To: David Malcolm, gcc-patches

On 01/09/2017 07:38 PM, David Malcolm wrote:
> The RTL backend code is full of singleton state, so we have to handle
> functions as soon as we parse them.  This requires various special-casing
> in the callgraph code.
>
> gcc/ChangeLog:
> 	* 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.
> 	* gimple-expr.c: Include "tree-pass.h".
> 	(gimple_has_body_p): Return false for __RTL functions.
> ---
>  gcc/cgraph.h      |  4 ++++
>  gcc/cgraphunit.c  | 41 ++++++++++++++++++++++++++++++++++++++---
>  gcc/gimple-expr.c |  3 ++-
>  3 files changed, 44 insertions(+), 4 deletions(-)
>

> diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
> index 81a3ae9..ed699e1 100644
> --- a/gcc/cgraphunit.c
> +++ b/gcc/cgraphunit.c
  @@ -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;
> +    }
So my concern here would be how this interacts with the rest of the 
cgraph machinery.  Essentially you're saying we've built all the 
properties for the given code.  But AFAICT that can't be true and cgraph 
isn't actually aware of any of the properties of the native RTL code 
(even such things as what functions the native RTL code might call).

So I guess my question is how do you ensure that even though cgraph 
hasn't looked at code that we're appropriately conservative with how the 
file is processed?  Particularly if there's other code in the source 
file that is expected to interact with the RTL native code?

Jeff

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 9e] Update "startwith" logic for pass-skipping to handle __RTL functions
  2017-01-10  2:04 ` [PATCH 9e] Update "startwith" logic for pass-skipping to handle __RTL functions David Malcolm
@ 2017-01-16 21:42   ` Jeff Law
  2017-01-17  9:28     ` Richard Biener
  0 siblings, 1 reply; 44+ messages in thread
From: Jeff Law @ 2017-01-16 21:42 UTC (permalink / raw)
  To: David Malcolm, gcc-patches

On 01/09/2017 07:38 PM, David Malcolm wrote:
> gcc/ChangeLog:
> 	* passes.c: Include "insn-addr.h".
> 	(should_skip_pass_p): Add logging.  Update logic for running
> 	"expand" to be compatible with both __GIMPLE and __RTL.  Guard
> 	property-provider override so it is only done for gimple passes.
> 	Don't skip dfinit.
> 	(skip_pass): New function.
> 	(execute_one_pass): Call skip_pass when skipping passes.
> ---
>  gcc/passes.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++-------
>  1 file changed, 58 insertions(+), 7 deletions(-)
>
> diff --git a/gcc/passes.c b/gcc/passes.c
> index 31262ed..6954d1e 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.  */
insn-addr?  Yuk.


>
>  using namespace gcc;
>
> @@ -2315,26 +2316,73 @@ should_skip_pass_p (opt_pass *pass)
>    if (!cfun->pass_startwith)
>      return false;
>
> -  /* We can't skip the lowering phase yet -- ideally we'd
> -     drive that phase fully via properties.  */
> -  if (!(cfun->curr_properties & PROP_ssa))
> -    return false;
> + /* For __GIMPLE functions, we have to at least start when we leave
> +     SSA.  */
> +  if (pass->properties_destroyed & PROP_ssa)
> +    {
> +      if (!quiet_flag)
> +	fprintf (stderr, "starting anyway when leaving SSA: %s\n", pass->name);
> +      cfun->pass_startwith = NULL;
> +      return false;
> +    }
This seems to need a comment -- it's not obvious how destroying the SSA 
property maps to a pass that can not be skipped.
>
>
> -  /* And also run any property provider.  */
> -  if (pass->properties_provided != 0)
> +  /* Run any property provider.  */
> +  if (pass->type == GIMPLE_PASS
> +      && pass->properties_provided != 0)
>      return false;
So comment needed here too.  I read this as "if a gimple pass provides a 
property then it should not be skipped.  Which means that an RTL pass 
that provides a property can?


>
> +  /* Don't skip df init; later RTL passes need it.  */
> +  if (strstr (pass->name, "dfinit") != NULL)
> +    return false;
Which seems like a failing in RTL passes saying they need DF init.



> +/* 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)
...
This all feels like a failing in how we handle state in the RTL world. 
And I suspect it's prone to error.  Imagine if I'm hacking on something 
in the RTL world and my code depends on something else being set up.   I 
really ought to have a way within my pass to indicate what I depend on. 
Having it hidden away in passes.c makes it easy to miss/forget.


> +{
> +  /* 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;
Seems like this ought to be a property provided by LRA/reload.


> +
> +  /* 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 ());
Similarly ought to be provided by shorten-branches

> +
> +  /* 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;
> +    }
> +}
This feels somewhat different, but still a hack.

I don't have strong suggestions on how to approach this, but what we've 
got here feels like a hack and one prone to bitrot.

jeff

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 9f] Add a way for the C frontend to compile __RTL-tagged functions
  2017-01-10  2:04 ` [PATCH 9f] Add a way for the C frontend to compile __RTL-tagged functions David Malcolm
@ 2017-01-16 21:55   ` Jeff Law
  2017-01-16 23:23     ` David Malcolm
  0 siblings, 1 reply; 44+ messages in thread
From: Jeff Law @ 2017-01-16 21:55 UTC (permalink / raw)
  To: David Malcolm, gcc-patches

On 01/09/2017 07:38 PM, David Malcolm wrote:
> The backend is full of singleton state, so we have to compile
> __RTL-functions as soon as we parse them.  This means that the
> C frontend needs to invoke the backed.
>
> This patch adds the support needed.
>
> Normally this would be a no-no, and including rtl headers is
> blocked by this within system.h:
>
>  /* Front ends should never have to include middle-end headers.  Enforce
>     this by poisoning the header double-include protection defines.  */
>  #ifdef IN_GCC_FRONTEND
>  #pragma GCC poison GCC_RTL_H GCC_EXCEPT_H GCC_EXPR_H
>  #endif
>
> Hence the patch puts the decl into a new header (run-rtl-passes.h)
> that's accessible to the C frontend without exposing any RTL
> internals.  (If adding a header for just this decl is overkill, is
> there a better place to put the decl?)
>
> gcc/ChangeLog:
> 	* Makefile.in (OBJS): Add run-rtl-passes.o.
> 	* pass_manager.h (gcc::pass_manager::get_rest_of_compilation): New
> 	accessor.
> 	(gcc::pass_manager::get_clean_slate): New accessor.
> 	* run-rtl-passes.c: New file.
> 	* run-rtl-passes.h: New file.
It feels like this is dependent upon something that I haven't seen?!? 
Where is get_rest_of_compilation used?  Where is pass_clean_state_1?


jeff

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 9h] testsuite: add platform-independent files
  2017-01-10  2:04 ` [PATCH 9h] testsuite: add platform-independent files David Malcolm
@ 2017-01-16 21:56   ` Jeff Law
  0 siblings, 0 replies; 44+ messages in thread
From: Jeff Law @ 2017-01-16 21:56 UTC (permalink / raw)
  To: David Malcolm, gcc-patches

On 01/09/2017 07:38 PM, David Malcolm wrote:
> This patch adds:
>   - an rtl.exp (to make it easy to run just the tests
> for __RTL-tagged functions)
>   - a test.c source file I used when generating the various RTL
> dumps (for reference)
>   - a couple of tests of __RTL parser errors
>
> gcc/testsuite/ChangeLog:
> 	* gcc.dg/rtl/rtl.exp: New file.
> 	* gcc.dg/rtl/test.c: New file.
> 	* gcc.dg/rtl/truncated-rtl-file.c: New test case.
> 	* gcc.dg/rtl/unknown-rtx-code.c: New test case.
OK.
jeff

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 9j] testsuite: add x86_64-specific files
  2017-01-10  2:04 ` [PATCH 9j] testsuite: add x86_64-specific files David Malcolm
@ 2017-01-16 21:59   ` Jeff Law
  0 siblings, 0 replies; 44+ messages in thread
From: Jeff Law @ 2017-01-16 21:59 UTC (permalink / raw)
  To: David Malcolm, gcc-patches

On 01/09/2017 07:38 PM, David Malcolm wrote:
> A collection of test cases, capturing the state of various
> functions at various places within the pass list, and verifying
> that we can restart at various passes.
>
> gcc/testsuite/ChangeLog:
> 	* gcc.dg/rtl/x86_64/dfinit.c: New test case.
> 	* gcc.dg/rtl/x86_64/different-structs.c: New test case.
> 	* gcc.dg/rtl/x86_64/final.c: New test case.
> 	* gcc.dg/rtl/x86_64/into-cfglayout.c: New test case.
> 	* gcc.dg/rtl/x86_64/ira.c: New test case.
> 	* gcc.dg/rtl/x86_64/pro_and_epilogue.c: New test case.
> 	* gcc.dg/rtl/x86_64/test-multiple-fns.c: New test case.
> 	* gcc.dg/rtl/x86_64/test-return-const.c.after-expand.c: New test case.
> 	* gcc.dg/rtl/x86_64/test-return-const.c.before-fwprop.c: New test case.
> 	* gcc.dg/rtl/x86_64/test-rtl.c: New test case.
> 	* gcc.dg/rtl/x86_64/test_1.h: New file.
> 	* gcc.dg/rtl/x86_64/times-two.c.after-expand.c: New test case.
> 	* gcc.dg/rtl/x86_64/times-two.c.before-df.c: New test case.
> 	* gcc.dg/rtl/x86_64/times-two.h: New file.
> 	* gcc.dg/rtl/x86_64/vregs.c: New test case.
This all looks fairly reasonable.

jeff

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 9i] testsuite: add aarch64-specific files
  2017-01-10  2:04 ` [PATCH 9i] testsuite: add aarch64-specific files David Malcolm
@ 2017-01-16 22:00   ` Jeff Law
  0 siblings, 0 replies; 44+ messages in thread
From: Jeff Law @ 2017-01-16 22:00 UTC (permalink / raw)
  To: David Malcolm, gcc-patches

On 01/09/2017 07:38 PM, David Malcolm wrote:
> gcc/testsuite/ChangeLog:
> 	* gcc.dg/rtl/aarch64/asr_div1.c: New test case.
> 	* gcc.dg/rtl/aarch64/pr71779.c: New test case.
OK.
jeff

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 9g] Extend .md and RTL parsing to support being wired up to cc1
  2017-01-10  2:04 ` [PATCH 9g] Extend .md and RTL parsing to support being wired up to cc1 David Malcolm
@ 2017-01-16 22:04   ` Jeff Law
  2017-01-16 23:09     ` David Malcolm
  0 siblings, 1 reply; 44+ messages in thread
From: Jeff Law @ 2017-01-16 22:04 UTC (permalink / raw)
  To: David Malcolm, gcc-patches

On 01/09/2017 07:38 PM, David Malcolm wrote:
> gcc/ChangeLog:
> 	* 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::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.
OK.

So what's left?

jeff

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 9g] Extend .md and RTL parsing to support being wired up to cc1
  2017-01-16 22:04   ` Jeff Law
@ 2017-01-16 23:09     ` David Malcolm
  0 siblings, 0 replies; 44+ messages in thread
From: David Malcolm @ 2017-01-16 23:09 UTC (permalink / raw)
  To: Jeff Law, gcc-patches

On Mon, 2017-01-16 at 15:04 -0700, Jeff Law wrote:
> On 01/09/2017 07:38 PM, David Malcolm wrote:
> > gcc/ChangeLog:
> > 	* 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::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.
> OK.
> 
> So what's left?

Thanks; I believe patches 9a-b, 9d, and 9g-9j are approved.
Patches 9c, 9e and 9f need work.  Am looking at them now.

Dave

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 9f] Add a way for the C frontend to compile __RTL-tagged functions
  2017-01-16 21:55   ` Jeff Law
@ 2017-01-16 23:23     ` David Malcolm
  2017-01-22  9:05       ` Jeff Law
  0 siblings, 1 reply; 44+ messages in thread
From: David Malcolm @ 2017-01-16 23:23 UTC (permalink / raw)
  To: Jeff Law, gcc-patches

On Mon, 2017-01-16 at 14:54 -0700, Jeff Law wrote:
> On 01/09/2017 07:38 PM, David Malcolm wrote:
> > The backend is full of singleton state, so we have to compile
> > __RTL-functions as soon as we parse them.  This means that the
> > C frontend needs to invoke the backed.
> > 
> > This patch adds the support needed.
> > 
> > Normally this would be a no-no, and including rtl headers is
> > blocked by this within system.h:
> > 
> >  /* Front ends should never have to include middle-end headers. 
> >  Enforce
> >     this by poisoning the header double-include protection defines.
> >   */
> >  #ifdef IN_GCC_FRONTEND
> >  #pragma GCC poison GCC_RTL_H GCC_EXCEPT_H GCC_EXPR_H
> >  #endif
> > 
> > Hence the patch puts the decl into a new header (run-rtl-passes.h)
> > that's accessible to the C frontend without exposing any RTL
> > internals.  (If adding a header for just this decl is overkill, is
> > there a better place to put the decl?)
> > 
> > gcc/ChangeLog:
> > 	* Makefile.in (OBJS): Add run-rtl-passes.o.
> > 	* pass_manager.h (gcc::pass_manager::get_rest_of_compilation):
> > New
> > 	accessor.
> > 	(gcc::pass_manager::get_clean_slate): New accessor.
> > 	* run-rtl-passes.c: New file.
> > 	* run-rtl-passes.h: New file.
> It feels like this is dependent upon something that I haven't seen?!?

I may have split things up a bit too much; sorry.  The code in this
patch is called by patch 9a.

>  
> Where is get_rest_of_compilation used? 

In this patch, in run-rtl-passes.c:run_rtl_passes, thusly:

+  opt_pass *rest_of_compilation
+    = g->get_passes ()->get_rest_of_compilation ();
+  gcc_assert (rest_of_compilation);
+  execute_pass_list (cfun, rest_of_compilation);


>  Where is pass_clean_state_1?

(as used in this part of the patch):

>	* pass_manager.h (gcc::pass_manager::get_rest_of_compilation):
>       New accessor.

+  opt_pass *get_clean_slate () const { return pass_clean_state_1; }

This is a new accessor method for the pass_manager class.
pass_clean_state_1 is private member data of the pass_manager, it's the
instance of class pass_clean_state.

This field of pass_manager is created by the 

  /* References to all of the individual passes.
     These fields are generated via macro expansion.

  (...etc...)

  #define NEXT_PASS(PASS, NUM) opt_pass *PASS ## _ ## NUM

  (...etc...)

  #include "pass-instances.def"

code within pass_manager.h.  This line within SRC/gcc/passes.def:

  NEXT_PASS (pass_clean_state);

becomes this line within BUILD/gcc/pass-instances.def:

  NEXT_PASS (pass_clean_state, 1);

and this means that we effectively have this field within class
pass_manager (along with dozens of others):

   opt_pass *pass_clean_state_1;

They're all private; hence the need for this accessor.

Similarly for get_rest_of_compilation.

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 9c] callgraph: handle __RTL functions
  2017-01-16 21:25   ` Jeff Law
@ 2017-01-17  9:21     ` Richard Biener
  2017-01-17 12:36       ` Jan Hubicka
  2017-01-18  0:35       ` Jeff Law
  0 siblings, 2 replies; 44+ messages in thread
From: Richard Biener @ 2017-01-17  9:21 UTC (permalink / raw)
  To: Jeff Law, Jan Hubicka; +Cc: David Malcolm, GCC Patches

On Mon, Jan 16, 2017 at 10:25 PM, Jeff Law <law@redhat.com> wrote:
> On 01/09/2017 07:38 PM, David Malcolm wrote:
>>
>> The RTL backend code is full of singleton state, so we have to handle
>> functions as soon as we parse them.  This requires various special-casing
>> in the callgraph code.
>>
>> gcc/ChangeLog:
>>         * 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.
>>         * gimple-expr.c: Include "tree-pass.h".
>>         (gimple_has_body_p): Return false for __RTL functions.
>> ---
>>  gcc/cgraph.h      |  4 ++++
>>  gcc/cgraphunit.c  | 41 ++++++++++++++++++++++++++++++++++++++---
>>  gcc/gimple-expr.c |  3 ++-
>>  3 files changed, 44 insertions(+), 4 deletions(-)
>>
>
>> diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
>> index 81a3ae9..ed699e1 100644
>> --- a/gcc/cgraphunit.c
>> +++ b/gcc/cgraphunit.c
>
>  @@ -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;
>> +    }
>
> So my concern here would be how this interacts with the rest of the cgraph
> machinery.  Essentially you're saying we've built all the properties for the
> given code.  But AFAICT that can't be true and cgraph isn't actually aware
> of any of the properties of the native RTL code (even such things as what
> functions the native RTL code might call).
>
> So I guess my question is how do you ensure that even though cgraph hasn't
> looked at code that we're appropriately conservative with how the file is
> processed?  Particularly if there's other code in the source file that is
> expected to interact with the RTL native code?

I think that as we're finalizing the function from the FE before the
cgraph is built
(and even throw away the RTL?) we have no other choice than treating a __RTL
function as black box which means treat it as possibly calling all function in
the TU and reading/writing/taking the address of all decls in the TU.  Consider

static int i;
static void foo () {}
int __RTL main()
{
  ... call foo, access i ...
}

which probably will right now optimize i and foo away and thus fail to link?

But I think we can sort out these "details" when we run into them...

Richard.

> Jeff

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 9e] Update "startwith" logic for pass-skipping to handle __RTL functions
  2017-01-16 21:42   ` Jeff Law
@ 2017-01-17  9:28     ` Richard Biener
  2017-01-17 21:10       ` [PATCH] Introduce opt_pass::skip virtual function David Malcolm
  2017-01-18 16:39       ` [PATCH 9e] Update "startwith" logic for pass-skipping to handle __RTL functions Jeff Law
  0 siblings, 2 replies; 44+ messages in thread
From: Richard Biener @ 2017-01-17  9:28 UTC (permalink / raw)
  To: Jeff Law; +Cc: David Malcolm, GCC Patches

On Mon, Jan 16, 2017 at 10:42 PM, Jeff Law <law@redhat.com> wrote:
> On 01/09/2017 07:38 PM, David Malcolm wrote:
>>
>> gcc/ChangeLog:
>>         * passes.c: Include "insn-addr.h".
>>         (should_skip_pass_p): Add logging.  Update logic for running
>>         "expand" to be compatible with both __GIMPLE and __RTL.  Guard
>>         property-provider override so it is only done for gimple passes.
>>         Don't skip dfinit.
>>         (skip_pass): New function.
>>         (execute_one_pass): Call skip_pass when skipping passes.
>> ---
>>  gcc/passes.c | 65
>> +++++++++++++++++++++++++++++++++++++++++++++++++++++-------
>>  1 file changed, 58 insertions(+), 7 deletions(-)
>>
>> diff --git a/gcc/passes.c b/gcc/passes.c
>> index 31262ed..6954d1e 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.  */
>
> insn-addr?  Yuk.
>
>
>>
>>  using namespace gcc;
>>
>> @@ -2315,26 +2316,73 @@ should_skip_pass_p (opt_pass *pass)
>>    if (!cfun->pass_startwith)
>>      return false;
>>
>> -  /* We can't skip the lowering phase yet -- ideally we'd
>> -     drive that phase fully via properties.  */
>> -  if (!(cfun->curr_properties & PROP_ssa))
>> -    return false;
>> + /* For __GIMPLE functions, we have to at least start when we leave
>> +     SSA.  */
>> +  if (pass->properties_destroyed & PROP_ssa)
>> +    {
>> +      if (!quiet_flag)
>> +       fprintf (stderr, "starting anyway when leaving SSA: %s\n",
>> pass->name);
>> +      cfun->pass_startwith = NULL;
>> +      return false;
>> +    }
>
> This seems to need a comment -- it's not obvious how destroying the SSA
> property maps to a pass that can not be skipped.
>>
>>
>>
>> -  /* And also run any property provider.  */
>> -  if (pass->properties_provided != 0)
>> +  /* Run any property provider.  */
>> +  if (pass->type == GIMPLE_PASS
>> +      && pass->properties_provided != 0)
>>      return false;
>
> So comment needed here too.  I read this as "if a gimple pass provides a
> property then it should not be skipped.  Which means that an RTL pass that
> provides a property can?
>
>
>>
>> +  /* Don't skip df init; later RTL passes need it.  */
>> +  if (strstr (pass->name, "dfinit") != NULL)
>> +    return false;
>
> Which seems like a failing in RTL passes saying they need DF init.
>
>
>
>> +/* 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)
>
> ...
> This all feels like a failing in how we handle state in the RTL world. And I
> suspect it's prone to error.  Imagine if I'm hacking on something in the RTL
> world and my code depends on something else being set up.   I really ought
> to have a way within my pass to indicate what I depend on. Having it hidden
> away in passes.c makes it easy to miss/forget.
>
>
>> +{
>> +  /* 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;
>
> Seems like this ought to be a property provided by LRA/reload.
>
>
>> +
>> +  /* 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 ());
>
> Similarly ought to be provided by shorten-branches
>
>> +
>> +  /* 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;
>> +    }
>> +}
>
> This feels somewhat different, but still a hack.
>
> I don't have strong suggestions on how to approach this, but what we've got
> here feels like a hack and one prone to bitrot.

All the above needs a bit of cleanup in the way we use (or not use) PROP_xxx.
For example right now you can't startwith a __GIMPLE with a pass inside the
loop pipeline because those passes expect loops to be initialized and be in
loop-closed SSA.  And with the hack above for the property providers you'll
always run pass_crited (that's a bad user of a PROP_).

Ideally we'd figure out required properties from the startwith pass
(but there's not
an easy way to compute it w/o actually "executing" the passes) and then enable
enough passes on the way to it providing those properties.

Or finally restructure things in a way that the pass manager automatically runs
property provider passes before passes requiring properties that are
not yet available...

Instead of those pass->name comparisions we could invent a new flag in the
pass structure whether a pass should always be run for __GIMPLE or ___RTL
but that's a bit noisy right now.

So I'm fine with the (localized) "hacks" for the moment.

Richard.

> jeff

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 9c] callgraph: handle __RTL functions
  2017-01-17  9:21     ` Richard Biener
@ 2017-01-17 12:36       ` Jan Hubicka
  2017-01-17 17:25         ` David Malcolm
  2017-01-18  0:35       ` Jeff Law
  1 sibling, 1 reply; 44+ messages in thread
From: Jan Hubicka @ 2017-01-17 12:36 UTC (permalink / raw)
  To: Richard Biener; +Cc: Jeff Law, Jan Hubicka, David Malcolm, GCC Patches

> On Mon, Jan 16, 2017 at 10:25 PM, Jeff Law <law@redhat.com> wrote:
> > On 01/09/2017 07:38 PM, David Malcolm wrote:
> >>
> >> The RTL backend code is full of singleton state, so we have to handle
> >> functions as soon as we parse them.  This requires various special-casing
> >> in the callgraph code.
> >>
> >> gcc/ChangeLog:
> >>         * 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.
> >>         * gimple-expr.c: Include "tree-pass.h".
> >>         (gimple_has_body_p): Return false for __RTL functions.
> >> ---
> >>  gcc/cgraph.h      |  4 ++++
> >>  gcc/cgraphunit.c  | 41 ++++++++++++++++++++++++++++++++++++++---
> >>  gcc/gimple-expr.c |  3 ++-
> >>  3 files changed, 44 insertions(+), 4 deletions(-)
> >>
> >
> >> diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
> >> index 81a3ae9..ed699e1 100644
> >> --- a/gcc/cgraphunit.c
> >> +++ b/gcc/cgraphunit.c
> >
> >  @@ -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;
> >> +    }
> >
> > So my concern here would be how this interacts with the rest of the cgraph
> > machinery.  Essentially you're saying we've built all the properties for the
> > given code.  But AFAICT that can't be true and cgraph isn't actually aware
> > of any of the properties of the native RTL code (even such things as what
> > functions the native RTL code might call).
> >
> > So I guess my question is how do you ensure that even though cgraph hasn't
> > looked at code that we're appropriately conservative with how the file is
> > processed?  Particularly if there's other code in the source file that is
> > expected to interact with the RTL native code?
> 
> I think that as we're finalizing the function from the FE before the
> cgraph is built
> (and even throw away the RTL?) we have no other choice than treating a __RTL
> function as black box which means treat it as possibly calling all function in
> the TU and reading/writing/taking the address of all decls in the TU.  Consider

I guess RTL frontend may be arranged to mark all such decls as used or just require
user to do it, like we do with asm statements.

I wonder why we need to insert those definitions into cgraph at first place...

Honza
> 
> static int i;
> static void foo () {}
> int __RTL main()
> {
>   ... call foo, access i ...
> }
> 
> which probably will right now optimize i and foo away and thus fail to link?
> 
> But I think we can sort out these "details" when we run into them...
> 
> Richard.
> 
> > Jeff

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 9c] callgraph: handle __RTL functions
  2017-01-17 12:36       ` Jan Hubicka
@ 2017-01-17 17:25         ` David Malcolm
  2017-01-18 12:51           ` Jan Hubicka
  0 siblings, 1 reply; 44+ messages in thread
From: David Malcolm @ 2017-01-17 17:25 UTC (permalink / raw)
  To: Jan Hubicka, Richard Biener; +Cc: Jeff Law, GCC Patches

On Tue, 2017-01-17 at 13:35 +0100, Jan Hubicka wrote:
> > On Mon, Jan 16, 2017 at 10:25 PM, Jeff Law <law@redhat.com> wrote:
> > > On 01/09/2017 07:38 PM, David Malcolm wrote:
> > > > 
> > > > The RTL backend code is full of singleton state, so we have to
> > > > handle
> > > > functions as soon as we parse them.  This requires various
> > > > special-casing
> > > > in the callgraph code.
> > > > 
> > > > gcc/ChangeLog:
> > > >         * 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.
> > > >         * gimple-expr.c: Include "tree-pass.h".
> > > >         (gimple_has_body_p): Return false for __RTL functions.
> > > > ---
> > > >  gcc/cgraph.h      |  4 ++++
> > > >  gcc/cgraphunit.c  | 41 ++++++++++++++++++++++++++++++++++++++-
> > > > --
> > > >  gcc/gimple-expr.c |  3 ++-
> > > >  3 files changed, 44 insertions(+), 4 deletions(-)
> > > > 
> > > 
> > > > diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
> > > > index 81a3ae9..ed699e1 100644
> > > > --- a/gcc/cgraphunit.c
> > > > +++ b/gcc/cgraphunit.c
> > > 
> > >  @@ -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;
> > > > +    }
> > > 
> > > So my concern here would be how this interacts with the rest of
> > > the cgraph
> > > machinery.  Essentially you're saying we've built all the
> > > properties for the
> > > given code.  But AFAICT that can't be true and cgraph isn't
> > > actually aware
> > > of any of the properties of the native RTL code (even such things
> > > as what
> > > functions the native RTL code might call).
> > > 
> > > So I guess my question is how do you ensure that even though
> > > cgraph hasn't
> > > looked at code that we're appropriately conservative with how the
> > > file is
> > > processed?  Particularly if there's other code in the source file
> > > that is
> > > expected to interact with the RTL native code?
> > 
> > I think that as we're finalizing the function from the FE before
> > the
> > cgraph is built
> > (and even throw away the RTL?) we have no other choice than
> > treating a __RTL
> > function as black box which means treat it as possibly calling all
> > function in
> > the TU and reading/writing/taking the address of all decls in the
> > TU.  Consider
> 
> I guess RTL frontend may be arranged to mark all such decls as used
> or just require
> user to do it, like we do with asm statements.
> 
> I wonder why we need to insert those definitions into cgraph at first
> place...

They're added to the cgraph by this call:

  /* Add to cgraph.  */
  cgraph_node::finalize_function (fndecl, false);

within function_reader::create_function (in r244110, though that code
isn't called yet; it's called by the stuff in patch 9).

If I hack out that call, so that __RTL functions aren't in the cgraph,
then I see lots of failures in the kit, for example here in predict.c:

maybe_hot_frequency_p (struct function *fun, int freq)
{
  struct cgraph_node *node = cgraph_node::get (fun->decl);

  [...read though node, so it must be non-NULL]

Similarly, this line in varasm.c's assemble_start_function assumes that
the fndecl has a symtab node:

  align = symtab_node::get (decl)->definition_alignment ();

etc.

I don't know how many other places make the assumption that cfun's
fndecl has a node in the callgraph.

Given that I want to have __RTL functions called by non-__RTL functions
(and the patch kit handles this), it seemed saner to go down the route
of adding the decl to the callgraph.

> Honza
> > 
> > static int i;
> > static void foo () {}
> > int __RTL main()
> > {
> >   ... call foo, access i ...
> > }
> > 
> > which probably will right now optimize i and foo away and thus fail
> > to link?

> > But I think we can sort out these "details" when we run into
> > them...
> > 
> > Richard.
> > 
> > > Jeff

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [PATCH] Introduce opt_pass::skip virtual function
  2017-01-17  9:28     ` Richard Biener
@ 2017-01-17 21:10       ` David Malcolm
  2017-01-18 16:39       ` [PATCH 9e] Update "startwith" logic for pass-skipping to handle __RTL functions Jeff Law
  1 sibling, 0 replies; 44+ messages in thread
From: David Malcolm @ 2017-01-17 21:10 UTC (permalink / raw)
  To: Richard Biener, Jeff Law; +Cc: gcc-patches, David Malcolm

On Tue, 2017-01-17 at 10:28 +0100, Richard Biener wrote:
> On Mon, Jan 16, 2017 at 10:42 PM, Jeff Law <law@redhat.com> wrote:
> > On 01/09/2017 07:38 PM, David Malcolm wrote:
> > >
> > > gcc/ChangeLog:
> > >         * passes.c: Include "insn-addr.h".
> > >         (should_skip_pass_p): Add logging.  Update logic for
> > > running
> > >         "expand" to be compatible with both __GIMPLE and __RTL.
> > >  Guard
> > >         property-provider override so it is only done for gimple
> > > passes.
> > >         Don't skip dfinit.
> > >         (skip_pass): New function.
> > >         (execute_one_pass): Call skip_pass when skipping passes.
> > > ---
> > >  gcc/passes.c | 65
> > > +++++++++++++++++++++++++++++++++++++++++++++++++++++-------
> > >  1 file changed, 58 insertions(+), 7 deletions(-)
> > >
> > > diff --git a/gcc/passes.c b/gcc/passes.c
> > > index 31262ed..6954d1e 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.  */
> >
> > insn-addr?  Yuk.
> >
> >
> > >
> > >  using namespace gcc;
> > >
> > > @@ -2315,26 +2316,73 @@ should_skip_pass_p (opt_pass *pass)
> > >    if (!cfun->pass_startwith)
> > >      return false;
> > >
> > > -  /* We can't skip the lowering phase yet -- ideally we'd
> > > -     drive that phase fully via properties.  */
> > > -  if (!(cfun->curr_properties & PROP_ssa))
> > > -    return false;
> > > + /* For __GIMPLE functions, we have to at least start when we
> > > leave
> > > +     SSA.  */
> > > +  if (pass->properties_destroyed & PROP_ssa)
> > > +    {
> > > +      if (!quiet_flag)
> > > +       fprintf (stderr, "starting anyway when leaving SSA:
> > > %s\n",
> > > pass->name);
> > > +      cfun->pass_startwith = NULL;
> > > +      return false;
> > > +    }
> >
> > This seems to need a comment -- it's not obvious how destroying the
> > SSA
> > property maps to a pass that can not be skipped.
> > >
> > >
> > >
> > > -  /* And also run any property provider.  */
> > > -  if (pass->properties_provided != 0)
> > > +  /* Run any property provider.  */
> > > +  if (pass->type == GIMPLE_PASS
> > > +      && pass->properties_provided != 0)
> > >      return false;
> >
> > So comment needed here too.  I read this as "if a gimple pass
> > provides a
> > property then it should not be skipped.  Which means that an RTL
> > pass that
> > provides a property can?
> >
> >
> > >
> > > +  /* Don't skip df init; later RTL passes need it.  */
> > > +  if (strstr (pass->name, "dfinit") != NULL)
> > > +    return false;
> >
> > Which seems like a failing in RTL passes saying they need DF init.
> >
> >
> >
> > > +/* 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)
> >
> > ...
> > This all feels like a failing in how we handle state in the RTL
> > world. And I
> > suspect it's prone to error.  Imagine if I'm hacking on something
> > in the RTL
> > world and my code depends on something else being set up.   I
> > really ought
> > to have a way within my pass to indicate what I depend on. Having
> > it hidden
> > away in passes.c makes it easy to miss/forget.
> >
> >
> > > +{
> > > +  /* 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;
> >
> > Seems like this ought to be a property provided by LRA/reload.
> >
> >
> > > +
> > > +  /* 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 ());
> >
> > Similarly ought to be provided by shorten-branches
> >
> > > +
> > > +  /* 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;
> > > +    }
> > > +}
> >
> > This feels somewhat different, but still a hack.
> >
> > I don't have strong suggestions on how to approach this, but what
> > we've got
> > here feels like a hack and one prone to bitrot.
>
> All the above needs a bit of cleanup in the way we use (or not use)
> PROP_xxx.
> For example right now you can't startwith a __GIMPLE with a pass
> inside the
> loop pipeline because those passes expect loops to be initialized and
> be in
> loop-closed SSA.  And with the hack above for the property providers
> you'll
> always run pass_crited (that's a bad user of a PROP_).
>
> Ideally we'd figure out required properties from the startwith pass
> (but there's not
> an easy way to compute it w/o actually "executing" the passes) and
> then enable
> enough passes on the way to it providing those properties.
>
> Or finally restructure things in a way that the pass manager
> automatically runs
> property provider passes before passes requiring properties that are
> not yet available...
>
> Instead of those pass->name comparisions we could invent a new flag
> in the
> pass structure whether a pass should always be run for __GIMPLE or
> ___RTL
> but that's a bit noisy right now.
>
> So I'm fine with the (localized) "hacks" for the moment.
>

Another approach for handling this would be to add another virtual function
to class opt_pass, something like:

  virtual void skip ();

The patch as-is groups together all of the various state-management
hacks into passes.c:skip_pass, whereas with a virtual function, all of
these hacks could be moved to the passes themselves.

Here's a patch (on top of 9e) which implements the idea.
Do you prefer this approach?

gcc/ChangeLog:
	* cfgrtl.c (pass_into_cfg_layout_mode::skip): New method.
	(pass_outof_cfg_layout_mode::skip): New method.
	* final.c (pass_shorten_branches::skip): New method.
	* ira.c (pass_reload::skip): New method.
	* passes.c: Drop redundant include of "insn-addr.h".
	(opt_pass::skip): New method.
	(skip_pass): Delete.
	(execute_one_pass): Use virtual function when skipping passes.
	* tree-pass.h (opt_pass::skip): New virtual function.
---
 gcc/cfgrtl.c    | 22 ++++++++++++++++++++++
 gcc/final.c     |  9 +++++++++
 gcc/ira.c       |  9 +++++++++
 gcc/passes.c    | 42 ++++++++----------------------------------
 gcc/tree-pass.h |  8 ++++++++
 5 files changed, 56 insertions(+), 34 deletions(-)

diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c
index b3b1146..953f807 100644
--- a/gcc/cfgrtl.c
+++ b/gcc/cfgrtl.c
@@ -3519,9 +3519,20 @@ public:
       cfg_layout_initialize (0);
       return 0;
     }
+  void skip (function *) FINAL OVERRIDE;
 
 }; // class pass_into_cfg_layout_mode
 
+/* Minimal version of this pass, for use when skipping this pass
+   with __RTL functions that start at a later pass.  */
+
+void
+pass_into_cfg_layout_mode::skip (function *)
+{
+  cfg_layout_rtl_register_cfg_hooks ();
+  cfun->curr_properties |= PROP_cfglayout;
+}
+
 } // anon namespace
 
 rtl_opt_pass *
@@ -3554,6 +3565,7 @@ public:
 
   /* opt_pass methods: */
   virtual unsigned int execute (function *);
+  void skip (function *) FINAL OVERRIDE;
 
 }; // class pass_outof_cfg_layout_mode
 
@@ -3571,6 +3583,16 @@ pass_outof_cfg_layout_mode::execute (function *fun)
   return 0;
 }
 
+/* Minimal version of this pass, for use when skipping this pass
+   with __RTL functions that start at a later pass.  */
+
+void
+pass_outof_cfg_layout_mode::skip (function *)
+{
+  rtl_register_cfg_hooks ();
+  cfun->curr_properties &= ~PROP_cfglayout;
+}
+
 } // anon namespace
 
 rtl_opt_pass *
diff --git a/gcc/final.c b/gcc/final.c
index 2483381..e869031 100644
--- a/gcc/final.c
+++ b/gcc/final.c
@@ -4594,6 +4594,15 @@ public:
       return rest_of_handle_shorten_branches ();
     }
 
+  /* The INSN_ADDRESSES vec is normally set up by shorten_branches.
+     If we're skipping the pass for an __RTL function that starts at a
+     later pass, set it up for the benefit of passes that run after
+     this.  */
+  void skip (function *) FINAL OVERRIDE
+  {
+    INSN_ADDRESSES_ALLOC (get_max_uid ());
+  }
+
 }; // class pass_shorten_branches
 
 } // anon namespace
diff --git a/gcc/ira.c b/gcc/ira.c
index 96b4b62..97f81da 100644
--- a/gcc/ira.c
+++ b/gcc/ira.c
@@ -5585,6 +5585,15 @@ public:
       return 0;
     }
 
+  /* Pass "reload" sets the global "reload_completed", and many
+     things depend on this (e.g. instructions in .md files).
+     Hence when skipping the pass for __RTL functions with "startwith" a
+     later pass, we need to set the flag.  */
+  void skip (function *) FINAL OVERRIDE
+  {
+    reload_completed = 1;
+  }
+
 }; // class pass_reload
 
 } // anon namespace
diff --git a/gcc/passes.c b/gcc/passes.c
index 6954d1e..deb72f0 100644
--- a/gcc/passes.c
+++ b/gcc/passes.c
@@ -59,7 +59,6 @@ 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;
 
@@ -100,6 +99,13 @@ opt_pass::execute (function *)
   return 0;
 }
 
+/* The base class implementation of "skip" is a no-op.  */
+
+void
+opt_pass::skip (function *)
+{
+}
+
 opt_pass::opt_pass (const pass_data &data, context *ctxt)
   : pass_data (data),
     sub (NULL),
@@ -2351,38 +2357,6 @@ should_skip_pass_p (opt_pass *pass)
   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. */
 
 bool
@@ -2424,7 +2398,7 @@ execute_one_pass (opt_pass *pass)
 
   if (should_skip_pass_p (pass))
     {
-      skip_pass (pass);
+      pass->skip (cfun);
       return true;
     }
 
diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h
index 85bfba7..c32e126 100644
--- a/gcc/tree-pass.h
+++ b/gcc/tree-pass.h
@@ -95,6 +95,14 @@ public:
      TODO_flags_finish.   */
   virtual unsigned int execute (function *fun);
 
+  /* A hook for use by the __GIMPLE and __RTL "frontends" when starting
+     at a specific pass.  This hook is called for all of the skipped passes
+     before the start pass, in order to give them a chance to update any
+     internal state that isn't captured in the __GIMPLE or __RTL dumps.
+     Any usage of this function is considered a wart, since any such state
+     really ought to be captured in the dump.  */
+  virtual void skip (function *fun);
+
 protected:
   opt_pass (const pass_data&, gcc::context *);
 
-- 
1.8.5.3

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 9c] callgraph: handle __RTL functions
  2017-01-17  9:21     ` Richard Biener
  2017-01-17 12:36       ` Jan Hubicka
@ 2017-01-18  0:35       ` Jeff Law
  1 sibling, 0 replies; 44+ messages in thread
From: Jeff Law @ 2017-01-18  0:35 UTC (permalink / raw)
  To: Richard Biener, Jan Hubicka; +Cc: David Malcolm, GCC Patches

On 01/17/2017 02:21 AM, Richard Biener wrote:
>>
>> So I guess my question is how do you ensure that even though cgraph hasn't
>> looked at code that we're appropriately conservative with how the file is
>> processed?  Particularly if there's other code in the source file that is
>> expected to interact with the RTL native code?
>
> I think that as we're finalizing the function from the FE before the
> cgraph is built
> (and even throw away the RTL?) we have no other choice than treating a __RTL
> function as black box which means treat it as possibly calling all function in
> the TU and reading/writing/taking the address of all decls in the TU.  Consider
>
> static int i;
> static void foo () {}
> int __RTL main()
> {
>   ... call foo, access i ...
> }
>
> which probably will right now optimize i and foo away and thus fail to link?
That's what I think will currently happen.  I don't know the IPA bits 
very well, so I could have missed something.


>
> But I think we can sort out these "details" when we run into them...
I can live with that -- I strongly suspect we're going to find all kinds 
of things of a similar nature the more we poke at this stuff.

With that in mind, I'll go ahead and ack 9c for the trunk with the 
explicit understanding that we know there's stuff that's going to break 
the harder we push it and we'll incrementally work to improve it.

It certainly helps that I see this as strictly for developers, not 
users.  So I'm willing to be more lax on a lot of stuff.

jeff

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 9c] callgraph: handle __RTL functions
  2017-01-17 17:25         ` David Malcolm
@ 2017-01-18 12:51           ` Jan Hubicka
  0 siblings, 0 replies; 44+ messages in thread
From: Jan Hubicka @ 2017-01-18 12:51 UTC (permalink / raw)
  To: David Malcolm; +Cc: Jan Hubicka, Richard Biener, Jeff Law, GCC Patches

> 
> They're added to the cgraph by this call:
> 
>   /* Add to cgraph.  */
>   cgraph_node::finalize_function (fndecl, false);
> 
> within function_reader::create_function (in r244110, though that code
> isn't called yet; it's called by the stuff in patch 9).
> 
> If I hack out that call, so that __RTL functions aren't in the cgraph,
> then I see lots of failures in the kit, for example here in predict.c:
> 
> maybe_hot_frequency_p (struct function *fun, int freq)
> {
>   struct cgraph_node *node = cgraph_node::get (fun->decl);
> 
>   [...read though node, so it must be non-NULL]
> 
> Similarly, this line in varasm.c's assemble_start_function assumes that
> the fndecl has a symtab node:
> 
>   align = symtab_node::get (decl)->definition_alignment ();
> 
> etc.
> 
> I don't know how many other places make the assumption that cfun's
> fndecl has a node in the callgraph.
> 
> Given that I want to have __RTL functions called by non-__RTL functions
> (and the patch kit handles this), it seemed saner to go down the route
> of adding the decl to the callgraph.

You need to have symbol in the symbol table, but you don't necessarily need to
finalize it.  You can do cgraph_node::get_cteate instead of finalize_function.
finalize_function is meant as an api for frontend saying "I am done working on
this definition and I want to pass it to middle-end", while the RTL front-end
at the moment does everything by itself (I must say I am bit worried about
consequences of this because it gets us back from unit-at-a-time to
sort-of-unit-at-a-time which used to be quite some pain, but we can work them
out incrementally).

RTL backend may at some point assert that callgraph node of function being
compiled is an analyzed definition.

I guess the patchset is fine as it is and I will clean it up next stage1.
It definitly adds less clutter than chkp.
Honza

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 9e] Update "startwith" logic for pass-skipping to handle __RTL functions
  2017-01-17  9:28     ` Richard Biener
  2017-01-17 21:10       ` [PATCH] Introduce opt_pass::skip virtual function David Malcolm
@ 2017-01-18 16:39       ` Jeff Law
  2017-01-18 17:19         ` David Malcolm
  2017-01-19  9:31         ` Richard Biener
  1 sibling, 2 replies; 44+ messages in thread
From: Jeff Law @ 2017-01-18 16:39 UTC (permalink / raw)
  To: Richard Biener; +Cc: David Malcolm, GCC Patches

On 01/17/2017 02:28 AM, Richard Biener wrote:
>>
>> This feels somewhat different, but still a hack.
>>
>> I don't have strong suggestions on how to approach this, but what we've got
>> here feels like a hack and one prone to bitrot.
>
> All the above needs a bit of cleanup in the way we use (or not use) PROP_xxx.
> For example right now you can't startwith a __GIMPLE with a pass inside the
> loop pipeline because those passes expect loops to be initialized and be in
> loop-closed SSA.  And with the hack above for the property providers you'll
> always run pass_crited (that's a bad user of a PROP_).
>
> Ideally we'd figure out required properties from the startwith pass
> (but there's not
> an easy way to compute it w/o actually "executing" the passes) and then enable
> enough passes on the way to it providing those properties.
>
> Or finally restructure things in a way that the pass manager automatically runs
> property provider passes before passes requiring properties that are
> not yet available...
>
> Instead of those pass->name comparisions we could invent a new flag in the
> pass structure whether a pass should always be run for __GIMPLE or ___RTL
> but that's a bit noisy right now.
>
> So I'm fine with the (localized) "hacks" for the moment.
David suggested that we could have a method in the pass manager that 
would be run if the pass is skipped.  "run_if_skipped" or some such.

What I like about that idea is the hack and the real code end up in the 
same place.  So someone working on (for example) reload has a much 
better chance of catching that they need to update the run_if_skipped 
method as they make changes to reload.  It doesn't fix all the problems 
in this space, but I think it's cleaner than bundling the hacks into the 
pass manager itself.

Would that work for you?  It does for me.

jeff

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 9e] Update "startwith" logic for pass-skipping to handle __RTL functions
  2017-01-18 16:39       ` [PATCH 9e] Update "startwith" logic for pass-skipping to handle __RTL functions Jeff Law
@ 2017-01-18 17:19         ` David Malcolm
  2017-01-19  9:31         ` Richard Biener
  1 sibling, 0 replies; 44+ messages in thread
From: David Malcolm @ 2017-01-18 17:19 UTC (permalink / raw)
  To: Jeff Law, Richard Biener; +Cc: GCC Patches

On Wed, 2017-01-18 at 09:36 -0700, Jeff Law wrote:
> On 01/17/2017 02:28 AM, Richard Biener wrote:
> > > 
> > > This feels somewhat different, but still a hack.
> > > 
> > > I don't have strong suggestions on how to approach this, but what
> > > we've got
> > > here feels like a hack and one prone to bitrot.
> > 
> > All the above needs a bit of cleanup in the way we use (or not use)
> > PROP_xxx.
> > For example right now you can't startwith a __GIMPLE with a pass
> > inside the
> > loop pipeline because those passes expect loops to be initialized
> > and be in
> > loop-closed SSA.  And with the hack above for the property
> > providers you'll
> > always run pass_crited (that's a bad user of a PROP_).
> > 
> > Ideally we'd figure out required properties from the startwith pass
> > (but there's not
> > an easy way to compute it w/o actually "executing" the passes) and
> > then enable
> > enough passes on the way to it providing those properties.
> > 
> > Or finally restructure things in a way that the pass manager
> > automatically runs
> > property provider passes before passes requiring properties that
> > are
> > not yet available...
> > 
> > Instead of those pass->name comparisions we could invent a new flag
> > in the
> > pass structure whether a pass should always be run for __GIMPLE or
> > ___RTL
> > but that's a bit noisy right now.
> > 
> > So I'm fine with the (localized) "hacks" for the moment.
> David suggested that we could have a method in the pass manager that 
> would be run if the pass is skipped.  "run_if_skipped" or some such.
> 
> What I like about that idea is the hack and the real code end up in
> the 
> same place.  So someone working on (for example) reload has a much 
> better chance of catching that they need to update the run_if_skipped
> method as they make changes to reload.  It doesn't fix all the
> problems 
> in this space, but I think it's cleaner than bundling the hacks into
> the 
> pass manager itself.
> 
> Would that work for you?  It does for me.
> 
> jeff

FWIW I posted an implementation of the idea here:
  https://gcc.gnu.org/ml/gcc-patches/2017-01/msg01268.html

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 9e] Update "startwith" logic for pass-skipping to handle __RTL functions
  2017-01-18 16:39       ` [PATCH 9e] Update "startwith" logic for pass-skipping to handle __RTL functions Jeff Law
  2017-01-18 17:19         ` David Malcolm
@ 2017-01-19  9:31         ` Richard Biener
  2017-01-19 16:52           ` [PATCH, v2] (9e) " David Malcolm
  2017-01-20 20:37           ` [PATCH 9e] " Jeff Law
  1 sibling, 2 replies; 44+ messages in thread
From: Richard Biener @ 2017-01-19  9:31 UTC (permalink / raw)
  To: Jeff Law; +Cc: David Malcolm, GCC Patches

On Wed, Jan 18, 2017 at 5:36 PM, Jeff Law <law@redhat.com> wrote:
> On 01/17/2017 02:28 AM, Richard Biener wrote:
>>>
>>>
>>> This feels somewhat different, but still a hack.
>>>
>>> I don't have strong suggestions on how to approach this, but what we've
>>> got
>>> here feels like a hack and one prone to bitrot.
>>
>>
>> All the above needs a bit of cleanup in the way we use (or not use)
>> PROP_xxx.
>> For example right now you can't startwith a __GIMPLE with a pass inside
>> the
>> loop pipeline because those passes expect loops to be initialized and be
>> in
>> loop-closed SSA.  And with the hack above for the property providers
>> you'll
>> always run pass_crited (that's a bad user of a PROP_).
>>
>> Ideally we'd figure out required properties from the startwith pass
>> (but there's not
>> an easy way to compute it w/o actually "executing" the passes) and then
>> enable
>> enough passes on the way to it providing those properties.
>>
>> Or finally restructure things in a way that the pass manager automatically
>> runs
>> property provider passes before passes requiring properties that are
>> not yet available...
>>
>> Instead of those pass->name comparisions we could invent a new flag in the
>> pass structure whether a pass should always be run for __GIMPLE or ___RTL
>> but that's a bit noisy right now.
>>
>> So I'm fine with the (localized) "hacks" for the moment.
>
> David suggested that we could have a method in the pass manager that would
> be run if the pass is skipped.  "run_if_skipped" or some such.
>
> What I like about that idea is the hack and the real code end up in the same
> place.  So someone working on (for example) reload has a much better chance
> of catching that they need to update the run_if_skipped method as they make
> changes to reload.  It doesn't fix all the problems in this space, but I
> think it's cleaner than bundling the hacks into the pass manager itself.
>
> Would that work for you?  It does for me.

I think that walks in the wrong direction and just distributes the
hack over multiple
files.

I'd rather have it in one place.

Richard.

> jeff
>

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [PATCH, v2] (9e) Update "startwith" logic for pass-skipping to handle __RTL functions
  2017-01-19  9:31         ` Richard Biener
@ 2017-01-19 16:52           ` David Malcolm
  2017-01-20  8:07             ` Richard Biener
  2017-01-23 23:59             ` [PATCH, v2] (9e) Update "startwith" logic for pass-skipping to handle __RTL functions Jeff Law
  2017-01-20 20:37           ` [PATCH 9e] " Jeff Law
  1 sibling, 2 replies; 44+ messages in thread
From: David Malcolm @ 2017-01-19 16:52 UTC (permalink / raw)
  To: Jeff Law, gcc-patches, Richard Biener; +Cc: David Malcolm

On Mon, 2017-01-16 at 14:42 -0700, Jeff Law wrote:
> On 01/09/2017 07:38 PM, David Malcolm wrote:
> > gcc/ChangeLog:
> > 	* passes.c: Include "insn-addr.h".
> > 	(should_skip_pass_p): Add logging.  Update logic for running
> > 	"expand" to be compatible with both __GIMPLE and __RTL.  Guard
> > 	property-provider override so it is only done for gimple
> > passes.
> > 	Don't skip dfinit.
> > 	(skip_pass): New function.
> > 	(execute_one_pass): Call skip_pass when skipping passes.
> > ---
> >  gcc/passes.c | 65
> > +++++++++++++++++++++++++++++++++++++++++++++++++++++-------
> >  1 file changed, 58 insertions(+), 7 deletions(-)
> > 
> > diff --git a/gcc/passes.c b/gcc/passes.c
> > index 31262ed..6954d1e 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.  */
> insn-addr?  Yuk.
> 
> 
> > 
> >  using namespace gcc;
> > 
> > @@ -2315,26 +2316,73 @@ should_skip_pass_p (opt_pass *pass)
> >    if (!cfun->pass_startwith)
> >      return false;
> > 
> > -  /* We can't skip the lowering phase yet -- ideally we'd
> > -     drive that phase fully via properties.  */
> > -  if (!(cfun->curr_properties & PROP_ssa))
> > -    return false;
> > + /* For __GIMPLE functions, we have to at least start when we
> > leave
> > +     SSA.  */
> > +  if (pass->properties_destroyed & PROP_ssa)
> > +    {
> > +      if (!quiet_flag)
> > +	fprintf (stderr, "starting anyway when leaving SSA: %s\n",
> > pass->name);
> > +      cfun->pass_startwith = NULL;
> > +      return false;
> > +    }
> This seems to need a comment -- it's not obvious how destroying the
> SSA
> property maps to a pass that can not be skipped.

Added:

  /* For __GIMPLE functions, we have to at least start when we leave
     SSA.  Hence, we need to detect the "expand" pass, and stop skipping
     when we encounter it.  A cheap way to identify "expand" is it to
     detect the destruction of PROP_ssa.
     For __RTL functions, we invoke "rest_of_compilation" directly, which
     is after "expand", and hence we don't reach this conditional.  */

> > -  /* And also run any property provider.  */
> > -  if (pass->properties_provided != 0)
> > +  /* Run any property provider.  */
> > +  if (pass->type == GIMPLE_PASS
> > +      && pass->properties_provided != 0)
> >      return false;
> So comment needed here too.  I read this as "if a gimple pass
> provides a
> property then it should not be skipped.  Which means that an RTL pass
> that provides a property can?

Added:

  /* For GIMPLE passes, run any property provider (but continue skipping
     afterwards).
     We don't want to force running RTL passes that are property providers:
     "expand" is covered above, and the only pass other than "expand" that
     provides a property is "into_cfglayout" (PROP_cfglayout), which does
     too much for a dumped __RTL function.  */

...the problem being that into_cfglayout's execute vfunc calls
cfg_layout_initialize, which does a lot more that just
cfg_layout_rtl_register_cfg_hooks (the skip hack does just the latter).

> > +  /* Don't skip df init; later RTL passes need it.  */
> > +  if (strstr (pass->name, "dfinit") != NULL)
> > +    return false;
> Which seems like a failing in RTL passes saying they need DF init.

There isn't a "PROP_df"; should there be?
Or is this hack accepable?

> > +/* 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)
> ...
> This all feels like a failing in how we handle state in the RTL
> world.
> And I suspect it's prone to error.  Imagine if I'm hacking on
> something
> in the RTL world and my code depends on something else being set up. 
>   I
> really ought to have a way within my pass to indicate what I depend
> on.
> Having it hidden away in passes.c makes it easy to miss/forget.

Indeed, it's a hack.  I preferred the vfunc idea, but Richi prefers
to keep it all in one place.

> > +{
> > +  /* 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;
> Seems like this ought to be a property provided by LRA/reload.

If we have a __RTL function with a "startwith" of a pass after reload,
we don't want to run "reload" when iterating through the pass list to
reach the start pass, since presumably it could change the insns.  So
if LRA/reload provide a property, say PROP_reload_completed, we'd still
need a way to *not* run reload, whilst setting the reload_completed
global.  So I don't think that a property necessarily buys us much
here (it'd still be a hack either way...).

Or is your observation more about having a way to identify the pass
without doing a strcmp?

> > +
> > +  /* 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 ());
> Similarly ought to be provided by shorten-branches

Similar to the reload_completed discussion above.


> > +
> > +  /* 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;
> > +    }
> > +}
> This feels somewhat different, but still a hack.
> 
> I don't have strong suggestions on how to approach this, but what
> we've
> got here feels like a hack and one prone to bitrot.

Given that Richi seems to prefer the "contain it all in once place"
to the virtual function idea, there's not much more I can offer to fix it.

Updated version of the patch attached (just adding the missing comments)

Is this version OK?

Changed in v2:
- added some comments to should_skip_pass_p

gcc/ChangeLog:
	* passes.c: Include "insn-addr.h".
	(should_skip_pass_p): Add logging.  Update logic for running
	"expand" to be compatible with both __GIMPLE and __RTL.  Guard
	property-provider override so it is only done for gimple passes.
	Don't skip dfinit.
	(skip_pass): New function.
	(execute_one_pass): Call skip_pass when skipping passes.
---
 gcc/passes.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 67 insertions(+), 7 deletions(-)

diff --git a/gcc/passes.c b/gcc/passes.c
index 31262ed..9886693 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;
 
@@ -2315,26 +2316,82 @@ should_skip_pass_p (opt_pass *pass)
   if (!cfun->pass_startwith)
     return false;
 
-  /* We can't skip the lowering phase yet -- ideally we'd
-     drive that phase fully via properties.  */
-  if (!(cfun->curr_properties & PROP_ssa))
-    return false;
+  /* For __GIMPLE functions, we have to at least start when we leave
+     SSA.  Hence, we need to detect the "expand" pass, and stop skipping
+     when we encounter it.  A cheap way to identify "expand" is it to
+     detect the destruction of PROP_ssa.
+     For __RTL functions, we invoke "rest_of_compilation" directly, which
+     is after "expand", and hence we don't reach this conditional.  */
+  if (pass->properties_destroyed & PROP_ssa)
+    {
+      if (!quiet_flag)
+	fprintf (stderr, "starting anyway when leaving SSA: %s\n", pass->name);
+      cfun->pass_startwith = NULL;
+      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;
     }
 
-  /* And also run any property provider.  */
-  if (pass->properties_provided != 0)
+  /* For GIMPLE passes, run any property provider (but continue skipping
+     afterwards).
+     We don't want to force running RTL passes that are property providers:
+     "expand" is covered above, and the only pass other than "expand" that
+     provides a property is "into_cfglayout" (PROP_cfglayout), which does
+     too much for a dumped __RTL function.  */
+  if (pass->type == GIMPLE_PASS
+      && pass->properties_provided != 0)
     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);
+
   /* If we get here, then we have a "startwith" that we haven't seen yet;
      skip the pass.  */
   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. */
 
 bool
@@ -2375,7 +2432,10 @@ execute_one_pass (opt_pass *pass)
     }
 
   if (should_skip_pass_p (pass))
-    return true;
+    {
+      skip_pass (pass);
+      return true;
+    }
 
   /* Pass execution event trigger: useful to identify passes being
      executed.  */
-- 
1.8.5.3

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH, v2] (9e) Update "startwith" logic for pass-skipping to handle __RTL functions
  2017-01-19 16:52           ` [PATCH, v2] (9e) " David Malcolm
@ 2017-01-20  8:07             ` Richard Biener
  2017-01-20 14:57               ` David Malcolm
  2017-01-23 23:59             ` [PATCH, v2] (9e) Update "startwith" logic for pass-skipping to handle __RTL functions Jeff Law
  1 sibling, 1 reply; 44+ messages in thread
From: Richard Biener @ 2017-01-20  8:07 UTC (permalink / raw)
  To: David Malcolm; +Cc: Jeff Law, GCC Patches

On Thu, Jan 19, 2017 at 6:22 PM, David Malcolm <dmalcolm@redhat.com> wrote:
> On Mon, 2017-01-16 at 14:42 -0700, Jeff Law wrote:
>> On 01/09/2017 07:38 PM, David Malcolm wrote:
>> > gcc/ChangeLog:
>> >     * passes.c: Include "insn-addr.h".
>> >     (should_skip_pass_p): Add logging.  Update logic for running
>> >     "expand" to be compatible with both __GIMPLE and __RTL.  Guard
>> >     property-provider override so it is only done for gimple
>> > passes.
>> >     Don't skip dfinit.
>> >     (skip_pass): New function.
>> >     (execute_one_pass): Call skip_pass when skipping passes.
>> > ---
>> >  gcc/passes.c | 65
>> > +++++++++++++++++++++++++++++++++++++++++++++++++++++-------
>> >  1 file changed, 58 insertions(+), 7 deletions(-)
>> >
>> > diff --git a/gcc/passes.c b/gcc/passes.c
>> > index 31262ed..6954d1e 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.  */
>> insn-addr?  Yuk.
>>
>>
>> >
>> >  using namespace gcc;
>> >
>> > @@ -2315,26 +2316,73 @@ should_skip_pass_p (opt_pass *pass)
>> >    if (!cfun->pass_startwith)
>> >      return false;
>> >
>> > -  /* We can't skip the lowering phase yet -- ideally we'd
>> > -     drive that phase fully via properties.  */
>> > -  if (!(cfun->curr_properties & PROP_ssa))
>> > -    return false;
>> > + /* For __GIMPLE functions, we have to at least start when we
>> > leave
>> > +     SSA.  */
>> > +  if (pass->properties_destroyed & PROP_ssa)
>> > +    {
>> > +      if (!quiet_flag)
>> > +   fprintf (stderr, "starting anyway when leaving SSA: %s\n",
>> > pass->name);
>> > +      cfun->pass_startwith = NULL;
>> > +      return false;
>> > +    }
>> This seems to need a comment -- it's not obvious how destroying the
>> SSA
>> property maps to a pass that can not be skipped.
>
> Added:
>
>   /* For __GIMPLE functions, we have to at least start when we leave
>      SSA.  Hence, we need to detect the "expand" pass, and stop skipping
>      when we encounter it.  A cheap way to identify "expand" is it to
>      detect the destruction of PROP_ssa.
>      For __RTL functions, we invoke "rest_of_compilation" directly, which
>      is after "expand", and hence we don't reach this conditional.  */
>
>> > -  /* And also run any property provider.  */
>> > -  if (pass->properties_provided != 0)
>> > +  /* Run any property provider.  */
>> > +  if (pass->type == GIMPLE_PASS
>> > +      && pass->properties_provided != 0)
>> >      return false;
>> So comment needed here too.  I read this as "if a gimple pass
>> provides a
>> property then it should not be skipped.  Which means that an RTL pass
>> that provides a property can?
>
> Added:
>
>   /* For GIMPLE passes, run any property provider (but continue skipping
>      afterwards).
>      We don't want to force running RTL passes that are property providers:
>      "expand" is covered above, and the only pass other than "expand" that
>      provides a property is "into_cfglayout" (PROP_cfglayout), which does
>      too much for a dumped __RTL function.  */
>
> ...the problem being that into_cfglayout's execute vfunc calls
> cfg_layout_initialize, which does a lot more that just
> cfg_layout_rtl_register_cfg_hooks (the skip hack does just the latter).
>
>> > +  /* Don't skip df init; later RTL passes need it.  */
>> > +  if (strstr (pass->name, "dfinit") != NULL)
>> > +    return false;
>> Which seems like a failing in RTL passes saying they need DF init.
>
> There isn't a "PROP_df"; should there be?
> Or is this hack accepable?
>
>> > +/* 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)
>> ...
>> This all feels like a failing in how we handle state in the RTL
>> world.
>> And I suspect it's prone to error.  Imagine if I'm hacking on
>> something
>> in the RTL world and my code depends on something else being set up.
>>   I
>> really ought to have a way within my pass to indicate what I depend
>> on.
>> Having it hidden away in passes.c makes it easy to miss/forget.
>
> Indeed, it's a hack.  I preferred the vfunc idea, but Richi prefers
> to keep it all in one place.
>
>> > +{
>> > +  /* 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;
>> Seems like this ought to be a property provided by LRA/reload.
>
> If we have a __RTL function with a "startwith" of a pass after reload,
> we don't want to run "reload" when iterating through the pass list to
> reach the start pass, since presumably it could change the insns.  So
> if LRA/reload provide a property, say PROP_reload_completed, we'd still
> need a way to *not* run reload, whilst setting the reload_completed
> global.  So I don't think that a property necessarily buys us much
> here (it'd still be a hack either way...).
>
> Or is your observation more about having a way to identify the pass
> without doing a strcmp?
>
>> > +
>> > +  /* 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 ());
>> Similarly ought to be provided by shorten-branches
>
> Similar to the reload_completed discussion above.
>
>
>> > +
>> > +  /* 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;
>> > +    }
>> > +}
>> This feels somewhat different, but still a hack.
>>
>> I don't have strong suggestions on how to approach this, but what
>> we've
>> got here feels like a hack and one prone to bitrot.
>
> Given that Richi seems to prefer the "contain it all in once place"
> to the virtual function idea, there's not much more I can offer to fix it.
>
> Updated version of the patch attached (just adding the missing comments)
>
> Is this version OK?

Ok.

Richard.

> Changed in v2:
> - added some comments to should_skip_pass_p
>
> gcc/ChangeLog:
>         * passes.c: Include "insn-addr.h".
>         (should_skip_pass_p): Add logging.  Update logic for running
>         "expand" to be compatible with both __GIMPLE and __RTL.  Guard
>         property-provider override so it is only done for gimple passes.
>         Don't skip dfinit.
>         (skip_pass): New function.
>         (execute_one_pass): Call skip_pass when skipping passes.
> ---
>  gcc/passes.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++------
>  1 file changed, 67 insertions(+), 7 deletions(-)
>
> diff --git a/gcc/passes.c b/gcc/passes.c
> index 31262ed..9886693 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;
>
> @@ -2315,26 +2316,82 @@ should_skip_pass_p (opt_pass *pass)
>    if (!cfun->pass_startwith)
>      return false;
>
> -  /* We can't skip the lowering phase yet -- ideally we'd
> -     drive that phase fully via properties.  */
> -  if (!(cfun->curr_properties & PROP_ssa))
> -    return false;
> +  /* For __GIMPLE functions, we have to at least start when we leave
> +     SSA.  Hence, we need to detect the "expand" pass, and stop skipping
> +     when we encounter it.  A cheap way to identify "expand" is it to
> +     detect the destruction of PROP_ssa.
> +     For __RTL functions, we invoke "rest_of_compilation" directly, which
> +     is after "expand", and hence we don't reach this conditional.  */
> +  if (pass->properties_destroyed & PROP_ssa)
> +    {
> +      if (!quiet_flag)
> +       fprintf (stderr, "starting anyway when leaving SSA: %s\n", pass->name);
> +      cfun->pass_startwith = NULL;
> +      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;
>      }
>
> -  /* And also run any property provider.  */
> -  if (pass->properties_provided != 0)
> +  /* For GIMPLE passes, run any property provider (but continue skipping
> +     afterwards).
> +     We don't want to force running RTL passes that are property providers:
> +     "expand" is covered above, and the only pass other than "expand" that
> +     provides a property is "into_cfglayout" (PROP_cfglayout), which does
> +     too much for a dumped __RTL function.  */
> +  if (pass->type == GIMPLE_PASS
> +      && pass->properties_provided != 0)
>      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);
> +
>    /* If we get here, then we have a "startwith" that we haven't seen yet;
>       skip the pass.  */
>    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. */
>
>  bool
> @@ -2375,7 +2432,10 @@ execute_one_pass (opt_pass *pass)
>      }
>
>    if (should_skip_pass_p (pass))
> -    return true;
> +    {
> +      skip_pass (pass);
> +      return true;
> +    }
>
>    /* Pass execution event trigger: useful to identify passes being
>       executed.  */
> --
> 1.8.5.3
>

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH, v2] (9e) Update "startwith" logic for pass-skipping to handle __RTL functions
  2017-01-20  8:07             ` Richard Biener
@ 2017-01-20 14:57               ` David Malcolm
  2017-01-20 15:20                 ` Richard Biener
  0 siblings, 1 reply; 44+ messages in thread
From: David Malcolm @ 2017-01-20 14:57 UTC (permalink / raw)
  To: Richard Biener; +Cc: Jeff Law, GCC Patches

On Fri, 2017-01-20 at 09:06 +0100, Richard Biener wrote:
> On Thu, Jan 19, 2017 at 6:22 PM, David Malcolm <dmalcolm@redhat.com>
> wrote:
> > On Mon, 2017-01-16 at 14:42 -0700, Jeff Law wrote:
> > > On 01/09/2017 07:38 PM, David Malcolm wrote:
> > > > gcc/ChangeLog:
> > > >     * passes.c: Include "insn-addr.h".
> > > >     (should_skip_pass_p): Add logging.  Update logic for
> > > > running
> > > >     "expand" to be compatible with both __GIMPLE and __RTL. 
> > > >  Guard
> > > >     property-provider override so it is only done for gimple
> > > > passes.
> > > >     Don't skip dfinit.
> > > >     (skip_pass): New function.
> > > >     (execute_one_pass): Call skip_pass when skipping passes.
> > > > ---
> > > >  gcc/passes.c | 65
> > > > +++++++++++++++++++++++++++++++++++++++++++++++++++++-------
> > > >  1 file changed, 58 insertions(+), 7 deletions(-)
> > > > 
> > > > diff --git a/gcc/passes.c b/gcc/passes.c
> > > > index 31262ed..6954d1e 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.  */
> > > insn-addr?  Yuk.
> > > 
> > > 
> > > > 
> > > >  using namespace gcc;
> > > > 
> > > > @@ -2315,26 +2316,73 @@ should_skip_pass_p (opt_pass *pass)
> > > >    if (!cfun->pass_startwith)
> > > >      return false;
> > > > 
> > > > -  /* We can't skip the lowering phase yet -- ideally we'd
> > > > -     drive that phase fully via properties.  */
> > > > -  if (!(cfun->curr_properties & PROP_ssa))
> > > > -    return false;
> > > > + /* For __GIMPLE functions, we have to at least start when we
> > > > leave
> > > > +     SSA.  */
> > > > +  if (pass->properties_destroyed & PROP_ssa)
> > > > +    {
> > > > +      if (!quiet_flag)
> > > > +   fprintf (stderr, "starting anyway when leaving SSA: %s\n",
> > > > pass->name);
> > > > +      cfun->pass_startwith = NULL;
> > > > +      return false;
> > > > +    }
> > > This seems to need a comment -- it's not obvious how destroying
> > > the
> > > SSA
> > > property maps to a pass that can not be skipped.
> > 
> > Added:
> > 
> >   /* For __GIMPLE functions, we have to at least start when we
> > leave
> >      SSA.  Hence, we need to detect the "expand" pass, and stop
> > skipping
> >      when we encounter it.  A cheap way to identify "expand" is it
> > to
> >      detect the destruction of PROP_ssa.
> >      For __RTL functions, we invoke "rest_of_compilation" directly,
> > which
> >      is after "expand", and hence we don't reach this conditional. 
> >  */
> > 
> > > > -  /* And also run any property provider.  */
> > > > -  if (pass->properties_provided != 0)
> > > > +  /* Run any property provider.  */
> > > > +  if (pass->type == GIMPLE_PASS
> > > > +      && pass->properties_provided != 0)
> > > >      return false;
> > > So comment needed here too.  I read this as "if a gimple pass
> > > provides a
> > > property then it should not be skipped.  Which means that an RTL
> > > pass
> > > that provides a property can?
> > 
> > Added:
> > 
> >   /* For GIMPLE passes, run any property provider (but continue
> > skipping
> >      afterwards).
> >      We don't want to force running RTL passes that are property
> > providers:
> >      "expand" is covered above, and the only pass other than
> > "expand" that
> >      provides a property is "into_cfglayout" (PROP_cfglayout),
> > which does
> >      too much for a dumped __RTL function.  */
> > 
> > ...the problem being that into_cfglayout's execute vfunc calls
> > cfg_layout_initialize, which does a lot more that just
> > cfg_layout_rtl_register_cfg_hooks (the skip hack does just the
> > latter).
> > 
> > > > +  /* Don't skip df init; later RTL passes need it.  */
> > > > +  if (strstr (pass->name, "dfinit") != NULL)
> > > > +    return false;
> > > Which seems like a failing in RTL passes saying they need DF
> > > init.
> > 
> > There isn't a "PROP_df"; should there be?
> > Or is this hack accepable?
> > 
> > > > +/* 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)
> > > ...
> > > This all feels like a failing in how we handle state in the RTL
> > > world.
> > > And I suspect it's prone to error.  Imagine if I'm hacking on
> > > something
> > > in the RTL world and my code depends on something else being set
> > > up.
> > >   I
> > > really ought to have a way within my pass to indicate what I
> > > depend
> > > on.
> > > Having it hidden away in passes.c makes it easy to miss/forget.
> > 
> > Indeed, it's a hack.  I preferred the vfunc idea, but Richi prefers
> > to keep it all in one place.
> > 
> > > > +{
> > > > +  /* 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;
> > > Seems like this ought to be a property provided by LRA/reload.
> > 
> > If we have a __RTL function with a "startwith" of a pass after
> > reload,
> > we don't want to run "reload" when iterating through the pass list
> > to
> > reach the start pass, since presumably it could change the insns. 
> >  So
> > if LRA/reload provide a property, say PROP_reload_completed, we'd
> > still
> > need a way to *not* run reload, whilst setting the reload_completed
> > global.  So I don't think that a property necessarily buys us much
> > here (it'd still be a hack either way...).
> > 
> > Or is your observation more about having a way to identify the pass
> > without doing a strcmp?
> > 
> > > > +
> > > > +  /* 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 ());
> > > Similarly ought to be provided by shorten-branches
> > 
> > Similar to the reload_completed discussion above.
> > 
> > 
> > > > +
> > > > +  /* 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;
> > > > +    }
> > > > +}
> > > This feels somewhat different, but still a hack.
> > > 
> > > I don't have strong suggestions on how to approach this, but what
> > > we've
> > > got here feels like a hack and one prone to bitrot.
> > 
> > Given that Richi seems to prefer the "contain it all in once place"
> > to the virtual function idea, there's not much more I can offer to
> > fix it.
> > 
> > Updated version of the patch attached (just adding the missing
> > comments)
> > 
> > Is this version OK?
> 
> Ok.
> 
> Richard.

[...snip...]

Thanks.

Current status of the RTL "frontend" is that patches 1-8 are in trunk,
so that we're building the code for reading RTL dumps, but patch 9 (the
code to wire that up to cc1 with "__RTL" so that it's actually usable
from DejaGnu) isn't.

I believe the only remaining part of patch 9 that hasn't been approved
yet is:

"[PATCH 9f] Add a way for the C frontend to compile __RTL-tagged
functions"
  https://gcc.gnu.org/ml/gcc-patches/2017-01/msg00590.html

Richi: if that patch is approved, are you OK with patch 9 in early
stage 4?

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH, v2] (9e) Update "startwith" logic for pass-skipping to handle __RTL functions
  2017-01-20 14:57               ` David Malcolm
@ 2017-01-20 15:20                 ` Richard Biener
  2017-01-24 17:55                   ` [committed][PATCH 9/9] Add "__RTL" to cc1 (v9) David Malcolm
  0 siblings, 1 reply; 44+ messages in thread
From: Richard Biener @ 2017-01-20 15:20 UTC (permalink / raw)
  To: David Malcolm; +Cc: Jeff Law, GCC Patches

On January 20, 2017 3:56:31 PM GMT+01:00, David Malcolm <dmalcolm@redhat.com> wrote:
>On Fri, 2017-01-20 at 09:06 +0100, Richard Biener wrote:
>> On Thu, Jan 19, 2017 at 6:22 PM, David Malcolm <dmalcolm@redhat.com>
>> wrote:
>> > On Mon, 2017-01-16 at 14:42 -0700, Jeff Law wrote:
>> > > On 01/09/2017 07:38 PM, David Malcolm wrote:
>> > > > gcc/ChangeLog:
>> > > >     * passes.c: Include "insn-addr.h".
>> > > >     (should_skip_pass_p): Add logging.  Update logic for
>> > > > running
>> > > >     "expand" to be compatible with both __GIMPLE and __RTL. 
>> > > >  Guard
>> > > >     property-provider override so it is only done for gimple
>> > > > passes.
>> > > >     Don't skip dfinit.
>> > > >     (skip_pass): New function.
>> > > >     (execute_one_pass): Call skip_pass when skipping passes.
>> > > > ---
>> > > >  gcc/passes.c | 65
>> > > > +++++++++++++++++++++++++++++++++++++++++++++++++++++-------
>> > > >  1 file changed, 58 insertions(+), 7 deletions(-)
>> > > > 
>> > > > diff --git a/gcc/passes.c b/gcc/passes.c
>> > > > index 31262ed..6954d1e 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.  */
>> > > insn-addr?  Yuk.
>> > > 
>> > > 
>> > > > 
>> > > >  using namespace gcc;
>> > > > 
>> > > > @@ -2315,26 +2316,73 @@ should_skip_pass_p (opt_pass *pass)
>> > > >    if (!cfun->pass_startwith)
>> > > >      return false;
>> > > > 
>> > > > -  /* We can't skip the lowering phase yet -- ideally we'd
>> > > > -     drive that phase fully via properties.  */
>> > > > -  if (!(cfun->curr_properties & PROP_ssa))
>> > > > -    return false;
>> > > > + /* For __GIMPLE functions, we have to at least start when we
>> > > > leave
>> > > > +     SSA.  */
>> > > > +  if (pass->properties_destroyed & PROP_ssa)
>> > > > +    {
>> > > > +      if (!quiet_flag)
>> > > > +   fprintf (stderr, "starting anyway when leaving SSA: %s\n",
>> > > > pass->name);
>> > > > +      cfun->pass_startwith = NULL;
>> > > > +      return false;
>> > > > +    }
>> > > This seems to need a comment -- it's not obvious how destroying
>> > > the
>> > > SSA
>> > > property maps to a pass that can not be skipped.
>> > 
>> > Added:
>> > 
>> >   /* For __GIMPLE functions, we have to at least start when we
>> > leave
>> >      SSA.  Hence, we need to detect the "expand" pass, and stop
>> > skipping
>> >      when we encounter it.  A cheap way to identify "expand" is it
>> > to
>> >      detect the destruction of PROP_ssa.
>> >      For __RTL functions, we invoke "rest_of_compilation" directly,
>> > which
>> >      is after "expand", and hence we don't reach this conditional. 
>> >  */
>> > 
>> > > > -  /* And also run any property provider.  */
>> > > > -  if (pass->properties_provided != 0)
>> > > > +  /* Run any property provider.  */
>> > > > +  if (pass->type == GIMPLE_PASS
>> > > > +      && pass->properties_provided != 0)
>> > > >      return false;
>> > > So comment needed here too.  I read this as "if a gimple pass
>> > > provides a
>> > > property then it should not be skipped.  Which means that an RTL
>> > > pass
>> > > that provides a property can?
>> > 
>> > Added:
>> > 
>> >   /* For GIMPLE passes, run any property provider (but continue
>> > skipping
>> >      afterwards).
>> >      We don't want to force running RTL passes that are property
>> > providers:
>> >      "expand" is covered above, and the only pass other than
>> > "expand" that
>> >      provides a property is "into_cfglayout" (PROP_cfglayout),
>> > which does
>> >      too much for a dumped __RTL function.  */
>> > 
>> > ...the problem being that into_cfglayout's execute vfunc calls
>> > cfg_layout_initialize, which does a lot more that just
>> > cfg_layout_rtl_register_cfg_hooks (the skip hack does just the
>> > latter).
>> > 
>> > > > +  /* Don't skip df init; later RTL passes need it.  */
>> > > > +  if (strstr (pass->name, "dfinit") != NULL)
>> > > > +    return false;
>> > > Which seems like a failing in RTL passes saying they need DF
>> > > init.
>> > 
>> > There isn't a "PROP_df"; should there be?
>> > Or is this hack accepable?
>> > 
>> > > > +/* 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)
>> > > ...
>> > > This all feels like a failing in how we handle state in the RTL
>> > > world.
>> > > And I suspect it's prone to error.  Imagine if I'm hacking on
>> > > something
>> > > in the RTL world and my code depends on something else being set
>> > > up.
>> > >   I
>> > > really ought to have a way within my pass to indicate what I
>> > > depend
>> > > on.
>> > > Having it hidden away in passes.c makes it easy to miss/forget.
>> > 
>> > Indeed, it's a hack.  I preferred the vfunc idea, but Richi prefers
>> > to keep it all in one place.
>> > 
>> > > > +{
>> > > > +  /* 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;
>> > > Seems like this ought to be a property provided by LRA/reload.
>> > 
>> > If we have a __RTL function with a "startwith" of a pass after
>> > reload,
>> > we don't want to run "reload" when iterating through the pass list
>> > to
>> > reach the start pass, since presumably it could change the insns. 
>> >  So
>> > if LRA/reload provide a property, say PROP_reload_completed, we'd
>> > still
>> > need a way to *not* run reload, whilst setting the reload_completed
>> > global.  So I don't think that a property necessarily buys us much
>> > here (it'd still be a hack either way...).
>> > 
>> > Or is your observation more about having a way to identify the pass
>> > without doing a strcmp?
>> > 
>> > > > +
>> > > > +  /* 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 ());
>> > > Similarly ought to be provided by shorten-branches
>> > 
>> > Similar to the reload_completed discussion above.
>> > 
>> > 
>> > > > +
>> > > > +  /* 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;
>> > > > +    }
>> > > > +}
>> > > This feels somewhat different, but still a hack.
>> > > 
>> > > I don't have strong suggestions on how to approach this, but what
>> > > we've
>> > > got here feels like a hack and one prone to bitrot.
>> > 
>> > Given that Richi seems to prefer the "contain it all in once place"
>> > to the virtual function idea, there's not much more I can offer to
>> > fix it.
>> > 
>> > Updated version of the patch attached (just adding the missing
>> > comments)
>> > 
>> > Is this version OK?
>> 
>> Ok.
>> 
>> Richard.
>
>[...snip...]
>
>Thanks.
>
>Current status of the RTL "frontend" is that patches 1-8 are in trunk,
>so that we're building the code for reading RTL dumps, but patch 9 (the
>code to wire that up to cc1 with "__RTL" so that it's actually usable
>from DejaGnu) isn't.
>
>I believe the only remaining part of patch 9 that hasn't been approved
>yet is:
>
>"[PATCH 9f] Add a way for the C frontend to compile __RTL-tagged
>functions"
>  https://gcc.gnu.org/ml/gcc-patches/2017-01/msg00590.html
>
>Richi: if that patch is approved, are you OK with patch 9 in early
>stage 4?

Yes.

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 9e] Update "startwith" logic for pass-skipping to handle __RTL functions
  2017-01-19  9:31         ` Richard Biener
  2017-01-19 16:52           ` [PATCH, v2] (9e) " David Malcolm
@ 2017-01-20 20:37           ` Jeff Law
  1 sibling, 0 replies; 44+ messages in thread
From: Jeff Law @ 2017-01-20 20:37 UTC (permalink / raw)
  To: Richard Biener; +Cc: David Malcolm, GCC Patches

On 01/19/2017 02:26 AM, Richard Biener wrote:
> On Wed, Jan 18, 2017 at 5:36 PM, Jeff Law <law@redhat.com> wrote:
>> On 01/17/2017 02:28 AM, Richard Biener wrote:
>>>>
>>>>
>>>> This feels somewhat different, but still a hack.
>>>>
>>>> I don't have strong suggestions on how to approach this, but what we've
>>>> got
>>>> here feels like a hack and one prone to bitrot.
>>>
>>>
>>> All the above needs a bit of cleanup in the way we use (or not use)
>>> PROP_xxx.
>>> For example right now you can't startwith a __GIMPLE with a pass inside
>>> the
>>> loop pipeline because those passes expect loops to be initialized and be
>>> in
>>> loop-closed SSA.  And with the hack above for the property providers
>>> you'll
>>> always run pass_crited (that's a bad user of a PROP_).
>>>
>>> Ideally we'd figure out required properties from the startwith pass
>>> (but there's not
>>> an easy way to compute it w/o actually "executing" the passes) and then
>>> enable
>>> enough passes on the way to it providing those properties.
>>>
>>> Or finally restructure things in a way that the pass manager automatically
>>> runs
>>> property provider passes before passes requiring properties that are
>>> not yet available...
>>>
>>> Instead of those pass->name comparisions we could invent a new flag in the
>>> pass structure whether a pass should always be run for __GIMPLE or ___RTL
>>> but that's a bit noisy right now.
>>>
>>> So I'm fine with the (localized) "hacks" for the moment.
>>
>> David suggested that we could have a method in the pass manager that would
>> be run if the pass is skipped.  "run_if_skipped" or some such.
>>
>> What I like about that idea is the hack and the real code end up in the same
>> place.  So someone working on (for example) reload has a much better chance
>> of catching that they need to update the run_if_skipped method as they make
>> changes to reload.  It doesn't fix all the problems in this space, but I
>> think it's cleaner than bundling the hacks into the pass manager itself.
>>
>> Would that work for you?  It does for me.
>
> I think that walks in the wrong direction and just distributes the
> hack over multiple
> files.
>
> I'd rather have it in one place.
We disagree, but I don't feel strongly enough about it to object. 
Though I'll probably chime in regularly as the list of hacks grows or 
gets out-of-date  :-)


Jeff

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH 9f] Add a way for the C frontend to compile __RTL-tagged functions
  2017-01-16 23:23     ` David Malcolm
@ 2017-01-22  9:05       ` Jeff Law
  0 siblings, 0 replies; 44+ messages in thread
From: Jeff Law @ 2017-01-22  9:05 UTC (permalink / raw)
  To: David Malcolm, gcc-patches

On 01/16/2017 04:23 PM, David Malcolm wrote:
> On Mon, 2017-01-16 at 14:54 -0700, Jeff Law wrote:
>> On 01/09/2017 07:38 PM, David Malcolm wrote:
>>> The backend is full of singleton state, so we have to compile
>>> __RTL-functions as soon as we parse them.  This means that the
>>> C frontend needs to invoke the backed.
>>>
>>> This patch adds the support needed.
>>>
>>> Normally this would be a no-no, and including rtl headers is
>>> blocked by this within system.h:
>>>
>>>  /* Front ends should never have to include middle-end headers.
>>>  Enforce
>>>     this by poisoning the header double-include protection defines.
>>>   */
>>>  #ifdef IN_GCC_FRONTEND
>>>  #pragma GCC poison GCC_RTL_H GCC_EXCEPT_H GCC_EXPR_H
>>>  #endif
>>>
>>> Hence the patch puts the decl into a new header (run-rtl-passes.h)
>>> that's accessible to the C frontend without exposing any RTL
>>> internals.  (If adding a header for just this decl is overkill, is
>>> there a better place to put the decl?)
>>>
>>> gcc/ChangeLog:
>>> 	* Makefile.in (OBJS): Add run-rtl-passes.o.
>>> 	* pass_manager.h (gcc::pass_manager::get_rest_of_compilation):
>>> New
>>> 	accessor.
>>> 	(gcc::pass_manager::get_clean_slate): New accessor.
>>> 	* run-rtl-passes.c: New file.
>>> 	* run-rtl-passes.h: New file.
>> It feels like this is dependent upon something that I haven't seen?!?
>
> I may have split things up a bit too much; sorry.  The code in this
> patch is called by patch 9a.
It happens.  It's the price we pay for asking for patches to be broken 
down into manageable hunks.   Joseph ack'd 9a and since it was just 
front-end stuff, I didn't take the time to look at it.

>
>>
>> Where is get_rest_of_compilation used?
>
> In this patch, in run-rtl-passes.c:run_rtl_passes, thusly:
Yea, I see it how.  Hidden by c++-ification :-)
>
> +  opt_pass *rest_of_compilation
> +    = g->get_passes ()->get_rest_of_compilation ();
> +  gcc_assert (rest_of_compilation);
> +  execute_pass_list (cfun, rest_of_compilation);
>
>
>>  Where is pass_clean_state_1?
>
> (as used in this part of the patch):
Nevermind.   We refer to pass_clean_state_1 and get_clean_slate.   I 
kept consistently using the wrong state/slate in my searches.  No wonder 
I was so confused.

Patch is OK.  THanks for your patience.

jeff


^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [PATCH, v2] (9e) Update "startwith" logic for pass-skipping to handle __RTL functions
  2017-01-19 16:52           ` [PATCH, v2] (9e) " David Malcolm
  2017-01-20  8:07             ` Richard Biener
@ 2017-01-23 23:59             ` Jeff Law
  1 sibling, 0 replies; 44+ messages in thread
From: Jeff Law @ 2017-01-23 23:59 UTC (permalink / raw)
  To: David Malcolm, gcc-patches, Richard Biener

On 01/19/2017 10:22 AM, David Malcolm wrote:
>
> ...the problem being that into_cfglayout's execute vfunc calls
> cfg_layout_initialize, which does a lot more that just
> cfg_layout_rtl_register_cfg_hooks (the skip hack does just the latter).
>
>>> +  /* Don't skip df init; later RTL passes need it.  */
>>> +  if (strstr (pass->name, "dfinit") != NULL)
>>> +    return false;
>> Which seems like a failing in RTL passes saying they need DF init.
>
> There isn't a "PROP_df"; should there be?
> Or is this hack accepable?
I think it's acceptable for now.  I think long term we're going to want 
some kind of DF properties.

>
>>> +{
>>> +  /* 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;
>> Seems like this ought to be a property provided by LRA/reload.
>
> If we have a __RTL function with a "startwith" of a pass after reload,
> we don't want to run "reload" when iterating through the pass list to
> reach the start pass, since presumably it could change the insns.  So
> if LRA/reload provide a property, say PROP_reload_completed, we'd still
> need a way to *not* run reload, whilst setting the reload_completed
> global.  So I don't think that a property necessarily buys us much
> here (it'd still be a hack either way...).
>
> Or is your observation more about having a way to identify the pass
> without doing a strcmp?
It's not really the strcmp, but the general hackishness of this stuff. 
I would also have preferred the virtual function for skipping a pass, 
but not enough to argue that much about it.

>
>>> +
>>> +  /* 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 ());
>> Similarly ought to be provided by shorten-branches
>
> Similar to the reload_completed discussion above.
Right.

>
>
>>> +
>>> +  /* 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;
>>> +    }
>>> +}
>> This feels somewhat different, but still a hack.
>>
>> I don't have strong suggestions on how to approach this, but what
>> we've
>> got here feels like a hack and one prone to bitrot.
>
> Given that Richi seems to prefer the "contain it all in once place"
> to the virtual function idea, there's not much more I can offer to fix it.
>
Agreed/

> Updated version of the patch attached (just adding the missing comments)
>
> Is this version OK?
>
> Changed in v2:
> - added some comments to should_skip_pass_p
>
> gcc/ChangeLog:
> 	* passes.c: Include "insn-addr.h".
> 	(should_skip_pass_p): Add logging.  Update logic for running
> 	"expand" to be compatible with both __GIMPLE and __RTL.  Guard
> 	property-provider override so it is only done for gimple passes.
> 	Don't skip dfinit.
> 	(skip_pass): New function.
> 	(execute_one_pass): Call skip_pass when skipping passes.
OK.  THanks for the updates.  It should make it easier for others to see 
what's going on in here.

jeff

^ permalink raw reply	[flat|nested] 44+ messages in thread

* [committed][PATCH 9/9] Add "__RTL" to cc1 (v9)
  2017-01-20 15:20                 ` Richard Biener
@ 2017-01-24 17:55                   ` David Malcolm
  2017-01-24 18:06                     ` Joseph Myers
  0 siblings, 1 reply; 44+ messages in thread
From: David Malcolm @ 2017-01-24 17:55 UTC (permalink / raw)
  To: Richard Biener; +Cc: Jeff Law, GCC Patches, David Malcolm

On Fri, 2017-01-20 at 16:16 +0100, Richard Biener wrote:
[...]

> > Richi: if that patch is approved, are you OK with patch 9 in early
> > stage 4?
> 
> Yes.

Thanks.

All of the various parts of patch 9 have now been approved.

I've rebased it, and merged the fixes identified in review.

Testing on i686-pc-linux-gnu identified some tests in
gcc.dg/rtl/x86_64 marked with:
  /* { dg-do run { target i?86-*-* x86_64-*-* } } */
that compile, but fail to run properly on i686.  It seems
unrealistic to expect RTL expanded for x86_64 to run successfully
on i686, so I changed those lines to:
  /* { dg-do run { x86_64-*-* } } */

Bootstrapped&regrtested on x86_64-pc-linux-gnu.
Verified build of stage1 and successfully tested rtl.exp on
powerpc-ibm-aix7.1.3.0 (gcc111) and on i686-pc-linux-gnu.

Committed to trunk (r244878).

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.
	* function.h (struct function): Update comment for field
	"pass_startwith".
	* gimple-expr.c: Include "tree-pass.h".
	(gimple_has_body_p): Return false for __RTL functions.
	* Makefile.in (OBJS): Add run-rtl-passes.o.
	* 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".
	(should_skip_pass_p): Add logging.  Update logic for running
	"expand" to be compatible with both __GIMPLE and __RTL.  Guard
	property-provider override so it is only done for gimple passes.
	Don't skip dfinit.
	(skip_pass): New function.
	(execute_one_pass): Call skip_pass when skipping passes.
	* 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::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 test case.
	* gcc.dg/rtl/aarch64/pr71779.c: New test case.
	* gcc.dg/rtl/rtl.exp: New file.
	* gcc.dg/rtl/test.c: New file.
	* gcc.dg/rtl/truncated-rtl-file.c: New test case.
	* gcc.dg/rtl/unknown-rtx-code.c: New test case.
	* gcc.dg/rtl/x86_64/dfinit.c: New test case.
	* gcc.dg/rtl/x86_64/different-structs.c: New test case.
	* gcc.dg/rtl/x86_64/final.c: New test case.
	* gcc.dg/rtl/x86_64/into-cfglayout.c: New test case.
	* gcc.dg/rtl/x86_64/ira.c: New test case.
	* gcc.dg/rtl/x86_64/pro_and_epilogue.c: New test case.
	* gcc.dg/rtl/x86_64/test-multiple-fns.c: New test case.
	* gcc.dg/rtl/x86_64/test-return-const.c.after-expand.c: New test case.
	* gcc.dg/rtl/x86_64/test-return-const.c.before-fwprop.c: New test case.
	* gcc.dg/rtl/x86_64/test-rtl.c: New test case.
	* gcc.dg/rtl/x86_64/test_1.h: New file.
	* gcc.dg/rtl/x86_64/times-two.c.after-expand.c: New test case.
	* gcc.dg/rtl/x86_64/times-two.c.before-df.c: New test case.
	* gcc.dg/rtl/x86_64/times-two.h: New file.
	* gcc.dg/rtl/x86_64/vregs.c: New test case.
---
 gcc/Makefile.in                                    |   1 +
 gcc/c-family/c-common.c                            |   1 +
 gcc/c-family/c-common.h                            |   3 +
 gcc/c/c-parser.c                                   | 109 ++++++++++++++++-
 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                                       |  74 ++++++++++--
 gcc/read-md.c                                      |  34 +++++-
 gcc/read-md.h                                      |   7 ++
 gcc/read-rtl-function.c                            |  81 ++++++++++---
 gcc/read-rtl-function.h                            |   3 +
 gcc/run-rtl-passes.c                               |  66 ++++++++++
 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/truncated-rtl-file.c      |   2 +
 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/times-two.h        |  22 ++++
 gcc/testsuite/gcc.dg/rtl/x86_64/vregs.c            | 112 +++++++++++++++++
 44 files changed, 1852 insertions(+), 43 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/truncated-rtl-file.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/times-two.h
 create mode 100644 gcc/testsuite/gcc.dg/rtl/x86_64/vregs.c

diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index df02246..821584a 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1433,6 +1433,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 15ead18..62b762b 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 06918db..9c28809 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 a3504d3..5c152ab 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -62,6 +62,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.
@@ -1311,6 +1313,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:
@@ -1547,7 +1551,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
@@ -2045,7 +2053,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
@@ -2077,12 +2085,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);
@@ -2113,7 +2137,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;
     }
 }
@@ -2605,7 +2628,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;
@@ -18296,4 +18325,74 @@ 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;
+	case CPP_EOF:
+	  error_at (start_loc, "no closing brace");
+	  free (start_with_pass);
+	  return;
+	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 ae01450..13e40e6 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 df11e50..7feb6d0 100644
--- a/gcc/c/gimple-parser.c
+++ b/gcc/c/gimple-parser.c
@@ -1118,18 +1118,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 fd36ce1..85cf13a 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 1bcf9b8..7a0e5bb 100644
--- a/gcc/cfg.c
+++ b/gcc/cfg.c
@@ -1095,6 +1095,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 d421d3b..b44f1e1 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 c7e355e..cafa38d 100644
--- a/gcc/cfgrtl.c
+++ b/gcc/cfgrtl.c
@@ -3651,7 +3651,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 5410a71..3889a3e 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -326,6 +326,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 81a3ae9..ed699e1 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 8a4c9f8..2483381 100644
--- a/gcc/final.c
+++ b/gcc/final.c
@@ -4699,7 +4699,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 fb8f57a..0f34bcd 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 b435b99..2ee87c2 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 4d15407..ae97cd4 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 ace68b8..587c3be 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;
 
@@ -2315,26 +2316,82 @@ should_skip_pass_p (opt_pass *pass)
   if (!cfun->pass_startwith)
     return false;
 
-  /* We can't skip the lowering phase yet -- ideally we'd
-     drive that phase fully via properties.  */
-  if (!(cfun->curr_properties & PROP_ssa))
-    return false;
+  /* For __GIMPLE functions, we have to at least start when we leave
+     SSA.  Hence, we need to detect the "expand" pass, and stop skipping
+     when we encounter it.  A cheap way to identify "expand" is it to
+     detect the destruction of PROP_ssa.
+     For __RTL functions, we invoke "rest_of_compilation" directly, which
+     is after "expand", and hence we don't reach this conditional.  */
+  if (pass->properties_destroyed & PROP_ssa)
+    {
+      if (!quiet_flag)
+	fprintf (stderr, "starting anyway when leaving SSA: %s\n", pass->name);
+      cfun->pass_startwith = NULL;
+      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;
     }
 
-  /* And also run any property provider.  */
-  if (pass->properties_provided != 0)
+  /* For GIMPLE passes, run any property provider (but continue skipping
+     afterwards).
+     We don't want to force running RTL passes that are property providers:
+     "expand" is covered above, and the only pass other than "expand" that
+     provides a property is "into_cfglayout" (PROP_cfglayout), which does
+     too much for a dumped __RTL function.  */
+  if (pass->type == GIMPLE_PASS
+      && pass->properties_provided != 0)
     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);
+
   /* If we get here, then we have a "startwith" that we haven't seen yet;
      skip the pass.  */
   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. */
 
 bool
@@ -2375,7 +2432,10 @@ execute_one_pass (opt_pass *pass)
     }
 
   if (should_skip_pass_p (pass))
-    return true;
+    {
+      skip_pass (pass);
+      return true;
+    }
 
   /* Pass execution event trigger: useful to identify passes being
      executed.  */
diff --git a/gcc/read-md.c b/gcc/read-md.c
index ac28944..4036afa 100644
--- a/gcc/read-md.c
+++ b/gcc/read-md.c
@@ -411,6 +411,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;
 }
 
@@ -991,7 +1001,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;
@@ -1314,6 +1326,26 @@ md_reader::read_file (const char *filename)
   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 4fcbcb4..fea7011 100644
--- a/gcc/read-md.h
+++ b/gcc/read-md.h
@@ -111,6 +111,9 @@ class md_reader
 
   bool read_md_files (int, const char **, bool (*) (const char *));
   bool read_file (const char *filename);
+  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
@@ -245,6 +248,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 9ef9610..bead858 100644
--- a/gcc/read-rtl-function.c
+++ b/gcc/read-rtl-function.c
@@ -475,22 +475,37 @@ function_reader::create_function ()
   /* We start in cfgrtl mode, rather than cfglayout mode.  */
   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 (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 (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);
 
@@ -1582,6 +1597,40 @@ read_rtl_function_body (const char *path)
   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;
+  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 45ada84..10ceab8 100644
--- a/gcc/read-rtl-function.h
+++ b/gcc/read-rtl-function.h
@@ -22,4 +22,7 @@ along with GCC; see the file COPYING3.  If not see
 
 extern bool read_rtl_function_body (const char *path);
 
+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..e1ac4bd
--- /dev/null
+++ b/gcc/run-rtl-passes.c
@@ -0,0 +1,66 @@
+/* run-rtl-passes.c - Run RTL passes directly from frontend
+   Copyright (C) 2016-2017 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 "rtl.h"
+#include "function.h"
+#include "basic-block.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 (&reg_obstack);
+
+  opt_pass *rest_of_compilation
+    = g->get_passes ()->get_rest_of_compilation ();
+  gcc_assert (rest_of_compilation);
+  execute_pass_list (cfun, rest_of_compilation);
+
+  opt_pass *clean_slate = g->get_passes ()->get_clean_slate ();
+  gcc_assert (clean_slate);
+  execute_pass_list (cfun, clean_slate);
+
+  bitmap_obstack_release (&reg_obstack);
+
+  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..1390303
--- /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-2017 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..a95c8c7
--- /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..9174abb
--- /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..70a6d8b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/rtl/rtl.exp
@@ -0,0 +1,41 @@
+#   Copyright (C) 2016-2017 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/truncated-rtl-file.c b/gcc/testsuite/gcc.dg/rtl/truncated-rtl-file.c
new file mode 100644
index 0000000..4dd8214
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/rtl/truncated-rtl-file.c
@@ -0,0 +1,2 @@
+void __RTL test (void)
+{ /* { dg-error "no closing brace" } */
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..75ab0bc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/rtl/x86_64/dfinit.c
@@ -0,0 +1,116 @@
+/* { dg-do run { target 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..90efaa7
--- /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..ff84c68
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/rtl/x86_64/final.c
@@ -0,0 +1,133 @@
+/* { dg-do compile { target 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..d0a82ff
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/rtl/x86_64/into-cfglayout.c
@@ -0,0 +1,117 @@
+/* { dg-do run { target 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..caf37b6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/rtl/x86_64/ira.c
@@ -0,0 +1,111 @@
+/* { dg-do run { target 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..dff4a1b
--- /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..6c1202d
--- /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..d83029e
--- /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..4496868
--- /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..b8d143e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/rtl/x86_64/times-two.c.after-expand.c
@@ -0,0 +1,70 @@
+/* { dg-do run { target 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..45f4961
--- /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/times-two.h b/gcc/testsuite/gcc.dg/rtl/x86_64/times-two.h
new file mode 100644
index 0000000..3b89cb9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/rtl/x86_64/times-two.h
@@ -0,0 +1,22 @@
+/* Shared test code for the various __RTL tests of times_two that
+   start at different passes.  */
+
+extern void abort (void);
+int times_two (int i);
+
+int main (void)
+{
+  if (times_two (0) != 0)
+    abort ();
+
+  if (times_two (1) != 2)
+    abort ();
+
+  if (times_two (100) != 200)
+    abort ();
+
+  if (times_two (-20) != -40)
+    abort ();
+
+  return 0;
+}
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..b97d606
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/rtl/x86_64/vregs.c
@@ -0,0 +1,112 @@
+/* { dg-do run { target 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

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [committed][PATCH 9/9] Add "__RTL" to cc1 (v9)
  2017-01-24 17:55                   ` [committed][PATCH 9/9] Add "__RTL" to cc1 (v9) David Malcolm
@ 2017-01-24 18:06                     ` Joseph Myers
  0 siblings, 0 replies; 44+ messages in thread
From: Joseph Myers @ 2017-01-24 18:06 UTC (permalink / raw)
  To: David Malcolm; +Cc: Richard Biener, Jeff Law, GCC Patches

On Tue, 24 Jan 2017, David Malcolm wrote:

>   /* { dg-do run { x86_64-*-* } } */

That's never correct, since x86_64-*-* can have -m32 multilibs and 
i?86-*-* can have 64-bit multilibs.  You always need to cover all relevant 
triplets and then restrict with effective-target selectors to relevant 
ABIs.

> +/* { dg-do compile { target aarch64-*-* } } */

Should be aarch64*-*-* to cover aarch64_be triplets (and then again 
restrict by ABI as necessary; any triplet might have both endiannesses as 
multilibs, and both LP64 and ILP32).

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 44+ messages in thread

end of thread, other threads:[~2017-01-24 17:55 UTC | newest]

Thread overview: 44+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-01-10  2:04 [PATCH 9/9] Add "__RTL" to cc1 (v8) David Malcolm
2017-01-10  2:04 ` [PATCH 9d] Don't call delete_tree_ssa for __RTL functions David Malcolm
2017-01-10 13:42   ` Richard Biener
2017-01-16 21:15     ` Jeff Law
2017-01-16 21:14   ` Jeff Law
2017-01-10  2:04 ` [PATCH 9h] testsuite: add platform-independent files David Malcolm
2017-01-16 21:56   ` Jeff Law
2017-01-10  2:04 ` [PATCH 9c] callgraph: handle __RTL functions David Malcolm
2017-01-16 21:25   ` Jeff Law
2017-01-17  9:21     ` Richard Biener
2017-01-17 12:36       ` Jan Hubicka
2017-01-17 17:25         ` David Malcolm
2017-01-18 12:51           ` Jan Hubicka
2017-01-18  0:35       ` Jeff Law
2017-01-10  2:04 ` [PATCH 9b] Don't assume that copy tables were initialized David Malcolm
2017-01-10 13:37   ` Richard Biener
2017-01-10  2:04 ` [PATCH 9g] Extend .md and RTL parsing to support being wired up to cc1 David Malcolm
2017-01-16 22:04   ` Jeff Law
2017-01-16 23:09     ` David Malcolm
2017-01-10  2:04 ` [PATCH 9i] testsuite: add aarch64-specific files David Malcolm
2017-01-16 22:00   ` Jeff Law
2017-01-10  2:04 ` [PATCH 9e] Update "startwith" logic for pass-skipping to handle __RTL functions David Malcolm
2017-01-16 21:42   ` Jeff Law
2017-01-17  9:28     ` Richard Biener
2017-01-17 21:10       ` [PATCH] Introduce opt_pass::skip virtual function David Malcolm
2017-01-18 16:39       ` [PATCH 9e] Update "startwith" logic for pass-skipping to handle __RTL functions Jeff Law
2017-01-18 17:19         ` David Malcolm
2017-01-19  9:31         ` Richard Biener
2017-01-19 16:52           ` [PATCH, v2] (9e) " David Malcolm
2017-01-20  8:07             ` Richard Biener
2017-01-20 14:57               ` David Malcolm
2017-01-20 15:20                 ` Richard Biener
2017-01-24 17:55                   ` [committed][PATCH 9/9] Add "__RTL" to cc1 (v9) David Malcolm
2017-01-24 18:06                     ` Joseph Myers
2017-01-23 23:59             ` [PATCH, v2] (9e) Update "startwith" logic for pass-skipping to handle __RTL functions Jeff Law
2017-01-20 20:37           ` [PATCH 9e] " Jeff Law
2017-01-10  2:04 ` [PATCH 9a] Add "__RTL" to C frontend David Malcolm
2017-01-10 22:57   ` Joseph Myers
2017-01-10  2:04 ` [PATCH 9f] Add a way for the C frontend to compile __RTL-tagged functions David Malcolm
2017-01-16 21:55   ` Jeff Law
2017-01-16 23:23     ` David Malcolm
2017-01-22  9:05       ` Jeff Law
2017-01-10  2:04 ` [PATCH 9j] testsuite: add x86_64-specific files David Malcolm
2017-01-16 21:59   ` Jeff Law

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