From 0cab00d8004d1f2a58042c5c773586a1577c3a8c Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Fri, 27 Dec 2013 21:18:56 -0500
Subject: [PATCH 011/159] FIXME: start adding rtx_base_insn (via
 FOR_BB_INSNS_REVERSE_SAFE)

---
 gcc/alias.c            |   3 +-
 gcc/auto-inc-dec.c     |  36 ++++++------
 gcc/basic-block.h      |  16 +++--
 gcc/bb-reorder.c       |   4 +-
 gcc/caller-save.c      |  12 ++--
 gcc/cfgexpand.c        |   2 +-
 gcc/cfgloop.c          |   2 +-
 gcc/cfgloopanal.c      |   4 +-
 gcc/cfgrtl.c           | 100 +++++++++++++++++---------------
 gcc/combine.c          |   7 ++-
 gcc/config/sh/sh.c     |  12 ++--
 gcc/cprop.c            |   8 +--
 gcc/cse.c              |   6 +-
 gcc/dce.c              |   6 +-
 gcc/df-core.c          |   4 +-
 gcc/df-problems.c      |  16 ++---
 gcc/df-scan.c          |  22 +++----
 gcc/dse.c              |   2 +-
 gcc/emit-rtl.c         | 154 ++++++++++++++++++++++++++-----------------------
 gcc/emit-rtl.h         |  16 +++--
 gcc/expr.c             |  46 ++++++++-------
 gcc/expr.h             |   8 +--
 gcc/final.c            |  18 +++---
 gcc/function.c         |  13 +++--
 gcc/fwprop.c           |   2 +-
 gcc/gcse.c             |  11 ++--
 gcc/haifa-sched.c      |  44 +++++++-------
 gcc/ifcvt.c            |  12 ++--
 gcc/init-regs.c        |   2 +-
 gcc/ira-build.c        |   2 +-
 gcc/ira-conflicts.c    |   2 +-
 gcc/ira-costs.c        |   9 +--
 gcc/ira-emit.c         |   5 +-
 gcc/ira-lives.c        |   2 +-
 gcc/ira.c              |  19 +++---
 gcc/jump.c             |  28 +++++----
 gcc/loop-invariant.c   |   7 ++-
 gcc/loop-iv.c          |   5 +-
 gcc/loop-unroll.c      |  20 +++----
 gcc/lower-subreg.c     |  29 +++++-----
 gcc/lra-assigns.c      |   4 +-
 gcc/lra-constraints.c  |   2 +-
 gcc/lra-eliminations.c |   2 +-
 gcc/lra-int.h          |   2 +-
 gcc/lra-lives.c        |   2 +-
 gcc/lra-spills.c       |   7 ++-
 gcc/lra.c              |  21 +++----
 gcc/mode-switching.c   |   2 +-
 gcc/optabs.c           |   4 +-
 gcc/postreload-gcse.c  |   6 +-
 gcc/postreload.c       |   2 +-
 gcc/predict.c          |   2 +-
 gcc/ree.c              |   3 +-
 gcc/reginfo.c          |   2 +-
 gcc/regrename.c        |   2 +-
 gcc/regstat.c          |   4 +-
 gcc/reload1.c          |   2 +-
 gcc/rtl.h              |  74 ++++++++++++++++++++----
 gcc/sched-rgn.c        |   4 +-
 gcc/sched-vis.c        |   2 +-
 gcc/sel-sched-ir.c     |  20 +++----
 gcc/sel-sched.c        |  14 ++---
 gcc/stack-ptr-mod.c    |   2 +-
 gcc/store-motion.c     |  10 ++--
 gcc/var-tracking.c     |   2 +-
 gcc/web.c              |   2 +-
 66 files changed, 511 insertions(+), 404 deletions(-)

diff --git a/gcc/alias.c b/gcc/alias.c
index 6a73b09..90de485 100644
--- a/gcc/alias.c
+++ b/gcc/alias.c
@@ -2911,7 +2911,8 @@ init_alias_analysis (void)
   int changed, pass;
   int i;
   unsigned int ui;
-  rtx insn, val;
+  rtx_base_insn insn;
+  rtx val;
   int rpo_cnt;
   int *rpo;
 
diff --git a/gcc/auto-inc-dec.c b/gcc/auto-inc-dec.c
index 6006b70..5b5813f 100644
--- a/gcc/auto-inc-dec.c
+++ b/gcc/auto-inc-dec.c
@@ -295,7 +295,7 @@ init_decision_table (void)
 
 static struct inc_insn
 {
-  rtx insn;           /* The insn being parsed.  */
+  rtx_base_insn insn; /* The insn being parsed.  */
   rtx pat;            /* The pattern of the insn.  */
   bool reg1_is_const; /* True if reg1 is const, false if reg1 is a reg.  */
   enum form form;
@@ -355,7 +355,7 @@ dump_inc_insn (FILE *file)
 
 static struct mem_insn
 {
-  rtx insn;           /* The insn being parsed.  */
+  rtx_base_insn insn; /* The insn being parsed.  */
   rtx pat;            /* The pattern of the insn.  */
   rtx *mem_loc;       /* The address of the field that holds the mem */
                       /* that is to be replaced.  */
@@ -397,9 +397,9 @@ dump_mem_insn (FILE *file)
    must be compared with the current block.
 */
 
-static rtx *reg_next_use = NULL;
-static rtx *reg_next_inc_use = NULL;
-static rtx *reg_next_def = NULL;
+static rtx_base_insn *reg_next_use = NULL;
+static rtx_base_insn *reg_next_inc_use = NULL;
+static rtx_base_insn *reg_next_def = NULL;
 
 
 /* Move dead note that match PATTERN to TO_INSN from FROM_INSN.  We do
@@ -436,10 +436,10 @@ move_dead_notes (rtx to_insn, rtx from_insn, rtx pattern)
 /* Create a mov insn DEST_REG <- SRC_REG and insert it before
    NEXT_INSN.  */
 
-static rtx
+static rtx_base_insn
 insert_move_insn_before (rtx next_insn, rtx dest_reg, rtx src_reg)
 {
-  rtx insns;
+  rtx_base_insn insns;
 
   start_sequence ();
   emit_move_insn (dest_reg, src_reg);
@@ -469,7 +469,7 @@ attempt_change (rtx new_addr, rtx inc_reg)
      handled mov free.  */
 
   basic_block bb = BLOCK_FOR_INSN (mem_insn.insn);
-  rtx mov_insn = NULL;
+  rtx_base_insn mov_insn = NULL;
   int regno;
   rtx mem = *mem_insn.mem_loc;
   enum machine_mode mode = GET_MODE (mem);
@@ -738,10 +738,10 @@ try_merge (void)
    NEXT_ARRAY) or defines (if reg_next_def is passed in NEXT_ARRAY)
    REGNO in BB.  */
 
-static rtx
-get_next_ref (int regno, basic_block bb, rtx *next_array)
+static rtx_base_insn
+get_next_ref (int regno, basic_block bb, rtx_base_insn *next_array)
 {
-  rtx insn = next_array[regno];
+  rtx_base_insn insn = next_array[regno];
 
   /* Lazy about cleaning out the next_arrays.  */
   if (insn && BLOCK_FOR_INSN (insn) != bb)
@@ -787,7 +787,7 @@ reverse_inc (void)
    processed.  */
 
 static bool
-parse_add_or_inc (rtx insn, bool before_mem)
+parse_add_or_inc (rtx_base_insn insn, bool before_mem)
 {
   rtx pat = single_set (insn);
   if (!pat)
@@ -966,7 +966,7 @@ find_address (rtx *address_of_x)
 static bool
 find_inc (bool first_try)
 {
-  rtx insn;
+  rtx_base_insn insn;
   basic_block bb = BLOCK_FOR_INSN (mem_insn.insn);
   rtx other_insn;
   df_ref *def_rec;
@@ -1333,8 +1333,8 @@ find_mem (rtx *address_of_x)
 static void
 merge_in_block (int max_reg, basic_block bb)
 {
-  rtx insn;
-  rtx curr;
+  rtx_base_insn insn;
+  rtx_base_insn curr;
   int success_in_block = 0;
 
   if (dump_file)
@@ -1477,9 +1477,9 @@ rest_of_handle_auto_inc_dec (void)
   df_note_add_problem ();
   df_analyze ();
 
-  reg_next_use = XCNEWVEC (rtx, max_reg);
-  reg_next_inc_use = XCNEWVEC (rtx, max_reg);
-  reg_next_def = XCNEWVEC (rtx, max_reg);
+  reg_next_use = XCNEWVEC (rtx_base_insn, max_reg);
+  reg_next_inc_use = XCNEWVEC (rtx_base_insn, max_reg);
+  reg_next_def = XCNEWVEC (rtx_base_insn, max_reg);
   FOR_EACH_BB (bb)
     merge_in_block (max_reg, bb);
 
diff --git a/gcc/basic-block.h b/gcc/basic-block.h
index ef66dfc..c538ae6 100644
--- a/gcc/basic-block.h
+++ b/gcc/basic-block.h
@@ -351,26 +351,30 @@ struct GTY(()) control_flow_graph {
 
 /* For iterating over insns in basic block.  */
 #define FOR_BB_INSNS(BB, INSN)			\
-  for ((INSN) = BB_HEAD (BB);			\
+  for ((INSN) = (BB_HEAD (BB) ? BB_HEAD (BB)->as_an_rtx_base_insn () : NULL); \
        (INSN) && (INSN) != NEXT_INSN (BB_END (BB));	\
        (INSN) = NEXT_INSN (INSN))
 
 /* For iterating over insns in basic block when we might remove the
    current insn.  */
 #define FOR_BB_INSNS_SAFE(BB, INSN, CURR)			\
-  for ((INSN) = BB_HEAD (BB), (CURR) = (INSN) ? NEXT_INSN ((INSN)): NULL;	\
+  for ((INSN) = (BB_HEAD (BB) ? BB_HEAD (BB)->as_an_rtx_base_insn () : NULL), \
+	 (CURR) = (INSN) ? NEXT_INSN ((INSN)) : NULL; \
        (INSN) && (INSN) != NEXT_INSN (BB_END (BB));	\
-       (INSN) = (CURR), (CURR) = (INSN) ? NEXT_INSN ((INSN)) : NULL)
+       (INSN) = (CURR), \
+	 (CURR) = (INSN) ? NEXT_INSN ((INSN)) : NULL)
 
 #define FOR_BB_INSNS_REVERSE(BB, INSN)		\
-  for ((INSN) = BB_END (BB);			\
+  for ((INSN) = (BB_END (BB) ? BB_END (BB)->as_an_rtx_base_insn () : NULL); \
        (INSN) && (INSN) != PREV_INSN (BB_HEAD (BB));	\
        (INSN) = PREV_INSN (INSN))
 
 #define FOR_BB_INSNS_REVERSE_SAFE(BB, INSN, CURR)	\
-  for ((INSN) = BB_END (BB),(CURR) = (INSN) ? PREV_INSN ((INSN)) : NULL;	\
+  for ((INSN) = (BB_END (BB) ? BB_END (BB)->as_an_rtx_base_insn () : NULL), \
+	 (CURR) = (INSN) ? PREV_INSN ((INSN)) : NULL; \
        (INSN) && (INSN) != PREV_INSN (BB_HEAD (BB));	\
-       (INSN) = (CURR), (CURR) = (INSN) ? PREV_INSN ((INSN)) : NULL)
+       (INSN) = (CURR), \
+	 (CURR) = (INSN) ? PREV_INSN ((INSN)) : NULL)
 
 /* Cycles through _all_ basic blocks, even the fake ones (entry and
    exit block).  */
diff --git a/gcc/bb-reorder.c b/gcc/bb-reorder.c
index ae0d1ce..096d940 100644
--- a/gcc/bb-reorder.c
+++ b/gcc/bb-reorder.c
@@ -1330,7 +1330,7 @@ copy_bb_p (const_basic_block bb, int code_may_grow)
 {
   int size = 0;
   int max_size = uncond_jump_length;
-  rtx insn;
+  rtx_base_insn insn;
 
   if (!bb->frequency)
     return false;
@@ -2416,7 +2416,7 @@ duplicate_computed_gotos (void)
      mark it in the candidates.  */
   FOR_EACH_BB (bb)
     {
-      rtx insn;
+      rtx_base_insn insn;
       edge e;
       edge_iterator ei;
       int size, all_flags;
diff --git a/gcc/caller-save.c b/gcc/caller-save.c
index b134cde..6450e5a 100644
--- a/gcc/caller-save.c
+++ b/gcc/caller-save.c
@@ -910,13 +910,13 @@ save_call_clobbered_regs (void)
 		  prev = PREV_INSN (ins);
 		  if (NOTE_P (ins))
 		    {
-		      NEXT_INSN (prev) = NEXT_INSN (ins);
-		      PREV_INSN (NEXT_INSN (ins)) = prev;
-		      PREV_INSN (ins) = insn;
-		      NEXT_INSN (ins) = NEXT_INSN (insn);
-		      NEXT_INSN (insn) = ins;
+		      prev->set_next_insn (NEXT_INSN (ins));
+		      NEXT_INSN (ins)->set_prev_insn (prev);
+		      ins->set_prev_insn (insn);
+		      ins->set_next_insn (NEXT_INSN (insn));
+		      insn->set_next_insn (ins);
 		      if (NEXT_INSN (ins))
-			PREV_INSN (NEXT_INSN (ins)) = ins;
+			NEXT_INSN (ins)->set_prev_insn (ins);
                       if (BB_END (bb) == insn)
 			BB_END (bb) = ins;
 		    }
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index 59a9dd4..7ffa468 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -5763,7 +5763,7 @@ gimple_expand_cfg (void)
 	{
 	  if (e->insns.r)
 	    {
-	      rebuild_jump_labels_chain (e->insns.r);
+	      rebuild_jump_labels_chain (e->insns.r->as_an_rtx_base_insn ());
 	      /* Put insns after parm birth, but before
 		 NOTE_INSNS_FUNCTION_BEG.  */
 	      if (e->src == ENTRY_BLOCK_PTR_FOR_FN (cfun)
diff --git a/gcc/cfgloop.c b/gcc/cfgloop.c
index 0b12e73..833f318 100644
--- a/gcc/cfgloop.c
+++ b/gcc/cfgloop.c
@@ -1735,7 +1735,7 @@ loop_exits_from_bb_p (struct loop *loop, basic_block bb)
 location_t
 get_loop_location (struct loop *loop)
 {
-  rtx insn = NULL;
+  rtx_base_insn insn = NULL;
   struct niter_desc *desc = NULL;
   edge exit;
 
diff --git a/gcc/cfgloopanal.c b/gcc/cfgloopanal.c
index 0cee6c6..696cb14 100644
--- a/gcc/cfgloopanal.c
+++ b/gcc/cfgloopanal.c
@@ -174,7 +174,7 @@ num_loop_insns (const struct loop *loop)
 {
   basic_block *bbs, bb;
   unsigned i, ninsns = 0;
-  rtx insn;
+  rtx_base_insn insn;
 
   bbs = get_loop_body (loop);
   for (i = 0; i < loop->num_nodes; i++)
@@ -198,7 +198,7 @@ average_num_loop_insns (const struct loop *loop)
 {
   basic_block *bbs, bb;
   unsigned i, binsns, ninsns, ratio;
-  rtx insn;
+  rtx_base_insn insn;
 
   ninsns = 0;
   bbs = get_loop_body (loop);
diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c
index f41d7a2..e1ba391 100644
--- a/gcc/cfgrtl.c
+++ b/gcc/cfgrtl.c
@@ -1059,11 +1059,11 @@ try_redirect_by_replacing_jump (edge e, basic_block target, bool in_cfglayout)
 	      if (BARRIER_P (insn))
 		{
 		  if (PREV_INSN (insn))
-		    NEXT_INSN (PREV_INSN (insn)) = NEXT_INSN (insn);
+		    PREV_INSN (insn)->set_next_insn (NEXT_INSN (insn));
 		  else
 		    BB_FOOTER (src) = NEXT_INSN (insn);
 		  if (NEXT_INSN (insn))
-		    PREV_INSN (NEXT_INSN (insn)) = PREV_INSN (insn);
+		    NEXT_INSN (insn)->set_prev_insn (PREV_INSN (insn));
 		}
 	      if (LABEL_P (insn))
 		break;
@@ -1131,14 +1131,14 @@ try_redirect_by_replacing_jump (edge e, basic_block target, bool in_cfglayout)
 	      update_bb_for_insn_chain (NEXT_INSN (BB_END (src)),
 				        PREV_INSN (barrier), src);
 
-	      NEXT_INSN (PREV_INSN (new_insn)) = NEXT_INSN (new_insn);
-	      PREV_INSN (NEXT_INSN (new_insn)) = PREV_INSN (new_insn);
+	      PREV_INSN (new_insn)->set_next_insn (NEXT_INSN (new_insn));
+	      NEXT_INSN (new_insn)->set_prev_insn (PREV_INSN (new_insn));
 
-	      NEXT_INSN (new_insn) = barrier;
-	      NEXT_INSN (PREV_INSN (barrier)) = new_insn;
+	      new_insn->set_next_insn (barrier);
+	      PREV_INSN (barrier)->set_next_insn (new_insn);
 
-	      PREV_INSN (new_insn) = PREV_INSN (barrier);
-	      PREV_INSN (barrier) = new_insn;
+	      new_insn->set_prev_insn (PREV_INSN (barrier));
+	      barrier->set_prev_insn (new_insn);
 	    }
 	}
     }
@@ -1286,7 +1286,7 @@ redirect_branch_edge (edge e, basic_block target)
 {
   rtx old_label = BB_HEAD (e->dest);
   basic_block src = e->src;
-  rtx insn = BB_END (src);
+  rtx_base_insn insn = BB_END (src)->as_an_rtx_base_insn ();
 
   /* We can only redirect non-fallthru edges of jump insn.  */
   if (e->flags & EDGE_FALLTHRU)
@@ -2649,7 +2649,7 @@ rtl_verify_bb_pointers (void)
   /* Check the general integrity of the basic blocks.  */
   FOR_EACH_BB_REVERSE (bb)
     {
-      rtx insn;
+      rtx_base_insn insn;
 
       if (!(bb->flags & BB_RTL))
 	{
@@ -2667,7 +2667,10 @@ rtl_verify_bb_pointers (void)
 	    err = 1;
 	  }
 
-      for (insn = BB_HEADER (bb); insn; insn = NEXT_INSN (insn))
+      for (insn =
+	     BB_HEADER (bb) ? BB_HEADER (bb)->as_an_rtx_base_insn () : NULL;
+	   insn;
+	   insn = NEXT_INSN (insn))
 	if (!BARRIER_P (insn)
 	    && BLOCK_FOR_INSN (insn) != NULL)
 	  {
@@ -2675,7 +2678,10 @@ rtl_verify_bb_pointers (void)
 		   INSN_UID (insn), bb->index);
 	    err = 1;
 	  }
-      for (insn = BB_FOOTER (bb); insn; insn = NEXT_INSN (insn))
+      for (insn =
+	     BB_FOOTER (bb) ? BB_FOOTER (bb)->as_an_rtx_base_insn () : NULL;
+	   insn;
+	   insn = NEXT_INSN (insn))
 	if (!BARRIER_P (insn)
 	    && BLOCK_FOR_INSN (insn) != NULL)
 	  {
@@ -3274,8 +3280,8 @@ fixup_abnormal_edges (void)
 			{
 			  /* We're not deleting it, we're moving it.  */
 			  INSN_DELETED_P (insn) = 0;
-			  PREV_INSN (insn) = NULL_RTX;
-			  NEXT_INSN (insn) = NULL_RTX;
+			  insn->set_prev_insn (NULL_RTX);
+			  insn->set_next_insn (NULL_RTX);
 
 			  insert_insn_on_edge (insn, e);
 			  inserted = true;
@@ -3303,15 +3309,15 @@ fixup_abnormal_edges (void)
 rtx
 unlink_insn_chain (rtx first, rtx last)
 {
-  rtx prevfirst = PREV_INSN (first);
-  rtx nextlast = NEXT_INSN (last);
+  rtx_base_insn prevfirst = PREV_INSN (first);
+  rtx_base_insn nextlast = NEXT_INSN (last);
 
-  PREV_INSN (first) = NULL;
-  NEXT_INSN (last) = NULL;
+  first->set_prev_insn (NULL);
+  last->set_next_insn (NULL);
   if (prevfirst)
-    NEXT_INSN (prevfirst) = nextlast;
+    prevfirst->set_next_insn (nextlast);
   if (nextlast)
-    PREV_INSN (nextlast) = prevfirst;
+    nextlast->set_prev_insn (prevfirst);
   else
     set_last_insn (prevfirst);
   if (!prevfirst)
@@ -3661,32 +3667,32 @@ fixup_reorder_chain (void)
       if (BB_HEADER (bb))
 	{
 	  if (insn)
-	    NEXT_INSN (insn) = BB_HEADER (bb);
+	    insn->set_next_insn (BB_HEADER (bb));
 	  else
 	    set_first_insn (BB_HEADER (bb));
-	  PREV_INSN (BB_HEADER (bb)) = insn;
+	  BB_HEADER (bb)->set_prev_insn (insn);
 	  insn = BB_HEADER (bb);
 	  while (NEXT_INSN (insn))
 	    insn = NEXT_INSN (insn);
 	}
       if (insn)
-	NEXT_INSN (insn) = BB_HEAD (bb);
+	insn->set_next_insn (BB_HEAD (bb));
       else
 	set_first_insn (BB_HEAD (bb));
-      PREV_INSN (BB_HEAD (bb)) = insn;
+      BB_HEAD (bb)->set_prev_insn (insn);
       insn = BB_END (bb);
       if (BB_FOOTER (bb))
 	{
-	  NEXT_INSN (insn) = BB_FOOTER (bb);
-	  PREV_INSN (BB_FOOTER (bb)) = insn;
+	  insn->set_next_insn (BB_FOOTER (bb));
+	  BB_FOOTER (bb)->set_prev_insn (insn);
 	  while (NEXT_INSN (insn))
 	    insn = NEXT_INSN (insn);
 	}
     }
 
-  NEXT_INSN (insn) = cfg_layout_function_footer;
+  insn->set_next_insn (cfg_layout_function_footer);
   if (cfg_layout_function_footer)
-    PREV_INSN (cfg_layout_function_footer) = insn;
+    cfg_layout_function_footer->set_prev_insn (insn);
 
   while (NEXT_INSN (insn))
     insn = NEXT_INSN (insn);
@@ -4421,15 +4427,15 @@ cfg_layout_delete_block (basic_block bb)
     {
       next = BB_HEAD (bb);
       if (prev)
-	NEXT_INSN (prev) = BB_HEADER (bb);
+	prev->set_next_insn (BB_HEADER (bb));
       else
 	set_first_insn (BB_HEADER (bb));
-      PREV_INSN (BB_HEADER (bb)) = prev;
+      BB_HEADER (bb)->set_prev_insn (prev);
       insn = BB_HEADER (bb);
       while (NEXT_INSN (insn))
 	insn = NEXT_INSN (insn);
-      NEXT_INSN (insn) = next;
-      PREV_INSN (next) = insn;
+      insn->set_next_insn (next);
+      next->set_prev_insn (insn);
     }
   next = NEXT_INSN (BB_END (bb));
   if (BB_FOOTER (bb))
@@ -4440,11 +4446,11 @@ cfg_layout_delete_block (basic_block bb)
 	  if (BARRIER_P (insn))
 	    {
 	      if (PREV_INSN (insn))
-		NEXT_INSN (PREV_INSN (insn)) = NEXT_INSN (insn);
+		PREV_INSN (insn)->set_next_insn (NEXT_INSN (insn));
 	      else
 		BB_FOOTER (bb) = NEXT_INSN (insn);
 	      if (NEXT_INSN (insn))
-		PREV_INSN (NEXT_INSN (insn)) = PREV_INSN (insn);
+		NEXT_INSN (insn)->set_prev_insn (PREV_INSN (insn));
 	    }
 	  if (LABEL_P (insn))
 	    break;
@@ -4453,13 +4459,13 @@ cfg_layout_delete_block (basic_block bb)
       if (BB_FOOTER (bb))
 	{
 	  insn = BB_END (bb);
-	  NEXT_INSN (insn) = BB_FOOTER (bb);
-	  PREV_INSN (BB_FOOTER (bb)) = insn;
+	  insn->set_next_insn (BB_FOOTER (bb));
+	  BB_FOOTER (bb)->set_prev_insn (insn);
 	  while (NEXT_INSN (insn))
 	    insn = NEXT_INSN (insn);
-	  NEXT_INSN (insn) = next;
+	  insn->set_next_insn (next);
 	  if (next)
-	    PREV_INSN (next) = insn;
+	    next->set_prev_insn (insn);
 	  else
 	    set_last_insn (insn);
 	}
@@ -4486,9 +4492,9 @@ cfg_layout_delete_block (basic_block bb)
       insn = remaints;
       while (NEXT_INSN (insn))
 	insn = NEXT_INSN (insn);
-      NEXT_INSN (insn) = *to;
+      insn->set_next_insn (*to);
       if (*to)
-	PREV_INSN (*to) = insn;
+	(*to)->set_prev_insn (insn);
       *to = remaints;
     }
 }
@@ -4584,8 +4590,8 @@ cfg_layout_merge_blocks (basic_block a, basic_block b)
 
 	  while (NEXT_INSN (last))
 	    last = NEXT_INSN (last);
-	  NEXT_INSN (last) = BB_FOOTER (b);
-	  PREV_INSN (BB_FOOTER (b)) = last;
+	  last->set_next_insn (BB_FOOTER (b));
+	  BB_FOOTER (b)->set_prev_insn (last);
 	}
       BB_FOOTER (b) = NULL;
     }
@@ -4603,8 +4609,8 @@ cfg_layout_merge_blocks (basic_block a, basic_block b)
  
 	  while (NEXT_INSN (last))
 	    last = NEXT_INSN (last);
-	  NEXT_INSN (last) = BB_FOOTER (a);
-	  PREV_INSN (BB_FOOTER (a)) = last;
+	  last->set_next_insn (BB_FOOTER (a));
+	  BB_FOOTER (a)->set_prev_insn (last);
 	  BB_FOOTER (a) = BB_HEADER (b);
 	}
       BB_HEADER (b) = NULL;
@@ -4679,7 +4685,7 @@ rtl_make_forwarder_block (edge fallthru ATTRIBUTE_UNUSED)
 static bool
 rtl_block_empty_p (basic_block bb)
 {
-  rtx insn;
+  rtx_base_insn insn;
 
   if (bb == ENTRY_BLOCK_PTR_FOR_FN (cfun)
       || bb == EXIT_BLOCK_PTR_FOR_FN (cfun))
@@ -4698,7 +4704,7 @@ rtl_block_empty_p (basic_block bb)
 static basic_block
 rtl_split_block_before_cond_jump (basic_block bb)
 {
-  rtx insn;
+  rtx_base_insn insn;
   rtx split_point = NULL;
   rtx last = NULL;
   bool found_code = false;
@@ -5008,7 +5014,7 @@ static void
 rtl_account_profile_record (basic_block bb, int after_pass,
 			    struct profile_record *record)
 {
-  rtx insn;
+  rtx_base_insn insn;
   FOR_BB_INSNS (bb, insn)
     if (INSN_P (insn))
       {
diff --git a/gcc/combine.c b/gcc/combine.c
index c7eb5e5..ddad93c 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -983,7 +983,8 @@ static void
 create_log_links (void)
 {
   basic_block bb;
-  rtx *next_use, insn;
+  rtx *next_use;
+  rtx_base_insn insn;
   df_ref *def_vec, *use_vec;
 
   next_use = XCNEWVEC (rtx, max_reg_num ());
@@ -2390,11 +2391,11 @@ update_cfg_for_uncondjump (rtx insn)
 	if (BARRIER_P (insn))
 	  {
 	    if (PREV_INSN (insn))
-	      NEXT_INSN (PREV_INSN (insn)) = NEXT_INSN (insn);
+	      PREV_INSN (insn)->set_next_insn (NEXT_INSN (insn));
 	    else
 	      BB_FOOTER (bb) = NEXT_INSN (insn);
 	    if (NEXT_INSN (insn))
-	      PREV_INSN (NEXT_INSN (insn)) = PREV_INSN (insn);
+	      NEXT_INSN (insn)->set_prev_insn (PREV_INSN (insn));
 	  }
 	else if (LABEL_P (insn))
 	  break;
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index e2f2b4f..c0086ff 100644
--- a/gcc/config/sh/sh.c
+++ b/gcc/config/sh/sh.c
@@ -195,7 +195,7 @@ static rtx gen_block_redirect (rtx, int, int);
 static void sh_reorg (void);
 static void sh_option_override (void);
 static void output_stack_adjust (int, rtx, int, HARD_REG_SET *, bool);
-static rtx frame_insn (rtx);
+static rtx_base_insn frame_insn (rtx);
 static rtx push (int);
 static void pop (int);
 static void push_regs (HARD_REG_SET *, int);
@@ -6751,7 +6751,7 @@ static void
 output_stack_adjust (int size, rtx reg, int epilogue_p,
 		     HARD_REG_SET *live_regs_mask, bool frame_p)
 {
-  rtx (*emit_fn) (rtx) = frame_p ? &frame_insn : &emit_insn;
+  rtx_base_insn (*emit_fn) (rtx) = frame_p ? &frame_insn : &emit_insn;
   if (size)
     {
       HOST_WIDE_INT align = STACK_BOUNDARY / BITS_PER_UNIT;
@@ -6911,12 +6911,12 @@ output_stack_adjust (int size, rtx reg, int epilogue_p,
 
 /* Emit the specified insn and mark it as frame related.
    FIXME: Rename this to emit_frame_insn.  */
-static rtx
+static rtx_base_insn
 frame_insn (rtx x)
 {
-  x = emit_insn (x);
-  RTX_FRAME_RELATED_P (x) = 1;
-  return x;
+  rtx_base_insn insn = emit_insn (x);
+  RTX_FRAME_RELATED_P (insn) = 1;
+  return insn;
 }
 
 /* Output RTL to push register RN onto the stack.  */
diff --git a/gcc/cprop.c b/gcc/cprop.c
index 9b8bd1e..0016033 100644
--- a/gcc/cprop.c
+++ b/gcc/cprop.c
@@ -402,7 +402,7 @@ compute_hash_table_work (struct hash_table_d *table)
 
   FOR_EACH_BB (bb)
     {
-      rtx insn;
+      rtx_base_insn insn;
 
       /* Reset tables used to keep track of what's not yet invalid [since
 	 the end of the block].  */
@@ -1229,7 +1229,7 @@ static int
 local_cprop_pass (void)
 {
   basic_block bb;
-  rtx insn;
+  rtx_base_insn insn;
   bool changed = false;
   unsigned i;
 
@@ -1660,7 +1660,7 @@ bypass_conditional_jumps (void)
   basic_block bb;
   int changed;
   rtx setcc;
-  rtx insn;
+  rtx_base_insn insn;
   rtx dest;
 
   /* Note we start at block 1.  */
@@ -1825,7 +1825,7 @@ one_cprop_pass (void)
   if (set_hash_table.n_elems > 0)
     {
       basic_block bb;
-      rtx insn;
+      rtx_base_insn insn;
 
       alloc_cprop_mem (last_basic_block, set_hash_table.n_elems);
       compute_cprop_data ();
diff --git a/gcc/cse.c b/gcc/cse.c
index d5357f0..2309623 100644
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -6321,7 +6321,7 @@ cse_prescan_path (struct cse_basic_block_data *data)
   for (path_entry = 0; path_entry < path_size; path_entry++)
     {
       basic_block bb;
-      rtx insn;
+      rtx_base_insn insn;
 
       bb = data->path[path_entry].bb;
 
@@ -6360,7 +6360,7 @@ cse_extended_basic_block (struct cse_basic_block_data *ebb_data)
   for (path_entry = 0; path_entry < path_size; path_entry++)
     {
       basic_block bb;
-      rtx insn;
+      rtx_base_insn insn;
 
       bb = ebb_data->path[path_entry].bb;
 
@@ -6484,7 +6484,7 @@ cse_extended_basic_block (struct cse_basic_block_data *ebb_data)
 
       /* If this is a conditional jump insn, record any known
 	 equivalences due to the condition being tested.  */
-      insn = BB_END (bb);
+      insn = BB_END (bb)->as_an_rtx_base_insn ();
       if (path_entry < path_size - 1
 	  && JUMP_P (insn)
 	  && single_set (insn)
diff --git a/gcc/dce.c b/gcc/dce.c
index 5c11cbe..42c2c27 100644
--- a/gcc/dce.c
+++ b/gcc/dce.c
@@ -509,7 +509,7 @@ static void
 reset_unmarked_insns_debug_uses (void)
 {
   basic_block bb;
-  rtx insn, next;
+  rtx_base_insn insn, next;
 
   FOR_EACH_BB_REVERSE (bb)
     FOR_BB_INSNS_REVERSE_SAFE (bb, insn, next)
@@ -547,7 +547,7 @@ static void
 delete_unmarked_insns (void)
 {
   basic_block bb;
-  rtx insn, next;
+  rtx_base_insn insn, next;
   bool must_clean = false;
 
   FOR_EACH_BB_REVERSE (bb)
@@ -614,7 +614,7 @@ static void
 prescan_insns_for_dce (bool fast)
 {
   basic_block bb;
-  rtx insn, prev;
+  rtx_base_insn insn, prev;
   bitmap arg_stores = NULL;
 
   if (dump_file)
diff --git a/gcc/df-core.c b/gcc/df-core.c
index 37876af..49d7e00 100644
--- a/gcc/df-core.c
+++ b/gcc/df-core.c
@@ -1789,7 +1789,7 @@ df_set_clean_cfg (void)
 df_ref
 df_bb_regno_first_def_find (basic_block bb, unsigned int regno)
 {
-  rtx insn;
+  rtx_base_insn insn;
   df_ref *def_rec;
   unsigned int uid;
 
@@ -1815,7 +1815,7 @@ df_bb_regno_first_def_find (basic_block bb, unsigned int regno)
 df_ref
 df_bb_regno_last_def_find (basic_block bb, unsigned int regno)
 {
-  rtx insn;
+  rtx_base_insn insn;
   df_ref *def_rec;
   unsigned int uid;
 
diff --git a/gcc/df-problems.c b/gcc/df-problems.c
index c6349c8..48ef85e 100644
--- a/gcc/df-problems.c
+++ b/gcc/df-problems.c
@@ -355,7 +355,7 @@ df_rd_bb_local_compute (unsigned int bb_index)
 {
   basic_block bb = BASIC_BLOCK (bb_index);
   struct df_rd_bb_info *bb_info = df_rd_get_bb_info (bb_index);
-  rtx insn;
+  rtx_base_insn insn;
 
   bitmap_clear (&seen_in_block);
   bitmap_clear (&seen_in_insn);
@@ -837,7 +837,7 @@ df_lr_bb_local_compute (unsigned int bb_index)
 {
   basic_block bb = BASIC_BLOCK (bb_index);
   struct df_lr_bb_info *bb_info = df_lr_get_bb_info (bb_index);
-  rtx insn;
+  rtx_base_insn insn;
   df_ref *def_rec;
   df_ref *use_rec;
 
@@ -1464,7 +1464,7 @@ df_live_bb_local_compute (unsigned int bb_index)
 {
   basic_block bb = BASIC_BLOCK (bb_index);
   struct df_live_bb_info *bb_info = df_live_get_bb_info (bb_index);
-  rtx insn;
+  rtx_base_insn insn;
   df_ref *def_rec;
   int luid = 0;
 
@@ -1984,7 +1984,7 @@ df_chain_remove_problem (void)
 
   EXECUTE_IF_SET_IN_BITMAP (df_chain->out_of_date_transfer_functions, 0, bb_index, bi)
     {
-      rtx insn;
+      rtx_base_insn insn;
       df_ref *def_rec;
       df_ref *use_rec;
       basic_block bb = BASIC_BLOCK (bb_index);
@@ -2107,7 +2107,7 @@ df_chain_create_bb (unsigned int bb_index)
 {
   basic_block bb = BASIC_BLOCK (bb_index);
   struct df_rd_bb_info *bb_info = df_rd_get_bb_info (bb_index);
-  rtx insn;
+  rtx_base_insn insn;
   bitmap_head cpy;
 
   bitmap_initialize (&cpy, &bitmap_default_obstack);
@@ -2533,7 +2533,7 @@ df_word_lr_bb_local_compute (unsigned int bb_index)
 {
   basic_block bb = BASIC_BLOCK (bb_index);
   struct df_word_lr_bb_info *bb_info = df_word_lr_get_bb_info (bb_index);
-  rtx insn;
+  rtx_base_insn insn;
   df_ref *def_rec;
   df_ref *use_rec;
 
@@ -3155,7 +3155,7 @@ df_note_bb_compute (unsigned int bb_index,
 		    bitmap live, bitmap do_not_gen, bitmap artificial_uses)
 {
   basic_block bb = BASIC_BLOCK (bb_index);
-  rtx insn;
+  rtx_base_insn insn;
   df_ref *def_rec;
   df_ref *use_rec;
   struct dead_debug_local debug;
@@ -4273,7 +4273,7 @@ df_md_bb_local_compute (unsigned int bb_index)
 {
   basic_block bb = BASIC_BLOCK (bb_index);
   struct df_md_bb_info *bb_info = df_md_get_bb_info (bb_index);
-  rtx insn;
+  rtx_base_insn insn;
 
   /* Artificials are only hard regs.  */
   if (!(df->changeable_flags & DF_NO_HARD_REGS))
diff --git a/gcc/df-scan.c b/gcc/df-scan.c
index eb7e4d4..5119177 100644
--- a/gcc/df-scan.c
+++ b/gcc/df-scan.c
@@ -283,7 +283,7 @@ df_scan_free_bb_info (basic_block bb, void *vbb_info)
   /* See if bb_info is initialized.  */
   if (bb_info->artificial_defs)
     {
-      rtx insn;
+      rtx_base_insn insn;
       FOR_BB_INSNS (bb, insn)
 	{
 	  if (INSN_P (insn))
@@ -403,7 +403,7 @@ df_scan_start_dump (FILE *file ATTRIBUTE_UNUSED)
   int icount = 0;
   int ccount = 0;
   basic_block bb;
-  rtx insn;
+  rtx_base_insn insn;
 
   fprintf (file, ";;  invalidated by call \t");
   df_print_regset (file, regs_invalidated_by_call_regset);
@@ -482,7 +482,7 @@ df_scan_start_block (basic_block bb, FILE *file)
     }
 #if 0
   {
-    rtx insn;
+    rtx_base_insn insn;
     FOR_BB_INSNS (bb, insn)
       if (INSN_P (insn))
 	df_insn_debug (insn, false, file);
@@ -1417,7 +1417,7 @@ df_insn_rescan_all (void)
 
   FOR_EACH_BB (bb)
     {
-      rtx insn;
+      rtx_base_insn insn;
       FOR_BB_INSNS (bb, insn)
 	{
 	  df_insn_rescan (insn);
@@ -1638,7 +1638,7 @@ df_reorganize_refs_by_reg_by_insn (struct df_ref_info *ref_info,
   EXECUTE_IF_SET_IN_BITMAP (df->blocks_to_analyze, 0, bb_index, bi)
     {
       basic_block bb = BASIC_BLOCK (bb_index);
-      rtx insn;
+      rtx_base_insn insn;
       df_ref *ref_rec;
 
       if (include_defs)
@@ -1692,7 +1692,7 @@ df_reorganize_refs_by_reg_by_insn (struct df_ref_info *ref_info,
   EXECUTE_IF_SET_IN_BITMAP (df->blocks_to_analyze, 0, bb_index, bi)
     {
       basic_block bb = BASIC_BLOCK (bb_index);
-      rtx insn;
+      rtx_base_insn insn;
       df_ref *ref_rec;
 
       if (include_defs)
@@ -1827,7 +1827,7 @@ df_reorganize_refs_by_insn_bb (basic_block bb, unsigned int offset,
 			       bool include_defs, bool include_uses,
 			       bool include_eq_uses)
 {
-  rtx insn;
+  rtx_base_insn insn;
 
   if (include_defs)
     offset = df_add_refs_to_table (offset, ref_info,
@@ -3523,7 +3523,7 @@ df_insn_refs_collect (struct df_collection_rec *collection_rec,
 void
 df_recompute_luids (basic_block bb)
 {
-  rtx insn;
+  rtx_base_insn insn;
   int luid = 0;
 
   df_grow_insn_info ();
@@ -3617,7 +3617,7 @@ void
 df_bb_refs_record (int bb_index, bool scan_insns)
 {
   basic_block bb = BASIC_BLOCK (bb_index);
-  rtx insn;
+  rtx_base_insn insn;
   int luid = 0;
 
   if (!df)
@@ -4150,7 +4150,7 @@ df_update_entry_exit_and_calls (void)
      in the set of registers clobbered across the call.  */
   FOR_EACH_BB (bb)
     {
-      rtx insn;
+      rtx_base_insn insn;
       FOR_BB_INSNS (bb, insn)
 	{
 	  if (INSN_P (insn) && CALL_P (insn))
@@ -4421,7 +4421,7 @@ df_insn_refs_verify (struct df_collection_rec *collection_rec,
 static bool
 df_bb_verify (basic_block bb)
 {
-  rtx insn;
+  rtx_base_insn insn;
   struct df_scan_bb_info *bb_info = df_scan_get_bb_info (bb->index);
   struct df_collection_rec collection_rec;
 
diff --git a/gcc/dse.c b/gcc/dse.c
index 2d8ce1e..0b68a36 100644
--- a/gcc/dse.c
+++ b/gcc/dse.c
@@ -2725,7 +2725,7 @@ dse_step1 (void)
 
       if (bb->index >= NUM_FIXED_BLOCKS)
 	{
-	  rtx insn;
+	  rtx_base_insn insn;
 
 	  cse_store_info_pool
 	    = create_alloc_pool ("cse_store_info_pool",
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
index b850aa5..9819905 100644
--- a/gcc/emit-rtl.c
+++ b/gcc/emit-rtl.c
@@ -3645,12 +3645,12 @@ try_split (rtx pat, rtx trial, int last)
 /* Make and return an INSN rtx, initializing all its slots.
    Store PATTERN in the pattern slots.  */
 
-rtx
+rtx_base_insn
 make_insn_raw (rtx pattern)
 {
-  rtx insn;
+  rtx_base_insn insn;
 
-  insn = rtx_alloc (INSN);
+  insn = rtx_alloc (INSN)->as_an_rtx_base_insn ();
 
   INSN_UID (insn) = cur_insn_uid++;
   PATTERN (insn) = pattern;
@@ -3676,12 +3676,12 @@ make_insn_raw (rtx pattern)
 
 /* Like `make_insn_raw' but make a DEBUG_INSN instead of an insn.  */
 
-static rtx
+static rtx_base_insn
 make_debug_insn_raw (rtx pattern)
 {
-  rtx insn;
+  rtx_debug_insn insn;
 
-  insn = rtx_alloc (DEBUG_INSN);
+  insn = rtx_alloc (DEBUG_INSN)->as_an_rtx_debug_insn ();
   INSN_UID (insn) = cur_debug_insn_uid++;
   if (cur_debug_insn_uid > MIN_NONDEBUG_INSN_UID)
     INSN_UID (insn) = cur_insn_uid++;
@@ -3697,7 +3697,7 @@ make_debug_insn_raw (rtx pattern)
 
 /* Like `make_insn_raw' but make a JUMP_INSN instead of an insn.  */
 
-static rtx
+static rtx_base_insn
 make_jump_insn_raw (rtx pattern)
 {
   rtx_jump_insn insn;
@@ -3717,12 +3717,12 @@ make_jump_insn_raw (rtx pattern)
 
 /* Like `make_insn_raw' but make a CALL_INSN instead of an insn.  */
 
-static rtx
+static rtx_base_insn
 make_call_insn_raw (rtx pattern)
 {
-  rtx insn;
+  rtx_call_insn insn;
 
-  insn = rtx_alloc (CALL_INSN);
+  insn = rtx_alloc (CALL_INSN)->as_an_rtx_call_insn ();
   INSN_UID (insn) = cur_insn_uid++;
 
   PATTERN (insn) = pattern;
@@ -3760,29 +3760,30 @@ make_note_raw (enum insn_note subtype)
 static inline void
 link_insn_into_chain (rtx insn, rtx prev, rtx next)
 {
-  PREV_INSN (insn) = prev;
-  NEXT_INSN (insn) = next;
+  insn->set_prev_insn (prev);
+  insn->set_next_insn (next);
   if (prev != NULL)
     {
-      NEXT_INSN (prev) = insn;
+      prev->set_next_insn (insn);
       if (NONJUMP_INSN_P (prev) && GET_CODE (PATTERN (prev)) == SEQUENCE)
 	{
 	  rtx sequence = PATTERN (prev);
-	  NEXT_INSN (XVECEXP (sequence, 0, XVECLEN (sequence, 0) - 1)) = insn;
+	  XVECEXP (sequence, 0,
+		   XVECLEN (sequence, 0) - 1)->set_next_insn (insn);
 	}
     }
   if (next != NULL)
     {
-      PREV_INSN (next) = insn;
+      next->set_prev_insn (insn);
       if (NONJUMP_INSN_P (next) && GET_CODE (PATTERN (next)) == SEQUENCE)
-	PREV_INSN (XVECEXP (PATTERN (next), 0, 0)) = insn;
+	XVECEXP (PATTERN (next), 0, 0)->set_prev_insn (insn);
     }
 
   if (NONJUMP_INSN_P (insn) && GET_CODE (PATTERN (insn)) == SEQUENCE)
     {
       rtx sequence = PATTERN (insn);
-      PREV_INSN (XVECEXP (sequence, 0, 0)) = prev;
-      NEXT_INSN (XVECEXP (sequence, 0, XVECLEN (sequence, 0) - 1)) = next;
+      XVECEXP (sequence, 0, 0)->set_prev_insn (prev);
+      XVECEXP (sequence, 0, XVECLEN (sequence, 0) - 1)->set_next_insn (next);
     }
 }
 
@@ -3948,23 +3949,24 @@ set_insn_deleted (rtx insn)
 void
 remove_insn (rtx insn)
 {
-  rtx next = NEXT_INSN (insn);
-  rtx prev = PREV_INSN (insn);
+  rtx_base_insn next = NEXT_INSN (insn);
+  rtx_base_insn prev = PREV_INSN (insn);
   basic_block bb;
 
   if (prev)
     {
-      NEXT_INSN (prev) = next;
+      prev->set_next_insn (next);
       if (NONJUMP_INSN_P (prev) && GET_CODE (PATTERN (prev)) == SEQUENCE)
 	{
 	  rtx sequence = PATTERN (prev);
-	  NEXT_INSN (XVECEXP (sequence, 0, XVECLEN (sequence, 0) - 1)) = next;
+	  XVECEXP (sequence, 0,
+		   XVECLEN (sequence, 0) - 1)->set_next_insn (next);
 	}
     }
   else if (get_insns () == insn)
     {
       if (next)
-        PREV_INSN (next) = NULL;
+        next->set_prev_insn (NULL);
       set_first_insn (next);
     }
   else
@@ -3983,9 +3985,9 @@ remove_insn (rtx insn)
 
   if (next)
     {
-      PREV_INSN (next) = prev;
+      next->set_prev_insn (prev);
       if (NONJUMP_INSN_P (next) && GET_CODE (PATTERN (next)) == SEQUENCE)
-	PREV_INSN (XVECEXP (PATTERN (next), 0, 0)) = prev;
+	XVECEXP (PATTERN (next), 0, 0)->set_prev_insn (prev);
     }
   else if (get_last_insn () == insn)
     set_last_insn (prev);
@@ -4051,7 +4053,7 @@ delete_insns_since (rtx from)
   if (from == 0)
     set_first_insn (0);
   else
-    NEXT_INSN (from) = 0;
+    from->set_next_insn (0);
   set_last_insn (from);
 }
 
@@ -4077,9 +4079,9 @@ reorder_insns_nobb (rtx from, rtx to, rtx after)
 
   /* Splice this bunch out of where it is now.  */
   if (PREV_INSN (from))
-    NEXT_INSN (PREV_INSN (from)) = NEXT_INSN (to);
+    PREV_INSN (from)->set_next_insn (NEXT_INSN (to));
   if (NEXT_INSN (to))
-    PREV_INSN (NEXT_INSN (to)) = PREV_INSN (from);
+    NEXT_INSN (to)->set_prev_insn (PREV_INSN (from));
   if (get_last_insn () == to)
     set_last_insn (PREV_INSN (from));
   if (get_insns () == from)
@@ -4087,11 +4089,11 @@ reorder_insns_nobb (rtx from, rtx to, rtx after)
 
   /* Make the new neighbors point to it and it to them.  */
   if (NEXT_INSN (after))
-    PREV_INSN (NEXT_INSN (after)) = to;
+    NEXT_INSN (after)->set_prev_insn (to);
 
-  NEXT_INSN (to) = NEXT_INSN (after);
-  PREV_INSN (from) = after;
-  NEXT_INSN (after) = from;
+  to->set_next_insn (NEXT_INSN (after));
+  from->set_prev_insn (after);
+  after->set_next_insn (from);
   if (after == get_last_insn ())
     set_last_insn (to);
 }
@@ -4154,16 +4156,16 @@ reorder_insns (rtx from, rtx to, rtx after)
    SEQUENCE rtl results in much fragmented RTL memory since the SEQUENCE
    generated would almost certainly die right after it was created.  */
 
-static rtx
+static rtx_base_insn
 emit_pattern_before_noloc (rtx x, rtx before, rtx last, basic_block bb,
-                           rtx (*make_raw) (rtx))
+                           rtx_base_insn (*make_raw) (rtx))
 {
-  rtx insn;
+  rtx_base_insn insn;
 
   gcc_assert (before);
 
   if (x == NULL_RTX)
-    return last;
+    return last->as_an_rtx_base_insn ();
 
   switch (GET_CODE (x))
     {
@@ -4174,10 +4176,10 @@ emit_pattern_before_noloc (rtx x, rtx before, rtx last, basic_block bb,
     case CODE_LABEL:
     case BARRIER:
     case NOTE:
-      insn = x;
+      insn = x->as_an_rtx_base_insn ();
       while (insn)
 	{
-	  rtx next = NEXT_INSN (insn);
+	  rtx_base_insn next = NEXT_INSN (insn);
 	  add_insn_before (insn, before, bb);
 	  last = insn;
 	  insn = next;
@@ -4196,12 +4198,12 @@ emit_pattern_before_noloc (rtx x, rtx before, rtx last, basic_block bb,
       break;
     }
 
-  return last;
+  return last->as_an_rtx_base_insn ();
 }
 
 /* Make X be output before the instruction BEFORE.  */
 
-rtx
+rtx_base_insn
 emit_insn_before_noloc (rtx x, rtx before, basic_block bb)
 {
   return emit_pattern_before_noloc (x, before, before, bb, make_insn_raw);
@@ -4266,10 +4268,10 @@ emit_label_before (rtx label, rtx before)
 /* Helper for emit_insn_after, handles lists of instructions
    efficiently.  */
 
-static rtx
+static rtx_base_insn
 emit_insn_after_1 (rtx first, rtx after, basic_block bb)
 {
-  rtx last;
+  rtx_base_insn last;
   rtx after_after;
   if (!bb && !BARRIER_P (after))
     bb = BLOCK_FOR_INSN (after);
@@ -4277,7 +4279,9 @@ emit_insn_after_1 (rtx first, rtx after, basic_block bb)
   if (bb)
     {
       df_set_bb_dirty (bb);
-      for (last = first; NEXT_INSN (last); last = NEXT_INSN (last))
+      for (last = first->as_an_rtx_base_insn ();
+	   NEXT_INSN (last);
+	   last = NEXT_INSN (last)->as_an_rtx_base_insn ())
 	if (!BARRIER_P (last))
 	  {
 	    set_block_for_insn (last, bb);
@@ -4292,16 +4296,18 @@ emit_insn_after_1 (rtx first, rtx after, basic_block bb)
 	BB_END (bb) = last;
     }
   else
-    for (last = first; NEXT_INSN (last); last = NEXT_INSN (last))
+    for (last = first->as_an_rtx_base_insn ();
+	 NEXT_INSN (last);
+	 last = NEXT_INSN (last)->as_an_rtx_base_insn ())
       continue;
 
   after_after = NEXT_INSN (after);
 
-  NEXT_INSN (after) = first;
-  PREV_INSN (first) = after;
-  NEXT_INSN (last) = after_after;
+  after->set_next_insn (first);
+  first->set_prev_insn (after);
+  last->set_next_insn (after_after);
   if (after_after)
-    PREV_INSN (after_after) = last;
+    after_after->set_prev_insn (last);
 
   if (after == get_last_insn ())
     set_last_insn (last);
@@ -4309,11 +4315,11 @@ emit_insn_after_1 (rtx first, rtx after, basic_block bb)
   return last;
 }
 
-static rtx
+static rtx_base_insn
 emit_pattern_after_noloc (rtx x, rtx after, basic_block bb,
-			  rtx (*make_raw)(rtx))
+			  rtx_base_insn (*make_raw)(rtx))
 {
-  rtx last = after;
+  rtx_base_insn last = after->as_an_rtx_base_insn ();
 
   gcc_assert (after);
 
@@ -4350,7 +4356,7 @@ emit_pattern_after_noloc (rtx x, rtx after, basic_block bb,
 /* Make X be output after the insn AFTER and set the BB of insn.  If
    BB is NULL, an attempt is made to infer the BB from AFTER.  */
 
-rtx
+rtx_base_insn
 emit_insn_after_noloc (rtx x, rtx after, basic_block bb)
 {
   return emit_pattern_after_noloc (x, after, bb, make_insn_raw);
@@ -4477,11 +4483,12 @@ emit_note_before (enum insn_note subtype, rtx before)
 /* Insert PATTERN after AFTER, setting its INSN_LOCATION to LOC.
    MAKE_RAW indicates how to turn PATTERN into a real insn.  */
 
-static rtx
+static rtx_base_insn
 emit_pattern_after_setloc (rtx pattern, rtx after, int loc,
-			   rtx (*make_raw) (rtx))
+			   rtx_base_insn (*make_raw) (rtx))
 {
-  rtx last = emit_pattern_after_noloc (pattern, after, NULL, make_raw);
+  rtx_base_insn last =
+    emit_pattern_after_noloc (pattern, after, NULL, make_raw);
 
   if (pattern == NULL_RTX || !loc)
     return last;
@@ -4502,9 +4509,9 @@ emit_pattern_after_setloc (rtx pattern, rtx after, int loc,
    into a real insn.  SKIP_DEBUG_INSNS indicates whether to insert after
    any DEBUG_INSNs.  */
 
-static rtx
+static rtx_base_insn
 emit_pattern_after (rtx pattern, rtx after, bool skip_debug_insns,
-		    rtx (*make_raw) (rtx))
+		    rtx_base_insn (*make_raw) (rtx))
 {
   rtx prev = after;
 
@@ -4520,14 +4527,14 @@ emit_pattern_after (rtx pattern, rtx after, bool skip_debug_insns,
 }
 
 /* Like emit_insn_after_noloc, but set INSN_LOCATION according to LOC.  */
-rtx
+rtx_base_insn
 emit_insn_after_setloc (rtx pattern, rtx after, int loc)
 {
   return emit_pattern_after_setloc (pattern, after, loc, make_insn_raw);
 }
 
 /* Like emit_insn_after_noloc, but set INSN_LOCATION according to AFTER.  */
-rtx
+rtx_base_insn
 emit_insn_after (rtx pattern, rtx after)
 {
   return emit_pattern_after (pattern, after, true, make_insn_raw);
@@ -4582,14 +4589,15 @@ emit_debug_insn_after (rtx pattern, rtx after)
    indicates if PATTERN is meant for an INSN as opposed to a JUMP_INSN,
    CALL_INSN, etc.  */
 
-static rtx
+static rtx_base_insn
 emit_pattern_before_setloc (rtx pattern, rtx before, int loc, bool insnp,
-			    rtx (*make_raw) (rtx))
+			    rtx_base_insn (*make_raw) (rtx))
 {
   rtx first = PREV_INSN (before);
-  rtx last = emit_pattern_before_noloc (pattern, before,
-                                        insnp ? before : NULL_RTX,
-                                        NULL, make_raw);
+  rtx_base_insn last =
+    emit_pattern_before_noloc (pattern, before,
+			       insnp ? before : NULL_RTX,
+			       NULL, make_raw);
 
   if (pattern == NULL_RTX || !loc)
     return last;
@@ -4614,9 +4622,9 @@ emit_pattern_before_setloc (rtx pattern, rtx before, int loc, bool insnp,
    before any DEBUG_INSNs.  INSNP indicates if PATTERN is meant for an
    INSN as opposed to a JUMP_INSN, CALL_INSN, etc.  */
 
-static rtx
+static rtx_base_insn
 emit_pattern_before (rtx pattern, rtx before, bool skip_debug_insns,
-		     bool insnp, rtx (*make_raw) (rtx))
+		     bool insnp, rtx_base_insn (*make_raw) (rtx))
 {
   rtx next = before;
 
@@ -4634,7 +4642,7 @@ emit_pattern_before (rtx pattern, rtx before, bool skip_debug_insns,
 }
 
 /* Like emit_insn_before_noloc, but set INSN_LOCATION according to LOC.  */
-rtx
+rtx_base_insn
 emit_insn_before_setloc (rtx pattern, rtx before, int loc)
 {
   return emit_pattern_before_setloc (pattern, before, loc, true,
@@ -4642,7 +4650,7 @@ emit_insn_before_setloc (rtx pattern, rtx before, int loc)
 }
 
 /* Like emit_insn_before_noloc, but set INSN_LOCATION according to BEFORE.  */
-rtx
+rtx_base_insn
 emit_insn_before (rtx pattern, rtx before)
 {
   return emit_pattern_before (pattern, before, true, true, make_insn_raw);
@@ -4704,11 +4712,11 @@ emit_debug_insn_before (rtx pattern, rtx before)
 
    Returns the last insn emitted.  */
 
-rtx
+rtx_base_insn
 emit_insn (rtx x)
 {
-  rtx last = get_last_insn ();
-  rtx insn;
+  rtx_base_insn last = get_last_insn ();
+  rtx_base_insn insn;
 
   if (x == NULL_RTX)
     return last;
@@ -4722,10 +4730,10 @@ emit_insn (rtx x)
     case CODE_LABEL:
     case BARRIER:
     case NOTE:
-      insn = x;
+      insn = x->as_an_rtx_base_insn ();
       while (insn)
 	{
-	  rtx next = NEXT_INSN (insn);
+	  rtx_base_insn next = NEXT_INSN (insn);
 	  add_insn (insn);
 	  last = insn;
 	  insn = next;
diff --git a/gcc/emit-rtl.h b/gcc/emit-rtl.h
index 301c67b..ff8e775 100644
--- a/gcc/emit-rtl.h
+++ b/gcc/emit-rtl.h
@@ -74,10 +74,14 @@ extern bool need_atomic_barrier_p (enum memmodel, bool);
 
 /* Return the first insn of the current sequence or current function.  */
 
-static inline rtx
+static inline rtx_base_insn
 get_insns (void)
 {
-  return crtl->emit.x_first_insn;
+  rtx tmp = crtl->emit.x_first_insn;
+  if (tmp)
+    return tmp->as_an_rtx_base_insn ();
+  else
+    return NULL;
 }
 
 /* Specify a new insn as the first in the chain.  */
@@ -91,10 +95,14 @@ set_first_insn (rtx insn)
 
 /* Return the last insn emitted in current sequence or current function.  */
 
-static inline rtx
+static inline rtx_base_insn
 get_last_insn (void)
 {
-  return crtl->emit.x_last_insn;
+  rtx tmp = crtl->emit.x_last_insn;
+  if (tmp)
+    return tmp->as_an_rtx_base_insn ();
+  else
+    return NULL;
 }
 
 /* Specify a new insn as the last in the chain.  */
diff --git a/gcc/expr.c b/gcc/expr.c
index 5fb46b7..a0f0098 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -148,7 +148,7 @@ static void store_by_pieces_1 (struct store_by_pieces_d *, unsigned int);
 static void store_by_pieces_2 (insn_gen_fn, machine_mode,
 			       struct store_by_pieces_d *);
 static tree clear_storage_libcall_fn (int);
-static rtx compress_float_constant (rtx, rtx);
+static rtx_base_insn compress_float_constant (rtx, rtx);
 static rtx get_subtarget (rtx);
 static void store_constructor_field (rtx, unsigned HOST_WIDE_INT,
 				     HOST_WIDE_INT, enum machine_mode,
@@ -3194,7 +3194,7 @@ emit_move_change_mode (enum machine_mode new_mode,
    an integer mode of the same size as MODE.  Returns the instruction
    emitted, or NULL if such a move could not be generated.  */
 
-static rtx
+static rtx_base_insn
 emit_move_via_integer (enum machine_mode mode, rtx x, rtx y, bool force)
 {
   enum machine_mode imode;
@@ -3203,19 +3203,19 @@ emit_move_via_integer (enum machine_mode mode, rtx x, rtx y, bool force)
   /* There must exist a mode of the exact size we require.  */
   imode = int_mode_for_mode (mode);
   if (imode == BLKmode)
-    return NULL_RTX;
+    return NULL_RTX_BASE_INSN;
 
   /* The target must support moves in this mode.  */
   code = optab_handler (mov_optab, imode);
   if (code == CODE_FOR_nothing)
-    return NULL_RTX;
+    return NULL_RTX_BASE_INSN;
 
   x = emit_move_change_mode (imode, mode, x, force);
   if (x == NULL_RTX)
-    return NULL_RTX;
+    return NULL_RTX_BASE_INSN;
   y = emit_move_change_mode (imode, mode, y, force);
   if (y == NULL_RTX)
-    return NULL_RTX;
+    return NULL_RTX_BASE_INSN;
   return emit_insn (GEN_FCN (code) (x, y));
 }
 
@@ -3280,7 +3280,7 @@ emit_move_resolve_push (enum machine_mode mode, rtx x)
    X is known to satisfy push_operand, and MODE is known to be complex.
    Returns the last instruction emitted.  */
 
-rtx
+rtx_base_insn
 emit_move_complex_push (enum machine_mode mode, rtx x, rtx y)
 {
   enum machine_mode submode = GET_MODE_INNER (mode);
@@ -3323,7 +3323,7 @@ emit_move_complex_push (enum machine_mode mode, rtx x, rtx y)
 /* A subroutine of emit_move_complex.  Perform the move from Y to X
    via two moves of the parts.  Returns the last instruction emitted.  */
 
-rtx
+rtx_base_insn
 emit_move_complex_parts (rtx x, rtx y)
 {
   /* Show the output dies here.  This is necessary for SUBREGs
@@ -3342,7 +3342,7 @@ emit_move_complex_parts (rtx x, rtx y)
 /* A subroutine of emit_move_insn_1.  Generate a move from Y into X.
    MODE is known to be complex.  Returns the last instruction emitted.  */
 
-static rtx
+static rtx_base_insn
 emit_move_complex (enum machine_mode mode, rtx x, rtx y)
 {
   bool try_int;
@@ -3382,7 +3382,7 @@ emit_move_complex (enum machine_mode mode, rtx x, rtx y)
 
   if (try_int)
     {
-      rtx ret;
+      rtx_base_insn ret;
 
       /* For memory to memory moves, optimal behavior can be had with the
 	 existing block move logic.  */
@@ -3404,10 +3404,10 @@ emit_move_complex (enum machine_mode mode, rtx x, rtx y)
 /* A subroutine of emit_move_insn_1.  Generate a move from Y into X.
    MODE is known to be MODE_CC.  Returns the last instruction emitted.  */
 
-static rtx
+static rtx_base_insn
 emit_move_ccmode (enum machine_mode mode, rtx x, rtx y)
 {
-  rtx ret;
+  rtx_base_insn ret;
 
   /* Assume all MODE_CC modes are equivalent; if we have movcc, use it.  */
   if (mode != CCmode)
@@ -3464,10 +3464,10 @@ undefined_operand_subword_p (const_rtx op, int i)
    pattern.  Note that you will get better code if you define such
    patterns, even if they must turn into multiple assembler instructions.  */
 
-static rtx
+static rtx_base_insn
 emit_move_multi_word (enum machine_mode mode, rtx x, rtx y)
 {
-  rtx last_insn = 0;
+  rtx_base_insn last_insn = 0;
   rtx seq, inner;
   bool need_clobber;
   int i;
@@ -3544,7 +3544,7 @@ emit_move_multi_word (enum machine_mode mode, rtx x, rtx y)
    Called just like emit_move_insn, but assumes X and Y
    are basically valid.  */
 
-rtx
+rtx_base_insn
 emit_move_insn_1 (rtx x, rtx y)
 {
   enum machine_mode mode = GET_MODE (x);
@@ -3563,7 +3563,7 @@ emit_move_insn_1 (rtx x, rtx y)
   if (GET_MODE_CLASS (mode) == MODE_DECIMAL_FLOAT
       || ALL_FIXED_POINT_MODE_P (mode))
     {
-      rtx result = emit_move_via_integer (mode, x, y, true);
+      rtx_base_insn result = emit_move_via_integer (mode, x, y, true);
 
       /* If we can't find an integer mode, use multi words.  */
       if (result)
@@ -3581,7 +3581,7 @@ emit_move_insn_1 (rtx x, rtx y)
      fits within a HOST_WIDE_INT.  */
   if (!CONSTANT_P (y) || GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
     {
-      rtx ret = emit_move_via_integer (mode, x, y, lra_in_progress);
+      rtx_base_insn ret = emit_move_via_integer (mode, x, y, lra_in_progress);
 
       if (ret)
 	{
@@ -3600,12 +3600,13 @@ emit_move_insn_1 (rtx x, rtx y)
 
    Return the last instruction emitted.  */
 
-rtx
+rtx_base_insn
 emit_move_insn (rtx x, rtx y)
 {
   enum machine_mode mode = GET_MODE (x);
   rtx y_cst = NULL_RTX;
-  rtx last_insn, set;
+  rtx_base_insn last_insn;
+  rtx set;
 
   gcc_assert (mode != BLKmode
 	      && (GET_MODE (y) == mode || GET_MODE (y) == VOIDmode));
@@ -3663,7 +3664,7 @@ emit_move_insn (rtx x, rtx y)
    perform the extension directly from constant or memory, then emit the
    move as an extension.  */
 
-static rtx
+static rtx_base_insn
 compress_float_constant (rtx x, rtx y)
 {
   enum machine_mode dstmode = GET_MODE (x);
@@ -3685,7 +3686,8 @@ compress_float_constant (rtx x, rtx y)
        srcmode = GET_MODE_WIDER_MODE (srcmode))
     {
       enum insn_code ic;
-      rtx trunc_y, last_insn;
+      rtx trunc_y;
+      rtx_base_insn last_insn;
 
       /* Skip if the target can't extend this way.  */
       ic = can_extend_p (dstmode, srcmode, 0);
@@ -3736,7 +3738,7 @@ compress_float_constant (rtx x, rtx y)
       return last_insn;
     }
 
-  return NULL_RTX;
+  return NULL_RTX_BASE_INSN;
 }
 
 /* Pushing data onto the stack.  */
diff --git a/gcc/expr.h b/gcc/expr.h
index f4b4bd1..b625127 100644
--- a/gcc/expr.h
+++ b/gcc/expr.h
@@ -405,13 +405,13 @@ extern rtx store_by_pieces (rtx, unsigned HOST_WIDE_INT,
 			    void *, unsigned int, bool, int);
 
 /* Emit insns to set X from Y.  */
-extern rtx emit_move_insn (rtx, rtx);
+extern rtx_base_insn emit_move_insn (rtx, rtx);
 
 /* Emit insns to set X from Y, with no frills.  */
-extern rtx emit_move_insn_1 (rtx, rtx);
+extern rtx_base_insn emit_move_insn_1 (rtx, rtx);
 
-extern rtx emit_move_complex_push (enum machine_mode, rtx, rtx);
-extern rtx emit_move_complex_parts (rtx, rtx);
+extern rtx_base_insn emit_move_complex_push (enum machine_mode, rtx, rtx);
+extern rtx_base_insn emit_move_complex_parts (rtx, rtx);
 
 /* Push a block of length SIZE (perhaps variable)
    and return an rtx to address the beginning of the block.  */
diff --git a/gcc/final.c b/gcc/final.c
index bc4972c..ba4f6ea 100644
--- a/gcc/final.c
+++ b/gcc/final.c
@@ -2854,7 +2854,7 @@ final_scan_insn (rtx insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED,
 	       emit them before the peephole.  */
 	    if (next != 0 && next != NEXT_INSN (insn))
 	      {
-		rtx note, prev = PREV_INSN (insn);
+		rtx_base_insn note, prev = PREV_INSN (insn);
 
 		for (note = NEXT_INSN (insn); note != next;
 		     note = NEXT_INSN (note))
@@ -2865,12 +2865,12 @@ final_scan_insn (rtx insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED,
 		   when generating a far jump in a delayed branch
 		   sequence.  */
 		note = NEXT_INSN (insn);
-		PREV_INSN (note) = prev;
-		NEXT_INSN (prev) = note;
-		NEXT_INSN (PREV_INSN (next)) = insn;
-		PREV_INSN (insn) = PREV_INSN (next);
-		NEXT_INSN (insn) = next;
-		PREV_INSN (next) = insn;
+		note->set_prev_insn (prev);
+		prev->set_next_insn (note);
+		PREV_INSN (next)->set_next_insn (insn);
+		insn->set_prev_insn (PREV_INSN (next));
+		insn->set_next_insn (next);
+		next->set_prev_insn (insn);
 	      }
 
 	    /* PEEPHOLE might have changed this.  */
@@ -4615,8 +4615,8 @@ rest_of_clean_state (void)
   for (insn = get_insns (); insn; insn = next)
     {
       next = NEXT_INSN (insn);
-      NEXT_INSN (insn) = NULL;
-      PREV_INSN (insn) = NULL;
+      insn->set_next_insn (NULL);
+      insn->set_prev_insn (NULL);
 
       if (final_output
 	  && (!NOTE_P (insn) ||
diff --git a/gcc/function.c b/gcc/function.c
index d0f4f37..1d338e5 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -5422,7 +5422,7 @@ next_block_for_reg (basic_block bb, int regno, int end_regno)
    after INSN in BB.  */
 
 static bool
-move_insn_for_shrink_wrap (basic_block bb, rtx insn,
+move_insn_for_shrink_wrap (basic_block bb, rtx_base_insn insn,
 			   const HARD_REG_SET uses,
 			   const HARD_REG_SET defs)
 {
@@ -5546,7 +5546,8 @@ move_insn_for_shrink_wrap (basic_block bb, rtx insn,
 static void
 prepare_shrink_wrap (basic_block entry_block)
 {
-  rtx insn, curr, x;
+  rtx_base_insn insn, curr;
+  rtx x;
   HARD_REG_SET uses, defs;
   df_ref *ref;
 
@@ -6046,7 +6047,7 @@ thread_prologue_and_epilogue_insns (void)
 
       FOR_EACH_BB (bb)
 	{
-	  rtx insn;
+	  rtx_base_insn insn;
 	  unsigned size = 0;
 
 	  FOR_BB_INSNS (bb, insn)
@@ -6754,7 +6755,8 @@ reposition_prologue_and_epilogue_notes (void)
 
       FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds)
 	{
-	  rtx insn, first = NULL, note = NULL;
+	  rtx_base_insn insn;
+	  rtx first = NULL, note = NULL;
 	  basic_block bb = e->src;
 
 	  /* Scan from the beginning until we reach the first epilogue insn. */
@@ -7186,7 +7188,8 @@ static unsigned
 rest_of_match_asm_constraints (void)
 {
   basic_block bb;
-  rtx insn, pat, *p_sets;
+  rtx_base_insn insn;
+  rtx pat, *p_sets;
   int noutputs;
 
   if (!crtl->has_asm_statement)
diff --git a/gcc/fwprop.c b/gcc/fwprop.c
index da40a67..66afa83 100644
--- a/gcc/fwprop.c
+++ b/gcc/fwprop.c
@@ -220,7 +220,7 @@ single_def_use_dom_walker::before_dom_children (basic_block bb)
   int bb_index = bb->index;
   struct df_md_bb_info *md_bb_info = df_md_get_bb_info (bb_index);
   struct df_lr_bb_info *lr_bb_info = df_lr_get_bb_info (bb_index);
-  rtx insn;
+  rtx_base_insn insn;
 
   bitmap_copy (local_md, &md_bb_info->in);
   bitmap_copy (local_lr, &lr_bb_info->in);
diff --git a/gcc/gcse.c b/gcc/gcse.c
index 2c1ca21..f32fcfd 100644
--- a/gcc/gcse.c
+++ b/gcc/gcse.c
@@ -864,7 +864,8 @@ can_assign_to_reg_without_clobbers_p (rtx x)
 				      gen_rtx_REG (word_mode,
 						   FIRST_PSEUDO_REGISTER * 2),
 				      const0_rtx));
-      NEXT_INSN (test_insn) = PREV_INSN (test_insn) = 0;
+      test_insn->set_next_insn (0);
+      test_insn->set_prev_insn (0);
     }
 
   /* Now make an insn like the one we would make when GCSE'ing and see if
@@ -1560,7 +1561,7 @@ compute_hash_table_work (struct hash_table_d *table)
 
   FOR_EACH_BB (current_bb)
     {
-      rtx insn;
+      rtx_base_insn insn;
       unsigned int regno;
 
       /* First pass over the instructions records information used to
@@ -3170,7 +3171,7 @@ hoist_code (void)
 
   FOR_EACH_BB (bb)
     {
-      rtx insn;
+      rtx_base_insn insn;
       int to_head;
 
       to_head = 0;
@@ -3503,7 +3504,7 @@ calculate_bb_reg_pressure (void)
 {
   int i;
   unsigned int j;
-  rtx insn;
+  rtx_base_insn insn;
   basic_block bb;
   bitmap curr_regs_live;
   bitmap_iterator bi;
@@ -3881,7 +3882,7 @@ compute_ld_motion_mems (void)
 {
   struct ls_expr * ptr;
   basic_block bb;
-  rtx insn;
+  rtx_base_insn insn;
 
   pre_ldst_mems = NULL;
   pre_ldst_table.create (13);
diff --git a/gcc/haifa-sched.c b/gcc/haifa-sched.c
index 8337715..9f26b51 100644
--- a/gcc/haifa-sched.c
+++ b/gcc/haifa-sched.c
@@ -1039,7 +1039,7 @@ static void
 initiate_bb_reg_pressure_info (basic_block bb)
 {
   unsigned int i ATTRIBUTE_UNUSED;
-  rtx insn;
+  rtx_base_insn insn;
 
   if (current_nr_blocks > 1)
     FOR_BB_INSNS (bb, insn)
@@ -3970,8 +3970,8 @@ concat_note_lists (rtx from_end, rtx *to_endp)
   while (PREV_INSN (from_start) != NULL)
     from_start = PREV_INSN (from_start);
 
-  PREV_INSN (from_start) = *to_endp;
-  NEXT_INSN (*to_endp) = from_start;
+  from_start->set_prev_insn (*to_endp);
+  (*to_endp)->set_next_insn (from_start);
   *to_endp = from_end;
 }
 
@@ -4012,10 +4012,10 @@ remove_notes (rtx head, rtx tail)
 	  remove_insn (insn);
 
 	  /* Add the note to list that ends at NOTE_LIST.  */
-	  PREV_INSN (insn) = note_list;
-	  NEXT_INSN (insn) = NULL_RTX;
+	  insn->set_prev_insn (note_list);
+	  insn->set_next_insn (NULL_RTX);
 	  if (note_list)
-	    NEXT_INSN (note_list) = insn;
+	    note_list->set_next_insn (insn);
 	  note_list = insn;
 	  break;
 	}
@@ -4805,10 +4805,10 @@ restore_other_notes (rtx head, basic_block head_bb)
       /* In the above cycle we've missed this note.  */
       set_block_for_insn (note_head, head_bb);
 
-      PREV_INSN (note_head) = PREV_INSN (head);
-      NEXT_INSN (PREV_INSN (head)) = note_head;
-      PREV_INSN (head) = note_list;
-      NEXT_INSN (note_list) = head;
+      note_head->set_prev_insn (PREV_INSN (head));
+      PREV_INSN (head)->set_next_insn (note_head);
+      head->set_prev_insn (note_list);
+      note_list->set_next_insn (head);
 
       if (BLOCK_FOR_INSN (head) != head_bb)
 	BB_END (head_bb) = note_list;
@@ -5204,14 +5204,14 @@ move_insn (rtx insn, rtx last, rtx nt)
       else
 	note = insn;
 
-      NEXT_INSN (PREV_INSN (insn)) = NEXT_INSN (note);
-      PREV_INSN (NEXT_INSN (note)) = PREV_INSN (insn);
+      PREV_INSN (insn)->set_next_insn (NEXT_INSN (note));
+      NEXT_INSN (note)->set_prev_insn (PREV_INSN (insn));
 
-      NEXT_INSN (note) = NEXT_INSN (last);
-      PREV_INSN (NEXT_INSN (last)) = note;
+      note->set_next_insn (NEXT_INSN (last));
+      NEXT_INSN (last)->set_prev_insn (note);
 
-      NEXT_INSN (last) = insn;
-      PREV_INSN (insn) = last;
+      last->set_next_insn (insn);
+      insn->set_prev_insn (last);
 
       bb = BLOCK_FOR_INSN (last);
 
@@ -8098,8 +8098,8 @@ unlink_bb_notes (basic_block first, basic_block last)
       next = NEXT_INSN (note);
       gcc_assert (prev && next);
 
-      NEXT_INSN (prev) = next;
-      PREV_INSN (next) = prev;
+      prev->set_next_insn (next);
+      next->set_prev_insn (prev);
 
       bb_header[last->index] = label;
 
@@ -8140,9 +8140,9 @@ restore_bb_notes (basic_block first)
 
       bb_header[first->index] = 0;
 
-      NEXT_INSN (prev) = label;
-      NEXT_INSN (note) = next;
-      PREV_INSN (next) = note;
+      prev->set_next_insn (label);
+      note->set_next_insn (next);
+      next->set_prev_insn (note);
 
       first = first->next_bb;
     }
@@ -8426,7 +8426,7 @@ haifa_init_h_i_d (bb_vec_t bbs)
   extend_h_i_d ();
   FOR_EACH_VEC_ELT (bbs, i, bb)
     {
-      rtx insn;
+      rtx_base_insn insn;
 
       FOR_BB_INSNS (bb, insn)
 	init_h_i_d (insn);
diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c
index ac0276c..ecec98c 100644
--- a/gcc/ifcvt.c
+++ b/gcc/ifcvt.c
@@ -2421,7 +2421,7 @@ noce_can_store_speculate_p (basic_block top_bb, const_rtx mem)
        dominator != NULL;
        dominator = get_immediate_dominator (CDI_POST_DOMINATORS, dominator))
     {
-      rtx insn;
+      rtx_base_insn insn;
 
       FOR_BB_INSNS (dominator, insn)
 	{
@@ -2723,11 +2723,11 @@ check_cond_move_block (basic_block bb,
 		       vec<rtx> *regs,
 		       rtx cond)
 {
-  rtx insn;
+  rtx_base_insn insn;
 
    /* We can only handle simple jumps at the end of the basic block.
       It is almost impossible to update the CFG otherwise.  */
-  insn = BB_END (bb);
+  insn = BB_END (bb)->as_an_rtx_base_insn ();
   if (JUMP_P (insn) && !onlyjump_p (insn))
     return FALSE;
 
@@ -2806,7 +2806,8 @@ cond_move_convert_if_block (struct noce_if_info *if_infop,
 			    bool else_block_p)
 {
   enum rtx_code code;
-  rtx insn, cond_arg0, cond_arg1;
+  rtx_base_insn insn;
+  rtx cond_arg0, cond_arg1;
 
   code = GET_CODE (cond);
   cond_arg0 = XEXP (cond, 0);
@@ -4158,7 +4159,8 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb,
   /* Try the NCE path if the CE path did not result in any changes.  */
   if (n_validated_changes == 0)
     {
-      rtx cond, insn;
+      rtx cond;
+      rtx_base_insn insn;
       regset live;
       bool success;
 
diff --git a/gcc/init-regs.c b/gcc/init-regs.c
index 2a15b3e..b96d1a8 100644
--- a/gcc/init-regs.c
+++ b/gcc/init-regs.c
@@ -61,7 +61,7 @@ initialize_uninitialized_regs (void)
 
   FOR_EACH_BB (bb)
     {
-      rtx insn;
+      rtx_base_insn insn;
       bitmap lr = DF_LR_IN (bb);
       bitmap ur = DF_LIVE_IN (bb);
       bitmap_clear (already_genned);
diff --git a/gcc/ira-build.c b/gcc/ira-build.c
index 09e22d7..e33709b 100644
--- a/gcc/ira-build.c
+++ b/gcc/ira-build.c
@@ -1923,7 +1923,7 @@ static void
 create_bb_allocnos (ira_loop_tree_node_t bb_node)
 {
   basic_block bb;
-  rtx insn;
+  rtx_base_insn insn;
   unsigned int i;
   bitmap_iterator bi;
 
diff --git a/gcc/ira-conflicts.c b/gcc/ira-conflicts.c
index ba0e4e5..0ca7633 100644
--- a/gcc/ira-conflicts.c
+++ b/gcc/ira-conflicts.c
@@ -421,7 +421,7 @@ static void
 add_copies (ira_loop_tree_node_t loop_tree_node)
 {
   basic_block bb;
-  rtx insn;
+  rtx_base_insn insn;
 
   bb = loop_tree_node->bb;
   if (bb == NULL)
diff --git a/gcc/ira-costs.c b/gcc/ira-costs.c
index d7299e6..246ba62 100644
--- a/gcc/ira-costs.c
+++ b/gcc/ira-costs.c
@@ -1289,8 +1289,8 @@ record_operand_costs (rtx insn, enum reg_class *pref)
 /* Process one insn INSN.  Scan it and record each time it would save
    code to put a certain allocnos in a certain class.  Return the last
    insn processed, so that the scan can be continued from there.  */
-static rtx
-scan_one_insn (rtx insn)
+static rtx_base_insn
+scan_one_insn (rtx_base_insn insn)
 {
   enum rtx_code pat_code;
   rtx set, note;
@@ -1473,7 +1473,7 @@ print_pseudo_costs (FILE *f)
 static void
 process_bb_for_costs (basic_block bb)
 {
-  rtx insn;
+  rtx_base_insn insn;
 
   frequency = REG_FREQ_FROM_BB (bb);
   if (frequency == 0)
@@ -1865,7 +1865,8 @@ process_bb_node_for_hard_reg_moves (ira_loop_tree_node_t loop_tree_node)
   ira_loop_tree_node_t curr_loop_tree_node;
   enum reg_class rclass;
   basic_block bb;
-  rtx insn, set, src, dst;
+  rtx_base_insn insn;
+  rtx set, src, dst;
 
   bb = loop_tree_node->bb;
   if (bb == NULL)
diff --git a/gcc/ira-emit.c b/gcc/ira-emit.c
index 198fa47..9b3d01a 100644
--- a/gcc/ira-emit.c
+++ b/gcc/ira-emit.c
@@ -557,7 +557,8 @@ change_loop (ira_loop_tree_node_t node)
   int regno;
   bool used_p;
   ira_allocno_t allocno, parent_allocno, *map;
-  rtx insn, original_reg;
+  rtx insn;
+  rtx original_reg;
   enum reg_class aclass, pclass;
   ira_loop_tree_node_t parent;
 
@@ -1234,7 +1235,7 @@ void
 ira_emit (bool loops_p)
 {
   basic_block bb;
-  rtx insn;
+  rtx_base_insn insn;
   edge_iterator ei;
   edge e;
   ira_allocno_t a;
diff --git a/gcc/ira-lives.c b/gcc/ira-lives.c
index 59f2b21..1f8256a 100644
--- a/gcc/ira-lives.c
+++ b/gcc/ira-lives.c
@@ -1126,7 +1126,7 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node)
   int i, freq;
   unsigned int j;
   basic_block bb;
-  rtx insn;
+  rtx_base_insn insn;
   bitmap_iterator bi;
   bitmap reg_live_out;
   unsigned int px;
diff --git a/gcc/ira.c b/gcc/ira.c
index b3477ae..f24de51 100644
--- a/gcc/ira.c
+++ b/gcc/ira.c
@@ -2126,7 +2126,8 @@ static void
 decrease_live_ranges_number (void)
 {
   basic_block bb;
-  rtx insn, set, src, dest, dest_death, p, q, note;
+  rtx_base_insn insn;
+  rtx set, src, dest, dest_death, p, q, note;
   int sregno, dregno;
 
   if (! flag_expensive_optimizations)
@@ -2360,7 +2361,7 @@ compute_regs_asm_clobbered (void)
 
   FOR_EACH_BB (bb)
     {
-      rtx insn;
+      rtx_base_insn insn;
       FOR_BB_INSNS_REVERSE (bb, insn)
 	{
 	  df_ref *def_rec;
@@ -4130,7 +4131,7 @@ build_insn_chain (void)
   FOR_EACH_BB_REVERSE (bb)
     {
       bitmap_iterator bi;
-      rtx insn;
+      rtx_base_insn insn;
 
       CLEAR_REG_SET (live_relevant_regs);
       bitmap_clear (live_subregs_used);
@@ -4328,12 +4329,12 @@ build_insn_chain (void)
       /* FIXME!! The following code is a disaster.  Reload needs to see the
 	 labels and jump tables that are just hanging out in between
 	 the basic blocks.  See pr33676.  */
-      insn = BB_HEAD (bb);
+      insn = BB_HEAD (bb)->as_an_rtx_base_insn ();
 
       /* Skip over the barriers and cruft.  */
       while (insn && (BARRIER_P (insn) || NOTE_P (insn)
 		      || BLOCK_FOR_INSN (insn) == bb))
-	insn = PREV_INSN (insn);
+	insn = PREV_INSN (insn)->as_an_rtx_base_insn ();
 
       /* While we add anything except barriers and notes, the focus is
 	 to get the labels and jump tables into the
@@ -4357,7 +4358,7 @@ build_insn_chain (void)
 	      c->insn = insn;
 	      bitmap_copy (&c->live_throughout, live_relevant_regs);
 	    }
-	  insn = PREV_INSN (insn);
+	  insn = PREV_INSN (insn)->as_an_rtx_base_insn ();
 	}
     }
 
@@ -4531,7 +4532,7 @@ find_moveable_pseudos (void)
   bitmap_initialize (&unusable_as_input, 0);
   FOR_EACH_BB (bb)
     {
-      rtx insn;
+      rtx_base_insn insn;
       bitmap transp = bb_transp_live + bb->index;
       bitmap moveable = bb_moveable_reg_sets + bb->index;
       bitmap local = bb_local + bb->index;
@@ -4595,7 +4596,7 @@ find_moveable_pseudos (void)
   FOR_EACH_BB (bb)
     {
       bitmap local = bb_local + bb->index;
-      rtx insn;
+      rtx_base_insn insn;
 
       FOR_BB_INSNS (bb, insn)
 	if (NONDEBUG_INSN_P (insn))
@@ -4907,7 +4908,7 @@ split_live_ranges_for_shrink_wrap (void)
 {
   basic_block bb, call_dom = NULL;
   basic_block first = single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun));
-  rtx insn, last_interesting_insn = NULL;
+  rtx_base_insn insn, last_interesting_insn = NULL;
   bitmap_head need_new, reachable;
   vec<basic_block> queue;
 
diff --git a/gcc/jump.c b/gcc/jump.c
index a27aaa9..e3bc6ee 100644
--- a/gcc/jump.c
+++ b/gcc/jump.c
@@ -63,7 +63,7 @@ along with GCC; see the file COPYING3.  If not see
    So perhaps let combiner do it.  */
 
 static void init_label_info (rtx);
-static void mark_all_labels (rtx);
+static void mark_all_labels (rtx_base_insn);
 static void mark_jump_label_1 (rtx, rtx, bool, bool);
 static void mark_jump_label_asm (rtx, rtx);
 static void redirect_exp_1 (rtx *, rtx, rtx, rtx);
@@ -72,7 +72,7 @@ static int returnjump_p_1 (rtx *, void *);
 
 /* Worker for rebuild_jump_labels and rebuild_jump_labels_chain.  */
 static void
-rebuild_jump_labels_1 (rtx f, bool count_forced)
+rebuild_jump_labels_1 (rtx_base_insn f, bool count_forced)
 {
   rtx insn;
 
@@ -96,7 +96,7 @@ rebuild_jump_labels_1 (rtx f, bool count_forced)
    instructions and jumping insns that have labels as operands
    (e.g. cbranchsi4).  */
 void
-rebuild_jump_labels (rtx f)
+rebuild_jump_labels (rtx_base_insn f)
 {
   rebuild_jump_labels_1 (f, true);
 }
@@ -105,7 +105,7 @@ rebuild_jump_labels (rtx f)
    forced_labels.  It can be used on insn chains that aren't the 
    main function chain.  */
 void
-rebuild_jump_labels_chain (rtx chain)
+rebuild_jump_labels_chain (rtx_base_insn chain)
 {
   rebuild_jump_labels_1 (chain, false);
 }
@@ -268,9 +268,9 @@ maybe_propagate_label_ref (rtx jump_insn, rtx prev_nonjump_insn)
    Combine consecutive labels, and count uses of labels.  */
 
 static void
-mark_all_labels (rtx f)
+mark_all_labels (rtx_base_insn f)
 {
-  rtx insn;
+  rtx_base_insn insn;
 
   if (current_ir_type () == IR_RTL_CFGLAYOUT)
     {
@@ -290,10 +290,18 @@ mark_all_labels (rtx f)
 	  /* In cfglayout mode, there may be non-insns between the
 	     basic blocks.  If those non-insns represent tablejump data,
 	     they contain label references that we must record.  */
-	  for (insn = BB_HEADER (bb); insn; insn = NEXT_INSN (insn))
+	  for (insn = (BB_HEADER (bb)
+		       ? BB_HEADER (bb)->as_an_rtx_base_insn ()
+		       : NULL);
+	       insn;
+	       insn = NEXT_INSN (insn))
 	    if (JUMP_TABLE_DATA_P (insn))
 	      mark_jump_label (PATTERN (insn), insn, 0);
-	  for (insn = BB_FOOTER (bb); insn; insn = NEXT_INSN (insn))
+	  for (insn = (BB_FOOTER (bb)
+		       ? BB_FOOTER (bb)->as_an_rtx_base_insn ()
+		       : NULL);
+	       insn;
+	       insn = NEXT_INSN (insn))
 	    if (JUMP_TABLE_DATA_P (insn))
 	      mark_jump_label (PATTERN (insn), insn, 0);
 	}
@@ -1398,10 +1406,10 @@ delete_for_peephole (rtx from, rtx to)
 	  /* We don't do this all at once, because we
 	     must preserve all NOTEs.  */
 	  if (prev)
-	    NEXT_INSN (prev) = next;
+	    prev->set_next_insn (next);
 
 	  if (next)
-	    PREV_INSN (next) = prev;
+	    next->set_prev_insn (prev);
 	}
 
       if (insn == to)
diff --git a/gcc/loop-invariant.c b/gcc/loop-invariant.c
index 9f1fc07..3661533 100644
--- a/gcc/loop-invariant.c
+++ b/gcc/loop-invariant.c
@@ -572,7 +572,7 @@ find_exits (struct loop *loop, basic_block *body,
   edge e;
   struct loop *outermost_exit = loop, *aexit;
   bool has_call = false;
-  rtx insn;
+  rtx_base_insn insn;
 
   for (i = 0; i < loop->num_nodes; i++)
     {
@@ -956,7 +956,7 @@ find_invariants_insn (rtx insn, bool always_reached, bool always_executed)
 static void
 find_invariants_bb (basic_block bb, bool always_reached, bool always_executed)
 {
-  rtx insn;
+  rtx_base_insn insn;
 
   FOR_BB_INSNS (bb, insn)
     {
@@ -1813,7 +1813,8 @@ calculate_loop_reg_pressure (void)
   unsigned int j;
   bitmap_iterator bi;
   basic_block bb;
-  rtx insn, link;
+  rtx_base_insn insn;
+  rtx link;
   struct loop *loop, *parent;
 
   FOR_EACH_LOOP (loop, 0)
diff --git a/gcc/loop-iv.c b/gcc/loop-iv.c
index c01ee17..e9b3080 100644
--- a/gcc/loop-iv.c
+++ b/gcc/loop-iv.c
@@ -1868,7 +1868,8 @@ static void
 simplify_using_initial_values (struct loop *loop, enum rtx_code op, rtx *expr)
 {
   bool expression_valid;
-  rtx head, tail, insn, cond_list, last_valid_expr;
+  rtx head, tail, cond_list, last_valid_expr;
+  rtx_base_insn insn;
   rtx neutral, aggr;
   regset altered, this_altered;
   edge e;
@@ -1948,7 +1949,7 @@ simplify_using_initial_values (struct loop *loop, enum rtx_code op, rtx *expr)
   cond_list = NULL_RTX;
   while (1)
     {
-      insn = BB_END (e->src);
+      insn = BB_END (e->src)->as_an_rtx_base_insn ();
       if (any_condjump_p (insn))
 	{
 	  rtx cond = get_condition (BB_END (e->src), NULL, false, true);
diff --git a/gcc/loop-unroll.c b/gcc/loop-unroll.c
index 557915f..5678de5 100644
--- a/gcc/loop-unroll.c
+++ b/gcc/loop-unroll.c
@@ -324,7 +324,7 @@ static bool
 loop_exit_at_end_p (struct loop *loop)
 {
   struct niter_desc *desc = get_simple_loop_desc (loop);
-  rtx insn;
+  rtx_base_insn insn;
 
   if (desc->in_edge->dest != loop->latch)
     return false;
@@ -1646,7 +1646,7 @@ referenced_in_one_insn_in_loop_p (struct loop *loop, rtx reg,
   basic_block *body, bb;
   unsigned i;
   int count_ref = 0;
-  rtx insn;
+  rtx_base_insn insn;
 
   body = get_loop_body (loop);
   for (i = 0; i < loop->num_nodes; i++)
@@ -1672,7 +1672,7 @@ reset_debug_uses_in_loop (struct loop *loop, rtx reg, int debug_uses)
 {
   basic_block *body, bb;
   unsigned i;
-  rtx insn;
+  rtx_base_insn insn;
 
   body = get_loop_body (loop);
   for (i = 0; debug_uses && i < loop->num_nodes; i++)
@@ -1916,7 +1916,7 @@ analyze_insns_in_loop (struct loop *loop)
   basic_block *body, bb;
   unsigned i;
   struct opt_info *opt_info = XCNEW (struct opt_info);
-  rtx insn;
+  rtx_base_insn insn;
   struct iv_to_split *ivts = NULL;
   struct var_to_expand *ves = NULL;
   iv_to_split **slot1;
@@ -2355,7 +2355,7 @@ apply_opt_in_copies (struct opt_info *opt_info,
 {
   unsigned i, delta;
   basic_block bb, orig_bb;
-  rtx insn, orig_insn, next;
+  rtx_base_insn insn, orig_insn, next;
   struct iv_to_split ivts_templ, *ivts;
   struct var_to_expand ve_templ, *ves;
 
@@ -2378,7 +2378,7 @@ apply_opt_in_copies (struct opt_info *opt_info,
       delta = determine_split_iv_delta ((size_t)bb->aux, n_copies,
 					unrolling);
       bb->aux = 0;
-      orig_insn = BB_HEAD (orig_bb);
+      orig_insn = BB_HEAD (orig_bb)->as_an_rtx_base_insn ();
       FOR_BB_INSNS_SAFE (bb, insn, next)
         {
 	  if (!INSN_P (insn)
@@ -2390,7 +2390,7 @@ apply_opt_in_copies (struct opt_info *opt_info,
 		 || (DEBUG_INSN_P (orig_insn)
 		     && (TREE_CODE (INSN_VAR_LOCATION_DECL (orig_insn))
 			 == LABEL_DECL)))
-            orig_insn = NEXT_INSN (orig_insn);
+            orig_insn = NEXT_INSN (orig_insn)->as_an_rtx_base_insn ();
 
           ivts_templ.insn = orig_insn;
           ve_templ.insn = orig_insn;
@@ -2424,7 +2424,7 @@ apply_opt_in_copies (struct opt_info *opt_info,
                   expand_var_during_unrolling (ves, insn);
                 }
             }
-          orig_insn = NEXT_INSN (orig_insn);
+          orig_insn = NEXT_INSN (orig_insn)->as_an_rtx_base_insn ();
         }
     }
 
@@ -2452,11 +2452,11 @@ apply_opt_in_copies (struct opt_info *opt_info,
 	continue;
 
       delta = determine_split_iv_delta (0, n_copies, unrolling);
-      for (orig_insn = BB_HEAD (orig_bb);
+      for (orig_insn = BB_HEAD (orig_bb)->as_an_rtx_base_insn ();
            orig_insn != NEXT_INSN (BB_END (bb));
            orig_insn = next)
         {
-          next = NEXT_INSN (orig_insn);
+          next = NEXT_INSN (orig_insn)->as_an_rtx_base_insn ();
 
           if (!INSN_P (orig_insn))
  	    continue;
diff --git a/gcc/lower-subreg.c b/gcc/lower-subreg.c
index e67bc35..5778e19 100644
--- a/gcc/lower-subreg.c
+++ b/gcc/lower-subreg.c
@@ -870,10 +870,11 @@ can_decompose_p (rtx x)
    we don't change anything, return INSN, otherwise return the start
    of the sequence of moves.  */
 
-static rtx
-resolve_simple_move (rtx set, rtx insn)
+static rtx_base_insn
+resolve_simple_move (rtx set, rtx_base_insn insn)
 {
-  rtx src, dest, real_dest, insns;
+  rtx src, dest, real_dest;
+  rtx_base_insn insns;
   enum machine_mode orig_mode, dest_mode;
   unsigned int words;
   bool pushing;
@@ -915,7 +916,8 @@ resolve_simple_move (rtx set, rtx insn)
 	  || (GET_MODE_SIZE (orig_mode)
 	      != GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest))))))
     {
-      rtx reg, minsn, smove;
+      rtx reg, smove;
+      rtx_base_insn minsn;
 
       reg = gen_reg_rtx (orig_mode);
       minsn = emit_move_insn (reg, src);
@@ -1062,7 +1064,8 @@ resolve_simple_move (rtx set, rtx insn)
 
   if (real_dest != NULL_RTX)
     {
-      rtx mdest, minsn, smove;
+      rtx mdest, smove;
+      rtx_base_insn minsn;
 
       if (dest_mode == orig_mode)
 	mdest = dest;
@@ -1236,33 +1239,33 @@ find_decomposable_shift_zext (rtx insn, bool speed_p)
    and 'set to zero' insn.  Return a pointer to the new insn when a
    replacement was done.  */
 
-static rtx
+static rtx_base_insn
 resolve_shift_zext (rtx insn)
 {
   rtx set;
   rtx op;
   rtx op_operand;
-  rtx insns;
+  rtx_base_insn insns;
   rtx src_reg, dest_reg, dest_upper, upper_src = NULL_RTX;
   int src_reg_num, dest_reg_num, offset1, offset2, src_offset;
 
   set = single_set (insn);
   if (!set)
-    return NULL_RTX;
+    return NULL_RTX_BASE_INSN;
 
   op = SET_SRC (set);
   if (GET_CODE (op) != ASHIFT
       && GET_CODE (op) != LSHIFTRT
       && GET_CODE (op) != ASHIFTRT
       && GET_CODE (op) != ZERO_EXTEND)
-    return NULL_RTX;
+    return NULL_RTX_BASE_INSN;
 
   op_operand = XEXP (op, 0);
 
   /* We can tear this operation apart only if the regs were already
      torn apart.  */
   if (!resolve_reg_p (SET_DEST (set)) && !resolve_reg_p (op_operand))
-    return NULL_RTX;
+    return NULL_RTX_BASE_INSN;
 
   /* src_reg_num is the number of the word mode register which we
      are operating on.  For a left shift and a zero_extend on little
@@ -1465,7 +1468,7 @@ decompose_multiword_subregs (bool decompose_copies)
   speed_p = optimize_function_for_speed_p (cfun);
   FOR_EACH_BB (bb)
     {
-      rtx insn;
+      rtx_base_insn insn;
 
       FOR_BB_INSNS (bb, insn)
 	{
@@ -1545,7 +1548,7 @@ decompose_multiword_subregs (bool decompose_copies)
 
       FOR_EACH_BB (bb)
 	{
-	  rtx insn;
+	  rtx_base_insn insn;
 
 	  FOR_BB_INSNS (bb, insn)
 	    {
@@ -1602,7 +1605,7 @@ decompose_multiword_subregs (bool decompose_copies)
 		    }
 		  else
 		    {
-		      rtx decomposed_shift;
+		      rtx_base_insn decomposed_shift;
 
 		      decomposed_shift = resolve_shift_zext (insn);
 		      if (decomposed_shift != NULL_RTX)
diff --git a/gcc/lra-assigns.c b/gcc/lra-assigns.c
index 88fc693..cf92a62 100644
--- a/gcc/lra-assigns.c
+++ b/gcc/lra-assigns.c
@@ -1166,7 +1166,7 @@ static void
 assign_by_spills (void)
 {
   int i, n, nfails, iter, regno, hard_regno, cost, restore_regno;
-  rtx insn;
+  rtx_base_insn insn;
   basic_block bb;
   bitmap_head changed_insns, do_not_assign_nonreload_pseudos;
   unsigned int u;
@@ -1253,7 +1253,7 @@ assign_by_spills (void)
 	    }
 	  EXECUTE_IF_SET_IN_BITMAP (&failed_reload_insns, 0, u, bi)
 	    {
-	      insn = lra_insn_recog_data[u]->insn;
+	      insn = lra_insn_recog_data[u]->insn->as_an_rtx_base_insn ();
 	      if (asm_noperands (PATTERN (insn)) >= 0)
 		{
 		  asm_p = true;
diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c
index bb5242a..e7caea6 100644
--- a/gcc/lra-constraints.c
+++ b/gcc/lra-constraints.c
@@ -4874,7 +4874,7 @@ add_to_inherit (int regno, rtx insns)
 static rtx
 get_last_insertion_point (basic_block bb)
 {
-  rtx insn;
+  rtx_base_insn insn;
 
   FOR_BB_INSNS_REVERSE (bb, insn)
     if (NONDEBUG_INSN_P (insn) || NOTE_INSN_BASIC_BLOCK_P (insn))
diff --git a/gcc/lra-eliminations.c b/gcc/lra-eliminations.c
index 915e3a0..caa0aa5 100644
--- a/gcc/lra-eliminations.c
+++ b/gcc/lra-eliminations.c
@@ -1280,7 +1280,7 @@ init_elimination (void)
 {
   bool stop_to_sp_elimination_p;
   basic_block bb;
-  rtx insn;
+  rtx_base_insn insn;
   struct elim_table *ep;
 
   init_elim_table ();
diff --git a/gcc/lra-int.h b/gcc/lra-int.h
index 6d8d80f..be2da2e 100644
--- a/gcc/lra-int.h
+++ b/gcc/lra-int.h
@@ -279,7 +279,7 @@ extern int lra_curr_reload_num;
 extern void lra_push_insn (rtx);
 extern void lra_push_insn_by_uid (unsigned int);
 extern void lra_push_insn_and_update_insn_regno_info (rtx);
-extern rtx lra_pop_insn (void);
+extern rtx_base_insn lra_pop_insn (void);
 extern unsigned int lra_insn_stack_length (void);
 
 extern rtx lra_create_new_reg_with_unique_value (enum machine_mode, rtx,
diff --git a/gcc/lra-lives.c b/gcc/lra-lives.c
index efc19f2..6acfdea 100644
--- a/gcc/lra-lives.c
+++ b/gcc/lra-lives.c
@@ -358,7 +358,7 @@ mark_regno_dead (int regno, enum machine_mode mode, int point)
 }
 
 /* Insn currently scanned.  */
-static rtx curr_insn;
+static rtx_base_insn curr_insn;
 /* The insn data.  */
 static lra_insn_recog_data_t curr_id;
 /* The insn static data.  */
diff --git a/gcc/lra-spills.c b/gcc/lra-spills.c
index 6bebb92..6a0d49a 100644
--- a/gcc/lra-spills.c
+++ b/gcc/lra-spills.c
@@ -256,7 +256,8 @@ assign_spill_hard_regs (int *pseudo_regnos, int n)
   enum reg_class rclass, spill_class;
   enum machine_mode mode;
   lra_live_range_t r;
-  rtx insn, set;
+  rtx_base_insn insn;
+  rtx set;
   basic_block bb;
   HARD_REG_SET conflict_hard_regs;
   bitmap_head ok_insn_bitmap;
@@ -463,7 +464,7 @@ static void
 spill_pseudos (void)
 {
   basic_block bb;
-  rtx insn;
+  rtx_base_insn insn;
   int i;
   bitmap_head spilled_pseudos, changed_insns;
 
@@ -679,7 +680,7 @@ lra_final_code_change (void)
 {
   int i, hard_regno;
   basic_block bb;
-  rtx insn, curr;
+  rtx_base_insn insn, curr;
   int max_regno = max_reg_num ();
 
   for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
diff --git a/gcc/lra.c b/gcc/lra.c
index d21d864..9bfd90d 100644
--- a/gcc/lra.c
+++ b/gcc/lra.c
@@ -1773,13 +1773,13 @@ lra_get_insn_regs (int uid)
 static sbitmap lra_constraint_insn_stack_bitmap;
 
 /* The stack itself.  */
-vec<rtx> lra_constraint_insn_stack;
+vec<rtx_base_insn> lra_constraint_insn_stack;
 
 /* Put INSN on the stack.  If ALWAYS_UPDATE is true, always update the reg
    info for INSN, otherwise only update it if INSN is not already on the
    stack.  */
 static inline void
-lra_push_insn_1 (rtx insn, bool always_update)
+lra_push_insn_1 (rtx_base_insn insn, bool always_update)
 {
   unsigned int uid = INSN_UID (insn);
   if (always_update)
@@ -1799,28 +1799,28 @@ lra_push_insn_1 (rtx insn, bool always_update)
 void
 lra_push_insn (rtx insn)
 {
-  lra_push_insn_1 (insn, false);
+  lra_push_insn_1 (insn->as_an_rtx_base_insn (), false);
 }
 
 /* Put INSN on the stack and update its reg info.  */
 void
 lra_push_insn_and_update_insn_regno_info (rtx insn)
 {
-  lra_push_insn_1 (insn, true);
+  lra_push_insn_1 (insn->as_an_rtx_base_insn (), true);
 }
 
 /* Put insn with UID on the stack.  */
 void
 lra_push_insn_by_uid (unsigned int uid)
 {
-  lra_push_insn (lra_insn_recog_data[uid]->insn);
+  lra_push_insn (lra_insn_recog_data[uid]->insn->as_an_rtx_base_insn ());
 }
 
 /* Take the last-inserted insns off the stack and return it.  */
-rtx
+rtx_base_insn
 lra_pop_insn (void)
 {
-  rtx insn = lra_constraint_insn_stack.pop ();
+  rtx_base_insn insn = lra_constraint_insn_stack.pop ();
   bitmap_clear_bit (lra_constraint_insn_stack_bitmap, INSN_UID (insn));
   return insn;
 }
@@ -1952,7 +1952,8 @@ remove_scratches (void)
   int i;
   bool insn_changed_p;
   basic_block bb;
-  rtx insn, reg;
+  rtx_base_insn insn;
+  rtx reg;
   sloc_t loc;
   lra_insn_recog_data_t id;
   struct lra_static_insn_data *static_id;
@@ -2046,7 +2047,7 @@ static void
 check_rtl (bool final_p)
 {
   basic_block bb;
-  rtx insn;
+  rtx_base_insn insn;
 
   lra_assert (! final_p || reload_completed);
   FOR_EACH_BB (bb)
@@ -2163,7 +2164,7 @@ update_inc_notes (void)
 {
   rtx *pnote;
   basic_block bb;
-  rtx insn;
+  rtx_base_insn insn;
 
   FOR_EACH_BB (bb)
     FOR_BB_INSNS (bb, insn)
diff --git a/gcc/mode-switching.c b/gcc/mode-switching.c
index ed45094..66250b7 100644
--- a/gcc/mode-switching.c
+++ b/gcc/mode-switching.c
@@ -452,7 +452,7 @@ create_pre_exit (int n_entities, int *entity_map, const int *num_modes)
 static int
 optimize_mode_switching (void)
 {
-  rtx insn;
+  rtx_base_insn insn;
   int e;
   basic_block bb;
   int need_commit = 0;
diff --git a/gcc/optabs.c b/gcc/optabs.c
index 50d7911..a5dc217 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -3939,12 +3939,12 @@ emit_libcall_block_1 (rtx insns, rtx target, rtx result, rtx equiv,
 	  if (! data.must_stay)
 	    {
 	      if (PREV_INSN (insn))
-		NEXT_INSN (PREV_INSN (insn)) = next;
+		PREV_INSN (insn)->set_next_insn (next);
 	      else
 		insns = next;
 
 	      if (next)
-		PREV_INSN (next) = PREV_INSN (insn);
+		next->set_prev_insn (PREV_INSN (insn));
 
 	      add_insn (insn);
 	    }
diff --git a/gcc/postreload-gcse.c b/gcc/postreload-gcse.c
index 9ce17e5..1e956e7 100644
--- a/gcc/postreload-gcse.c
+++ b/gcc/postreload-gcse.c
@@ -261,7 +261,7 @@ alloc_mem (void)
 {
   int i;
   basic_block bb;
-  rtx insn;
+  rtx_base_insn insn;
 
   /* Find the largest UID and create a mapping from UIDs to CUIDs.  */
   uid_cuid = XCNEWVEC (int, get_max_uid () + 1);
@@ -830,7 +830,7 @@ compute_hash_table (void)
 
   FOR_EACH_BB (bb)
     {
-      rtx insn;
+      rtx_base_insn insn;
 
       /* First pass over the instructions records information used to
 	 determine when registers and memory are last set.
@@ -1153,7 +1153,7 @@ cleanup:
 static void
 eliminate_partially_redundant_loads (void)
 {
-  rtx insn;
+  rtx_base_insn insn;
   basic_block bb;
 
   /* Note we start at block 1.  */
diff --git a/gcc/postreload.c b/gcc/postreload.c
index b0c6342..d16a3bf 100644
--- a/gcc/postreload.c
+++ b/gcc/postreload.c
@@ -207,7 +207,7 @@ reload_cse_regs_1 (void)
 {
   bool cfg_changed = false;
   basic_block bb;
-  rtx insn;
+  rtx_base_insn insn;
   rtx testreg = gen_rtx_REG (VOIDmode, -1);
 
   cselib_init (CSELIB_RECORD_MEMORY);
diff --git a/gcc/predict.c b/gcc/predict.c
index 1cd3fa6..a4cad93 100644
--- a/gcc/predict.c
+++ b/gcc/predict.c
@@ -2930,7 +2930,7 @@ expensive_function_p (int threshold)
   limit = ENTRY_BLOCK_PTR_FOR_FN (cfun)->frequency * threshold;
   FOR_EACH_BB (bb)
     {
-      rtx insn;
+      rtx_base_insn insn;
 
       FOR_BB_INSNS (bb, insn)
 	if (active_insn_p (insn))
diff --git a/gcc/ree.c b/gcc/ree.c
index 87427fd..ec695db 100644
--- a/gcc/ree.c
+++ b/gcc/ree.c
@@ -832,7 +832,8 @@ find_removable_extensions (void)
 {
   vec<ext_cand> insn_list = vNULL;
   basic_block bb;
-  rtx insn, set;
+  rtx_base_insn insn;
+  rtx set;
   unsigned *def_map = XCNEWVEC (unsigned, max_insn_uid);
 
   FOR_EACH_BB (bb)
diff --git a/gcc/reginfo.c b/gcc/reginfo.c
index db66a09..a50c289 100644
--- a/gcc/reginfo.c
+++ b/gcc/reginfo.c
@@ -1257,7 +1257,7 @@ void
 init_subregs_of_mode (void)
 {
   basic_block bb;
-  rtx insn;
+  rtx_base_insn insn;
   bitmap_obstack srom_obstack;
   bitmap subregs_of_mode;
 
diff --git a/gcc/regrename.c b/gcc/regrename.c
index 5e86fa5..2f43dae 100644
--- a/gcc/regrename.c
+++ b/gcc/regrename.c
@@ -724,7 +724,7 @@ regrename_analyze (bitmap bb_mask)
 	  open_chains = NULL;
 	  if (insn_rr.exists ())
 	    {
-	      rtx insn;
+	      rtx_base_insn insn;
 	      FOR_BB_INSNS (bb1, insn)
 		{
 		  insn_rr_info *p = &insn_rr[INSN_UID (insn)];
diff --git a/gcc/regstat.c b/gcc/regstat.c
index 85678a7..cb9c02e 100644
--- a/gcc/regstat.c
+++ b/gcc/regstat.c
@@ -121,7 +121,7 @@ regstat_bb_compute_ri (unsigned int bb_index,
 		       int *local_live_last_luid)
 {
   basic_block bb = BASIC_BLOCK (bb_index);
-  rtx insn;
+  rtx_base_insn insn;
   df_ref *def_rec;
   df_ref *use_rec;
   int luid = 0;
@@ -441,7 +441,7 @@ static void
 regstat_bb_compute_calls_crossed (unsigned int bb_index, bitmap live)
 {
   basic_block bb = BASIC_BLOCK (bb_index);
-  rtx insn;
+  rtx_base_insn insn;
   df_ref *def_rec;
   df_ref *use_rec;
 
diff --git a/gcc/reload1.c b/gcc/reload1.c
index 8972cbe..9a28153 100644
--- a/gcc/reload1.c
+++ b/gcc/reload1.c
@@ -1594,7 +1594,7 @@ calculate_elim_costs_all_insns (void)
 
   FOR_EACH_BB (bb)
     {
-      rtx insn;
+      rtx_base_insn insn;
       elim_bb = bb;
 
       FOR_BB_INSNS (bb, insn)
diff --git a/gcc/rtl.h b/gcc/rtl.h
index bc0933d..411de1d 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_base_insn
+  as_an_rtx_base_insn ()
+  {
+    return as_a <rtx_base_insn_def> (this);
+  }
+
   inline rtx_debug_insn
   as_an_rtx_debug_insn ()
   {
@@ -412,6 +418,14 @@ public:
   {
     return as_a <rtx_note_def> (this);
   }
+
+public:
+
+  /* These methods will eventually be moved to the rtx_base_insn_def
+     subclass and accept another rtx_base_insn.  */
+
+  inline void set_prev_insn (rtx new_prev);
+  inline void set_next_insn (rtx new_next);
 };
 
 
@@ -561,6 +575,7 @@ is_a_helper <rtx_note_def>::test (rtx rt)
 #define RTX_CODE_SIZE(CODE) rtx_code_size[CODE]
 
 #define NULL_RTX (rtx) 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
 
@@ -682,6 +697,18 @@ struct GTY((variable_size)) rtvec_def {
 /* Predicate yielding nonzero iff X is a data for a jump table.  */
 #define JUMP_TABLE_DATA_P(INSN) (GET_CODE (INSN) == JUMP_TABLE_DATA)
 
+template <>
+template <>
+inline bool
+is_a_helper <rtx_base_insn_def>::test (rtx rt)
+{
+  return (INSN_P (rt)
+	  || NOTE_P (rt)
+	  || JUMP_TABLE_DATA_P (rt)
+	  || BARRIER_P (rt)
+	  || LABEL_P (rt));
+}
+
 /* 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)
@@ -1031,8 +1058,31 @@ extern void rtl_check_failed_flag (const char *, const_rtx, const char *,
 #define INSN_UID(INSN)  XINT (INSN, 0)
 
 /* Chain insns together in sequence.  */
-#define PREV_INSN(INSN)	XEXP (INSN, 1)
-#define NEXT_INSN(INSN)	XEXP (INSN, 2)
+static inline rtx_base_insn PREV_INSN (const_rtx insn)
+{
+  if (XEXP (insn, 1))
+    return XEXP (insn, 1)->as_an_rtx_base_insn ();
+  else
+    return NULL;
+}
+
+static inline rtx_base_insn NEXT_INSN (const_rtx insn)
+{
+  if (XEXP (insn, 2))
+    return XEXP (insn, 2)->as_an_rtx_base_insn ();
+  else
+    return NULL;
+}
+
+inline void rtx_def::set_prev_insn (rtx new_prev)
+{
+  XEXP (this, 1) = new_prev;
+}
+
+inline void rtx_def::set_next_insn (rtx new_next)
+{
+  XEXP (this, 2) = new_next;
+}
 
 #define BLOCK_FOR_INSN(INSN) XBBDEF (INSN, 3)
 
@@ -2062,9 +2112,9 @@ extern rtx assign_stack_temp_for_type (enum machine_mode, HOST_WIDE_INT, tree);
 extern rtx assign_temp (tree, int, int);
 
 /* In emit-rtl.c */
-extern rtx emit_insn_before (rtx, rtx);
-extern rtx emit_insn_before_noloc (rtx, rtx, basic_block);
-extern rtx emit_insn_before_setloc (rtx, rtx, int);
+extern rtx_base_insn emit_insn_before (rtx, rtx);
+extern rtx_base_insn emit_insn_before_noloc (rtx, rtx, basic_block);
+extern rtx_base_insn emit_insn_before_setloc (rtx, rtx, int);
 extern rtx_jump_insn emit_jump_insn_before (rtx, rtx);
 extern rtx_jump_insn emit_jump_insn_before_noloc (rtx, rtx);
 extern rtx_jump_insn emit_jump_insn_before_setloc (rtx, rtx, int);
@@ -2077,9 +2127,9 @@ extern rtx emit_debug_insn_before_setloc (rtx, rtx, int);
 extern rtx emit_barrier_before (rtx);
 extern rtx emit_label_before (rtx, rtx);
 extern rtx_note emit_note_before (enum insn_note, rtx);
-extern rtx emit_insn_after (rtx, rtx);
-extern rtx emit_insn_after_noloc (rtx, rtx, basic_block);
-extern rtx emit_insn_after_setloc (rtx, rtx, int);
+extern rtx_base_insn emit_insn_after (rtx, rtx);
+extern rtx_base_insn emit_insn_after_noloc (rtx, rtx, basic_block);
+extern rtx_base_insn emit_insn_after_setloc (rtx, rtx, int);
 extern rtx_jump_insn emit_jump_insn_after (rtx, rtx);
 extern rtx_jump_insn emit_jump_insn_after_noloc (rtx, rtx);
 extern rtx_jump_insn emit_jump_insn_after_setloc (rtx, rtx, int);
@@ -2092,7 +2142,7 @@ extern rtx emit_debug_insn_after_setloc (rtx, rtx, int);
 extern rtx emit_barrier_after (rtx);
 extern rtx emit_label_after (rtx, rtx);
 extern rtx_note emit_note_after (enum insn_note, rtx);
-extern rtx emit_insn (rtx);
+extern rtx_base_insn emit_insn (rtx);
 extern rtx emit_debug_insn (rtx);
 extern rtx emit_jump_insn (rtx);
 extern rtx emit_call_insn (rtx);
@@ -2105,7 +2155,7 @@ extern rtx gen_clobber (rtx);
 extern rtx emit_clobber (rtx);
 extern rtx gen_use (rtx);
 extern rtx emit_use (rtx);
-extern rtx make_insn_raw (rtx);
+extern rtx_base_insn make_insn_raw (rtx);
 extern void add_function_usage_to (rtx, rtx);
 extern rtx last_call_insn (void);
 extern rtx previous_insn (rtx);
@@ -2729,8 +2779,8 @@ extern unsigned int reg_or_subregno (const_rtx);
 extern int redirect_jump_1 (rtx, rtx);
 extern void redirect_jump_2 (rtx, rtx, rtx, int, int);
 extern int redirect_jump (rtx, rtx, int);
-extern void rebuild_jump_labels (rtx);
-extern void rebuild_jump_labels_chain (rtx);
+extern void rebuild_jump_labels (rtx_base_insn);
+extern void rebuild_jump_labels_chain (rtx_base_insn);
 extern rtx reversed_comparison (const_rtx, enum machine_mode);
 extern enum rtx_code reversed_comparison_code (const_rtx, const_rtx);
 extern enum rtx_code reversed_comparison_code_parts (enum rtx_code, const_rtx,
diff --git a/gcc/sched-rgn.c b/gcc/sched-rgn.c
index 1663e2f..0e4e35a 100644
--- a/gcc/sched-rgn.c
+++ b/gcc/sched-rgn.c
@@ -253,7 +253,7 @@ static int
 is_cfg_nonregular (void)
 {
   basic_block b;
-  rtx insn;
+  rtx_base_insn insn;
 
   /* If we have a label that could be the target of a nonlocal goto, then
      the cfg is not well structured.  */
@@ -535,7 +535,7 @@ rgn_estimate_number_of_insns (basic_block bb)
 
   if (MAY_HAVE_DEBUG_INSNS)
     {
-      rtx insn;
+      rtx_base_insn insn;
 
       FOR_BB_INSNS (bb, insn)
 	if (DEBUG_INSN_P (insn))
diff --git a/gcc/sched-vis.c b/gcc/sched-vis.c
index a965c4d..18e8646 100644
--- a/gcc/sched-vis.c
+++ b/gcc/sched-vis.c
@@ -815,7 +815,7 @@ dump_rtl_slim (FILE *f, const_rtx first, const_rtx last,
 void
 rtl_dump_bb_for_graph (pretty_printer *pp, basic_block bb)
 {
-  rtx insn;
+  rtx_base_insn insn;
   bool first = true;
 
   /* TODO: inter-bb stuff.  */
diff --git a/gcc/sel-sched-ir.c b/gcc/sel-sched-ir.c
index d3eee98..9e95191 100644
--- a/gcc/sel-sched-ir.c
+++ b/gcc/sel-sched-ir.c
@@ -1418,11 +1418,11 @@ sel_move_insn (expr_t expr, int seqno, insn_t after)
 
   /* Assert that in move_op we disconnected this insn properly.  */
   gcc_assert (EXPR_VINSN (INSN_EXPR (insn)) != NULL);
-  PREV_INSN (insn) = after;
-  NEXT_INSN (insn) = next;
+  insn->set_prev_insn (after);
+  insn->set_next_insn (next);
 
-  NEXT_INSN (after) = insn;
-  PREV_INSN (next) = insn;
+  after->set_next_insn (insn);
+  next->set_prev_insn (insn);
 
   /* Update links from insn to bb and vice versa.  */
   df_insn_change_bb (insn, bb);
@@ -2797,7 +2797,7 @@ sched_scan (const struct sched_scan_info_def *ssi, bb_vec_t bbs)
   if (ssi->init_insn)
     FOR_EACH_VEC_ELT (bbs, i, bb)
       {
-	rtx insn;
+	rtx_base_insn insn;
 
 	FOR_BB_INSNS (bb, insn)
 	  ssi->init_insn (insn);
@@ -3942,8 +3942,8 @@ sel_remove_insn (insn_t insn, bool only_disconnect, bool full_tidying)
   /* It is necessary to NULL these fields in case we are going to re-insert
      INSN into the insns stream, as will usually happen in the ONLY_DISCONNECT
      case, but also for NOPs that we will return to the nop pool.  */
-  PREV_INSN (insn) = NULL_RTX;
-  NEXT_INSN (insn) = NULL_RTX;
+  insn->set_prev_insn (NULL);
+  insn->set_next_insn (NULL);
   set_block_for_insn (insn, NULL);
 
   return tidy_control_flow (bb, full_tidying);
@@ -4932,7 +4932,7 @@ recompute_rev_top_order (void)
 void
 clear_outdated_rtx_info (basic_block bb)
 {
-  rtx insn;
+  rtx_base_insn insn;
 
   FOR_BB_INSNS (bb, insn)
     if (INSN_P (insn))
@@ -4973,8 +4973,8 @@ get_bb_note_from_pool (void)
     {
       rtx_note note = bb_note_pool.pop ();
 
-      PREV_INSN (note) = NULL_RTX;
-      NEXT_INSN (note) = NULL_RTX;
+      note->set_prev_insn (NULL);
+      note->set_next_insn (NULL);
 
       return note;
     }
diff --git a/gcc/sel-sched.c b/gcc/sel-sched.c
index 1e3fcf0..89d43f7 100644
--- a/gcc/sel-sched.c
+++ b/gcc/sel-sched.c
@@ -5218,14 +5218,14 @@ move_nop_to_previous_block (insn_t nop, basic_block prev_bb)
   gcc_assert (prev_insn != NULL_RTX
               && PREV_INSN (note) == prev_insn);
 
-  NEXT_INSN (prev_insn) = nop;
-  PREV_INSN (nop) = prev_insn;
+  prev_insn->set_next_insn (nop);
+  nop->set_prev_insn (prev_insn);
 
-  PREV_INSN (note) = nop;
-  NEXT_INSN (note) = next_insn;
+  note->set_prev_insn (nop);
+  note->set_next_insn (next_insn);
 
-  NEXT_INSN (nop) = note;
-  PREV_INSN (next_insn) = note;
+  nop->set_next_insn (note);
+  next_insn->set_prev_insn (note);
 
   BB_END (prev_bb) = nop;
   BLOCK_FOR_INSN (nop) = prev_bb;
@@ -7025,7 +7025,7 @@ simplify_changed_insns (void)
   for (i = 0; i < current_nr_blocks; i++)
     {
       basic_block bb = BASIC_BLOCK (BB_TO_BLOCK (i));
-      rtx insn;
+      rtx_base_insn insn;
 
       FOR_BB_INSNS (bb, insn)
 	if (INSN_P (insn))
diff --git a/gcc/stack-ptr-mod.c b/gcc/stack-ptr-mod.c
index 68ccd16..48f2457 100644
--- a/gcc/stack-ptr-mod.c
+++ b/gcc/stack-ptr-mod.c
@@ -52,7 +52,7 @@ static void
 notice_stack_pointer_modification (void)
 {
   basic_block bb;
-  rtx insn;
+  rtx_base_insn insn;
 
   /* Assume that the stack pointer is unchanging if alloca hasn't
      been used.  */
diff --git a/gcc/store-motion.c b/gcc/store-motion.c
index 378d6c7..5eed3c1 100644
--- a/gcc/store-motion.c
+++ b/gcc/store-motion.c
@@ -644,7 +644,8 @@ compute_store_table (void)
 #ifdef ENABLE_CHECKING
   unsigned regno;
 #endif
-  rtx insn, tmp;
+  rtx_base_insn insn;
+  rtx tmp;
   df_ref *def_rec;
   int *last_set_in, *already_set;
   struct st_expr * ptr, **prev_next_ptr_ptr;
@@ -1010,7 +1011,8 @@ build_store_vectors (void)
 {
   basic_block bb;
   int *regs_set_in_block;
-  rtx insn, st;
+  rtx_base_insn insn;
+  rtx st;
   struct st_expr * ptr;
   unsigned int max_gcse_regno = max_reg_num ();
 
@@ -1026,7 +1028,7 @@ build_store_vectors (void)
     {
       for (st = ptr->avail_stores; st != NULL; st = XEXP (st, 1))
 	{
-	  insn = XEXP (st, 0);
+	  insn = XEXP (st, 0)->as_an_rtx_base_insn ();
 	  bb = BLOCK_FOR_INSN (insn);
 
 	  /* If we've already seen an available expression in this block,
@@ -1046,7 +1048,7 @@ build_store_vectors (void)
 
       for (st = ptr->antic_stores; st != NULL; st = XEXP (st, 1))
 	{
-	  insn = XEXP (st, 0);
+	  insn = XEXP (st, 0)->as_an_rtx_base_insn ();
 	  bb = BLOCK_FOR_INSN (insn);
 	  bitmap_set_bit (st_antloc[bb->index], ptr->index);
 	}
diff --git a/gcc/var-tracking.c b/gcc/var-tracking.c
index 14f906f..d6dd056 100644
--- a/gcc/var-tracking.c
+++ b/gcc/var-tracking.c
@@ -10135,7 +10135,7 @@ static void
 delete_debug_insns (void)
 {
   basic_block bb;
-  rtx insn, next;
+  rtx_base_insn insn, next;
 
   if (!MAY_HAVE_DEBUG_INSNS)
     return;
diff --git a/gcc/web.c b/gcc/web.c
index 8e8c465..e321c33 100644
--- a/gcc/web.c
+++ b/gcc/web.c
@@ -342,7 +342,7 @@ web_main (void)
   unsigned int *used;
   basic_block bb;
   unsigned int uses_num = 0;
-  rtx insn;
+  rtx_base_insn insn;
 
   df_set_flags (DF_NO_HARD_REGS + DF_EQ_NOTES);
   df_set_flags (DF_RD_PRUNE_DEAD_DEFS);
-- 
1.7.11.7

