This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 5/5] Reuse recog_op_alt cache in LRA


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;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]