From c92a692bd0078418c7ef63b6c1ff6e65b83b3b88 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Wed, 11 May 2016 16:30:06 -0400
Subject: [PATCH 21/23] FIXME: enough to get C frontend to load and dump RTL

---
 gcc/c/c-parser.c        | 29 +++++-------------------
 gcc/read-md.c           | 34 +++++++++++++++++++++++++++-
 gcc/read-md.h           |  6 +++++
 gcc/read-rtl-function.c | 60 ++++++++++++++++++++++++++++++++++++++++---------
 gcc/read-rtl-function.h |  3 +++
 gcc/system.h            |  2 +-
 6 files changed, 99 insertions(+), 35 deletions(-)

diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index 3c7c481..19ab233 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -59,6 +59,9 @@ along with GCC; see the file COPYING3.  If not see
 #include "gimple-expr.h"
 #include "context.h"
 #include "read-rtl-function.h"
+#include "rtl.h"
+#include "emit-rtl.h"
+#include "cfgrtl.h"
 
 /* We need to walk over decls with incomplete struct/union/enum types
    after parsing the whole translation unit.
@@ -18105,31 +18108,11 @@ c_parser_parse_rtl_body (c_parser *parser)
   /* Consume the closing brace.  */
   c_parser_consume_token (parser);
 
-  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;
-    }
-  if (exploc_start.line >= exploc_end.line)
-    {
-      error_at (end_loc, "start of RTL fragment must be on an earlier line than end");
-      return;
-    }
-
-  auto_vec<const char *> argv (2);
-  argv.safe_push (progname);
-  argv.safe_push (exploc_start.file);
-
-  if (!read_rtl_function_body (argv.length (), argv.address (), NULL))
+  if (!read_rtl_function_body_from_file_range (start_loc, end_loc))
     return;
 
-#if 0
-  /* Copy the relevant fragment of the input file to a tempfile.  */
-  FILE *outfile = fopen ("/tmp/hack.rtl", "w");
-#endif
+  /* Using this requires un-poisoning rtl.h.  */
+  print_rtl_with_bb (stdout, get_insns (), 1024);
 }
 
 #include "gt-c-c-parser.h"
diff --git a/gcc/read-md.c b/gcc/read-md.c
index d84b832..fddd66c 100644
--- a/gcc/read-md.c
+++ b/gcc/read-md.c
@@ -402,6 +402,16 @@ rtx_reader::read_char (void)
 
   update_location (true);
 
+  /* If we're filtering lines, treat everything outside the
+     range of interest as a space.  */
+  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;
 }
 
@@ -988,7 +998,9 @@ rtx_reader::rtx_reader (line_maps *line_table)
   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)
 {
   rtx_reader_line_table = m_line_table;
 
@@ -1313,6 +1325,26 @@ rtx_reader::read_md_files (int argc, const char **argv,
   return !seen_error ();
 }
 
+/* FIXME.  */
+
+bool
+rtx_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 !seen_error ();
+}
+
 /* class noop_reader : public rtx_reader */
 
 /* A dummy implementation which skips unknown directives.  */
diff --git a/gcc/read-md.h b/gcc/read-md.h
index 893a65d..03d984e 100644
--- a/gcc/read-md.h
+++ b/gcc/read-md.h
@@ -89,6 +89,9 @@ class rtx_reader
   virtual ~rtx_reader ();
 
   bool read_md_files (int, const char **, bool (*) (const char *));
+  bool read_file_fragment (const char *filename,
+			   int first_line,
+			   int last_line);
 
   /* A hook that handles a single .md-file directive, up to but not
      including the closing ')'.  It takes two arguments: the file position
@@ -193,6 +196,9 @@ class rtx_reader
 
   /* A pointer to the null terminator of the md include chain.  */
   file_name_list **m_last_dir_md_include_ptr;
+
+  int m_first_line;
+  int m_last_line;
 };
 
 /* Global singleton.  */
diff --git a/gcc/read-rtl-function.c b/gcc/read-rtl-function.c
index 7fa0d68..90689ff 100644
--- a/gcc/read-rtl-function.c
+++ b/gcc/read-rtl-function.c
@@ -794,17 +794,12 @@ function_reader::create_cfg_edges ()
     }
 }
 
-bool
-read_rtl_function_body (int argc, const char **argv,
-			bool (*parse_opt) (const char *))
+static void
+postprocess (function_reader *reader)
 {
-  function_reader reader (line_table);
-  if (!reader.read_md_files (argc, argv, parse_opt))
-    return false;
-
-  reader.create_function ();
-  reader.apply_fixups ();
-  reader.create_cfg_edges ();
+  reader->create_function ();
+  reader->apply_fixups ();
+  reader->create_cfg_edges ();
 
   /* Ensure x_cur_insn_uid is 1 more than the biggest insn UID seen.
      This is normally updated by the various make_*insn_raw functions.  */
@@ -817,6 +812,51 @@ read_rtl_function_body (int argc, const char **argv,
   }
 
   crtl->init_stack_alignment ();
+}
+
+bool
+read_rtl_function_body (int argc, const char **argv,
+			bool (*parse_opt) (const char *))
+{
+  function_reader reader (line_table);
+  if (!reader.read_md_files (argc, argv, parse_opt))
+    return false;
+
+  postprocess (&reader);
+
+  return true;
+}
+
+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;
+    }
+
+  in_rtl_frontend_p = true;
+
+  initialize_rtl ();
+  crtl->emit.init_emit ();
+  init_varasm_status ();
+
+  function_reader reader (line_table);
+  if (!reader.read_file_fragment (exploc_start.file, exploc_start.line,
+				  exploc_end.line - 1))
+    return false;
+
+  postprocess (&reader);
 
   return true;
 }
diff --git a/gcc/read-rtl-function.h b/gcc/read-rtl-function.h
index 06130da..1d5d4cc 100644
--- a/gcc/read-rtl-function.h
+++ b/gcc/read-rtl-function.h
@@ -23,4 +23,7 @@ along with GCC; see the file COPYING3.  If not see
 extern bool read_rtl_function_body (int argc, const char **argv,
 				    bool (*parse_opt) (const char *));
 
+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/system.h b/gcc/system.h
index 984f302..267aa56 100644
--- a/gcc/system.h
+++ b/gcc/system.h
@@ -1015,7 +1015,7 @@ extern void fancy_abort (const char *, int, const char *) ATTRIBUTE_NORETURN;
 /* 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
+//pragma GCC poison GCC_RTL_H GCC_EXCEPT_H GCC_EXPR_H
 #endif
 
 /* Note: not all uses of the `index' token (e.g. variable names and
-- 
1.8.5.3

