diff mbox

[1/5] Flatten recog_op_alt and reorder entries

Message ID 87ioomfhat.fsf_-_@talisman.default
State New
Headers show

Commit Message

Richard Sandiford May 31, 2014, 9:06 a.m. UTC
As described in the covering note, this patch converts recog_op_alt
into a flat array and orders the entries in the same way as the
LRA cache.  Several places just want the information for alternative
which_alternative, so I added a convenience function for that.

Thanks,
Richard


gcc/
	* recog.h (recog_op_alt): Convert to a flat array.
	(which_op_alt): New function.
	* recog.c (recog_op_alt): Convert to a flat array.
	(preprocess_constraints): Update accordingly, grouping all
	operands of the same alternative together, rather than the
	other way around.
	* ira-lives.c (check_and_make_def_conflict): Likewise.
	(make_early_clobber_and_input_conflicts): Likewise.
	* config/i386/i386.c (ix86_legitimate_combined_insn): Likewise.
	* reg-stack.c (check_asm_stack_operands): Use which_op_alt.
	(subst_asm_stack_regs): Likewise.
	* regcprop.c (copyprop_hardreg_forward_1): Likewise.
	* regrename.c (hide_operands, record_out_operands): Likewise.
	(build_def_use): Likewise.
	* sel-sched.c (get_reg_class): Likewise.
	* config/arm/arm.c (note_invalid_constants): Likewise.

Comments

Jeff Law June 3, 2014, 9:50 p.m. UTC | #1
On 05/31/14 03:06, Richard Sandiford wrote:
> As described in the covering note, this patch converts recog_op_alt
> into a flat array and orders the entries in the same way as the
> LRA cache.  Several places just want the information for alternative
> which_alternative, so I added a convenience function for that.
>
> Thanks,
> Richard
>
>
> gcc/
> 	* recog.h (recog_op_alt): Convert to a flat array.
> 	(which_op_alt): New function.
> 	* recog.c (recog_op_alt): Convert to a flat array.
> 	(preprocess_constraints): Update accordingly, grouping all
> 	operands of the same alternative together, rather than the
> 	other way around.
> 	* ira-lives.c (check_and_make_def_conflict): Likewise.
> 	(make_early_clobber_and_input_conflicts): Likewise.
> 	* config/i386/i386.c (ix86_legitimate_combined_insn): Likewise.
> 	* reg-stack.c (check_asm_stack_operands): Use which_op_alt.
> 	(subst_asm_stack_regs): Likewise.
> 	* regcprop.c (copyprop_hardreg_forward_1): Likewise.
> 	* regrename.c (hide_operands, record_out_operands): Likewise.
> 	(build_def_use): Likewise.
> 	* sel-sched.c (get_reg_class): Likewise.
> 	* config/arm/arm.c (note_invalid_constants): Likewise.
Largely mechanical.  Looks good to me.

Jeff
diff mbox

Patch

Index: gcc/recog.h
===================================================================
--- gcc/recog.h	2014-05-31 08:54:10.351219264 +0100
+++ gcc/recog.h	2014-05-31 08:57:21.608789337 +0100
@@ -256,9 +256,20 @@  struct recog_data_d
 
 extern struct recog_data_d recog_data;
 
-/* Contains a vector of operand_alternative structures for every operand.
-   Set up by preprocess_constraints.  */
-extern struct operand_alternative recog_op_alt[MAX_RECOG_OPERANDS][MAX_RECOG_ALTERNATIVES];
+extern struct operand_alternative recog_op_alt[MAX_RECOG_OPERANDS
+					       * MAX_RECOG_ALTERNATIVES];
+
+/* Return a pointer to an array in which index OP describes the constraints
+   on operand OP of the current instruction alternative (which_alternative).
+   Only valid after calling preprocess_constraints and constrain_operands.  */
+
+inline static operand_alternative *
+which_op_alt ()
+{
+  gcc_checking_assert (IN_RANGE (which_alternative, 0,
+				 recog_data.n_alternatives - 1));
+  return &recog_op_alt[which_alternative * recog_data.n_operands];
+}
 
 /* A table defined in insn-output.c that give information about
    each insn-code value.  */
Index: gcc/recog.c
===================================================================
--- gcc/recog.c	2014-05-31 08:54:10.351219264 +0100
+++ gcc/recog.c	2014-05-31 08:57:57.642085058 +0100
@@ -78,9 +78,11 @@  struct target_recog *this_target_recog =
 
 struct recog_data_d recog_data;
 
-/* Contains a vector of operand_alternative structures for every operand.
+/* Contains a vector of operand_alternative structures, such that
+   operand OP of alternative A is at index A * n_operands + OP.
    Set up by preprocess_constraints.  */
-struct operand_alternative recog_op_alt[MAX_RECOG_OPERANDS][MAX_RECOG_ALTERNATIVES];
+struct operand_alternative recog_op_alt[MAX_RECOG_OPERANDS
+					* MAX_RECOG_ALTERNATIVES];
 
 /* On return from `constrain_operands', indicate which alternative
    was satisfied.  */
@@ -2330,24 +2332,25 @@  preprocess_constraints (void)
 {
   int i;
 
-  for (i = 0; i < recog_data.n_operands; i++)
-    memset (recog_op_alt[i], 0, (recog_data.n_alternatives
-				 * sizeof (struct operand_alternative)));
+  int n_operands = recog_data.n_operands;
+  int n_alternatives = recog_data.n_alternatives;
+  int n_entries = n_operands * n_alternatives;
+  memset (recog_op_alt, 0, n_entries * sizeof (struct operand_alternative));
 
-  for (i = 0; i < recog_data.n_operands; i++)
+  for (i = 0; i < n_operands; i++)
     {
       int j;
       struct operand_alternative *op_alt;
       const char *p = recog_data.constraints[i];
 
-      op_alt = recog_op_alt[i];
+      op_alt = recog_op_alt;
 
-      for (j = 0; j < recog_data.n_alternatives; j++)
+      for (j = 0; j < n_alternatives; j++, op_alt += n_operands)
 	{
-	  op_alt[j].cl = NO_REGS;
-	  op_alt[j].constraint = p;
-	  op_alt[j].matches = -1;
-	  op_alt[j].matched = -1;
+	  op_alt[i].cl = NO_REGS;
+	  op_alt[i].constraint = p;
+	  op_alt[i].matches = -1;
+	  op_alt[i].matched = -1;
 
 	  if (!TEST_BIT (recog_data.enabled_alternatives, j))
 	    {
@@ -2357,7 +2360,7 @@  preprocess_constraints (void)
 
 	  if (*p == '\0' || *p == ',')
 	    {
-	      op_alt[j].anything_ok = 1;
+	      op_alt[i].anything_ok = 1;
 	      continue;
 	    }
 
@@ -2385,77 +2388,77 @@  preprocess_constraints (void)
 		  break;
 
 		case '?':
-		  op_alt[j].reject += 6;
+		  op_alt[i].reject += 6;
 		  break;
 		case '!':
-		  op_alt[j].reject += 600;
+		  op_alt[i].reject += 600;
 		  break;
 		case '&':
-		  op_alt[j].earlyclobber = 1;
+		  op_alt[i].earlyclobber = 1;
 		  break;
 
 		case '0': case '1': case '2': case '3': case '4':
 		case '5': case '6': case '7': case '8': case '9':
 		  {
 		    char *end;
-		    op_alt[j].matches = strtoul (p, &end, 10);
-		    recog_op_alt[op_alt[j].matches][j].matched = i;
+		    op_alt[i].matches = strtoul (p, &end, 10);
+		    op_alt[op_alt[i].matches].matched = i;
 		    p = end;
 		  }
 		  continue;
 
 		case TARGET_MEM_CONSTRAINT:
-		  op_alt[j].memory_ok = 1;
+		  op_alt[i].memory_ok = 1;
 		  break;
 		case '<':
-		  op_alt[j].decmem_ok = 1;
+		  op_alt[i].decmem_ok = 1;
 		  break;
 		case '>':
-		  op_alt[j].incmem_ok = 1;
+		  op_alt[i].incmem_ok = 1;
 		  break;
 		case 'V':
-		  op_alt[j].nonoffmem_ok = 1;
+		  op_alt[i].nonoffmem_ok = 1;
 		  break;
 		case 'o':
-		  op_alt[j].offmem_ok = 1;
+		  op_alt[i].offmem_ok = 1;
 		  break;
 		case 'X':
-		  op_alt[j].anything_ok = 1;
+		  op_alt[i].anything_ok = 1;
 		  break;
 
 		case 'p':
-		  op_alt[j].is_address = 1;
-		  op_alt[j].cl = reg_class_subunion[(int) op_alt[j].cl]
+		  op_alt[i].is_address = 1;
+		  op_alt[i].cl = reg_class_subunion[(int) op_alt[i].cl]
 		      [(int) base_reg_class (VOIDmode, ADDR_SPACE_GENERIC,
 					     ADDRESS, SCRATCH)];
 		  break;
 
 		case 'g':
 		case 'r':
-		  op_alt[j].cl =
-		   reg_class_subunion[(int) op_alt[j].cl][(int) GENERAL_REGS];
+		  op_alt[i].cl =
+		   reg_class_subunion[(int) op_alt[i].cl][(int) GENERAL_REGS];
 		  break;
 
 		default:
 		  if (EXTRA_MEMORY_CONSTRAINT (c, p))
 		    {
-		      op_alt[j].memory_ok = 1;
+		      op_alt[i].memory_ok = 1;
 		      break;
 		    }
 		  if (EXTRA_ADDRESS_CONSTRAINT (c, p))
 		    {
-		      op_alt[j].is_address = 1;
-		      op_alt[j].cl
+		      op_alt[i].is_address = 1;
+		      op_alt[i].cl
 			= (reg_class_subunion
-			   [(int) op_alt[j].cl]
+			   [(int) op_alt[i].cl]
 			   [(int) base_reg_class (VOIDmode, ADDR_SPACE_GENERIC,
 						  ADDRESS, SCRATCH)]);
 		      break;
 		    }
 
-		  op_alt[j].cl
+		  op_alt[i].cl
 		    = (reg_class_subunion
-		       [(int) op_alt[j].cl]
+		       [(int) op_alt[i].cl]
 		       [(int) REG_CLASS_FROM_CONSTRAINT ((unsigned char) c, p)]);
 		  break;
 		}
Index: gcc/ira-lives.c
===================================================================
--- gcc/ira-lives.c	2014-05-31 08:54:10.351219264 +0100
+++ gcc/ira-lives.c	2014-05-31 08:54:12.238234755 +0100
@@ -624,30 +624,35 @@  check_and_make_def_conflict (int alt, in
 
   advance_p = true;
 
-  for (use = 0; use < recog_data.n_operands; use++)
+  int n_operands = recog_data.n_operands;
+  operand_alternative *op_alt = &recog_op_alt[alt * n_operands];
+  for (use = 0; use < n_operands; use++)
     {
       int alt1;
 
       if (use == def || recog_data.operand_type[use] == OP_OUT)
 	continue;
 
-      if (recog_op_alt[use][alt].anything_ok)
+      if (op_alt[use].anything_ok)
 	use_cl = ALL_REGS;
       else
-	use_cl = recog_op_alt[use][alt].cl;
+	use_cl = op_alt[use].cl;
 
       /* If there's any alternative that allows USE to match DEF, do not
 	 record a conflict.  If that causes us to create an invalid
 	 instruction due to the earlyclobber, reload must fix it up.  */
       for (alt1 = 0; alt1 < recog_data.n_alternatives; alt1++)
-	if (recog_op_alt[use][alt1].matches == def
-	    || (use < recog_data.n_operands - 1
-		&& recog_data.constraints[use][0] == '%'
-		&& recog_op_alt[use + 1][alt1].matches == def)
-	    || (use >= 1
-		&& recog_data.constraints[use - 1][0] == '%'
-		&& recog_op_alt[use - 1][alt1].matches == def))
-	  break;
+	{
+	  operand_alternative *op_alt1 = &recog_op_alt[alt1 * n_operands];
+	  if (op_alt1[use].matches == def
+	      || (use < n_operands - 1
+		  && recog_data.constraints[use][0] == '%'
+		  && op_alt1[use + 1].matches == def)
+	      || (use >= 1
+		  && recog_data.constraints[use - 1][0] == '%'
+		  && op_alt1[use - 1].matches == def))
+	    break;
+	}
 
       if (alt1 < recog_data.n_alternatives)
 	continue;
@@ -655,15 +660,15 @@  check_and_make_def_conflict (int alt, in
       advance_p = check_and_make_def_use_conflict (dreg, orig_dreg, def_cl,
 						   use, use_cl, advance_p);
 
-      if ((use_match = recog_op_alt[use][alt].matches) >= 0)
+      if ((use_match = op_alt[use].matches) >= 0)
 	{
 	  if (use_match == def)
 	    continue;
 
-	  if (recog_op_alt[use_match][alt].anything_ok)
+	  if (op_alt[use_match].anything_ok)
 	    use_cl = ALL_REGS;
 	  else
-	    use_cl = recog_op_alt[use_match][alt].cl;
+	    use_cl = op_alt[use_match].cl;
 	  advance_p = check_and_make_def_use_conflict (dreg, orig_dreg, def_cl,
 						       use, use_cl, advance_p);
 	}
@@ -681,26 +686,29 @@  make_early_clobber_and_input_conflicts (
   int def, def_match;
   enum reg_class def_cl;
 
-  for (alt = 0; alt < recog_data.n_alternatives; alt++)
-    for (def = 0; def < recog_data.n_operands; def++)
+  int n_alternatives = recog_data.n_alternatives;
+  int n_operands = recog_data.n_operands;
+  operand_alternative *op_alt = recog_op_alt;
+  for (alt = 0; alt < n_alternatives; alt++, op_alt += n_operands)
+    for (def = 0; def < n_operands; def++)
       {
 	def_cl = NO_REGS;
-	if (recog_op_alt[def][alt].earlyclobber)
+	if (op_alt[def].earlyclobber)
 	  {
-	    if (recog_op_alt[def][alt].anything_ok)
+	    if (op_alt[def].anything_ok)
 	      def_cl = ALL_REGS;
 	    else
-	      def_cl = recog_op_alt[def][alt].cl;
+	      def_cl = op_alt[def].cl;
 	    check_and_make_def_conflict (alt, def, def_cl);
 	  }
-	if ((def_match = recog_op_alt[def][alt].matches) >= 0
-	    && (recog_op_alt[def_match][alt].earlyclobber
-		|| recog_op_alt[def][alt].earlyclobber))
+	if ((def_match = op_alt[def].matches) >= 0
+	    && (op_alt[def_match].earlyclobber
+		|| op_alt[def].earlyclobber))
 	  {
-	    if (recog_op_alt[def_match][alt].anything_ok)
+	    if (op_alt[def_match].anything_ok)
 	      def_cl = ALL_REGS;
 	    else
-	      def_cl = recog_op_alt[def_match][alt].cl;
+	      def_cl = op_alt[def_match].cl;
 	    check_and_make_def_conflict (alt, def, def_cl);
 	  }
       }
Index: gcc/config/i386/i386.c
===================================================================
--- gcc/config/i386/i386.c	2014-05-31 08:54:10.351219264 +0100
+++ gcc/config/i386/i386.c	2014-05-31 08:54:12.236234739 +0100
@@ -5828,11 +5828,13 @@  ix86_legitimate_combined_insn (rtx insn)
       extract_insn (insn);
       preprocess_constraints ();
 
-      for (i = 0; i < recog_data.n_operands; i++)
+      int n_operands = recog_data.n_operands;
+      int n_alternatives = recog_data.n_alternatives;
+      for (i = 0; i < n_operands; i++)
 	{
 	  rtx op = recog_data.operand[i];
 	  enum machine_mode mode = GET_MODE (op);
-	  struct operand_alternative *op_alt;
+	  operand_alternative *op_alt;
 	  int offset = 0;
 	  bool win;
 	  int j;
@@ -5867,19 +5869,19 @@  ix86_legitimate_combined_insn (rtx insn)
 	  if (!(REG_P (op) && HARD_REGISTER_P (op)))
 	    continue;
 
-	  op_alt = recog_op_alt[i];
+	  op_alt = recog_op_alt;
 
 	  /* Operand has no constraints, anything is OK.  */
- 	  win = !recog_data.n_alternatives;
+ 	  win = !n_alternatives;
 
-	  for (j = 0; j < recog_data.n_alternatives; j++)
+	  for (j = 0; j < n_alternatives; j++, op_alt += n_operands)
 	    {
-	      if (op_alt[j].anything_ok
-		  || (op_alt[j].matches != -1
+	      if (op_alt[i].anything_ok
+		  || (op_alt[i].matches != -1
 		      && operands_match_p
 			  (recog_data.operand[i],
-			   recog_data.operand[op_alt[j].matches]))
-		  || reg_fits_class_p (op, op_alt[j].cl, offset, mode))
+			   recog_data.operand[op_alt[i].matches]))
+		  || reg_fits_class_p (op, op_alt[i].cl, offset, mode))
 		{
 		  win = true;
 		  break;
Index: gcc/reg-stack.c
===================================================================
--- gcc/reg-stack.c	2014-05-31 08:54:10.351219264 +0100
+++ gcc/reg-stack.c	2014-05-31 08:57:21.608789337 +0100
@@ -462,7 +462,6 @@  check_asm_stack_operands (rtx insn)
 
   char reg_used_as_output[FIRST_PSEUDO_REGISTER];
   char implicitly_dies[FIRST_PSEUDO_REGISTER];
-  int alt;
 
   rtx *clobber_reg = 0;
   int n_inputs, n_outputs;
@@ -471,19 +470,19 @@  check_asm_stack_operands (rtx insn)
      alternative matches, this asm is malformed.  */
   extract_insn (insn);
   constrain_operands (1);
-  alt = which_alternative;
 
   preprocess_constraints ();
 
   get_asm_operands_in_out (body, &n_outputs, &n_inputs);
 
-  if (alt < 0)
+  if (which_alternative < 0)
     {
       malformed_asm = 1;
       /* Avoid further trouble with this insn.  */
       PATTERN (insn) = gen_rtx_USE (VOIDmode, const0_rtx);
       return 0;
     }
+  operand_alternative *op_alt = which_op_alt ();
 
   /* Strip SUBREGs here to make the following code simpler.  */
   for (i = 0; i < recog_data.n_operands; i++)
@@ -527,7 +526,7 @@  check_asm_stack_operands (rtx insn)
   for (i = 0; i < n_outputs; i++)
     if (STACK_REG_P (recog_data.operand[i]))
       {
-	if (reg_class_size[(int) recog_op_alt[i][alt].cl] != 1)
+	if (reg_class_size[(int) op_alt[i].cl] != 1)
 	  {
 	    error_for_asm (insn, "output constraint %d must specify a single register", i);
 	    malformed_asm = 1;
@@ -582,7 +581,7 @@  check_asm_stack_operands (rtx insn)
 	  if (operands_match_p (clobber_reg[j], recog_data.operand[i]))
 	    break;
 
-	if (j < n_clobbers || recog_op_alt[i][alt].matches >= 0)
+	if (j < n_clobbers || op_alt[i].matches >= 0)
 	  implicitly_dies[REGNO (recog_data.operand[i])] = 1;
       }
 
@@ -610,7 +609,7 @@  check_asm_stack_operands (rtx insn)
      record any earlyclobber.  */
 
   for (i = n_outputs; i < n_outputs + n_inputs; i++)
-    if (recog_op_alt[i][alt].matches == -1)
+    if (op_alt[i].matches == -1)
       {
 	int j;
 
@@ -2006,7 +2005,6 @@  subst_stack_regs_pat (rtx insn, stack_pt
 subst_asm_stack_regs (rtx insn, stack_ptr regstack)
 {
   rtx body = PATTERN (insn);
-  int alt;
 
   rtx *note_reg;		/* Array of note contents */
   rtx **note_loc;		/* Address of REG field of each note */
@@ -2030,14 +2028,12 @@  subst_asm_stack_regs (rtx insn, stack_pt
      such an insn in check_asm_stack_operands.  */
   extract_insn (insn);
   constrain_operands (1);
-  alt = which_alternative;
 
   preprocess_constraints ();
+  operand_alternative *op_alt = which_op_alt ();
 
   get_asm_operands_in_out (body, &n_outputs, &n_inputs);
 
-  gcc_assert (alt >= 0);
-
   /* Strip SUBREGs here to make the following code simpler.  */
   for (i = 0; i < recog_data.n_operands; i++)
     if (GET_CODE (recog_data.operand[i]) == SUBREG
@@ -2118,9 +2114,8 @@  subst_asm_stack_regs (rtx insn, stack_pt
 
   for (i = n_outputs; i < n_outputs + n_inputs; i++)
     if (STACK_REG_P (recog_data.operand[i])
-	&& reg_class_subset_p (recog_op_alt[i][alt].cl,
-			       FLOAT_REGS)
-	&& recog_op_alt[i][alt].cl != FLOAT_REGS)
+	&& reg_class_subset_p (op_alt[i].cl, FLOAT_REGS)
+	&& op_alt[i].cl != FLOAT_REGS)
       {
 	/* If an operand needs to be in a particular reg in
 	   FLOAT_REGS, the constraint was either 't' or 'u'.  Since
@@ -2208,7 +2203,7 @@  subst_asm_stack_regs (rtx insn, stack_pt
 	  if (operands_match_p (clobber_reg[j], recog_data.operand[i]))
 	    break;
 
-	if (j < n_clobbers || recog_op_alt[i][alt].matches >= 0)
+	if (j < n_clobbers || op_alt[i].matches >= 0)
 	  {
 	    /* recog_data.operand[i] might not be at the top of stack.
 	       But that's OK, because all we need to do is pop the
Index: gcc/regcprop.c
===================================================================
--- gcc/regcprop.c	2014-05-31 08:54:10.351219264 +0100
+++ gcc/regcprop.c	2014-05-31 08:57:21.608789337 +0100
@@ -745,7 +745,7 @@  copyprop_hardreg_forward_1 (basic_block
 
   for (insn = BB_HEAD (bb); ; insn = NEXT_INSN (insn))
     {
-      int n_ops, i, alt, predicated;
+      int n_ops, i, predicated;
       bool is_asm, any_replacements;
       rtx set;
       rtx link;
@@ -775,7 +775,7 @@  copyprop_hardreg_forward_1 (basic_block
       if (! constrain_operands (1))
 	fatal_insn_not_found (insn);
       preprocess_constraints ();
-      alt = which_alternative;
+      operand_alternative *op_alt = which_op_alt ();
       n_ops = recog_data.n_operands;
       is_asm = asm_noperands (PATTERN (insn)) >= 0;
 
@@ -786,10 +786,10 @@  copyprop_hardreg_forward_1 (basic_block
       predicated = GET_CODE (PATTERN (insn)) == COND_EXEC;
       for (i = 0; i < n_ops; ++i)
 	{
-	  int matches = recog_op_alt[i][alt].matches;
+	  int matches = op_alt[i].matches;
 	  if (matches >= 0)
-	    recog_op_alt[i][alt].cl = recog_op_alt[matches][alt].cl;
-	  if (matches >= 0 || recog_op_alt[i][alt].matched >= 0
+	    op_alt[i].cl = op_alt[matches].cl;
+	  if (matches >= 0 || op_alt[i].matched >= 0
 	      || (predicated && recog_data.operand_type[i] == OP_OUT))
 	    recog_data.operand_type[i] = OP_INOUT;
 	}
@@ -800,7 +800,7 @@  copyprop_hardreg_forward_1 (basic_block
 
       /* For each earlyclobber operand, zap the value data.  */
       for (i = 0; i < n_ops; i++)
-	if (recog_op_alt[i][alt].earlyclobber)
+	if (op_alt[i].earlyclobber)
 	  kill_value (recog_data.operand[i], vd);
 
       /* Within asms, a clobber cannot overlap inputs or outputs.
@@ -814,7 +814,7 @@  copyprop_hardreg_forward_1 (basic_block
 
       /* Kill all early-clobbered operands.  */
       for (i = 0; i < n_ops; i++)
-	if (recog_op_alt[i][alt].earlyclobber)
+	if (op_alt[i].earlyclobber)
 	  kill_value (recog_data.operand[i], vd);
 
       /* If we have dead sets in the insn, then we need to note these as we
@@ -936,17 +936,15 @@  copyprop_hardreg_forward_1 (basic_block
 
 	  if (recog_data.operand_type[i] == OP_IN)
 	    {
-	      if (recog_op_alt[i][alt].is_address)
+	      if (op_alt[i].is_address)
 		replaced[i]
 		  = replace_oldest_value_addr (recog_data.operand_loc[i],
-					       recog_op_alt[i][alt].cl,
-					       VOIDmode, ADDR_SPACE_GENERIC,
-					       insn, vd);
+					       op_alt[i].cl, VOIDmode,
+					       ADDR_SPACE_GENERIC, insn, vd);
 	      else if (REG_P (recog_data.operand[i]))
 		replaced[i]
 		  = replace_oldest_value_reg (recog_data.operand_loc[i],
-					      recog_op_alt[i][alt].cl,
-					      insn, vd);
+					      op_alt[i].cl, insn, vd);
 	      else if (MEM_P (recog_data.operand[i]))
 		replaced[i] = replace_oldest_value_mem (recog_data.operand[i],
 							insn, vd);
Index: gcc/regrename.c
===================================================================
--- gcc/regrename.c	2014-05-31 08:54:10.351219264 +0100
+++ gcc/regrename.c	2014-05-31 08:57:21.608789337 +0100
@@ -1427,7 +1427,7 @@  hide_operands (int n_ops, rtx *old_opera
 	       unsigned HOST_WIDE_INT do_not_hide, bool inout_and_ec_only)
 {
   int i;
-  int alt = which_alternative;
+  operand_alternative *op_alt = which_op_alt ();
   for (i = 0; i < n_ops; i++)
     {
       old_operands[i] = recog_data.operand[i];
@@ -1439,7 +1439,7 @@  hide_operands (int n_ops, rtx *old_opera
       if (do_not_hide & (1 << i))
 	continue;
       if (!inout_and_ec_only || recog_data.operand_type[i] == OP_INOUT
-	  || recog_op_alt[i][alt].earlyclobber)
+	  || op_alt[i].earlyclobber)
 	*recog_data.operand_loc[i] = cc0_rtx;
     }
   for (i = 0; i < recog_data.n_dups; i++)
@@ -1449,7 +1449,7 @@  hide_operands (int n_ops, rtx *old_opera
       if (do_not_hide & (1 << opn))
 	continue;
       if (!inout_and_ec_only || recog_data.operand_type[opn] == OP_INOUT
-	  || recog_op_alt[opn][alt].earlyclobber)
+	  || op_alt[opn].earlyclobber)
 	*recog_data.dup_loc[i] = cc0_rtx;
     }
 }
@@ -1478,7 +1478,7 @@  restore_operands (rtx insn, int n_ops, r
 record_out_operands (rtx insn, bool earlyclobber, insn_rr_info *insn_info)
 {
   int n_ops = recog_data.n_operands;
-  int alt = which_alternative;
+  operand_alternative *op_alt = which_op_alt ();
 
   int i;
 
@@ -1489,12 +1489,12 @@  record_out_operands (rtx insn, bool earl
 		  ? recog_data.operand_loc[opn]
 		  : recog_data.dup_loc[i - n_ops]);
       rtx op = *loc;
-      enum reg_class cl = recog_op_alt[opn][alt].cl;
+      enum reg_class cl = op_alt[opn].cl;
 
       struct du_head *prev_open;
 
       if (recog_data.operand_type[opn] != OP_OUT
-	  || recog_op_alt[opn][alt].earlyclobber != earlyclobber)
+	  || op_alt[opn].earlyclobber != earlyclobber)
 	continue;
 
       if (insn_info)
@@ -1539,7 +1539,6 @@  build_def_use (basic_block bb)
 	  rtx old_operands[MAX_RECOG_OPERANDS];
 	  rtx old_dups[MAX_DUP_OPERANDS];
 	  int i;
-	  int alt;
 	  int predicated;
 	  enum rtx_code set_code = SET;
 	  enum rtx_code clobber_code = CLOBBER;
@@ -1572,7 +1571,7 @@  build_def_use (basic_block bb)
 	  if (! constrain_operands (1))
 	    fatal_insn_not_found (insn);
 	  preprocess_constraints ();
-	  alt = which_alternative;
+	  operand_alternative *op_alt = which_op_alt ();
 	  n_ops = recog_data.n_operands;
 	  untracked_operands = 0;
 
@@ -1595,10 +1594,10 @@  build_def_use (basic_block bb)
 	  for (i = 0; i < n_ops; ++i)
 	    {
 	      rtx op = recog_data.operand[i];
-	      int matches = recog_op_alt[i][alt].matches;
+	      int matches = op_alt[i].matches;
 	      if (matches >= 0)
-		recog_op_alt[i][alt].cl = recog_op_alt[matches][alt].cl;
-	      if (matches >= 0 || recog_op_alt[i][alt].matched >= 0
+		op_alt[i].cl = op_alt[matches].cl;
+	      if (matches >= 0 || op_alt[i].matched >= 0
 	          || (predicated && recog_data.operand_type[i] == OP_OUT))
 		{
 		  recog_data.operand_type[i] = OP_INOUT;
@@ -1682,7 +1681,7 @@  build_def_use (basic_block bb)
 	      rtx *loc = (i < n_ops
 			  ? recog_data.operand_loc[opn]
 			  : recog_data.dup_loc[i - n_ops]);
-	      enum reg_class cl = recog_op_alt[opn][alt].cl;
+	      enum reg_class cl = op_alt[opn].cl;
 	      enum op_type type = recog_data.operand_type[opn];
 
 	      /* Don't scan match_operand here, since we've no reg class
@@ -1694,7 +1693,7 @@  build_def_use (basic_block bb)
 
 	      if (insn_info)
 		cur_operand = i == opn ? insn_info->op_info + i : NULL;
-	      if (recog_op_alt[opn][alt].is_address)
+	      if (op_alt[opn].is_address)
 		scan_rtx_address (insn, loc, cl, mark_read,
 				  VOIDmode, ADDR_SPACE_GENERIC);
 	      else
Index: gcc/sel-sched.c
===================================================================
--- gcc/sel-sched.c	2014-05-31 08:54:10.351219264 +0100
+++ gcc/sel-sched.c	2014-05-31 08:57:21.608789337 +0100
@@ -1014,20 +1014,20 @@  vinsn_writes_one_of_regs_p (vinsn_t vi,
 static enum reg_class
 get_reg_class (rtx insn)
 {
-  int alt, i, n_ops;
+  int i, n_ops;
 
   extract_insn (insn);
   if (! constrain_operands (1))
     fatal_insn_not_found (insn);
   preprocess_constraints ();
-  alt = which_alternative;
   n_ops = recog_data.n_operands;
 
+  operand_alternative *op_alt = which_op_alt ();
   for (i = 0; i < n_ops; ++i)
     {
-      int matches = recog_op_alt[i][alt].matches;
+      int matches = op_alt[i].matches;
       if (matches >= 0)
-	recog_op_alt[i][alt].cl = recog_op_alt[matches][alt].cl;
+	op_alt[i].cl = op_alt[matches].cl;
     }
 
   if (asm_noperands (PATTERN (insn)) > 0)
@@ -1037,7 +1037,7 @@  get_reg_class (rtx insn)
 	  {
 	    rtx *loc = recog_data.operand_loc[i];
 	    rtx op = *loc;
-	    enum reg_class cl = recog_op_alt[i][alt].cl;
+	    enum reg_class cl = op_alt[i].cl;
 
 	    if (REG_P (op)
 		&& REGNO (op) == ORIGINAL_REGNO (op))
@@ -1051,7 +1051,7 @@  get_reg_class (rtx insn)
       for (i = 0; i < n_ops + recog_data.n_dups; i++)
        {
 	 int opn = i < n_ops ? i : recog_data.dup_num[i - n_ops];
-	 enum reg_class cl = recog_op_alt[opn][alt].cl;
+	 enum reg_class cl = op_alt[opn].cl;
 
 	 if (recog_data.operand_type[opn] == OP_OUT ||
 	     recog_data.operand_type[opn] == OP_INOUT)
Index: gcc/config/arm/arm.c
===================================================================
--- gcc/config/arm/arm.c	2014-05-31 08:54:10.351219264 +0100
+++ gcc/config/arm/arm.c	2014-05-31 08:57:21.608789337 +0100
@@ -16872,6 +16872,7 @@  note_invalid_constants (rtx insn, HOST_W
      this insn.  */
   preprocess_constraints ();
 
+  operand_alternative *op_alt = which_op_alt ();
   for (opno = 0; opno < recog_data.n_operands; opno++)
     {
       /* Things we need to fix can only occur in inputs.  */
@@ -16882,7 +16883,7 @@  note_invalid_constants (rtx insn, HOST_W
 	 of constants in this alternative is really to fool reload
 	 into allowing us to accept one there.  We need to fix them up
 	 now so that we output the right code.  */
-      if (recog_op_alt[opno][which_alternative].memory_ok)
+      if (op_alt[opno].memory_ok)
 	{
 	  rtx op = recog_data.operand[opno];