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