Index: lra-constraints.c
===================================================================
--- lra-constraints.c	(revision 178737)
+++ lra-constraints.c	(working copy)
@@ -270,7 +270,8 @@ init_curr_insn_input_reloads (void)
    NEW_CLASS.  Print info about it using TITLE.  Output a new line if
    NL_P.  */
 static void
-change_class (int regno, enum reg_class new_class, const char *title, bool nl_p)
+change_class (int regno, enum reg_class new_class,
+	      const char *title, bool nl_p)
 {
   int curr_regno;
 
@@ -1143,6 +1144,10 @@ static int best_losers, best_overall;
 /* Number of small register classes used for operands of the best
    alternative.  */
 static int best_small_class_operands_num;
+/* Overall number hard registers used for reloads.  For example, on
+   some targets we need 2 general registers to reload DFmode and only
+   one floating point register.  */
+static int best_reload_nregs;
 /* Overall number reflecting distances of previous reloading the same
    value.  It is used to improve inheritance chances.  */
 static int best_reload_sum;
@@ -1415,7 +1420,9 @@ process_alt_operands (int only_alternati
   rtx no_subreg_operand[MAX_RECOG_OPERANDS], operand_reg[MAX_RECOG_OPERANDS];
   int hard_regno[MAX_RECOG_OPERANDS];
   enum machine_mode biggest_mode[MAX_RECOG_OPERANDS];
-  int reload_sum;
+  int reload_nregs, reload_sum;
+  bool costly_p;
+  enum reg_class cl;
 
   /* Calculate some data common for all alternatives to speed up the
      function.  */
@@ -1460,7 +1467,7 @@ process_alt_operands (int only_alternati
 	  (only_alternative >= 0 && nalt != only_alternative))
 	continue;
 
-      overall = losers = reject = reload_sum = 0;
+      overall = losers = reject = reload_nregs = reload_sum = 0;
       for (nop = 0; nop < n_operands; nop++)
 	reject += (curr_static_id
 		   ->operand_alternative[nalt * n_operands + nop].reject);
@@ -1481,8 +1488,8 @@ process_alt_operands (int only_alternati
 	  /* False if a constant forced into memory would be OK for
 	     this operand.  */
 	  bool constmemok;
-	  enum reg_class this_alternative;
-	  HARD_REG_SET this_alternative_set;
+	  enum reg_class this_alternative, this_costly_alternative;
+	  HARD_REG_SET this_alternative_set, this_costly_alternative_set;
 	  bool this_alternative_match_win, this_alternative_win;
 	  bool this_alternative_offmemok;
 	  int invalidate_m;
@@ -1510,13 +1517,14 @@ process_alt_operands (int only_alternati
 	  early_clobber_p = false;
 	  p = curr_static_id->operand_alternative[opalt_num].constraint;
       
-	  this_alternative = NO_REGS;
+	  this_costly_alternative = this_alternative = NO_REGS;
 	  /* We update set of possible hard regs besides its class
 	     because reg class might be inaccurate.  For example,
 	     union of LO_REGS (l), HI_REGS(h), and STACK_REG(k) in ARM
 	     is translated in HI_REGS because classes are merged by
 	     pairs and there is no accurate intermediate class.  */
 	  CLEAR_HARD_REG_SET (this_alternative_set);
+	  CLEAR_HARD_REG_SET (this_costly_alternative_set);
 	  this_alternative_win = false;
 	  this_alternative_match_win = false;
 	  this_alternative_offmemok = false;
@@ -1534,349 +1542,378 @@ process_alt_operands (int only_alternati
 	     letter after reloads, or set WINREG if this operand could
 	     fit after reloads provided the constraint allows some
 	     registers.  */
-  
+	  costly_p = false;
 	  do
-	    switch ((c = *p, len = CONSTRAINT_LEN (c, p)), c)
-	      {
-	      case '\0':
-		len = 0;
-		break;
-	      case ',':
-		c = '\0';
-		break;
-	
-	      case '=':  case '+':  case '*': case '?': case '!':
-		break;
-	
-	      case '%':
-		/* We only support one commutative marker, the first
-		   one.  We already set commutative above.  */
-		break;
-	
-	      case '&':
-		early_clobber_p = true;
-		break;
-	
-	      case '#':
-		/* Ignore rest of this alternative.  */
-		c = '\0';
-		break;
-	
-	      case '0':  case '1':  case '2':  case '3':  case '4':
-	      case '5':  case '6':  case '7':  case '8':  case '9':
+	    {
+	      switch ((c = *p, len = CONSTRAINT_LEN (c, p)), c)
 		{
-		  int m_hregno, m_offset;
-		  bool match_p;
-
-		  m = strtoul (p, &end, 10);
-		  p = end;
+		case '\0':
 		  len = 0;
-		  gcc_assert (nop > m);
-	  
-		  this_alternative_matches = m;
-		  lra_get_hard_regno_and_offset (*curr_id->operand_loc[m],
-						 &m_hregno, &m_offset);
-		  m_hregno = get_final_hard_regno (m_hregno, m_offset);
-		  /* We are supposed to match a previous operand.  If
-		     we do, we win if that one did.  If we do not,
-		     count both of the operands as losers.  (This is
-		     too conservative, since most of the time only a
-		     single reload insn will be needed to make the two
-		     operands win.  As a result, this alternative may
-		     be rejected when it is actually desirable.)  */
-		  /* If it conflicts with others.  */
-		  match_p = false;
-		  if (operands_match_p (*curr_id->operand_loc[nop],
-					*curr_id->operand_loc[m], m_hregno))
-		    {
-		      int i;
-
-		      for (i = 0; i < early_clobbered_regs_num; i++)
-			if (early_clobbered_nops[i] == m)
-			  break;
-		      /* We should reject matching of an early clobber
-			 operand if the matching operand is not dying
-			 in the insn.  */
-		      if (i >= early_clobbered_regs_num
-			  || operand_reg[nop] == NULL_RTX
-			  || (find_regno_note (curr_insn, REG_DEAD,
-					       REGNO (operand_reg[nop]))
-			      != NULL_RTX))
-			match_p = true;
-		    }
-		  if (match_p)
-		    {
-		      /* If we are matching a non-offsettable address
-			 where an offsettable address was expected,
-			 then we must reject this combination, because
-			 we can't reload it.  */
-		      if (curr_alt_offmemok[m]
-			  && MEM_P (*curr_id->operand_loc[m])
-			  && curr_alt[m] == NO_REGS && ! curr_alt_win[m])
-			continue;
-	      
-		      did_match = curr_alt_win[m];
-		    }
-		  else
-		    {
-		      /* Operands don't match.  */
-		      /* Retroactively mark the operand we had to
-			 match as a loser, if it wasn't already and it
-			 wasn't matched to a register constraint (e.g
-			 it might be matched by memory).  */
-		      if (curr_alt_win[m]
-			  && (operand_reg[m] == NULL_RTX || hard_regno[m] < 0))
-			losers++;
-		      invalidate_m = m;
-		      if (curr_alt[m] == NO_REGS)
-			continue;
-	      
-		      /* We prefer no matching alternatives because it
-			 gives more freedom in RA.  */
-		      if (operand_reg[nop] == NULL_RTX
-			  || (find_regno_note (curr_insn, REG_DEAD,
-					       REGNO (operand_reg[nop]))
-			      == NULL_RTX))
-			reject += 2;
-		    }
-		  /* This can be fixed with reloads if the operand we
-		     are supposed to match can be fixed with
-		     reloads.  */
-		  badop = false;
-		  this_alternative = curr_alt[m];
-		  COPY_HARD_REG_SET (this_alternative_set, curr_alt_set[m]);
-
-		  /* If we have to reload this operand and some
-		     previous operand also had to match the same thing
-		     as this operand, we don't know how to do that.
-		     So reject this alternative.  */
-		  if (! did_match)
-		    for (i = 0; i < nop; i++)
-		      if (curr_alt_matches[i] == this_alternative_matches)
-			badop = true;
-	  
 		  break;
-		}
-	
-	      case 'p':
-		this_alternative
-		  = (reg_class_subunion
-		     [this_alternative]
-		     [base_reg_class (VOIDmode, ADDRESS, SCRATCH)]);
-		IOR_HARD_REG_SET (this_alternative_set,
-				  reg_class_contents
-				  [base_reg_class
-				   (VOIDmode, ADDRESS, SCRATCH)]);
-		win = true;
-		badop = false;
-		break;
-	
-	      case TARGET_MEM_CONSTRAINT:
-		if (MEM_P (op)
-		    || (REG_P (op)
-			&& REGNO (op) >= FIRST_PSEUDO_REGISTER
-			&& in_mem_p (REGNO (op))))
-		  win = true;
-		if (CONST_POOL_OK_P (mode, op))
-		  badop = false;
-		constmemok = true;
-		break;
-	
-	      case '<':
-		if (MEM_P (op)
-		    && (GET_CODE (XEXP (op, 0)) == PRE_DEC
-			|| GET_CODE (XEXP (op, 0)) == POST_DEC))
-		  win = true;
-		break;
-	
-	      case '>':
-		if (MEM_P (op)
-		    && (GET_CODE (XEXP (op, 0)) == PRE_INC
-			|| GET_CODE (XEXP (op, 0)) == POST_INC))
-		  win = true;
-		break;
-	
-		/* Memory op whose address is not
-		   offsettable.  */
-	      case 'V':
-		if (MEM_P (op)
-		    && ! offsettable_nonstrict_memref_p (op))
-		  win = true;
-		break;
-	
-		/* Memory operand whose address is offsettable.  */
-	      case 'o':
-		if ((MEM_P (op)
-		     && offsettable_nonstrict_memref_p (op))
-		    || (REG_P (op)
-			&& REGNO (op) >= FIRST_PSEUDO_REGISTER
-			&& in_mem_p (REGNO (op))))
-		  win = true;
-		if (CONST_POOL_OK_P (mode, op) || MEM_P (op))
-		  badop = false;
-		constmemok = true;
-		offmemok = true;
-		break;
-	
-	      case 'E':
-	      case 'F':
-		if (GET_CODE (op) == CONST_DOUBLE
-		    || (GET_CODE (op) == CONST_VECTOR
-			&& (GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT)))
-		  win = true;
-		break;
-	
-	      case 'G':
-	      case 'H':
-		if (GET_CODE (op) == CONST_DOUBLE
-		    && CONST_DOUBLE_OK_FOR_CONSTRAINT_P (op, c, p))
-		  win = true;
-		break;
-	
-	      case 's':
-		if (CONST_INT_P (op)
-		    || (GET_CODE (op) == CONST_DOUBLE && mode == VOIDmode))
-		  break;
-	      case 'i':
-		if (CONSTANT_P (op)
-		    && (! flag_pic || LEGITIMATE_PIC_OPERAND_P (op)))
-		  win = true;
-		break;
-	
-	      case 'n':
-		if (CONST_INT_P (op)
-		    || (GET_CODE (op) == CONST_DOUBLE && mode == VOIDmode))
-		  win = true;
-		break;
-	
-	      case 'I':
-	      case 'J':
-	      case 'K':
-	      case 'L':
-	      case 'M':
-	      case 'N':
-	      case 'O':
-	      case 'P':
-		if (CONST_INT_P (op)
-		    && CONST_OK_FOR_CONSTRAINT_P (INTVAL (op), c, p))
-		  win = true;
-		break;
-	
-	      case 'X':
-		/* This constraint should be excluded by the fast
-		   track.  */
-		gcc_unreachable ();
-		break;
-	
-	      case 'g':
-		if (/* A PLUS is never a valid operand, but LRA can
-		       make it from a register when eliminating
-		       registers.  */
-		    GET_CODE (op) != PLUS
-		    && (! CONSTANT_P (op) || ! flag_pic
-			|| LEGITIMATE_PIC_OPERAND_P (op))
-		    && (! REG_P (op)
-			|| (REGNO (op) >= FIRST_PSEUDO_REGISTER
-			    && in_mem_p (REGNO (op)))))
-		  win = true;
-		/* Drop through into 'r' case.  */
-	
-	      case 'r':
-		this_alternative
-		  = reg_class_subunion[this_alternative][GENERAL_REGS];
-		IOR_HARD_REG_SET (this_alternative_set,
-				  reg_class_contents[GENERAL_REGS]);
-		goto reg;
+		case ',':
+		  c = '\0';
+		  break;
 	
-	      default:
-		if (REG_CLASS_FROM_CONSTRAINT (c, p) == NO_REGS)
+		case '=':  case '+': case '?': case '*': case '!':
+		case ' ': case '\t':
+		  break;
+		  
+		case '%':
+		  /* We only support one commutative marker, the first
+		     one.  We already set commutative above.  */
+		  break;
+		  
+		case '&':
+		  early_clobber_p = true;
+		  break;
+		  
+		case '#':
+		  /* Ignore rest of this alternative.  */
+		  c = '\0';
+		  break;
+		  
+		case '0':  case '1':  case '2':  case '3':  case '4':
+		case '5':  case '6':  case '7':  case '8':  case '9':
 		  {
-#ifdef EXTRA_CONSTRAINT_STR
-		    if (EXTRA_MEMORY_CONSTRAINT (c, p))
+		    int m_hregno, m_offset;
+		    bool match_p;
+		    
+		    m = strtoul (p, &end, 10);
+		    p = end;
+		    len = 0;
+		    gcc_assert (nop > m);
+		    
+		    this_alternative_matches = m;
+		    lra_get_hard_regno_and_offset (*curr_id->operand_loc[m],
+						   &m_hregno, &m_offset);
+		    m_hregno = get_final_hard_regno (m_hregno, m_offset);
+		    /* We are supposed to match a previous operand.
+		       If we do, we win if that one did.  If we do
+		       not, count both of the operands as losers.
+		       (This is too conservative, since most of the
+		       time only a single reload insn will be needed
+		       to make the two operands win.  As a result,
+		       this alternative may be rejected when it is
+		       actually desirable.)  */
+		    /* If it conflicts with others.  */
+		    match_p = false;
+		    if (operands_match_p (*curr_id->operand_loc[nop],
+					  *curr_id->operand_loc[m], m_hregno))
 		      {
-			if (EXTRA_CONSTRAINT_STR (op, c, p))
-			  win = true;
-			/* For regno_equiv_mem_loc we have to
-			   check.  */
-			else if (REG_P (op)
-				 && REGNO (op) >= FIRST_PSEUDO_REGISTER
-				 && in_mem_p (REGNO (op)))
-			  {
-			    /* We could transform spilled memory
-			       finally to indirect memory.  */
-			    if (EXTRA_CONSTRAINT_STR (get_indirect_mem (mode),
-						      c, p))
-			      win = true;
-			  }
-		
-			/* If we didn't already win, we can reload
-			   constants via force_const_mem, and other
-			   MEMs by reloading the address like for
-			   'o'.  */
-			if (CONST_POOL_OK_P (mode, op) || MEM_P (op))
-			  badop = false;
-			constmemok = true;
-			offmemok = true;
-			break;
+			int i;
+			
+			for (i = 0; i < early_clobbered_regs_num; i++)
+			  if (early_clobbered_nops[i] == m)
+			    break;
+			/* We should reject matching of an early
+			   clobber operand if the matching operand is
+			   not dying in the insn.  */
+			if (i >= early_clobbered_regs_num
+			    || operand_reg[nop] == NULL_RTX
+			    || (find_regno_note (curr_insn, REG_DEAD,
+						 REGNO (operand_reg[nop]))
+				!= NULL_RTX))
+			  match_p = true;
 		      }
-		    if (EXTRA_ADDRESS_CONSTRAINT (c, p))
+		    if (match_p)
 		      {
-			if (EXTRA_CONSTRAINT_STR (op, c, p))
-			  win = true;
-		
-			/* If we didn't already win, we can reload the
-			   address into a base register.  */
-			this_alternative
-			  = (reg_class_subunion
-			     [this_alternative]
-			     [base_reg_class (VOIDmode, ADDRESS, SCRATCH)]);
-			IOR_HARD_REG_SET
-			  (this_alternative_set,
-			   reg_class_contents[base_reg_class
-					      (VOIDmode, ADDRESS, SCRATCH)]);
-			badop = false;
-			break;
+			/* If we are matching a non-offsettable
+			   address where an offsettable address was
+			   expected, then we must reject this
+			   combination, because we can't reload
+			   it.  */
+			if (curr_alt_offmemok[m]
+			    && MEM_P (*curr_id->operand_loc[m])
+			    && curr_alt[m] == NO_REGS && ! curr_alt_win[m])
+			  continue;
+			
+			did_match = curr_alt_win[m];
 		      }
-	    
-		    if (EXTRA_CONSTRAINT_STR (op, c, p))
-		      win = true;
-		    else if (REG_P (op)
-			     && REGNO (op) >= FIRST_PSEUDO_REGISTER
-			     && in_mem_p (REGNO (op)))
+		    else
 		      {
-			/* We could transform spilled memory finally
-			   to indirect memory.  */
-			if (EXTRA_CONSTRAINT_STR (get_indirect_mem (mode),
-						  c, p))
-			  win = true;
+			/* Operands don't match.  */
+			/* Retroactively mark the operand we had to
+			   match as a loser, if it wasn't already and
+			   it wasn't matched to a register constraint
+			   (e.g it might be matched by memory).  */
+			if (curr_alt_win[m]
+			    && (operand_reg[m] == NULL_RTX || hard_regno[m] < 0))
+			  {
+			    losers++;
+			    if (curr_alt[m] != NO_REGS)
+			      reload_nregs
+				+= (ira_reg_class_max_nregs[curr_alt[m]]
+				    [GET_MODE (*curr_id->operand_loc[m])]);
+			}
+			invalidate_m = m;
+			if (curr_alt[m] == NO_REGS)
+			  continue;
+			
+			/* We prefer no matching alternatives because
+			   it gives more freedom in RA.  */
+			if (operand_reg[nop] == NULL_RTX
+			    || (find_regno_note (curr_insn, REG_DEAD,
+						 REGNO (operand_reg[nop]))
+				== NULL_RTX))
+			  reject += 2;
 		      }
-#endif
+		    /* This can be fixed with reloads if the operand
+		       we are supposed to match can be fixed with
+		       reloads.  */
+		    badop = false;
+		    this_alternative = curr_alt[m];
+		    COPY_HARD_REG_SET (this_alternative_set, curr_alt_set[m]);
+		    
+		    /* If we have to reload this operand and some
+		       previous operand also had to match the same
+		       thing as this operand, we don't know how to do
+		       that.  So reject this alternative.  */
+		    if (! did_match)
+		      for (i = 0; i < nop; i++)
+			if (curr_alt_matches[i] == this_alternative_matches)
+			  badop = true;
+		    
 		    break;
 		  }
+		  
+		case 'p':
+		  cl = base_reg_class (VOIDmode, ADDRESS, SCRATCH);
+		  this_alternative = reg_class_subunion[this_alternative][cl];
+		  IOR_HARD_REG_SET (this_alternative_set, reg_class_contents[cl]);
+		  if (costly_p)
+		    {
+		      this_costly_alternative
+			= reg_class_subunion[this_costly_alternative][cl];
+		      IOR_HARD_REG_SET (this_costly_alternative_set,
+					reg_class_contents[cl]);
+		    }
+		  win = true;
+		  badop = false;
+		  break;
+		  
+		case TARGET_MEM_CONSTRAINT:
+		  if (MEM_P (op)
+		      || (REG_P (op)
+			  && REGNO (op) >= FIRST_PSEUDO_REGISTER
+			  && in_mem_p (REGNO (op))))
+		    win = true;
+		  if (CONST_POOL_OK_P (mode, op))
+		    badop = false;
+		  constmemok = true;
+		  break;
+		  
+		case '<':
+		  if (MEM_P (op)
+		      && (GET_CODE (XEXP (op, 0)) == PRE_DEC
+			  || GET_CODE (XEXP (op, 0)) == POST_DEC))
+		    win = true;
+		  break;
+		  
+		case '>':
+		  if (MEM_P (op)
+		      && (GET_CODE (XEXP (op, 0)) == PRE_INC
+			  || GET_CODE (XEXP (op, 0)) == POST_INC))
+		    win = true;
+		  break;
+		  
+		/* Memory op whose address is not offsettable.  */
+		case 'V':
+		  if (MEM_P (op)
+		      && ! offsettable_nonstrict_memref_p (op))
+		    win = true;
+		  break;
+		  
+		  /* Memory operand whose address is offsettable.  */
+		case 'o':
+		  if ((MEM_P (op)
+		       && offsettable_nonstrict_memref_p (op))
+		      || (REG_P (op)
+			  && REGNO (op) >= FIRST_PSEUDO_REGISTER
+			  && in_mem_p (REGNO (op))))
+		    win = true;
+		  if (CONST_POOL_OK_P (mode, op) || MEM_P (op))
+		    badop = false;
+		  constmemok = true;
+		  offmemok = true;
+		  break;
+		  
+		case 'E':
+		case 'F':
+		  if (GET_CODE (op) == CONST_DOUBLE
+		      || (GET_CODE (op) == CONST_VECTOR
+			  && (GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT)))
+		    win = true;
+		  break;
+		  
+		case 'G':
+		case 'H':
+		  if (GET_CODE (op) == CONST_DOUBLE
+		      && CONST_DOUBLE_OK_FOR_CONSTRAINT_P (op, c, p))
+		    win = true;
+		  break;
+		  
+		case 's':
+		  if (CONST_INT_P (op)
+		      || (GET_CODE (op) == CONST_DOUBLE && mode == VOIDmode))
+		    break;
+		case 'i':
+		  if (CONSTANT_P (op)
+		      && (! flag_pic || LEGITIMATE_PIC_OPERAND_P (op)))
+		    win = true;
+		  break;
+		  
+		case 'n':
+		  if (CONST_INT_P (op)
+		      || (GET_CODE (op) == CONST_DOUBLE && mode == VOIDmode))
+		    win = true;
+		  break;
 	
-		this_alternative
-		  = (reg_class_subunion
-		     [this_alternative][REG_CLASS_FROM_CONSTRAINT (c, p)]);
-		IOR_HARD_REG_SET
-		  (this_alternative_set,
-		   reg_class_contents[REG_CLASS_FROM_CONSTRAINT (c, p)]);
-	      reg:
-		if (mode == BLKmode)
+		case 'I':
+		case 'J':
+		case 'K':
+		case 'L':
+		case 'M':
+		case 'N':
+		case 'O':
+		case 'P':
+		  if (CONST_INT_P (op)
+		      && CONST_OK_FOR_CONSTRAINT_P (INTVAL (op), c, p))
+		    win = true;
 		  break;
-		winreg = true;
-		if (REG_P (op))
-		  {
-		    if (hard_regno[nop] >= 0
-			&& in_hard_reg_set_p (this_alternative_set,
-					      mode, hard_regno[nop]))
-		      win = true;
-		    else if (hard_regno[nop] < 0
-			     && in_class_p (REGNO (op),
-					    this_alternative, NULL))
-		      win = true;
-		  }
-		break;
-	      }
+		  
+		case 'X':
+		  /* This constraint should be excluded by the fast
+		     track.  */
+		  gcc_unreachable ();
+		  break;
+		  
+		case 'g':
+		  if (/* A PLUS is never a valid operand, but LRA can
+			 make it from a register when eliminating
+			 registers.  */
+		      GET_CODE (op) != PLUS
+		      && (! CONSTANT_P (op) || ! flag_pic
+			  || LEGITIMATE_PIC_OPERAND_P (op))
+		      && (! REG_P (op)
+			  || (REGNO (op) >= FIRST_PSEUDO_REGISTER
+			      && in_mem_p (REGNO (op)))))
+		    win = true;
+		  /* Drop through into 'r' case.  */
+		  
+		case 'r':
+		  this_alternative
+		    = reg_class_subunion[this_alternative][GENERAL_REGS];
+		  IOR_HARD_REG_SET (this_alternative_set,
+				    reg_class_contents[GENERAL_REGS]);
+		  if (costly_p)
+		    {
+		      this_costly_alternative
+			= reg_class_subunion[this_costly_alternative][GENERAL_REGS];
+		      IOR_HARD_REG_SET (this_costly_alternative_set,
+					reg_class_contents[GENERAL_REGS]);
+		    }
+		  goto reg;
+		  
+		default:
+		  if (REG_CLASS_FROM_CONSTRAINT (c, p) == NO_REGS)
+		    {
+#ifdef EXTRA_CONSTRAINT_STR
+		      if (EXTRA_MEMORY_CONSTRAINT (c, p))
+			{
+			  if (EXTRA_CONSTRAINT_STR (op, c, p))
+			    win = true;
+			  /* For regno_equiv_mem_loc we have to
+			     check.  */
+			  else if (REG_P (op)
+				   && REGNO (op) >= FIRST_PSEUDO_REGISTER
+				   && in_mem_p (REGNO (op)))
+			    {
+			      /* We could transform spilled memory
+				 finally to indirect memory.  */
+			      if (EXTRA_CONSTRAINT_STR (get_indirect_mem (mode),
+							c, p))
+				win = true;
+			    }
+			  
+			  /* If we didn't already win, we can reload
+			     constants via force_const_mem, and other
+			     MEMs by reloading the address like for
+			     'o'.  */
+			  if (CONST_POOL_OK_P (mode, op) || MEM_P (op))
+			    badop = false;
+			  constmemok = true;
+			  offmemok = true;
+			  break;
+			}
+		      if (EXTRA_ADDRESS_CONSTRAINT (c, p))
+			{
+			  if (EXTRA_CONSTRAINT_STR (op, c, p))
+			    win = true;
+			  
+			  /* If we didn't already win, we can reload
+			     the address into a base register.  */
+			  cl = base_reg_class (VOIDmode, ADDRESS, SCRATCH);
+			  this_alternative
+			    = reg_class_subunion[this_alternative][cl];
+			  IOR_HARD_REG_SET (this_alternative_set,
+					    reg_class_contents[cl]);
+			  if (costly_p)
+			    {
+			      this_costly_alternative
+				= reg_class_subunion[this_costly_alternative][cl];
+			      IOR_HARD_REG_SET (this_costly_alternative_set,
+						reg_class_contents[cl]);
+			    }
+			  badop = false;
+			  break;
+			}
+		      
+		      if (EXTRA_CONSTRAINT_STR (op, c, p))
+			win = true;
+		      else if (REG_P (op)
+			       && REGNO (op) >= FIRST_PSEUDO_REGISTER
+			       && in_mem_p (REGNO (op)))
+			{
+			  /* We could transform spilled memory finally
+			     to indirect memory.  */
+			  if (EXTRA_CONSTRAINT_STR (get_indirect_mem (mode),
+						    c, p))
+			    win = true;
+			}
+#endif
+		      break;
+		    }
+		  
+		  cl = REG_CLASS_FROM_CONSTRAINT (c, p);
+		  this_alternative = reg_class_subunion[this_alternative][cl];
+		  IOR_HARD_REG_SET (this_alternative_set, reg_class_contents[cl]);
+		  if (costly_p)
+		    {
+		      this_costly_alternative
+			= reg_class_subunion[this_costly_alternative][cl];
+		      IOR_HARD_REG_SET (this_costly_alternative_set,
+					reg_class_contents[cl]);
+		    }
+		reg:
+		  if (mode == BLKmode)
+		    break;
+		  winreg = true;
+		  if (REG_P (op))
+		    {
+		      if (hard_regno[nop] >= 0
+			  && in_hard_reg_set_p (this_alternative_set,
+						mode, hard_regno[nop]))
+			win = true;
+		      else if (hard_regno[nop] < 0
+			       && in_class_p (REGNO (op),
+					      this_alternative, NULL))
+			win = true;
+		    }
+		  break;
+		}
+	      if (c != ' ' && c != '\t')
+		costly_p = c == '*';
+	    }
 	  while ((p += len), c);
   
 	  /* If this operand could be handled with a reg, and some reg
@@ -1888,10 +1925,24 @@ process_alt_operands (int only_alternati
 	  if (win)
 	    {
 	      this_alternative_win = true;
-	      if (operand_reg[nop] != NULL_RTX && hard_regno[nop] < 0)
-		/* Prefer won reg to spilled pseudo under other equal
-		   conditions.  */
-		reject++;
+	      if (operand_reg[nop] != NULL_RTX)
+		{
+		  if (hard_regno[nop] >= 0)
+		    {
+		      if (in_hard_reg_set_p (this_costly_alternative_set,
+					     mode, hard_regno[nop]))
+			reject++;
+		    }
+		  else
+		    {
+		      /* Prefer won reg to spilled pseudo under other equal
+			 conditions.  */
+		      reject++;
+		      if (in_class_p (REGNO (operand_reg[nop]),
+				      this_costly_alternative, NULL))
+			reject++;
+		    }
+		}
 	    }
 	  else if (did_match)
 	    this_alternative_match_win = true;
@@ -1906,6 +1957,8 @@ process_alt_operands (int only_alternati
 		       (reg_class_contents[this_alternative],
 			lra_no_alloc_regs)));
 	      this_alternative_offmemok = offmemok;
+	      if (this_costly_alternative != NO_REGS)
+		reject++;
 	      /* If the operand is dying, has a matching constraint,
 		 and satisfies constraints of the matched operand
 		 which failed to satisfy the own constraints, we do
@@ -2003,7 +2056,7 @@ process_alt_operands (int only_alternati
 	      /* Input reloads can be inherited more often than output
 		 reloads can be removed, so penalize output
 		 reloads.  */
-	      if (curr_static_id->operand[nop].type != OP_IN)
+	      if (!REG_P (op) || curr_static_id->operand[nop].type != OP_IN)
 		reject++;
 	      /* SUBREGS ??? */
 	      if (this_alternative_matches >= 0)
@@ -2012,6 +2065,9 @@ process_alt_operands (int only_alternati
 		}
 	      else if (no_regs_p && ! this_alternative_offmemok && ! constmemok)
 		goto fail;
+
+	      if (! no_regs_p)
+		reload_nregs += ira_reg_class_max_nregs[this_alternative][mode];
 	    }
   
 	  if (early_clobber_p)
@@ -2128,7 +2184,9 @@ process_alt_operands (int only_alternati
 			  < best_small_class_operands_num
 			  || (small_class_operands_num
 			      == best_small_class_operands_num
-			      && best_reload_sum < reload_sum))))))
+			      && (reload_nregs < best_reload_nregs
+				  || (reload_nregs == best_reload_nregs
+				      && best_reload_sum < reload_sum))))))))
 	{
 	  for (nop = 0; nop < n_operands; nop++)
 	    {
@@ -2145,6 +2203,7 @@ process_alt_operands (int only_alternati
 	  best_overall = overall;
 	  best_losers = losers;
 	  best_small_class_operands_num = small_class_operands_num;
+	  best_reload_nregs = reload_nregs;
 	  best_reload_sum = reload_sum;
 	  goal_alt_number = nalt;
 	}
@@ -3045,7 +3104,8 @@ curr_insn_transform (void)
 	  return false;
 	}
     }
-  if (before != NULL_RTX || after != NULL_RTX || max_regno_before != max_reg_num ())
+  if (before != NULL_RTX || after != NULL_RTX
+      || max_regno_before != max_reg_num ())
     change_p = true;
   if (change_p)
     {
@@ -3504,7 +3564,8 @@ lra_inheritance (void)
 				       * lra_constraint_new_regno_start);
   memset (reload_insn_check, 0,
 	  sizeof (int) * lra_constraint_new_regno_start);
-  reload_insn = (rtx *) xmalloc (sizeof (rtx) * lra_constraint_new_regno_start);
+  reload_insn
+    = (rtx *) xmalloc (sizeof (rtx) * lra_constraint_new_regno_start);
   FOR_EACH_BB (bb)
     {
       head = BB_HEAD (bb);
Index: lra-eliminations.c
===================================================================
--- lra-eliminations.c	(revision 178734)
+++ lra-eliminations.c	(working copy)
@@ -671,49 +671,46 @@ mark_not_eliminable (rtx x)
     case POST_DEC:
     case POST_MODIFY:
     case PRE_MODIFY:
-      /* If we modify the source of an elimination rule, disable it.  */
-      for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
-	if (ep->from_rtx == XEXP (x, 0)
-	    || (ep->to_rtx == XEXP (x, 0)
-		&& ep->to_rtx != hard_frame_pointer_rtx))
-	  setup_can_eliminate (ep, false);
-
-      /* These two aren't unary operators.  */
-      if (code == POST_MODIFY || code == PRE_MODIFY)
-	break;
-
-      mark_not_eliminable (XEXP (x, 0));
-      return;
-
-    case SUBREG:
-      mark_not_eliminable (SUBREG_REG (x));
+      if (REG_P (XEXP (x, 0)) && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER)
+	/* If we modify the source of an elimination rule, disable it.  */
+	for (ep = reg_eliminate;
+	     ep < &reg_eliminate[NUM_ELIMINABLE_REGS];
+	       ep++)
+	  if (ep->from_rtx == XEXP (x, 0)
+	      || (ep->to_rtx == XEXP (x, 0)
+		  && ep->to_rtx != hard_frame_pointer_rtx))
+	    setup_can_eliminate (ep, false);
       return;
 
     case USE:
-      /* If using a register that is the source of an eliminate we still
-	 think can be performed, note it cannot be performed since we don't
-	 know how this register is used.  */
-      for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
-	if (ep->from_rtx == XEXP (x, 0) && ep->to_rtx != hard_frame_pointer_rtx)
-	  setup_can_eliminate (ep, false);
-
-      mark_not_eliminable (XEXP (x, 0));
+      if (REG_P (XEXP (x, 0)) && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER)
+	/* If using a register that is the source of an eliminate we
+	   still think can be performed, note it cannot be performed
+	   since we don't know how this register is used.  */
+	for (ep = reg_eliminate;
+	     ep < &reg_eliminate[NUM_ELIMINABLE_REGS];
+	     ep++)
+	  if (ep->from_rtx == XEXP (x, 0)
+	      && ep->to_rtx != hard_frame_pointer_rtx)
+	    setup_can_eliminate (ep, false);
       return;
 
     case CLOBBER:
-      /* If clobbering a register that is the replacement register for an
-	 elimination we still think can be performed, note that it cannot
-	 be performed.  Otherwise, we need not be concerned about it.  */
-      for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
-	if (ep->to_rtx == XEXP (x, 0) && ep->to_rtx != hard_frame_pointer_rtx)
-	  setup_can_eliminate (ep, false);
-
-      mark_not_eliminable (XEXP (x, 0));
+      if (REG_P (XEXP (x, 0)) && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER)
+	/* If clobbering a register that is the replacement register for an
+	   elimination we still think can be performed, note that it cannot
+	   be performed.  Otherwise, we need not be concerned about it.  */
+	for (ep = reg_eliminate;
+	     ep < &reg_eliminate[NUM_ELIMINABLE_REGS];
+	     ep++)
+	  if (ep->to_rtx == XEXP (x, 0)
+	      && ep->to_rtx != hard_frame_pointer_rtx)
+	    setup_can_eliminate (ep, false);
       return;
 
     case SET:
       /* Check for setting a register that we know about.  */
-      if (REG_P (SET_DEST (x)))
+      if (REG_P (SET_DEST (x)) && REGNO (SET_DEST (x)) < FIRST_PSEUDO_REGISTER)
 	{
 	  /* See if this is setting the replacement register for an
 	     elimination.
