From 603444b9c3dd04ea3d8ae01bd3782afa4ba6c5c2 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Fri, 11 Jul 2014 13:00:23 -0400
Subject: [PATCH 249/249] FIXME: Experiments with introducing an rtx_set
 subclass of rtx_def

---
 gcc/alias.c          |  3 ++-
 gcc/auto-inc-dec.c   |  7 ++++---
 gcc/bt-load.c        |  2 +-
 gcc/calls.c          |  2 +-
 gcc/cfgcleanup.c     |  3 ++-
 gcc/cfgloopanal.c    |  2 +-
 gcc/combine.c        | 12 ++++++------
 gcc/coretypes.h      |  1 +
 gcc/emit-rtl.c       |  6 ++++++
 gcc/gengenrtl.c      |  1 +
 gcc/loop-invariant.c |  2 +-
 gcc/lower-subreg.c   |  2 +-
 gcc/rtl.h            | 21 +++++++++++++++++----
 gcc/rtlanal.c        | 10 +++++-----
 14 files changed, 49 insertions(+), 25 deletions(-)

diff --git a/gcc/alias.c b/gcc/alias.c
index 903840c..1a30fe2 100644
--- a/gcc/alias.c
+++ b/gcc/alias.c
@@ -2924,7 +2924,8 @@ init_alias_analysis (void)
 	    {
 	      if (NONDEBUG_INSN_P (insn))
 		{
-		  rtx note, set;
+		  rtx note;
+		  rtx_set *set;
 
 #if defined (HAVE_prologue) || defined (HAVE_epilogue)
 		  /* The prologue/epilogue insns are not threaded onto the
diff --git a/gcc/auto-inc-dec.c b/gcc/auto-inc-dec.c
index 739fc87..d859648 100644
--- a/gcc/auto-inc-dec.c
+++ b/gcc/auto-inc-dec.c
@@ -296,7 +296,7 @@ init_decision_table (void)
 static struct inc_insn
 {
   rtx_insn *insn;     /* The insn being parsed.  */
-  rtx pat;            /* The pattern of the insn.  */
+  rtx_set *pat;            /* The pattern of the insn.  */
   bool reg1_is_const; /* True if reg1 is const, false if reg1 is a reg.  */
   enum form form;
   rtx reg_res;
@@ -482,7 +482,8 @@ attempt_change (rtx new_addr, rtx inc_reg)
   XEXP (mem_tmp, 0) = new_addr;
 
   old_cost = (set_src_cost (mem, speed)
-	      + set_rtx_cost (PATTERN (inc_insn.insn), speed));
+	      + set_rtx_cost (as_a <rtx_set *> (PATTERN (inc_insn.insn)),
+			      speed));
   new_cost = set_src_cost (mem_tmp, speed);
 
   /* The first item of business is to see if this is profitable.  */
@@ -789,7 +790,7 @@ reverse_inc (void)
 static bool
 parse_add_or_inc (rtx_insn *insn, bool before_mem)
 {
-  rtx pat = single_set (insn);
+  rtx_set *pat = single_set (insn);
   if (!pat)
     return false;
 
diff --git a/gcc/bt-load.c b/gcc/bt-load.c
index 58dbc09..c05c737 100644
--- a/gcc/bt-load.c
+++ b/gcc/bt-load.c
@@ -1162,7 +1162,7 @@ move_btr_def (basic_block new_def_bb, int btr, btr_def def, bitmap live_range,
   rtx_insn *new_insn;
   enum machine_mode btr_mode;
   btr_user user;
-  rtx set;
+  rtx_set *set;
 
   if (dump_file)
     fprintf(dump_file, "migrating to basic block %d, using reg %d\n",
diff --git a/gcc/calls.c b/gcc/calls.c
index a3b9993..49fe5b2 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -1714,7 +1714,7 @@ internal_arg_pointer_based_exp_scan (void)
 
   while (insn)
     {
-      rtx set = single_set (insn);
+      rtx_set *set = single_set (insn);
       if (set && REG_P (SET_DEST (set)) && !HARD_REGISTER_P (SET_DEST (set)))
 	{
 	  rtx val = NULL_RTX;
diff --git a/gcc/cfgcleanup.c b/gcc/cfgcleanup.c
index fe0de9f..1dead61 100644
--- a/gcc/cfgcleanup.c
+++ b/gcc/cfgcleanup.c
@@ -1017,7 +1017,8 @@ equal_different_set_p (rtx p1, rtx s1, rtx p2, rtx s2)
 static enum replace_direction
 can_replace_by (rtx_insn *i1, rtx_insn *i2)
 {
-  rtx s1, s2, d1, d2, src1, src2, note1, note2;
+  rtx_set *s1, *s2;
+  rtx d1, d2, src1, src2, note1, note2;
   bool c1, c2;
 
   /* Check for 2 sets.  */
diff --git a/gcc/cfgloopanal.c b/gcc/cfgloopanal.c
index 7ea1a5f..314e36c 100644
--- a/gcc/cfgloopanal.c
+++ b/gcc/cfgloopanal.c
@@ -308,7 +308,7 @@ static unsigned
 seq_cost (const rtx_insn *seq, bool speed)
 {
   unsigned cost = 0;
-  rtx set;
+  rtx_set *set;
 
   for (; seq; seq = NEXT_INSN (seq))
     {
diff --git a/gcc/combine.c b/gcc/combine.c
index 7665a1a..5ed1dd9 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -419,7 +419,7 @@ static rtx *find_split_point (rtx *, rtx_insn *, bool);
 static rtx subst (rtx, rtx, rtx, int, int, int);
 static rtx combine_simplify_rtx (rtx, enum machine_mode, int, int);
 static rtx simplify_if_then_else (rtx);
-static rtx simplify_set (rtx);
+static rtx simplify_set (rtx_set *);
 static rtx simplify_logical (rtx);
 static rtx expand_compound_operation (rtx);
 static const_rtx expand_field_assignment (const_rtx);
@@ -434,7 +434,7 @@ static rtx force_to_mode (rtx, enum machine_mode,
 static rtx if_then_else_cond (rtx, rtx *, rtx *);
 static rtx known_cond (rtx, enum rtx_code, rtx, rtx);
 static int rtx_equal_for_field_assignment_p (rtx, rtx);
-static rtx make_field_assignment (rtx);
+static rtx_set *make_field_assignment (rtx_set *);
 static rtx apply_distributive_law (rtx);
 static rtx distribute_and_simplify_rtx (rtx, int);
 static rtx simplify_and_const_int_1 (enum machine_mode, rtx,
@@ -5867,7 +5867,7 @@ combine_simplify_rtx (rtx x, enum machine_mode op0_mode, int in_dest,
       return expand_compound_operation (x);
 
     case SET:
-      return simplify_set (x);
+      return simplify_set (as_a <rtx_set *> (x));
 
     case AND:
     case IOR:
@@ -6240,7 +6240,7 @@ simplify_if_then_else (rtx x)
 /* Simplify X, a SET expression.  Return the new expression.  */
 
 static rtx
-simplify_set (rtx x)
+simplify_set (rtx_set *x)
 {
   rtx src = SET_SRC (x);
   rtx dest = SET_DEST (x);
@@ -8971,8 +8971,8 @@ rtx_equal_for_field_assignment_p (rtx x, rtx y)
 
    We only handle the most common cases.  */
 
-static rtx
-make_field_assignment (rtx x)
+static rtx_set *
+make_field_assignment (rtx_set *x)
 {
   rtx dest = SET_DEST (x);
   rtx src = SET_SRC (x);
diff --git a/gcc/coretypes.h b/gcc/coretypes.h
index 5ba83b1..90108b3 100644
--- a/gcc/coretypes.h
+++ b/gcc/coretypes.h
@@ -73,6 +73,7 @@ class rtx_def;
     class rtx_barrier;           /* BARRIER_P (X) */
     class rtx_code_label;        /* LABEL_P (X) */
     class rtx_note;              /* NOTE_P (X) */
+  class rtx_set;                 /* GET_CODE (X) == SET */
 
 struct rtvec_def;
 typedef struct rtvec_def *rtvec;
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
index 2fc07d6..4cd21d9 100644
--- a/gcc/emit-rtl.c
+++ b/gcc/emit-rtl.c
@@ -418,6 +418,12 @@ gen_rtx_INSN_LIST (enum machine_mode mode, rtx insn, rtx insn_list)
 						 insn_list));
 }
 
+rtx_set *
+gen_rtx_SET (enum machine_mode mode, rtx dest, rtx src)
+{
+  return as_a <rtx_set *> (gen_rtx_fmt_ee (SET, mode, dest, src));
+}
+
 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 885dd20..823cf59 100644
--- a/gcc/gengenrtl.c
+++ b/gcc/gengenrtl.c
@@ -125,6 +125,7 @@ special_rtx (int idx)
 {
   return (strcmp (defs[idx].enumname, "EXPR_LIST") == 0
 	  || strcmp (defs[idx].enumname, "INSN_LIST") == 0
+	  || strcmp (defs[idx].enumname, "SET") == 0
 	  || strcmp (defs[idx].enumname, "CONST_INT") == 0
 	  || strcmp (defs[idx].enumname, "REG") == 0
 	  || strcmp (defs[idx].enumname, "SUBREG") == 0
diff --git a/gcc/loop-invariant.c b/gcc/loop-invariant.c
index 5592cd4..0a0e5da 100644
--- a/gcc/loop-invariant.c
+++ b/gcc/loop-invariant.c
@@ -687,7 +687,7 @@ create_new_invariant (struct def *def, rtx_insn *insn, bitmap depends_on,
 		      bool always_executed)
 {
   struct invariant *inv = XNEW (struct invariant);
-  rtx set = single_set (insn);
+  rtx_set *set = single_set (insn);
   bool speed = optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn));
 
   inv->def = def;
diff --git a/gcc/lower-subreg.c b/gcc/lower-subreg.c
index 3451a5e..016795c 100644
--- a/gcc/lower-subreg.c
+++ b/gcc/lower-subreg.c
@@ -122,7 +122,7 @@ struct cost_rtxes {
   rtx shift;
 
   /* A SET of TARGET.  */
-  rtx set;
+  rtx_set *set;
 };
 
 /* Return the cost of a CODE shift in mode MODE by OP1 bits, using the
diff --git a/gcc/rtl.h b/gcc/rtl.h
index 01c98fa..616da7b 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -631,6 +631,10 @@ class GTY(()) rtx_note : public rtx_insn
      from rtl.def.  */
 };
 
+class GTY(()) rtx_set : public rtx_insn
+{
+};
+
 /* The size in bytes of an rtx header (code, mode and flags).  */
 #define RTX_HDR_SIZE offsetof (struct rtx_def, u)
 
@@ -920,6 +924,14 @@ is_a_helper <rtx_note *>::test (rtx_insn *insn)
   return NOTE_P (insn);
 }
 
+template <>
+template <>
+inline bool
+is_a_helper <rtx_set *>::test (rtx rt)
+{
+  return GET_CODE (rt) == SET;
+}
+
 /* Predicate yielding nonzero iff X is a return or simple_return.  */
 #define ANY_RETURN_P(X) \
   (GET_CODE (X) == RETURN || GET_CODE (X) == SIMPLE_RETURN)
@@ -2041,7 +2053,7 @@ extern enum rtx_code get_index_code (const struct address_info *);
    rather than size.  */
 
 static inline int
-set_rtx_cost (rtx x, bool speed_p)
+set_rtx_cost (rtx_set *x, bool speed_p)
 {
   return rtx_cost (x, INSN, 4, speed_p);
 }
@@ -2707,8 +2719,8 @@ extern void set_insn_deleted (rtx);
 /* Single set is implemented as macro for performance reasons.  */
 #define single_set(I) (INSN_P (I) \
 		       ? (GET_CODE (PATTERN (I)) == SET \
-			  ? PATTERN (I) : single_set_1 (I)) \
-		       : NULL_RTX)
+			  ? as_a <rtx_set *> (PATTERN (I)) : single_set_1 (I)) \
+		       : NULL)
 #define single_set_1(I) single_set_2 (I, PATTERN (I))
 
 /* Structure used for passing data to REPLACE_LABEL.  */
@@ -2742,7 +2754,7 @@ extern int modified_between_p (const_rtx, const_rtx, const_rtx);
 extern int no_labels_between_p (const rtx_insn *, const rtx_insn *);
 extern int modified_in_p (const_rtx, const_rtx);
 extern int reg_set_p (const_rtx, const_rtx);
-extern rtx single_set_2 (const_rtx, const_rtx);
+extern rtx_set *single_set_2 (const_rtx, const_rtx);
 extern int multiple_sets (const_rtx);
 extern int set_noop_p (const_rtx);
 extern int noop_move_p (const_rtx);
@@ -3073,6 +3085,7 @@ get_mem_attrs (const_rtx x)
 
 extern rtx_expr_list *gen_rtx_EXPR_LIST (enum machine_mode, rtx, rtx);
 extern rtx_insn_list *gen_rtx_INSN_LIST (enum machine_mode, rtx, rtx);
+extern rtx_set *gen_rtx_SET (enum machine_mode mode, rtx dest, rtx src);
 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);
diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c
index d434030..8872664 100644
--- a/gcc/rtlanal.c
+++ b/gcc/rtlanal.c
@@ -1097,10 +1097,10 @@ record_hard_reg_uses (rtx *px, void *data)
    It may also have CLOBBERs, USEs, or SET whose output
    will not be used, which we ignore.  */
 
-rtx
+rtx_set *
 single_set_2 (const_rtx insn, const_rtx pat)
 {
-  rtx set = NULL;
+  rtx_set *set = NULL;
   int set_verified = 1;
   int i;
 
@@ -1133,14 +1133,14 @@ single_set_2 (const_rtx insn, const_rtx pat)
 		    set_verified = 1;
 		}
 	      if (!set)
-		set = sub, set_verified = 0;
+		set = as_a <rtx_set *> (sub), set_verified = 0;
 	      else if (!find_reg_note (insn, REG_UNUSED, SET_DEST (sub))
 		       || side_effects_p (sub))
-		return NULL_RTX;
+		return NULL;
 	      break;
 
 	    default:
-	      return NULL_RTX;
+	      return NULL;
 	    }
 	}
     }
-- 
1.8.5.3

