The operand_alternative cache was LRA's only per-subtarget state
so a lot of this patch is removing the associated initialisation
and target_globals stuff.

I called the preprocess_constraints functions in lra_set_insn_recog_data
rather than setup_operand_alternative because lra_set_insn_recog_data
already has a local constraints array (needed for asms).
setup_operand_alternative is now only called in the uncached case.

Thanks,
Richard


gcc/
        * lra-int.h (lra_static_insn_data): Make operand_alternative a
        const pointer.
        (target_lra_int, default_target_lra_int, this_target_lra_int)
        (op_alt_data): Delete.
        * lra.h (lra_init): Delete.
        * lra.c (default_target_lra_int, this_target_lra_int): Delete.
        (init_insn_code_data_once): Remove op_alt_data handling.
        (finish_insn_code_data_once): Likewise.
        (init_op_alt_data): Delete.
        (get_static_insn_data): Initialize operand_alternative to null.
        (free_insn_recog_data): Cast operand_alternative before freeing it.
        (setup_operand_alternative): Take the operand_alternative as
        parameter and assume it isn't already cached in the static
        insn data.
        (lra_set_insn_recog_data): Update accordingly.
        (lra_init): Delete.
        * ira.c (ira_init): Don't call lra_init.
        * target-globals.h (this_target_lra_int): Declare.
        (target_globals): Remove lra_int.
        (restore_target_globals): Update accordingly.
        * target-globals.c: Don't include lra-int.h.
        (default_target_globals, save_target_globals): Remove lra_int.

Index: gcc/lra-int.h
===================================================================
--- gcc/lra-int.h       2014-05-31 08:54:08.894207303 +0100
+++ gcc/lra-int.h       2014-05-31 09:25:56.876885502 +0100
@@ -198,7 +198,7 @@ struct lra_static_insn_data
   /* Array [n_alternatives][n_operand] of static constraint info for
      given operand in given alternative.  This info can be changed if
      the target reg info is changed.  */
-  struct operand_alternative *operand_alternative;
+  const struct operand_alternative *operand_alternative;
 };
 
 /* LRA internal info about an insn (LRA internal insn
@@ -495,21 +495,3 @@ lra_assign_reg_val (int from, int to)
   lra_reg_info[to].val = lra_reg_info[from].val;
   lra_reg_info[to].offset = lra_reg_info[from].offset;
 }
-
-
-struct target_lra_int
-{
-  /* Map INSN_UID -> the operand alternative data (NULL if unknown).
-     We assume that this data is valid until register info is changed
-     because classes in the data can be changed.  */
-  struct operand_alternative *x_op_alt_data[LAST_INSN_CODE];
-};
-
-extern struct target_lra_int default_target_lra_int;
-#if SWITCHABLE_TARGET
-extern struct target_lra_int *this_target_lra_int;
-#else
-#define this_target_lra_int (&default_target_lra_int)
-#endif
-
-#define op_alt_data (this_target_lra_int->x_op_alt_data)
Index: gcc/lra.h
===================================================================
--- gcc/lra.h   2014-05-31 08:54:08.894207303 +0100
+++ gcc/lra.h   2014-05-31 09:25:56.951886120 +0100
@@ -36,5 +36,4 @@ extern rtx lra_create_new_reg (enum mach
 extern rtx lra_eliminate_regs (rtx, enum machine_mode, rtx);
 extern void lra (FILE *);
 extern void lra_init_once (void);
-extern void lra_init (void);
 extern void lra_finish_once (void);
Index: gcc/lra.c
===================================================================
--- gcc/lra.c   2014-05-31 08:54:08.894207303 +0100
+++ gcc/lra.c   2014-05-31 09:25:56.891885625 +0100
@@ -553,11 +553,6 @@ finish_insn_regs (void)
 /* This page contains code dealing LRA insn info (or in other words
    LRA internal insn representation).  */
 
-struct target_lra_int default_target_lra_int;
-#if SWITCHABLE_TARGET
-struct target_lra_int *this_target_lra_int = &default_target_lra_int;
-#endif
-
 /* Map INSN_CODE -> the static insn data.  This info is valid during
    all translation unit.  */
 struct lra_static_insn_data *insn_code_data[LAST_INSN_CODE];
@@ -599,7 +594,6 @@ static struct lra_static_insn_data debug
 init_insn_code_data_once (void)
 {
   memset (insn_code_data, 0, sizeof (insn_code_data));
-  memset (op_alt_data, 0, sizeof (op_alt_data));
 }
 
 /* Called once per compiler work to finalize some LRA data related to
@@ -613,25 +607,9 @@ finish_insn_code_data_once (void)
     {
       if (insn_code_data[i] != NULL)
        free (insn_code_data[i]);
-      if (op_alt_data[i] != NULL)
-       free (op_alt_data[i]);
     }
 }
 
-/* Initialize LRA info about operands in insn alternatives.  */
-static void
-init_op_alt_data (void)
-{
- int i;
-
-  for (i = 0; i < LAST_INSN_CODE; i++)
-    if (op_alt_data[i] != NULL)
-      {
-       free (op_alt_data[i]);
-       op_alt_data[i] = NULL;
-      }
-}
-
 /* Return static insn data, allocate and setup if necessary.  Although
    dup_num is static data (it depends only on icode), to set it up we
    need to extract insn first. So recog_data should be valid for
@@ -650,6 +628,7 @@ get_static_insn_data (int icode, int nop
            + sizeof (struct lra_operand_data) * nop
            + sizeof (int) * ndup;
   data = XNEWVAR (struct lra_static_insn_data, n_bytes);
+  data->operand_alternative = NULL;
   data->n_operands = nop;
   data->n_dups = ndup;
   data->n_alternatives = nalt;
@@ -727,7 +706,8 @@ free_insn_recog_data (lra_insn_recog_dat
   if (data->icode < 0 && NONDEBUG_INSN_P (data->insn))
     {
       if (data->insn_static_data->operand_alternative != NULL)
-       free (data->insn_static_data->operand_alternative);
+       free (const_cast <operand_alternative *>
+             (data->insn_static_data->operand_alternative));
       free_insn_regs (data->insn_static_data->hard_regs);
       free (data->insn_static_data);
     }
@@ -752,173 +732,38 @@ finish_insn_recog_data (void)
 
 /* Setup info about operands in alternatives of LRA DATA of insn.  */
 static void
-setup_operand_alternative (lra_insn_recog_data_t data)
+setup_operand_alternative (lra_insn_recog_data_t data,
+                          const operand_alternative *op_alt)
 {
-  int i, nop, nalt;
+  int i, j, nop, nalt;
   int icode = data->icode;
   struct lra_static_insn_data *static_data = data->insn_static_data;
 
-  if (icode >= 0
-      && (static_data->operand_alternative = op_alt_data[icode]) != NULL)
-    return;
   static_data->commutative = -1;
   nop = static_data->n_operands;
-  if (nop == 0)
-    {
-      static_data->operand_alternative = NULL;
-      return;
-    }
   nalt = static_data->n_alternatives;
-  static_data->operand_alternative = XNEWVEC (struct operand_alternative,
-                                             nalt * nop);
-  memset (static_data->operand_alternative, 0,
-         nalt * nop * sizeof (struct operand_alternative));
-  if (icode >= 0)
-    op_alt_data[icode] = static_data->operand_alternative;
+  static_data->operand_alternative = op_alt;
   for (i = 0; i < nop; i++)
     {
-      int j;
-      struct operand_alternative *op_alt_start, *op_alt;
-      const char *p = static_data->operand[i].constraint;
-
-      static_data->operand[i].early_clobber = 0;
-      op_alt_start = &static_data->operand_alternative[i];
-
-      for (j = 0; j < nalt; j++)
-       {
-         op_alt = op_alt_start + j * nop;
-         op_alt->cl = NO_REGS;
-         op_alt->constraint = p;
-         op_alt->matches = -1;
-         op_alt->matched = -1;
-
-         if (*p == '\0' || *p == ',')
-           {
-             op_alt->anything_ok = 1;
-             continue;
-           }
-
-         for (;;)
-           {
-             char c = *p;
-             if (c == '#')
-               do
-                 c = *++p;
-               while (c != ',' && c != '\0');
-             if (c == ',' || c == '\0')
-               {
-                 p++;
-                 break;
-               }
-
-             switch (c)
-               {
-               case '=': case '+': case '*':
-               case 'E': case 'F': case 'G': case 'H':
-               case 's': case 'i': case 'n':
-               case 'I': case 'J': case 'K': case 'L':
-               case 'M': case 'N': case 'O': case 'P':
-                 /* These don't say anything we care about.  */
-                 break;
-
-               case '%':
-                 /* We currently only support one commutative pair of
-                    operands.  */
-                 if (static_data->commutative < 0)
-                   static_data->commutative = i;
-                 else
-                   lra_assert (data->icode < 0); /* Asm  */
-
-                 /* The last operand should not be marked
-                    commutative.  */
-                 lra_assert (i != nop - 1);
-                 break;
-
-               case '?':
-                 op_alt->reject += LRA_LOSER_COST_FACTOR;
-                 break;
-               case '!':
-                 op_alt->reject += LRA_MAX_REJECT;
-                 break;
-               case '&':
-                 op_alt->earlyclobber = 1;
-                 static_data->operand[i].early_clobber = 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->matches = strtoul (p, &end, 10);
-                   static_data->operand_alternative
-                     [j * nop + op_alt->matches].matched = i;
-                   p = end;
-                 }
-                 continue;
-
-               case TARGET_MEM_CONSTRAINT:
-                 op_alt->memory_ok = 1;
-                 break;
-               case '<':
-                 op_alt->decmem_ok = 1;
-                 break;
-               case '>':
-                 op_alt->incmem_ok = 1;
-                 break;
-               case 'V':
-                 op_alt->nonoffmem_ok = 1;
-                 break;
-               case 'o':
-                 op_alt->offmem_ok = 1;
-                 break;
-               case 'X':
-                 op_alt->anything_ok = 1;
-                 break;
-
-               case 'p':
-                 static_data->operand[i].is_address = true;
-                 op_alt->is_address = 1;
-                 op_alt->cl = (reg_class_subunion[(int) op_alt->cl]
-                               [(int) base_reg_class (VOIDmode,
-                                                      ADDR_SPACE_GENERIC,
-                                                      ADDRESS, SCRATCH)]);
-                 break;
-
-               case 'g':
-               case 'r':
-                 op_alt->cl =
-                  reg_class_subunion[(int) op_alt->cl][(int) GENERAL_REGS];
-                 break;
-
-               default:
-                 if (EXTRA_MEMORY_CONSTRAINT (c, p))
-                   {
-                     op_alt->memory_ok = 1;
-                     break;
-                   }
-                 if (EXTRA_ADDRESS_CONSTRAINT (c, p))
-                   {
-                     static_data->operand[i].is_address = true;
-                     op_alt->is_address = 1;
-                     op_alt->cl
-                       = (reg_class_subunion
-                          [(int) op_alt->cl]
-                          [(int) base_reg_class (VOIDmode, ADDR_SPACE_GENERIC,
-                                                 ADDRESS, SCRATCH)]);
-                     break;
-                   }
-
-                 op_alt->cl
-                   = (reg_class_subunion
-                      [(int) op_alt->cl]
-                      [(int)
-                       REG_CLASS_FROM_CONSTRAINT ((unsigned char) c, p)]);
-                 break;
-               }
-             p += CONSTRAINT_LEN (c, p);
-           }
+      static_data->operand[i].early_clobber = false;
+      static_data->operand[i].is_address = false;
+      if (static_data->operand[i].constraint[0] == '%')
+       {
+         /* We currently only support one commutative pair of operands.  */
+         if (static_data->commutative < 0)
+           static_data->commutative = i;
+         else
+           lra_assert (icode < 0); /* Asm  */
+         /* The last operand should not be marked commutative.  */
+         lra_assert (i != nop - 1);
        }
     }
+  for (j = 0; j < nalt; j++)
+    for (i = 0; i < nop; i++, op_alt++)
+      {
+       static_data->operand[i].early_clobber |= op_alt->earlyclobber;
+       static_data->operand[i].is_address |= op_alt->is_address;
+      }
 }
 
 /* Recursively process X and collect info about registers, which are
@@ -1077,12 +922,13 @@ lra_set_insn_recog_data (rtx insn)
     }
   if (icode < 0)
     {
-      int nop;
+      int nop, nalt;
       enum machine_mode operand_mode[MAX_RECOG_OPERANDS];
       const char *constraints[MAX_RECOG_OPERANDS];
 
       nop = asm_noperands (PATTERN (insn));
       data->operand_loc = data->dup_loc = NULL;
+      nalt = 1;
       if (nop < 0)
        {
          /* Its is a special insn like USE or CLOBBER.  We should
@@ -1092,7 +938,7 @@ lra_set_insn_recog_data (rtx insn)
                      || GET_CODE (PATTERN (insn)) == CLOBBER
                      || GET_CODE (PATTERN (insn)) == ASM_INPUT);
          data->insn_static_data = insn_static_data
-           = get_static_insn_data (-1, 0, 0, 1);
+           = get_static_insn_data (-1, 0, 0, nalt);
        }
       else
        {
@@ -1106,16 +952,15 @@ lra_set_insn_recog_data (rtx insn)
          decode_asm_operands (PATTERN (insn), NULL,
                               data->operand_loc,
                               constraints, operand_mode, NULL);
-         n = 1;
          if (nop > 0)
            {
              const char *p =  recog_data.constraints[0];
 
              for (p =  constraints[0]; *p; p++)
-               n += *p == ',';
+               nalt += *p == ',';
            }
          data->insn_static_data = insn_static_data
-           = get_static_insn_data (-1, nop, 0, n);
+           = get_static_insn_data (-1, nop, 0, nalt);
          for (i = 0; i < nop; i++)
            {
              insn_static_data->operand[i].mode = operand_mode[i];
@@ -1131,6 +976,13 @@ lra_set_insn_recog_data (rtx insn)
             : insn_static_data->operand[i].constraint[0] == '+' ? OP_INOUT
             : OP_IN);
       data->enabled_alternatives = ALL_ALTERNATIVES;
+      if (nop > 0)
+       {
+         operand_alternative *op_alt = XCNEWVEC (operand_alternative,
+                                                 nalt * nop);
+         preprocess_constraints (nop, nalt, constraints, op_alt);
+         setup_operand_alternative (data, op_alt);
+       }
     }
   else
     {
@@ -1158,6 +1010,11 @@ lra_set_insn_recog_data (rtx insn)
        }
       data->dup_loc = locs;
       data->enabled_alternatives = get_enabled_alternatives (insn);
+      const operand_alternative *op_alt = preprocess_insn_constraints (icode);
+      if (!insn_static_data->operand_alternative)
+       setup_operand_alternative (data, op_alt);
+      else if (op_alt != insn_static_data->operand_alternative)
+       insn_static_data->operand_alternative = op_alt;
     }
   if (GET_CODE (PATTERN (insn)) == CLOBBER || GET_CODE (PATTERN (insn)) == USE)
     insn_static_data->hard_regs = NULL;
@@ -1165,7 +1022,6 @@ lra_set_insn_recog_data (rtx insn)
     insn_static_data->hard_regs
       = collect_non_operand_hard_regs (&PATTERN (insn), data,
                                       NULL, OP_IN, false);
-  setup_operand_alternative (data);
   data->arg_hard_regs = NULL;
   if (CALL_P (insn))
     {
@@ -2451,13 +2307,6 @@ lra_init_once (void)
   init_insn_code_data_once ();
 }
 
-/* Initialize LRA whenever register-related information is changed.  */
-void
-lra_init (void)
-{
-  init_op_alt_data ();
-}
-
 /* Called once per compiler to finish LRA data which are initialize
    once.  */
 void
Index: gcc/ira.c
===================================================================
--- gcc/ira.c   2014-05-31 08:54:08.894207303 +0100
+++ gcc/ira.c   2014-05-31 09:25:56.934885982 +0100
@@ -1715,7 +1715,6 @@ ira_init (void)
   clarify_prohibited_class_mode_regs ();
   setup_hard_regno_aclass ();
   ira_init_costs ();
-  lra_init ();
 }
 
 /* Function called once at the end of compiler work.  */
Index: gcc/target-globals.h
===================================================================
--- gcc/target-globals.h        2014-05-31 08:54:08.894207303 +0100
+++ gcc/target-globals.h        2014-05-31 09:25:56.914885815 +0100
@@ -33,7 +33,6 @@ #define TARGET_GLOBALS_H 1
 extern struct target_cfgloop *this_target_cfgloop;
 extern struct target_ira *this_target_ira;
 extern struct target_ira_int *this_target_ira_int;
-extern struct target_lra_int *this_target_lra_int;
 extern struct target_builtins *this_target_builtins;
 extern struct target_gcse *this_target_gcse;
 extern struct target_bb_reorder *this_target_bb_reorder;
@@ -53,7 +52,6 @@ struct GTY(()) target_globals {
   struct target_cfgloop *GTY((skip)) cfgloop;
   void *GTY((atomic)) ira;
   void *GTY((atomic)) ira_int;
-  void *GTY((atomic)) lra_int;
   struct target_builtins *GTY((skip)) builtins;
   struct target_gcse *GTY((skip)) gcse;
   struct target_bb_reorder *GTY((skip)) bb_reorder;
@@ -81,7 +79,6 @@ restore_target_globals (struct target_gl
   this_target_cfgloop = g->cfgloop;
   this_target_ira = (struct target_ira *) g->ira;
   this_target_ira_int = (struct target_ira_int *) g->ira_int;
-  this_target_lra_int = (struct target_lra_int *) g->lra_int;
   this_target_builtins = g->builtins;
   this_target_gcse = g->gcse;
   this_target_bb_reorder = g->bb_reorder;
Index: gcc/target-globals.c
===================================================================
--- gcc/target-globals.c        2014-05-31 08:54:08.894207303 +0100
+++ gcc/target-globals.c        2014-05-31 09:25:56.909885775 +0100
@@ -38,7 +38,6 @@ Software Foundation; either version 3, o
 #include "libfuncs.h"
 #include "cfgloop.h"
 #include "ira-int.h"
-#include "lra-int.h"
 #include "builtins.h"
 #include "gcse.h"
 #include "bb-reorder.h"
@@ -59,7 +58,6 @@ struct target_globals default_target_glo
   &default_target_cfgloop,
   &default_target_ira,
   &default_target_ira_int,
-  &default_target_lra_int,
   &default_target_builtins,
   &default_target_gcse,
   &default_target_bb_reorder,
@@ -96,7 +94,6 @@ save_target_globals (void)
   g->cfgloop = &p->cfgloop;
   g->ira = ggc_internal_cleared_alloc (sizeof (struct target_ira));
   g->ira_int = ggc_internal_cleared_alloc (sizeof (struct target_ira_int));
-  g->lra_int = ggc_internal_cleared_alloc (sizeof (struct target_lra_int));
   g->builtins = &p->builtins;
   g->gcse = &p->gcse;
   g->bb_reorder = &p->bb_reorder;

Reply via email to