Index: lra-eliminations.c
===================================================================
--- lra-eliminations.c	(revision 189236)
+++ lra-eliminations.c	(working copy)
@@ -225,18 +225,22 @@ lra_get_elimation_hard_regno (int hard_r
   return ep->to;
 }
 
-/* Return elimination which will be used for HARD_REGNO, NULL otherwise.  */
+/* Return elimination which will be used for hard reg REG, NULL
+   otherwise.  */
 static struct elim_table *
-get_elimination (int hard_regno)
+get_elimination (rtx reg)
 {
+  int hard_regno;
   struct elim_table *ep;
   HOST_WIDE_INT offset;
 
-  if (hard_regno < 0 || hard_regno >= FIRST_PSEUDO_REGISTER)
+  lra_assert (REG_P (reg));
+  if ((hard_regno = REGNO (reg)) < 0 || hard_regno >= FIRST_PSEUDO_REGISTER)
+    return NULL;
+  if ((ep = elimination_map[hard_regno]) != NULL)
+    return ep->from_rtx != reg ? NULL : ep;
+  if ((offset = self_elim_offsets[hard_regno]) == 0)
     return NULL;
-  if ((ep = elimination_map[hard_regno]) != NULL
-      || (offset = self_elim_offsets[hard_regno]) == 0)
-    return ep;
   /* This is an iteration to restore offsets just after HARD_REGNO
      stopped to be eliminable.  */
   self_elim_table.from = self_elim_table.to = hard_regno;
@@ -268,7 +272,6 @@ lra_eliminate_regs_1 (rtx x, enum machin
 {
   enum rtx_code code = GET_CODE (x);
   struct elim_table *ep;
-  int regno;
   rtx new_rtx;
   int i, j;
   const char *fmt;
@@ -295,24 +298,18 @@ lra_eliminate_regs_1 (rtx x, enum machin
       return x;
 
     case REG:
-      regno = REGNO (x);
-
       /* First handle the case where we encounter a bare register that
 	 is eliminable.  Replace it with a PLUS.  */
-      if (regno < FIRST_PSEUDO_REGISTER)
+      if ((ep = get_elimination (x)) != NULL)
 	{
-	  if ((ep = get_elimination (regno)) != NULL)
-	    {
-	      rtx to = subst_p ? ep->to_rtx : ep->from_rtx;
-
-	      if (update_p)
-		return plus_constant (Pmode, to,
-				      ep->offset - ep->previous_offset);
-	      else if (full_p)
-		return plus_constant (Pmode, to, ep->offset);
-	      else
-		return to;
-	    }
+	  rtx to = subst_p ? ep->to_rtx : ep->from_rtx;
+	  
+	  if (update_p)
+	    return plus_constant (Pmode, to, ep->offset - ep->previous_offset);
+	  else if (full_p)
+	    return plus_constant (Pmode, to, ep->offset);
+	  else
+	    return to;
 	}
       return x;
 
@@ -333,11 +330,9 @@ lra_eliminate_regs_1 (rtx x, enum machin
     case PLUS:
       /* If this is the sum of an eliminable register and a constant, rework
 	 the sum.  */
-      if (REG_P (XEXP (x, 0))
-	  && (regno = REGNO (XEXP (x, 0))) < FIRST_PSEUDO_REGISTER
-	  && CONSTANT_P (XEXP (x, 1)))
+      if (REG_P (XEXP (x, 0)) && CONSTANT_P (XEXP (x, 1)))
 	{
-	  if ((ep = get_elimination (regno)) != NULL)
+	  if ((ep = get_elimination (XEXP (x, 0))) != NULL)
 	    {
 	      HOST_WIDE_INT offset;
 	      rtx to = subst_p ? ep->to_rtx : ep->from_rtx;
@@ -407,27 +402,25 @@ lra_eliminate_regs_1 (rtx x, enum machin
 	 so that we have (plus (mult ..) ..).  This is needed in order
 	 to keep load-address insns valid.   This case is pathological.
 	 We ignore the possibility of overflow here.  */
-      if (REG_P (XEXP (x, 0))
-	  && (regno = REGNO (XEXP (x, 0))) < FIRST_PSEUDO_REGISTER
-	  && CONST_INT_P (XEXP (x, 1)))
-	  if ((ep = get_elimination (regno)) != NULL)
-	    {
-	      rtx to = subst_p ? ep->to_rtx : ep->from_rtx;
-	      
-	      if (update_p)
-		return
-		  plus_constant (Pmode,
-				 gen_rtx_MULT (Pmode, to, XEXP (x, 1)),
-				 (ep->offset - ep->previous_offset)
-				 * INTVAL (XEXP (x, 1)));
-	      else if (full_p)
-		return
-		  plus_constant (Pmode,
-				 gen_rtx_MULT (Pmode, to, XEXP (x, 1)),
-				 ep->offset * INTVAL (XEXP (x, 1)));
-	      else
-		return gen_rtx_MULT (Pmode, to, XEXP (x, 1));
-	    }
+      if (REG_P (XEXP (x, 0)) && CONST_INT_P (XEXP (x, 1))
+	  && (ep = get_elimination (XEXP (x, 0))) != NULL)
+	{
+	  rtx to = subst_p ? ep->to_rtx : ep->from_rtx;
+	  
+	  if (update_p)
+	    return
+	      plus_constant (Pmode,
+			     gen_rtx_MULT (Pmode, to, XEXP (x, 1)),
+			     (ep->offset - ep->previous_offset)
+			     * INTVAL (XEXP (x, 1)));
+	  else if (full_p)
+	    return
+	      plus_constant (Pmode,
+			     gen_rtx_MULT (Pmode, to, XEXP (x, 1)),
+			     ep->offset * INTVAL (XEXP (x, 1)));
+	  else
+	    return gen_rtx_MULT (Pmode, to, XEXP (x, 1));
+	}
       
       /* ... fall through ...  */
 
@@ -769,7 +762,7 @@ eliminate_regs_in_insn (rtx insn, bool r
   int icode = recog_memoized (insn);
   rtx old_set = single_set (insn);
   bool val;
-  int i, regno;
+  int i;
   rtx substed_operand[MAX_RECOG_OPERANDS];
   rtx orig_operand[MAX_RECOG_OPERANDS];
   struct elim_table *ep;
@@ -787,93 +780,88 @@ eliminate_regs_in_insn (rtx insn, bool r
       return;
     }
 
+  /* Check for setting an eliminable register.  */
   if (old_set != 0 && REG_P (SET_DEST (old_set))
-      && (regno = REGNO (SET_DEST (old_set))) < FIRST_PSEUDO_REGISTER)
+      && (ep = get_elimination (SET_DEST (old_set))) != NULL)
     {
-      /* Check for setting an eliminable register.  */
-      if ((ep = get_elimination (regno)) != NULL)
-	{
-	  bool delete_p = replace_p;
-
+      bool delete_p = replace_p;
+      
 #ifdef HARD_FRAME_POINTER_REGNUM
-	  /* If this is setting the frame pointer register to the
-	     hardware frame pointer register and this is an
-	     elimination that will be done (tested above), this insn
-	     is really adjusting the frame pointer downward to
-	     compensate for the adjustment done before a nonlocal
-	     goto.  */
-	  if (ep->from == FRAME_POINTER_REGNUM
-	      && ep->to == HARD_FRAME_POINTER_REGNUM)
+      /* If this is setting the frame pointer register to the hardware
+	 frame pointer register and this is an elimination that will
+	 be done (tested above), this insn is really adjusting the
+	 frame pointer downward to compensate for the adjustment done
+	 before a nonlocal goto.  */
+      if (ep->from == FRAME_POINTER_REGNUM
+	  && ep->to == HARD_FRAME_POINTER_REGNUM)
+	{
+	  if (replace_p)
 	    {
-	      if (replace_p)
-		{
-		  SET_DEST (old_set) = ep->to_rtx;
-		  lra_update_insn_recog_data (insn);
-		  return;
-		}
-	      else
+	      SET_DEST (old_set) = ep->to_rtx;
+	      lra_update_insn_recog_data (insn);
+	      return;
+	    }
+	  else
+	    {
+	      rtx base = SET_SRC (old_set);
+	      HOST_WIDE_INT offset = 0;
+	      rtx base_insn = insn;
+	      
+	      while (base != ep->to_rtx)
 		{
-		  rtx base = SET_SRC (old_set);
-		  HOST_WIDE_INT offset = 0;
-		  rtx base_insn = insn;
-
-		  while (base != ep->to_rtx)
+		  rtx prev_insn, prev_set;
+		  
+		  if (GET_CODE (base) == PLUS && CONST_INT_P (XEXP (base, 1)))
 		    {
-		      rtx prev_insn, prev_set;
-		      
-		      if (GET_CODE (base) == PLUS
-			  && CONST_INT_P (XEXP (base, 1)))
-			{
-			  offset += INTVAL (XEXP (base, 1));
-			  base = XEXP (base, 0);
-			}
-		      else if ((prev_insn = prev_nonnote_insn (base_insn)) != 0
-			       && (prev_set = single_set (prev_insn)) != 0
-			       && rtx_equal_p (SET_DEST (prev_set), base))
-			{
-			  base = SET_SRC (prev_set);
-			  base_insn = prev_insn;
-			}
-		      else
-			break;
+		      offset += INTVAL (XEXP (base, 1));
+		      base = XEXP (base, 0);
 		    }
-
-		  if (base == ep->to_rtx)
+		  else if ((prev_insn = prev_nonnote_insn (base_insn)) != 0
+			   && (prev_set = single_set (prev_insn)) != 0
+			   && rtx_equal_p (SET_DEST (prev_set), base))
 		    {
-		      rtx src;
-		      
-		      offset -= (ep->offset - ep->previous_offset);
-		      src = plus_constant (Pmode, ep->to_rtx, offset);
-		      
-		      /* First see if this insn remains valid when we
-			 make the change.  If not, keep the INSN_CODE
-			 the same and let reload fit it up.  */
-		      validate_change (insn, &SET_SRC (old_set), src, 1);
-		      validate_change (insn, &SET_DEST (old_set),
-				       ep->from_rtx, 1);
-		      if (! apply_change_group ())
-			{
-			  SET_SRC (old_set) = src;
-			  SET_DEST (old_set) = ep->from_rtx;
-			}
-		      lra_update_insn_recog_data (insn);
-		      return;
+		      base = SET_SRC (prev_set);
+		      base_insn = prev_insn;
 		    }
+		  else
+		    break;
+		}
+	      
+	      if (base == ep->to_rtx)
+		{
+		  rtx src;
+		  
+		  offset -= (ep->offset - ep->previous_offset);
+		  src = plus_constant (Pmode, ep->to_rtx, offset);
+		  
+		  /* First see if this insn remains valid when we
+		     make the change.  If not, keep the INSN_CODE
+		     the same and let reload fit it up.  */
+		  validate_change (insn, &SET_SRC (old_set), src, 1);
+		  validate_change (insn, &SET_DEST (old_set),
+				   ep->from_rtx, 1);
+		  if (! apply_change_group ())
+		    {
+		      SET_SRC (old_set) = src;
+		      SET_DEST (old_set) = ep->from_rtx;
+		    }
+		  lra_update_insn_recog_data (insn);
+		  return;
 		}
-
-	     
-	      /* We can't delete this insn, but needn't process it
-		 since it won't be used unless something changes. */
-	      delete_p = false;
 	    }
-#endif
 	  
-	  /* This insn isn't serving a useful purpose.  We delete it
-	     when REPLACE is set.  */
-	  if (delete_p)
-	    lra_delete_dead_insn (insn);
-	  return;
+	  
+	  /* We can't delete this insn, but needn't process it
+	     since it won't be used unless something changes. */
+	  delete_p = false;
 	}
+#endif
+      
+      /* This insn isn't serving a useful purpose.  We delete it
+	 when REPLACE is set.  */
+      if (delete_p)
+	lra_delete_dead_insn (insn);
+      return;
     }
 
   /* We allow one special case which happens to work on all machines we
@@ -909,8 +897,7 @@ eliminate_regs_in_insn (rtx insn, bool r
       if (GET_CODE (reg) == SUBREG)
 	reg = SUBREG_REG (reg);
 
-      if (REG_P (reg) && (regno = REGNO (reg)) < FIRST_PSEUDO_REGISTER
-	  && (ep = get_elimination (regno)) != NULL)
+      if (REG_P (reg) && (ep = get_elimination (reg)) != NULL)
 	{
 	  rtx to_rtx = replace_p ? ep->to_rtx : ep->from_rtx;
 	  
@@ -1234,7 +1221,7 @@ lra_eliminate_reg_if_possible (rtx *loc)
       /* Virtual registers are not allocatable. ??? */
       || ! TEST_HARD_REG_BIT (lra_no_alloc_regs, regno))
     return;
-  if ((ep = get_elimination (regno)) != NULL)
+  if ((ep = get_elimination (*loc)) != NULL)
     *loc = ep->to_rtx;
 }
 
