From dbda84ffbee5fb629476c9788b18489e3ada07c0 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Tue, 7 Jan 2014 14:00:50 -0500
Subject: [PATCH 085/159] FIXME: add rtx_insn_list subclass

---
 gcc/coretypes.h | 11 +++++++++--
 gcc/emit-rtl.c  |  7 +++++++
 gcc/gengenrtl.c |  3 ++-
 gcc/rtl.h       | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 69 insertions(+), 3 deletions(-)

diff --git a/gcc/coretypes.h b/gcc/coretypes.h
index a90fd4b..37b61e0 100644
--- a/gcc/coretypes.h
+++ b/gcc/coretypes.h
@@ -57,8 +57,11 @@ typedef const struct simple_bitmap_def *const_sbitmap;
 
    The underlying class hierarchy looks like this:
       -+-rtx (any kind of expression)
-          |-rtx_base_insn (something that can be part of an insn list)
-          |  |-rtx_debug_insn (GET_CODE (X) == DEBUG_INSN)
+	  |-rtx_insn_list (a node within an externally singly-linked list of
+	  |                rtx_base_insn)
+	  |-rtx_base_insn (something that can be part of the internally
+	  |  |             doubly-linked list of instructions)
+	  |  |-rtx_debug_insn (GET_CODE (X) == DEBUG_INSN)
 	  |  |-rtx_jump_insn  (GET_CODE (X) == JUMP_INSN)
 	  |  |-rtx_call_insn  (etc)
 	  |  |-rtx_jump_table_data
@@ -79,6 +82,10 @@ struct rtvec_def;
 typedef struct rtvec_def *rtvec;
 typedef const struct rtvec_def *const_rtvec;
 
+struct rtx_insn_list_def;
+typedef struct rtx_insn_list_def *rtx_insn_list;
+typedef const struct rtx_insn_list_def *const_rtx_insn_list;
+
 struct rtx_base_insn_def;
 typedef struct rtx_base_insn_def *rtx_base_insn;
 typedef const struct rtx_base_insn_def *const_rtx_base_insn;
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
index 19b0507..ab6c4b3 100644
--- a/gcc/emit-rtl.c
+++ b/gcc/emit-rtl.c
@@ -394,6 +394,13 @@ gen_raw_REG (enum machine_mode mode, int regno)
    functions do the raw handling.  If you add to this list, modify
    special_rtx in gengenrtl.c as well.  */
 
+rtx_insn_list
+gen_rtx_INSN_LIST (enum machine_mode mode, rtx insn, rtx insn_list)
+{
+  return gen_rtx_fmt_ue (INSN_LIST, mode, insn,
+			 insn_list)->as_an_rtx_insn_list ();
+}
+
 rtx
 gen_rtx_CONST_INT (enum machine_mode mode ATTRIBUTE_UNUSED, HOST_WIDE_INT arg)
 {
diff --git a/gcc/gengenrtl.c b/gcc/gengenrtl.c
index 4a35683..caca702 100644
--- a/gcc/gengenrtl.c
+++ b/gcc/gengenrtl.c
@@ -123,7 +123,8 @@ special_format (const char *fmt)
 static int
 special_rtx (int idx)
 {
-  return (strcmp (defs[idx].enumname, "CONST_INT") == 0
+  return (strcmp (defs[idx].enumname, "INSN_LIST") == 0
+	  || strcmp (defs[idx].enumname, "CONST_INT") == 0
 	  || strcmp (defs[idx].enumname, "REG") == 0
 	  || strcmp (defs[idx].enumname, "SUBREG") == 0
 	  || strcmp (defs[idx].enumname, "MEM") == 0
diff --git a/gcc/rtl.h b/gcc/rtl.h
index 6cb8efb..9f3438d 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -371,6 +371,12 @@ public:
      Keep these in the same order as the corresponding DEF_RTL_EXPR within
      rtl.def.  */
 
+  inline rtx_insn_list
+  as_an_rtx_insn_list ()
+  {
+    return as_a <rtx_insn_list_def> (this);
+  }
+
   inline rtx_base_insn
   as_an_rtx_base_insn ()
   {
@@ -441,6 +447,30 @@ public:
   inline void set_next_insn (rtx new_next);
 };
 
+/* A node for constructing singly-linked lists of rtx_base_insn,
+   where the list is "external" to the insn (as opposed to the
+   doubly-linked list embedded within rtx_base_insn itself).  */
+
+struct GTY(()) rtx_insn_list_def : public rtx_def
+{
+  /* No extra fields, but adds invariant: (GET_CODE (X) == INSN_LIST).  */
+
+public:
+  /* Get next in list.  */
+  rtx_insn_list next () const;
+
+  /* Get at the underlying instruction.  */
+  rtx_base_insn insn () const;
+
+};
+
+template <>
+template <>
+inline bool
+is_a_helper <rtx_insn_list_def>::test (rtx rt)
+{
+  return rt->code == INSN_LIST;
+}
 
 struct GTY(()) rtx_base_insn_def : public rtx_def
 {
@@ -607,6 +637,7 @@ is_a_helper <rtx_label_ref_def>::test (rtx rt)
 #define RTX_CODE_SIZE(CODE) rtx_code_size[CODE]
 
 #define NULL_RTX (rtx) 0
+#define NULL_RTX_INSN_LIST (rtx_insn_list) 0
 #define NULL_RTX_BASE_INSN (rtx_base_insn) 0
 #define NULL_RTX_CODE_LABEL (rtx_code_label) 0
 #define NULL_RTX_NOTE (rtx_note) 0
@@ -1095,6 +1126,25 @@ extern void rtl_check_failed_flag (const char *, const_rtx, const char *,
 
 #define XC2EXP(RTX, N, C1, C2)      (RTL_CHECKC2 (RTX, N, C1, C2).rt_rtx)
 
+
+inline rtx_insn_list rtx_insn_list_def::next () const
+{
+  rtx tmp = XEXP (this, 1);
+  if (tmp)
+    return tmp->as_an_rtx_insn_list ();
+  else
+    return NULL;
+}
+
+inline rtx_base_insn rtx_insn_list_def::insn () const
+{
+  rtx tmp = XEXP (this, 0);
+  if (tmp)
+    return tmp->as_an_rtx_base_insn ();
+  else
+    return NULL;
+}
+
 /* ACCESS MACROS for particular fields of insns.  */
 
 /* Holds a unique number for each insn.
@@ -2672,6 +2722,7 @@ get_mem_attrs (const_rtx x)
    generation functions included above do the raw handling.  If you
    add to this list, modify special_rtx in gengenrtl.c as well.  */
 
+extern rtx_insn_list gen_rtx_INSN_LIST (enum machine_mode, rtx, rtx);
 extern rtx gen_rtx_CONST_INT (enum machine_mode, HOST_WIDE_INT);
 extern rtx gen_rtx_CONST_VECTOR (enum machine_mode, rtvec);
 extern rtx gen_raw_REG (enum machine_mode, int);
-- 
1.7.11.7

