Patchwork [lra] patch to speed LRA up

login
register
mail settings
Submitter Vladimir Makarov
Date June 8, 2012, 8:46 p.m.
Message ID <4FD264AE.5040104@redhat.com>
Download mbox | patch
Permalink /patch/163847/
State New
Headers show

Comments

Vladimir Makarov - June 8, 2012, 8:46 p.m.
The following patch is to speed LRA up a bit.  It also adds 2012 to 
copyright.

The patch was sucessfully bootstrapped on x86-64.

Committed as rev. 188341.

2012-06-08  Vladimir Makarov <vmakarov@redhat.com>

         * lra-assigns.c: Add 2012 to copyright header.  Use lra_assert
         instead of gcc_assert.

         * lra-coalesce.c: Ditto.

         * lra-eliminations.c: Ditto.

         * lra-equivs.c: Ditto.

         * lra-lives.c: Ditto.

         * lra-spills.c: Ditto.

         * lra.c: Ditto.
         (insn_recog_data_len): Rename to lra_insn_recog_data_len.
         (insn_recog_data): Rename to lra_insn_recog_data.
         (lra_get_insn_recog_data): Rename to lra_set_insn_recog_data.
         Remove code for accessing cached value.

         * lra-constraints.c: Add 2012 to copyright header.  Use lra_assert
         instead of gcc_assert.
         (check_and_process_move): Remove unnecessary side_effects_p call.

         * lra-int.h: Ditto.
         (lra_assert): Define it.
         (lra_insn_recog_data_len, lra_insn_recog_data): New externals.
         (lra_get_insn_recog_data): Rename to lra_set_insn_recog_data.
         (lra_get_insn_recog_data): New inline function.

         * lra.h: Add 2012 to copyright.

Patch

Index: lra-assigns.c
===================================================================
--- lra-assigns.c	(revision 188333)
+++ lra-assigns.c	(working copy)
@@ -1,5 +1,5 @@ 
 /* Assign reload pseudos.
-   Copyright (C) 2010, 2011
+   Copyright (C) 2010, 2011, 2012
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -68,7 +68,7 @@  process_copy_to_form_thread (int regno1,
 {
   int last, regno1_first, regno2_first;
 
-  gcc_assert (regno1 >= lra_constraint_new_regno_start
+  lra_assert (regno1 >= lra_constraint_new_regno_start
 	      && regno2 >= lra_constraint_new_regno_start);
   regno1_first = regno_assign_info[regno1].first;
   regno2_first = regno_assign_info[regno2].first;
@@ -84,7 +84,7 @@  process_copy_to_form_thread (int regno1,
 	+= regno_assign_info[regno2_first].freq;
     }
   regno_assign_info[regno1_first].freq -= 2 * copy_freq;
-  gcc_assert (regno_assign_info[regno1_first].freq >= 0);
+  lra_assert (regno_assign_info[regno1_first].freq >= 0);
 }
 
 /* Initialize REGNO_ASSIGN_INFO and form threads.  */
@@ -132,7 +132,7 @@  reload_pseudo_compare_func (const void *
   enum reg_class cl2 = regno_allocno_class_array[r2];
   int diff;
   
-  gcc_assert (r1 >= lra_constraint_new_regno_start
+  lra_assert (r1 >= lra_constraint_new_regno_start
 	      && r2 >= lra_constraint_new_regno_start);
   
   /* Prefer to assign reload registers with smaller classes first to
@@ -406,7 +406,7 @@  find_hard_regno_for (int regno, int *cos
 			       conflict_regno)
     if (val != lra_reg_info[conflict_regno].val)
       {
-	gcc_assert (live_pseudos_reg_renumber[conflict_regno] < 0);
+	lra_assert (live_pseudos_reg_renumber[conflict_regno] < 0);
 	if ((hard_regno
 	     = lra_reg_info[conflict_regno].preferred_hard_regno1) >= 0)
 	  {
@@ -432,7 +432,7 @@  find_hard_regno_for (int regno, int *cos
   /* That is important for allocation of multi-word pseudos.  */
   IOR_COMPL_HARD_REG_SET (conflict_set, reg_class_contents[rclass]);
   /* ?!? may be cover class for the old.  */
-  gcc_assert (rclass != NO_REGS);
+  lra_assert (rclass != NO_REGS);
   rclass_size = ira_class_hard_regs_num[rclass];
   best_hard_regno = -1;
   for (i = 0; i < rclass_size; i++)
@@ -550,7 +550,7 @@  lra_setup_reg_renumber (int regno, int h
   if ((hr = hard_regno) < 0)
     hr = reg_renumber[regno];
   reg_renumber[regno] = hard_regno;
-  gcc_assert (hr >= 0);
+  lra_assert (hr >= 0);
   for (i = 0; i < hard_regno_nregs[hr][PSEUDO_REGNO_MODE (regno)]; i++)
     if (hard_regno < 0)
       lra_hard_reg_usage[hr + i] -= lra_reg_info[regno].freq;
@@ -668,7 +668,7 @@  spill_for (int regno, bitmap spilled_pse
   bitmap_iterator bi, bi2;
 
   rclass = regno_allocno_class_array[regno];
-  gcc_assert (reg_renumber[regno] < 0 && rclass != NO_REGS);
+  lra_assert (reg_renumber[regno] < 0 && rclass != NO_REGS);
   bitmap_clear (&ignore_pseudos_bitmap);
   bitmap_clear (&best_spill_pseudos_bitmap);
   EXECUTE_IF_SET_IN_BITMAP (&lra_reg_info[regno].insn_bitmap, 0, uid, bi)
@@ -696,7 +696,7 @@  spill_for (int regno, bitmap spilled_pse
 	{
 	  if (try_hard_reg_pseudos_check[hard_regno + j] != curr_pseudo_check)
 	    continue;
-	  gcc_assert (! bitmap_empty_p (&try_hard_reg_pseudos[hard_regno + j]));
+	  lra_assert (! bitmap_empty_p (&try_hard_reg_pseudos[hard_regno + j]));
 	  bitmap_ior_into (&spill_pseudos_bitmap,
 			   &try_hard_reg_pseudos[hard_regno + j]);
 	}
@@ -836,7 +836,7 @@  assign_hard_regno (int hard_regno, int r
 {
   int i;
 
-  gcc_assert (hard_regno >= 0);
+  lra_assert (hard_regno >= 0);
   lra_setup_reg_renumber (regno, hard_regno, true);
   update_lives (regno, false);
   for (i = 0;
@@ -887,7 +887,7 @@  setup_live_pseudos_and_spill_after_risky
     {
       regno = sorted_pseudos[i];
       hard_regno = reg_renumber[regno];
-      gcc_assert (hard_regno >= 0);
+      lra_assert (hard_regno >= 0);
       mode = lra_reg_info[regno].biggest_mode;
       sparseset_clear (live_range_hard_reg_pseudos);
       for (r = lra_reg_info[regno].live_ranges; r != NULL; r = r->next)
@@ -954,7 +954,7 @@  improve_inheritance (bitmap changed_pseu
     {
       regno = sorted_pseudos[i];
       hard_regno = reg_renumber[regno];
-      gcc_assert (hard_regno >= 0);
+      lra_assert (hard_regno >= 0);
       for (cp = lra_reg_info[regno].copies; cp != NULL; cp = next_cp)
 	{
 	  if (cp->regno1 == regno)
@@ -1063,7 +1063,7 @@  assign_by_spills (void)
 	}
       if (nfails == 0)
 	break;
-      gcc_assert (iter == 0);
+      lra_assert (iter == 0);
       /* This is a very rare event.  We can not assign a hard
 	 register to reload pseudo because the hard register was
 	 assigned to another reload pseudo on a previous
Index: lra.c
===================================================================
--- lra.c	(revision 188333)
+++ lra.c	(working copy)
@@ -1,5 +1,5 @@ 
 /* LRA (local register allocator) driver and LRA utilities.
-   Copyright (C) 2010, 2011
+   Copyright (C) 2010, 2011, 2012
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -78,7 +78,7 @@  lra_create_new_reg_with_unique_value (en
 
   if (original == NULL_RTX || (mode = GET_MODE (original)) == VOIDmode)
     mode = md_mode;
-  gcc_assert (mode != VOIDmode);
+  lra_assert (mode != VOIDmode);
   new_reg = gen_reg_rtx (mode);
   if (original == NULL_RTX || ! REG_P (original))
     {
@@ -231,7 +231,7 @@  lra_emit_add (rtx x, rtx y, rtx z)
 	{
 	  /* Its is not an address generation.  Probably we have no 3 op
 	     add.  Last chance is to use 2-op add insn.  */
-	  gcc_assert (x != y && x != z);
+	  lra_assert (x != y && x != z);
 	  emit_move_insn (x, z);
 	  insn = gen_add2_insn (x, y);
 	  emit_insn (insn);
@@ -243,7 +243,7 @@  lra_emit_add (rtx x, rtx y, rtx z)
 	  if (disp == NULL_RTX)
 	    {
 	      /* Generate x = index_scale; x = x + base.  */
-	      gcc_assert (index_scale != NULL_RTX && base != NULL_RTX);
+	      lra_assert (index_scale != NULL_RTX && base != NULL_RTX);
 	      emit_move_insn (x, index_scale);
 	      insn = gen_add2_insn (x, base);
 	      emit_insn (insn);
@@ -251,7 +251,7 @@  lra_emit_add (rtx x, rtx y, rtx z)
 	  else if (scale == NULL_RTX)
 	    {
 	      /* Try x = base + disp.  */
-	      gcc_assert (base != NULL_RTX);
+	      lra_assert (base != NULL_RTX);
 	      last = get_last_insn ();
 	      insn = emit_move_insn (x, gen_rtx_PLUS (GET_MODE (base),
 						      base, disp));
@@ -511,10 +511,10 @@  get_static_insn_data (int icode, int nop
 {
   struct lra_static_insn_data *data;
 
-  gcc_assert (icode < CODE_FOR_nothing);
+  lra_assert (icode < CODE_FOR_nothing);
   if (icode >= 0 && (data = insn_code_data[icode]) != NULL)
     return data;
-  gcc_assert (nop >= 0 && ndup >= 0 && nalt >= 0);
+  lra_assert (nop >= 0 && ndup >= 0 && nalt >= 0);
   data = ((struct lra_static_insn_data *)
 	  xmalloc (sizeof (struct lra_static_insn_data)
 		   + sizeof (struct lra_operand_data) * nop
@@ -551,17 +551,17 @@  get_static_insn_data (int icode, int nop
 }
 
 /* The current length of the following array.  */
-static int insn_recog_data_len;
+int lra_insn_recog_data_len;
 
 /* Map INSN_UID -> the insn recog data (NULL if unknown).  */
-static lra_insn_recog_data_t *insn_recog_data;
+lra_insn_recog_data_t *lra_insn_recog_data;
 
 /* Initialize LRA data about insns.  */
 static void
 init_insn_recog_data (void)
 {
-  insn_recog_data_len = 0;
-  insn_recog_data = NULL;
+  lra_insn_recog_data_len = 0;
+  lra_insn_recog_data = NULL;
   init_insn_regs ();
 }
 
@@ -571,16 +571,16 @@  check_and_expand_insn_recog_data (int in
 {
   int i, old;
 
-  if (insn_recog_data_len > index)
+  if (lra_insn_recog_data_len > index)
     return;
-  old = insn_recog_data_len;
-  insn_recog_data_len = index * 3 / 2 + 1;
-  insn_recog_data
-    = (lra_insn_recog_data_t *) xrealloc (insn_recog_data,
-					  insn_recog_data_len
+  old = lra_insn_recog_data_len;
+  lra_insn_recog_data_len = index * 3 / 2 + 1;
+  lra_insn_recog_data
+    = (lra_insn_recog_data_t *) xrealloc (lra_insn_recog_data,
+					  lra_insn_recog_data_len
 					  * sizeof (lra_insn_recog_data_t));
-  for (i = old; i < insn_recog_data_len; i++)
-    insn_recog_data[i] = NULL;
+  for (i = old; i < lra_insn_recog_data_len; i++)
+    lra_insn_recog_data[i] = NULL;
 }
 
 /* Finish LRA DATA about insn.  */
@@ -616,11 +616,11 @@  finish_insn_recog_data (void)
   int i;
   lra_insn_recog_data_t data;
 
-  for (i = 0; i < insn_recog_data_len; i++)
-    if ((data = insn_recog_data[i]) != NULL)
+  for (i = 0; i < lra_insn_recog_data_len; i++)
+    if ((data = lra_insn_recog_data[i]) != NULL)
       free_insn_recog_data (data);
   finish_insn_regs ();
-  free (insn_recog_data);
+  free (lra_insn_recog_data);
 }
 
 /* Setup info about operands in alternatives of LRA DATA of insn.  */
@@ -701,11 +701,11 @@  setup_operand_alternative (lra_insn_reco
 		  if (static_data->commutative < 0)
 		    static_data->commutative = i;
 		  else
-		    gcc_assert (data->icode < 0); /* Asm  */
+		    lra_assert (data->icode < 0); /* Asm  */
 
 		  /* The last operand should not be marked
 		     commutative.  */
-		  gcc_assert (i != nop - 1);
+		  lra_assert (i != nop - 1);
 		  break;
 
 		case '?':
@@ -912,10 +912,10 @@  collect_non_operand_hard_regs (rtx *x, l
   return list;
 }
 
-/* Return info about INSN.  Set up the info if it is not set up
+/* Set up and return info about INSN.  Set up the info if it is not set up
    yet.  */
 lra_insn_recog_data_t
-lra_get_insn_recog_data (rtx insn)
+lra_set_insn_recog_data (rtx insn)
 {
   lra_insn_recog_data_t data;
   int i, n, icode;
@@ -924,14 +924,6 @@  lra_get_insn_recog_data (rtx insn)
   struct lra_static_insn_data *insn_static_data;
 
   check_and_expand_insn_recog_data (uid);
-  if ((data = insn_recog_data[uid]) != NULL)
-    {
-      /* Check that we did not change insn strcuture without updating
-	 the info.  */
-      gcc_assert (data->insn == insn
-		  && (INSN_CODE (insn) < 0 || data->icode == INSN_CODE (insn)));
-      return data;
-    }
   if (DEBUG_INSN_P (insn))
     icode = -1;
   else
@@ -943,7 +935,7 @@  lra_get_insn_recog_data (rtx insn)
     }
   data
     = (lra_insn_recog_data_t) xmalloc (sizeof (struct lra_insn_recog_data));
-  insn_recog_data[uid] = data;
+  lra_insn_recog_data[uid] = data;
   data->insn = insn;
   data->used_insn_alternative = -1;
   data->icode = icode;
@@ -976,7 +968,7 @@  lra_get_insn_recog_data (rtx insn)
 	{
 	  /* expand_asm_operands makes sure there aren't too many
 	     operands.  */
-	  gcc_assert (nop <= MAX_RECOG_OPERANDS);
+	  lra_assert (nop <= MAX_RECOG_OPERANDS);
 	  if (nop != 0)
 	    data->operand_loc = (rtx **) xmalloc (nop * sizeof (rtx *));
 	  /* Now get the operand values and constraints out of the
@@ -1042,7 +1034,7 @@  lra_get_insn_recog_data (rtx insn)
 	bool *bp;
 
 	n = insn_static_data->n_alternatives;
-	gcc_assert (n >= 0);
+	lra_assert (n >= 0);
 	data->alternative_enabled_p
 	  = bp = (bool *) xmalloc (n * sizeof (bool));
 	/* Cache the insn because we don't want to call extract_insn
@@ -1085,7 +1077,7 @@  lra_get_insn_recog_data (rtx insn)
 	    && REG_P (XEXP (XEXP (link, 0), 0)))
 	  {
 	    regno = REGNO (XEXP (XEXP (link, 0), 0));
-	    gcc_assert (regno < FIRST_PSEUDO_REGISTER);
+	    lra_assert (regno < FIRST_PSEUDO_REGISTER);
 	    /* It is an argument register.  */
 	    for (i = (hard_regno_nregs
 		      [regno][GET_MODE (XEXP (XEXP (link, 0), 0))]) - 1;
@@ -1148,8 +1140,8 @@  get_insn_recog_data_by_uid (int uid)
 {
   lra_insn_recog_data_t data;
 
-  data = insn_recog_data[uid];
-  gcc_assert (data != NULL);
+  data = lra_insn_recog_data[uid];
+  lra_assert (data != NULL);
   return data;
 }
 
@@ -1159,10 +1151,10 @@  invalidate_insn_recog_data (int uid)
 {
   lra_insn_recog_data_t data;
 
-  data = insn_recog_data[uid];
-  gcc_assert (data != NULL);
+  data = lra_insn_recog_data[uid];
+  lra_assert (data != NULL);
   free_insn_recog_data (data);
-  insn_recog_data[uid] = NULL;
+  lra_insn_recog_data[uid] = NULL;
 }
 
 /* Update all the insn info about INSN.  It is usually called when
@@ -1176,7 +1168,7 @@  lra_update_insn_recog_data (rtx insn)
   struct lra_static_insn_data *insn_static_data;
   
   check_and_expand_insn_recog_data (uid);
-  if ((data = insn_recog_data[uid]) != NULL
+  if ((data = lra_insn_recog_data[uid]) != NULL
       && data->icode != INSN_CODE (insn))
     {
       invalidate_insn_data_regno_info (data, insn, get_insn_freq (insn));
@@ -1198,7 +1190,7 @@  lra_update_insn_recog_data (rtx insn)
       nop = asm_noperands (PATTERN (insn));
       if (nop >= 0)
 	{
-	  gcc_assert (nop == data->insn_static_data->n_operands);
+	  lra_assert (nop == data->insn_static_data->n_operands);
 	  /* Now get the operand values and constraints out of the
 	     insn.  */
 	  decode_asm_operands (PATTERN (insn), NULL,
@@ -1209,7 +1201,7 @@  lra_update_insn_recog_data (rtx insn)
 	    int i;
 
 	    for (i = 0; i < nop; i++)
-	      gcc_assert
+	      lra_assert
 		(insn_static_data->operand[i].mode == operand_mode[i]
 		 && insn_static_data->operand[i].constraint == constraints[i]
 		 && ! insn_static_data->operand[i].is_operator);
@@ -1221,7 +1213,7 @@  lra_update_insn_recog_data (rtx insn)
 	int i;
 
 	for (i = 0; i < insn_static_data->n_operands; i++)
-	  gcc_assert
+	  lra_assert
 	    (insn_static_data->operand[i].type
 	     == (insn_static_data->operand[i].constraint[0] == '=' ? OP_OUT
 		 : insn_static_data->operand[i].constraint[0] == '+' ? OP_INOUT
@@ -1246,14 +1238,14 @@  lra_update_insn_recog_data (rtx insn)
 	
 	n = insn_static_data->n_alternatives;
 	bp = data->alternative_enabled_p;
-	gcc_assert (n >= 0 && bp != NULL);
+	lra_assert (n >= 0 && bp != NULL);
 	/* Cache the insn to prevent extract_insn call from
 	   get_attr_enabled.  */
 	recog_data.insn = insn;
        	for (i = 0; i < n; i++)
 	  {
 	    which_alternative = i;
-	    gcc_assert (bp[i] == get_attr_enabled (insn));
+	    lra_assert (bp[i] == get_attr_enabled (insn));
 	  }
       }
 #endif
@@ -1280,8 +1272,8 @@  lra_set_used_insn_alternative_by_uid (in
   lra_insn_recog_data_t data;
 
   check_and_expand_insn_recog_data (uid);
-  data = insn_recog_data[uid];
-  gcc_assert (data != NULL);
+  data = lra_insn_recog_data[uid];
+  lra_assert (data != NULL);
   data->used_insn_alternative = alt;
 }
 
@@ -1416,7 +1408,7 @@  lra_create_copy (int regno1, int regno2,
   bool regno1_dest_p;
   lra_copy_t cp;
 
-  gcc_assert (regno1 != regno2);
+  lra_assert (regno1 != regno2);
   regno1_dest_p = true;
   if (regno1 > regno2)
     {
@@ -1508,7 +1500,7 @@  add_regs_to_insn_regno_info (lra_insn_re
 	      if (curr->early_clobber != early_clobber)
 		curr->early_clobber = true;
 	    }
-	  gcc_assert (curr != NULL);
+	  lra_assert (curr != NULL);
 	}
       return;
     }
@@ -1571,8 +1563,8 @@  get_insn_freq (rtx insn)
     return REG_FREQ_FROM_BB (bb);
   else
     {
-      gcc_assert
-	(insn_recog_data[INSN_UID (insn)]->insn_static_data->n_operands == 0);
+      lra_assert
+	(lra_insn_recog_data[INSN_UID (insn)]->insn_static_data->n_operands == 0);
       /* We don't care about such insn, e.g. it might be jump with
 	 addr_vec.  */
       return 1;
@@ -1602,7 +1594,7 @@  invalidate_insn_data_regno_info (lra_ins
 	{
 	  lra_reg_info[i].nrefs--;
 	  lra_reg_info[i].freq -= freq;
-	  gcc_assert (lra_reg_info[i].nrefs >= 0 && lra_reg_info[i].freq >= 0);
+	  lra_assert (lra_reg_info[i].nrefs >= 0 && lra_reg_info[i].freq >= 0);
 	}
     }
   data->regs = NULL;
@@ -1696,7 +1688,7 @@  lra_push_insn (rtx insn)
 void
 lra_push_insn_by_uid (unsigned int uid)
 {
-  lra_push_insn (insn_recog_data[uid]->insn);
+  lra_push_insn (lra_insn_recog_data[uid]->insn);
 }
 
 /* Put INSN on the stack and update its reg info.  */
@@ -1872,7 +1864,7 @@  restore_scratches (void)
 	{
 	  /* It should be only case when scratch register with chosen
 	     constraint 'X' did not get memory or hard register.  */
-	  gcc_assert (lra_former_scratch_p (regno));
+	  lra_assert (lra_former_scratch_p (regno));
 	  *id->operand_loc[loc->nop]
 	    = gen_rtx_SCRATCH (GET_MODE (*id->operand_loc[loc->nop]));
 	  lra_update_dup (id, loc->nop);
@@ -1902,7 +1894,7 @@  check_rtl (bool final_p)
   rtx insn;
   lra_insn_recog_data_t id;
 
-  gcc_assert (! final_p || reload_completed);
+  lra_assert (! final_p || reload_completed);
   FOR_EACH_BB (bb)
     FOR_BB_INSNS (bb, insn)
     if (NONDEBUG_INSN_P (insn)
@@ -1915,7 +1907,7 @@  check_rtl (bool final_p)
 	if (final_p)
 	  {
 	    extract_insn (insn);
-	    gcc_assert (constrain_operands (1));
+	    lra_assert (constrain_operands (1));
 	    continue;
 	  }
 	if (insn_invalid_p (insn))
Index: lra-coalesce.c
===================================================================
--- lra-coalesce.c	(revision 188333)
+++ lra-coalesce.c	(working copy)
@@ -1,5 +1,5 @@ 
 /* Coalesce spilled pseudos.
-   Copyright (C) 2010, 2011
+   Copyright (C) 2010, 2011, 2012
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -269,7 +269,7 @@  lra_coalesce (void)
 	{
 	  mv = sorted_moves[i];
 	  set = single_set (mv);
-	  gcc_assert (set != NULL && REG_P (SET_SRC (set))
+	  lra_assert (set != NULL && REG_P (SET_SRC (set))
 		      && REG_P (SET_DEST (set)));
 	  sregno = REGNO (SET_SRC (set));
 	  dregno = REGNO (SET_DEST (set));
@@ -299,7 +299,7 @@  lra_coalesce (void)
 	{
 	  mv = sorted_moves[i];
 	  set = single_set (mv);
-	  gcc_assert (set != NULL && REG_P (SET_SRC (set))
+	  lra_assert (set != NULL && REG_P (SET_SRC (set))
 		      && REG_P (SET_DEST (set)));
 	  sregno = REGNO (SET_SRC (set));
 	  dregno = REGNO (SET_DEST (set));
Index: lra-constraints.c
===================================================================
--- lra-constraints.c	(revision 188333)
+++ lra-constraints.c	(working copy)
@@ -1,5 +1,5 @@ 
 /* Code for RTL transformations to satisfy insn constraints.
-   Copyright (C) 2010, 2011
+   Copyright (C) 2010, 2011, 2012
    Free Software Foundation, Inc.
 
    This file is part of GCC.
@@ -271,7 +271,7 @@  get_reload_reg (enum op_type type, enum
     }
   else
     {
-      gcc_assert (! side_effects_p (original));
+      lra_assert (! side_effects_p (original));
       res_p = false;
       *result_reg = curr_insn_input_reloads[i].reg;
       regno = REGNO (*result_reg);
@@ -285,7 +285,7 @@  get_reload_reg (enum op_type type, enum
       if (lra_dump_file != NULL)
 	 fprintf (lra_dump_file, "\n");
     }
-  gcc_assert (curr_insn_input_reloads_num < LRA_MAX_INSN_RELOADS);
+  lra_assert (curr_insn_input_reloads_num < LRA_MAX_INSN_RELOADS);
   curr_insn_input_reloads[curr_insn_input_reloads_num].input = original;
   curr_insn_input_reloads[curr_insn_input_reloads_num++].reg = *result_reg;
   return res_p;
@@ -403,7 +403,7 @@  extract_loc_address_regs (bool top_p, en
 	  {
 	    extract_loc_address_regs (false, mode, as, arg0_loc, false, PLUS,
 				      code1, modify_p, ad);
-	    gcc_assert (CONSTANT_P (arg1)); /* It should be a displacement.  */
+	    lra_assert (CONSTANT_P (arg1)); /* It should be a displacement.  */
 	    ad->disp_loc = arg1_loc;
 	  }
 	/* If index and base registers are the same on this machine,
@@ -506,7 +506,7 @@  extract_loc_address_regs (bool top_p, en
       extract_loc_address_regs (false, mode, as, &XEXP (x, 0), false,
 				code, GET_CODE (XEXP (XEXP (x, 1), 1)),
 				true, ad);
-      gcc_assert (rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)));
+      lra_assert (rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)));
       ad->base_reg_loc2 = &XEXP (XEXP (x, 1), 0);
       if (REG_P (XEXP (XEXP (x, 1), 1)))
 	extract_loc_address_regs (false, mode, as, &XEXP (XEXP (x, 1), 1),
@@ -583,7 +583,7 @@  extract_address_regs (enum machine_mode
 int
 lra_constraint_offset (int regno, enum machine_mode mode)
 {
-  gcc_assert (regno < FIRST_PSEUDO_REGISTER);
+  lra_assert (regno < FIRST_PSEUDO_REGISTER);
   /* On a WORDS_BIG_ENDIAN machine, point to the last register of a
      multiple hard register group of scalar integer registers, so that
      for example (reg:DI 0) and (reg:SI 1) will be considered the same
@@ -1058,7 +1058,7 @@  check_and_process_move (bool *change_p,
   secondary_reload_info sri;
 
   *sec_mem_p = *change_p = false;
-  if ((set = single_set (curr_insn)) == NULL || side_effects_p (set))
+  if ((set = single_set (curr_insn)) == NULL)
     return false;
   dreg = dest = SET_DEST (set);
   sreg = src = SET_SRC (set);
@@ -1271,7 +1271,7 @@  process_addr_reg (rtx *loc, rtx *before,
 	}
       return true;
     }
-  gcc_assert (REG_P (reg));
+  lra_assert (REG_P (reg));
   final_regno = regno = REGNO (reg);
   if (regno < FIRST_PSEUDO_REGISTER)
     {
@@ -1634,7 +1634,7 @@  process_alt_operands (int only_alternati
 
 	  /* An empty constraint should be excluded by the fast
 	     track.  */
-	  gcc_assert (*p != 0 && *p != ',');
+	  lra_assert (*p != 0 && *p != ',');
   
 	  /* Scan this alternative's specs for this operand; set WIN
 	     if the operand fits any letter in this alternative.
@@ -1681,7 +1681,7 @@  process_alt_operands (int only_alternati
 		    m = strtoul (p, &end, 10);
 		    p = end;
 		    len = 0;
-		    gcc_assert (nop > m);
+		    lra_assert (nop > m);
 		    
 		    this_alternative_matches = m;
 		    lra_get_hard_regno_and_offset (*curr_id->operand_loc[m],
@@ -1754,7 +1754,7 @@  process_alt_operands (int only_alternati
 			if (operand_reg[nop] == NULL_RTX
 			    || (find_regno_note (curr_insn, REG_DEAD,
 						 REGNO (operand_reg[nop]))
-				== NULL_RTX))
+				 == NULL_RTX))
 			  reject += 2;
 		      }
 		    /* This can be fixed with reloads if the operand
@@ -2265,7 +2265,7 @@  process_alt_operands (int only_alternati
 	  else
 	    {
 	      /* Remember pseudos used for match reloads are never inherited.  */
-	      gcc_assert (curr_alt_matches[i] >= 0);
+	      lra_assert (curr_alt_matches[i] >= 0);
 	      curr_alt_win[curr_alt_matches[i]] = false;
 	    }
 	  curr_alt_win[i] = curr_alt_match_win[i] = false;
@@ -2336,7 +2336,7 @@  valid_address_p (enum machine_mode mode
 		 rtx addr, addr_space_t as)
 {
 #ifdef GO_IF_LEGITIMATE_ADDRESS
-  gcc_assert (ADDR_SPACE_GENERIC_P (as));
+  lra_assert (ADDR_SPACE_GENERIC_P (as));
   GO_IF_LEGITIMATE_ADDRESS (mode, addr, win);
   return 0;
   
@@ -2356,7 +2356,7 @@  base_plus_disp_to_reg (enum machine_mode
   enum reg_class cl;
   rtx new_reg;
 
-  gcc_assert (ad->base_reg_loc != NULL && ad->disp_loc != NULL);
+  lra_assert (ad->base_reg_loc != NULL && ad->disp_loc != NULL);
   cl = base_reg_class (mode, as, ad->base_outer_code, ad->index_code);
   new_reg = lra_create_new_reg (Pmode, NULL_RTX, cl, "base + disp");
   lra_emit_add (new_reg, *ad->base_reg_loc, *ad->disp_loc);
@@ -2420,7 +2420,7 @@  equiv_address_substitution (struct addre
   scale = 1;
   if (ad->index_loc != NULL && GET_CODE (*ad->index_loc) == MULT)
     {
-      gcc_assert (CONST_INT_P (XEXP (*ad->index_loc, 1)));
+      lra_assert (CONST_INT_P (XEXP (*ad->index_loc, 1)));
       scale = INTVAL (XEXP (*ad->index_loc, 1));
     }
   if (index_reg != new_index_reg)
@@ -2470,7 +2470,7 @@  exchange_plus_ops (rtx x)
 {
   rtx op0;
 
-  gcc_assert (GET_CODE (x) == PLUS);
+  lra_assert (GET_CODE (x) == PLUS);
   op0 = XEXP (x, 0);
   XEXP (x, 0) = XEXP (x, 1);
   XEXP (x, 1) = op0;
@@ -2595,9 +2595,9 @@  process_address (int nop, rtx *before, r
 	  /* index * scale + disp => new base + index * scale  */
 	  enum reg_class cl = base_reg_class (mode, as, SCRATCH, SCRATCH);
 
-	  gcc_assert (INDEX_REG_CLASS != NO_REGS);
+	  lra_assert (INDEX_REG_CLASS != NO_REGS);
 	  new_reg = lra_create_new_reg (Pmode, NULL_RTX, cl, "disp");
-	  gcc_assert (GET_CODE (*addr_loc) == PLUS);
+	  lra_assert (GET_CODE (*addr_loc) == PLUS);
 	  lra_emit_move (new_reg, *ad.disp_loc);
 	  if (CONSTANT_P (XEXP (*addr_loc, 1)))
 	    XEXP (*addr_loc, 1) = XEXP (*addr_loc, 0);
@@ -2668,9 +2668,9 @@  emit_inc (enum reg_class new_rclass, rtx
 
   if (GET_CODE (value) == PRE_MODIFY || GET_CODE (value) == POST_MODIFY)
     {
-      gcc_assert (GET_CODE (XEXP (value, 1)) == PLUS
+      lra_assert (GET_CODE (XEXP (value, 1)) == PLUS
 		  || GET_CODE (XEXP (value, 1)) == MINUS);
-      gcc_assert (rtx_equal_p (XEXP (XEXP (value, 1), 0), XEXP (value, 0)));
+      lra_assert (rtx_equal_p (XEXP (XEXP (value, 1), 0), XEXP (value, 0)));
       plus_p = GET_CODE (XEXP (value, 1)) == PLUS;
       inc = XEXP (XEXP (value, 1), 1);
     }
@@ -2857,7 +2857,7 @@  curr_insn_transform (void)
       if (subst != old)
 	{
 	  subst = copy_rtx (subst);
-	  gcc_assert (REG_P (old));
+	  lra_assert (REG_P (old));
 	  if (GET_CODE (op) == SUBREG)
 	    SUBREG_REG (op) = subst;
 	  else
@@ -3012,9 +3012,9 @@  curr_insn_transform (void)
       rtx new_reg, set, src, dest;
       enum machine_mode sec_mode;
 
-      gcc_assert (sec_mem_p);
+      lra_assert (sec_mem_p);
       set = single_set (curr_insn);
-      gcc_assert (set != NULL_RTX && ! side_effects_p (set));
+      lra_assert (set != NULL_RTX && ! side_effects_p (set));
       dest = SET_DEST (set);
       src = SET_SRC (set);
 #ifdef SECONDARY_MEMORY_NEEDED_MODE
@@ -3025,7 +3025,7 @@  curr_insn_transform (void)
       new_reg = lra_create_new_reg (sec_mode, NULL_RTX,
 				    NO_REGS, "secondary");
       /* If the mode is changed, it should be wider.  */
-      gcc_assert (GET_MODE_SIZE (GET_MODE (new_reg))
+      lra_assert (GET_MODE_SIZE (GET_MODE (new_reg))
 		  >= GET_MODE_SIZE (GET_MODE (src)));
       after = emit_spill_move (false, new_reg, dest, INSN_CODE (curr_insn));
       lra_process_new_insns (curr_insn, NULL_RTX, after,
@@ -3037,7 +3037,7 @@  curr_insn_transform (void)
     }
 #endif
 
-  gcc_assert (goal_alt_number >= 0);
+  lra_assert (goal_alt_number >= 0);
   lra_set_used_insn_alternative (curr_insn, goal_alt_number);
 
   if (lra_dump_file != NULL)
@@ -3070,7 +3070,7 @@  curr_insn_transform (void)
 	  ;
 	/* We allows matching one output operand and several input
 	   operands.  */
-	gcc_assert (k == 0
+	lra_assert (k == 0
 		    || (curr_static_id->operand[j].type == OP_OUT
 			&& curr_static_id->operand[i].type == OP_IN
 			&& (curr_static_id->operand
@@ -3100,7 +3100,7 @@  curr_insn_transform (void)
 
 	    if (new_class != NO_REGS && get_reg_class (regno) != new_class)
 	      {
-		gcc_assert (ok_p);
+		lra_assert (ok_p);
 		change_class (regno, new_class, "      Change", true);
 	      }
 	  }
@@ -3301,7 +3301,7 @@  curr_insn_transform (void)
 	match_reload (i, goal_alt_matched[i], goal_alt[i], &before, &after);
       else
 	{
-	  gcc_assert (INSN_CODE (curr_insn) < 0);
+	  lra_assert (INSN_CODE (curr_insn) < 0);
 	  error_for_asm (curr_insn,
 			 "inconsistent operand constraints in an %<asm%>");
 	  /* Avoid further trouble with this insn.  */
@@ -3613,7 +3613,7 @@  lra_constraints (bool first_p)
 	    int j, nregs = hard_regno_nregs[hard_regno][PSEUDO_REGNO_MODE (i)];
 	    
 	    for (j = 0; j < nregs; j++)
-	      gcc_assert (df_regs_ever_live_p (hard_regno + j));
+	      lra_assert (df_regs_ever_live_p (hard_regno + j));
 	  }
     }
 #endif
@@ -3756,7 +3756,7 @@  inherit_reload_reg (bool def_p, bool uni
   rtx original_reg = regno_reg_rtx[original_regno];
   rtx new_reg, new_insns, usage_insn;
 
-  gcc_assert (! usage_insns[original_regno].after_p);
+  lra_assert (! usage_insns[original_regno].after_p);
   if (lra_dump_file != NULL)
     fprintf (lra_dump_file,
 	     "    <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
@@ -3840,13 +3840,13 @@  inherit_reload_reg (bool def_p, bool uni
       if (GET_CODE (next_usage_insns) != INSN_LIST)
 	{
 	  usage_insn = next_usage_insns;
-	  gcc_assert (NONDEBUG_INSN_P (usage_insn));
+	  lra_assert (NONDEBUG_INSN_P (usage_insn));
 	  next_usage_insns = NULL;
 	}
       else
 	{
 	  usage_insn = XEXP (next_usage_insns, 0);
-	  gcc_assert (DEBUG_INSN_P (usage_insn));
+	  lra_assert (DEBUG_INSN_P (usage_insn));
 	  next_usage_insns = XEXP (next_usage_insns, 1);
 	}
       substitute_pseudo (&usage_insn, original_regno, new_reg);
@@ -3870,7 +3870,7 @@  inherit_reload_reg (bool def_p, bool uni
 static inline bool
 need_for_call_save_p (int regno)
 {
-  gcc_assert (regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] >= 0);
+  lra_assert (regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] >= 0);
   return (usage_insns[regno].calls_num < calls_num
 	  && (lra_hard_reg_set_intersection_p
 	      (reg_renumber[regno], PSEUDO_REGNO_MODE (regno),
@@ -3894,7 +3894,7 @@  need_for_split_p (HARD_REG_SET potential
 {
   int hard_regno = regno < FIRST_PSEUDO_REGISTER ? regno : reg_renumber[regno];
 
-  gcc_assert (hard_regno >= 0);
+  lra_assert (hard_regno >= 0);
   return ((TEST_HARD_REG_BIT (potential_reload_hard_regs, hard_regno)
 	   && ! TEST_HARD_REG_BIT (lra_no_alloc_regs, hard_regno)
 	   && (usage_insns[regno].reloads_num
@@ -3982,7 +3982,7 @@  split_reg (bool before_p, int original_r
       call_save_p = need_for_call_save_p (original_regno);
     }
   original_reg = regno_reg_rtx[original_regno];
-  gcc_assert (hard_regno >= 0);
+  lra_assert (hard_regno >= 0);
   if (lra_dump_file != NULL)
     fprintf (lra_dump_file,
 	     "    ((((((((((((((((((((((((((((((((((((((((((((((((\n");
@@ -4032,7 +4032,7 @@  split_reg (bool before_p, int original_r
     }
   if (NEXT_INSN (save) != NULL_RTX)
     {
-      gcc_assert (! call_save_p);
+      lra_assert (! call_save_p);
       if (lra_dump_file != NULL)
 	{
 	  fprintf (lra_dump_file,
@@ -4055,7 +4055,7 @@  split_reg (bool before_p, int original_r
     }
   if (NEXT_INSN (restore) != NULL_RTX)
     {
-      gcc_assert (! call_save_p);
+      lra_assert (! call_save_p);
       if (lra_dump_file != NULL)
 	{
 	  fprintf (lra_dump_file,
@@ -4081,7 +4081,7 @@  split_reg (bool before_p, int original_r
 	  break;
 	}
       usage_insn = XEXP (next_usage_insns, 0);
-      gcc_assert (DEBUG_INSN_P (usage_insn));
+      lra_assert (DEBUG_INSN_P (usage_insn));
       next_usage_insns = XEXP (next_usage_insns, 1);
       substitute_pseudo (&usage_insn, original_regno, new_reg);
       lra_update_insn_regno_info (usage_insn);
@@ -4093,8 +4093,8 @@  split_reg (bool before_p, int original_r
 			  -1, 0);
 	}
     }
-  gcc_assert (NONDEBUG_INSN_P (usage_insn));
-  gcc_assert (usage_insn != insn || (after_p && before_p));
+  lra_assert (NONDEBUG_INSN_P (usage_insn));
+  lra_assert (usage_insn != insn || (after_p && before_p));
   lra_process_new_insns (usage_insn, after_p ? NULL_RTX : restore,
 			 after_p ? restore : NULL_RTX,
 			 call_save_p
@@ -4240,7 +4240,7 @@  add_to_inherit (int regno, rtx insns)
   for (i = 0; i < to_inherit_num; i++)
     if (to_inherit[i].regno == regno)
       return;
-  gcc_assert (to_inherit_num < LRA_MAX_INSN_RELOADS);
+  lra_assert (to_inherit_num < LRA_MAX_INSN_RELOADS);
   to_inherit[to_inherit_num].regno = regno;
   to_inherit[to_inherit_num++].insns = insns;
 }
@@ -4272,7 +4272,7 @@  get_live_on_other_edges (basic_block fro
   edge e;
   edge_iterator ei;
 
-  gcc_assert (to != NULL);
+  lra_assert (to != NULL);
   bitmap_clear (res);
   FOR_EACH_EDGE (e, ei, from->succs)
     if (e->dest != to)
@@ -4851,7 +4851,7 @@  remove_inheritance_pseudos (bitmap remov
 			  == lra_reg_info[prev_sregno].restore_regno)
 		      && ! bitmap_bit_p (remove_pseudos, prev_sregno))
 		    {
-		      gcc_assert (GET_MODE (SET_SRC (prev_set))
+		      lra_assert (GET_MODE (SET_SRC (prev_set))
 				  == GET_MODE (regno_reg_rtx[sregno]));
 		      if (GET_CODE (SET_SRC (set)) == SUBREG)
 			SUBREG_REG (SET_SRC (set)) = SET_SRC (prev_set);
Index: lra-eliminations.c
===================================================================
--- lra-eliminations.c	(revision 188333)
+++ lra-eliminations.c	(working copy)
@@ -1,5 +1,5 @@ 
 /* Code for RTL register eliminations.
-   Copyright (C) 2010, 2011
+   Copyright (C) 2010, 2011, 2012
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -243,7 +243,7 @@  get_elimination (int hard_regno)
   self_elim_table.from_rtx
     = self_elim_table.to_rtx
     = eliminable_reg_rtx[hard_regno];
-  gcc_assert (self_elim_table.from_rtx != NULL);
+  lra_assert (self_elim_table.from_rtx != NULL);
   self_elim_table.offset = offset;
   return &self_elim_table;
 }
@@ -775,7 +775,7 @@  eliminate_regs_in_insn (rtx insn, bool r
 
   if (icode < 0 && asm_noperands (PATTERN (insn)) < 0 && ! DEBUG_INSN_P (insn))
     {
-      gcc_assert (GET_CODE (PATTERN (insn)) == USE
+      lra_assert (GET_CODE (PATTERN (insn)) == USE
 		  || GET_CODE (PATTERN (insn)) == CLOBBER
 		  || GET_CODE (PATTERN (insn)) == ADDR_VEC
 		  || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
@@ -975,7 +975,7 @@  eliminate_regs_in_insn (rtx insn, bool r
 		 eliminate this reg.  */
 	      for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS];
 		   ep++)
-		gcc_assert (ep->from_rtx != orig_operand[i]
+		lra_assert (ep->from_rtx != orig_operand[i]
 			    || ! ep->can_eliminate);
 	    }
 
@@ -1113,7 +1113,7 @@  update_reg_eliminate (bitmap insns_with_
 	      /* Prevent the hard register into which we eliminate now
 		 from the usage for pseudos.  */
 	      SET_HARD_REG_BIT (temp_hard_reg_set, ep1->to);
-	      gcc_assert (ep1->previous_offset == 0);
+	      lra_assert (ep1->previous_offset == 0);
 	      ep1->previous_offset = ep->offset;
 	    }
 	  else
@@ -1225,7 +1225,7 @@  lra_eliminate_reg_if_possible (rtx *loc)
   int regno;
   struct elim_table *ep;
 
-  gcc_assert (REG_P (*loc));
+  lra_assert (REG_P (*loc));
   if ((regno = REGNO (*loc)) >= FIRST_PSEUDO_REGISTER
       /* Virtual registers are not allocatable. ??? */
       || ! TEST_HARD_REG_BIT (lra_no_alloc_regs, regno))
Index: lra-equivs.c
===================================================================
--- lra-equivs.c	(revision 188333)
+++ lra-equivs.c	(working copy)
@@ -1,5 +1,5 @@ 
 /* Dealing with equivalences.
-   Copyright (C) 2010, 2011
+   Copyright (C) 2010, 2011, 2012
    Free Software Foundation, Inc.
    Contributed by Vladimir Makarov <vmakarov@redhat.com>.
 
@@ -76,7 +76,7 @@  resize_regno_equiv (int max_ind)
   if (lra_regno_equiv_init_insns == NULL)
     {
       lra_regno_equiv_size = expanded_size;
-      gcc_assert (lra_regno_equiv_mem_loc == NULL
+      lra_assert (lra_regno_equiv_mem_loc == NULL
 		  && lra_regno_equiv_const == NULL
 		  && lra_regno_equiv_invariant == NULL);
       lra_regno_equiv_init_insns
@@ -587,7 +587,7 @@  update_equiv_regs (void)
 	  note = find_reg_note (insn, REG_EQUIV, NULL_RTX);
 	  if (note)
 	    {
-	      gcc_assert (REG_P (dest));
+	      lra_assert (REG_P (dest));
 	      regno = REGNO (dest);
 
 	      /* Note that we don't want to clear
@@ -851,7 +851,7 @@  update_equiv_regs (void)
 		   not used, flow would have deleted the setting
 		   insns.)  Hence there can only be one insn in
 		   regno_equiv[REGNO].init_insns.  */
-		gcc_assert (regno_equiv[regno].init_insns
+		lra_assert (regno_equiv[regno].init_insns
 			    && !XEXP (regno_equiv[regno].init_insns, 1));
 		equiv_insn = XEXP (regno_equiv[regno].init_insns, 0);
 
Index: lra.h
===================================================================
--- lra.h	(revision 188333)
+++ lra.h	(working copy)
@@ -1,6 +1,6 @@ 
 /* Communication between the Local Register Allocator (LRA) and
    the rest of the compiler.
-   Copyright (C) 2010, 2011
+   Copyright (C) 2010, 2011, 2012
    Free Software Foundation, Inc.
    Contributed by Vladimir Makarov <vmakarov@redhat.com>.
 
Index: lra-int.h
===================================================================
--- lra-int.h	(revision 188333)
+++ lra-int.h	(working copy)
@@ -1,5 +1,5 @@ 
 /* Local Register Allocator (LRA) intercommunication header file.
-   Copyright (C) 2010, 2011
+   Copyright (C) 2010, 2011, 2012
    Free Software Foundation, Inc.
    Contributed by Vladimir Makarov <vmakarov@redhat.com>.
 
@@ -23,6 +23,14 @@  along with GCC; see the file COPYING3.
 #include "bitmap.h"
 #include "insn-attr.h"
 
+#ifdef ENABLE_CHECKING
+#define lra_assert(c) gcc_assert (c)
+#else
+/* Always define and include C, so that warnings for empty body in an
+  ‘if’ statement and unused variable do not occur.  */
+#define lra_assert(c) ((void)(0 && (c)))
+#endif
+
 /* The parameter used to prevent infinite reloading for an insn.  Each
    insn operands might require a reload and, if it is a memory, its
    base and index registers might require a reload too.  */
@@ -233,6 +241,9 @@  extern bool lra_reg_spill_p;
 
 extern HARD_REG_SET lra_no_alloc_regs;
 
+extern int lra_insn_recog_data_len;
+extern lra_insn_recog_data_t *lra_insn_recog_data;
+
 extern bitmap_head lra_constraint_insn_stack_bitmap;
 extern VEC (rtx, heap) *lra_constraint_insn_stack;
 
@@ -254,7 +265,7 @@  extern void lra_update_dups (lra_insn_re
 
 extern void lra_process_new_insns (rtx, rtx, rtx, const char *);
 
-extern lra_insn_recog_data_t lra_get_insn_recog_data (rtx);
+extern lra_insn_recog_data_t lra_set_insn_recog_data (rtx);
 extern lra_insn_recog_data_t lra_update_insn_recog_data (rtx);
 extern void lra_set_used_insn_alternative (rtx, int);
 extern void lra_set_used_insn_alternative_by_uid (int, int);
@@ -361,7 +372,7 @@  lra_hard_reg_set_intersection_p (int har
 {
   int i;
 
-  gcc_assert (hard_regno >= 0);
+  lra_assert (hard_regno >= 0);
   for (i = hard_regno_nregs[hard_regno][mode] - 1; i >= 0; i--)
     if (TEST_HARD_REG_BIT (hard_regset, hard_regno + i))
       return true;
@@ -415,3 +426,22 @@  lra_update_dup (lra_insn_recog_data_t id
     if (static_id->dup_num[i] == nop)
       *id->dup_loc[i] = *id->operand_loc[nop];
 }
+
+/* Return info about INSN.  Set up the info if it is not done yet.  */
+static inline lra_insn_recog_data_t
+lra_get_insn_recog_data (rtx insn)
+{
+  lra_insn_recog_data_t data;
+  unsigned int uid = INSN_UID (insn);
+
+  if (lra_insn_recog_data_len > (int) uid
+      && (data = lra_insn_recog_data[uid]) != NULL)
+    {
+      /* Check that we did not change insn structure without updating
+	 the info.  */
+      lra_assert (data->insn == insn
+		  && (INSN_CODE (insn) < 0 || data->icode == INSN_CODE (insn)));
+      return data;
+    }
+  return lra_set_insn_recog_data (insn);
+}
Index: lra-lives.c
===================================================================
--- lra-lives.c	(revision 188333)
+++ lra-lives.c	(working copy)
@@ -1,5 +1,5 @@ 
 /* Build live ranges for pseudos.
-   Copyright (C) 2010, 2011
+   Copyright (C) 2010, 2011, 2012
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -219,7 +219,7 @@  lra_merge_live_ranges (lra_live_range_t
 	first = r1;
       else
 	last->next = r1;
-      gcc_assert (r1->next == NULL);
+      lra_assert (r1->next == NULL);
     }
   else if (r2 != NULL)
     {
@@ -227,11 +227,11 @@  lra_merge_live_ranges (lra_live_range_t
 	first = r2;
       else
 	last->next = r2;
-      gcc_assert (r2->next == NULL);
+      lra_assert (r2->next == NULL);
     }
   else
     {
-      gcc_assert (last->next == NULL);
+      lra_assert (last->next == NULL);
     }
   return first;
 }
@@ -284,7 +284,7 @@  make_hard_regno_born (int regno)
 {
   unsigned int i;
 
-  gcc_assert (regno < FIRST_PSEUDO_REGISTER);
+  lra_assert (regno < FIRST_PSEUDO_REGISTER);
   if (TEST_HARD_REG_BIT (lra_no_alloc_regs, regno)
       || TEST_HARD_REG_BIT (hard_regs_live, regno))
     return;
@@ -302,7 +302,7 @@  make_hard_regno_dead (int regno)
   if (TEST_HARD_REG_BIT (lra_no_alloc_regs, regno)
       || ! TEST_HARD_REG_BIT (hard_regs_live, regno))
     return;
-  gcc_assert (regno < FIRST_PSEUDO_REGISTER);
+  lra_assert (regno < FIRST_PSEUDO_REGISTER);
   sparseset_set_bit (start_dying, regno);
   CLEAR_HARD_REG_BIT (hard_regs_live, regno);
 }
@@ -315,8 +315,8 @@  mark_pseudo_live (int regno)
 {
   lra_live_range_t p;
 
-  gcc_assert (regno >= FIRST_PSEUDO_REGISTER);
-  gcc_assert (! sparseset_bit_p (pseudos_live, regno));
+  lra_assert (regno >= FIRST_PSEUDO_REGISTER);
+  lra_assert (! sparseset_bit_p (pseudos_live, regno));
   sparseset_set_bit (pseudos_live, regno);
   IOR_HARD_REG_SET (lra_reg_info[regno].conflict_hard_regs, hard_regs_live);
   
@@ -335,14 +335,14 @@  mark_pseudo_dead (int regno)
 {
   lra_live_range_t p;
 
-  gcc_assert (regno >= FIRST_PSEUDO_REGISTER);
-  gcc_assert (sparseset_bit_p (pseudos_live, regno));
+  lra_assert (regno >= FIRST_PSEUDO_REGISTER);
+  lra_assert (sparseset_bit_p (pseudos_live, regno));
   sparseset_clear_bit (pseudos_live, regno);
   sparseset_set_bit (start_dying, regno);
   if (complete_info_p || lra_get_regno_hard_regno (regno) < 0)
     {
       p = lra_reg_info[regno].live_ranges;
-      gcc_assert (p != NULL);
+      lra_assert (p != NULL);
       p->finish = curr_point;
     }
 }
@@ -426,7 +426,7 @@  void
 lra_setup_reload_pseudo_preferenced_hard_reg (int regno,
 					      int hard_regno, int profit)
 {
-  gcc_assert (regno >= lra_constraint_new_regno_start);
+  lra_assert (regno >= lra_constraint_new_regno_start);
   if (lra_reg_info[regno].preferred_hard_regno1 == hard_regno)
     lra_reg_info[regno].preferred_hard_regno_profit1 += profit;
   else if (lra_reg_info[regno].preferred_hard_regno2 == hard_regno)
@@ -814,7 +814,7 @@  remove_some_program_points_and_update_li
     {
       for (r = lra_reg_info[i].live_ranges; r != NULL; r = r->next)
 	{
-	  gcc_assert (r->start <= r->finish);
+	  lra_assert (r->start <= r->finish);
 	  SET_BIT (born, r->start);
 	  SET_BIT (dead, r->finish);
 	}
Index: lra-spills.c
===================================================================
--- lra-spills.c	(revision 188333)
+++ lra-spills.c	(working copy)
@@ -1,5 +1,5 @@ 
 /* Change pseudos by memory.
-   Copyright (C) 2010, 2011
+   Copyright (C) 2010, 2011, 2012
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -105,7 +105,7 @@  assign_mem_slot (int i)
   unsigned int min_align = max_ref_width * BITS_PER_UNIT;
   int adjust = 0;
 
-  gcc_assert (regno_reg_rtx[i] != NULL_RTX && REG_P (regno_reg_rtx[i])
+  lra_assert (regno_reg_rtx[i] != NULL_RTX && REG_P (regno_reg_rtx[i])
 	      && lra_reg_info[i].nrefs != 0 && reg_renumber[i] < 0);
   
   x = slots[pseudo_slots[i].slot_num].mem;
@@ -266,7 +266,7 @@  assign_spill_hard_regs (int *pseudo_regn
 	for (p = r->start; p <= r->finish; p++)
 	  IOR_HARD_REG_SET (conflict_hard_regs, reserved_hard_regs[p]);
       spill_class = targetm.spill_class (lra_get_allocno_class (regno));
-      gcc_assert (spill_class != NO_REGS);
+      lra_assert (spill_class != NO_REGS);
       spill_class_size = ira_class_hard_regs_num[spill_class];
       mode = lra_reg_info[regno].biggest_mode;
       for (k = 0; k < spill_class_size; k++)
@@ -488,7 +488,7 @@  lra_spill (void)
 	spill_hard_reg[i] = NULL_RTX;
 	pseudo_regnos[n++] = i;
       }
-  gcc_assert (n > 0);
+  lra_assert (n > 0);
   pseudo_slots = (struct pseudo_slot *) xmalloc (sizeof (struct pseudo_slot)
 						 * regs_num);
   slots = (struct slot *) xmalloc (sizeof (struct slot) * regs_num);
@@ -548,7 +548,7 @@  lra_hard_reg_substitution (void)
 
 	      if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
 		{
-		  gcc_assert (REGNO (SUBREG_REG (op)) < FIRST_PSEUDO_REGISTER);
+		  lra_assert (REGNO (SUBREG_REG (op)) < FIRST_PSEUDO_REGISTER);
 		  alter_subreg (id->operand_loc[i]);
 		  lra_update_dup (id, i);
 		}