public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* Make lra use per-alternative earlyclobber info
@ 2019-07-30 10:01 Richard Sandiford
  2019-07-30 23:32 ` Vladimir Makarov
  0 siblings, 1 reply; 2+ messages in thread
From: Richard Sandiford @ 2019-07-30 10:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: vmakarov

lra_insn_reg and lra_operand_data have both a bitmask of earlyclobber
alternatives and an overall boolean.  The danger is that we then test
the overall boolean when really we should be testing for a particular
alternative.  This patch gets rid of the boolean and tests the mask
against zero when we really do need to test "any alternative might
be earlyclobber".  (I think the only instance of that is the
LRA_UNKNOWN_ALT handling in lra-lives.c:reg_early_clobber_p.)

This is needed (and tested) by an upcoming SVE patch.

Tested on aarch64-linux-gnu, aarch64_be-elf and x86_64-linux-gnu.
OK to install?

Thanks,
Richard


2019-07-30  Richard Sandiford  <richard.sandiford@arm.com>

gcc/
	* lra-int.h (lra_operand_data): Remove early_clobber field.
	(lra_insn_reg): Likewise.
	* lra.c (debug_operand_data): Update accordingly.
	(setup_operand_alternative): Likewise.
	(new_insn_reg): Likewise.  Remove early_clobber parameter.
	(collect_non_operand_hard_regs): Update call accordingly.
	Don't assign to lra_insn_reg::early_clobber.
	(add_regs_to_insn_regno_info): Remove early_clobber parameter
	and update calls to new_insn_reg.
	(lra_update_insn_regno_info): Update calls accordingly.
	* lra-constraints.c (update_and_check_small_class_inputs): Take the
	alternative number as a parameter and test whether the operand
	is earlyclobbered in that particular alternative.
	(process_alt_operands): Update call accordingly.  Use per-alternative
	checks for earyclobber here too.
	* lra-lives.c (reg_early_clobber_p): Check early_clobber_alts
	against zero for IRA_UNKNOWN_ALT.

Index: gcc/lra-int.h
===================================================================
--- gcc/lra-int.h	2019-07-10 19:41:21.607936374 +0100
+++ gcc/lra-int.h	2019-07-30 10:51:22.999621161 +0100
@@ -142,10 +142,6 @@ struct lra_operand_data
   unsigned int strict_low : 1;
   /* True if the operand is an operator.  */
   unsigned int is_operator : 1;
-  /* True if there is an early clobber alternative for this operand.
-     This field is set up every time when corresponding
-     operand_alternative in lra_static_insn_data is set up.  */
-  unsigned int early_clobber : 1;
   /* True if the operand is an address.  */
   unsigned int is_address : 1;
 };
@@ -164,9 +160,6 @@ struct lra_insn_reg
   /* True if the reg is accessed through a subreg and the subreg is
      just a part of the register.  */
   unsigned int subreg_p : 1;
-  /* True if there is an early clobber alternative for this
-     operand.  */
-  unsigned int early_clobber : 1;
   /* True if the reg is clobber highed by the operand.  */
   unsigned int clobber_high : 1;
   /* The corresponding regno of the register.  */
Index: gcc/lra.c
===================================================================
--- gcc/lra.c	2019-07-10 19:41:21.611936343 +0100
+++ gcc/lra.c	2019-07-30 10:51:22.999621161 +0100
@@ -536,16 +536,14 @@ object_allocator<lra_insn_reg> lra_insn_
 
 /* Create LRA insn related info about a reference to REGNO in INSN
    with TYPE (in/out/inout), biggest reference mode MODE, flag that it
-   is reference through subreg (SUBREG_P), flag that is early
-   clobbered in the insn (EARLY_CLOBBER), and reference to the next
+   is reference through subreg (SUBREG_P), and reference to the next
    insn reg info (NEXT).  If REGNO can be early clobbered,
    alternatives in which it can be early clobbered are given by
    EARLY_CLOBBER_ALTS.  CLOBBER_HIGH marks if reference is a clobber
    high.  */
 static struct lra_insn_reg *
 new_insn_reg (rtx_insn *insn, int regno, enum op_type type,
-	      machine_mode mode,
-	      bool subreg_p, bool early_clobber,
+	      machine_mode mode, bool subreg_p,
 	      alternative_mask early_clobber_alts,
 	      struct lra_insn_reg *next, bool clobber_high)
 {
@@ -556,7 +554,6 @@ new_insn_reg (rtx_insn *insn, int regno,
       && partial_subreg_p (lra_reg_info[regno].biggest_mode, mode))
     lra_reg_info[regno].biggest_mode = mode;
   ir->subreg_p = subreg_p;
-  ir->early_clobber = early_clobber;
   ir->early_clobber_alts = early_clobber_alts;
   ir->clobber_high = clobber_high;
   ir->regno = regno;
@@ -605,7 +602,7 @@ static struct lra_operand_data debug_ope
     0, /* early_clobber_alts */
     E_VOIDmode, /* We are not interesting in the operand mode.  */
     OP_IN,
-    0, 0, 0, 0
+    0, 0, 0
   };
 
 /* The following data are used as static insn data for all debug
@@ -801,7 +798,6 @@ setup_operand_alternative (lra_insn_reco
   for (i = 0; i < nop; i++)
     {
       static_data->operand[i].early_clobber_alts = 0;
-      static_data->operand[i].early_clobber = false;
       static_data->operand[i].is_address = false;
       if (static_data->operand[i].constraint[0] == '%')
 	{
@@ -817,7 +813,6 @@ setup_operand_alternative (lra_insn_reco
   for (j = 0; j < nalt; j++)
     for (i = 0; i < nop; i++, op_alt++)
       {
-	static_data->operand[i].early_clobber |= op_alt->earlyclobber;
 	if (op_alt->earlyclobber)
 	  static_data->operand[i].early_clobber_alts |= (alternative_mask) 1 << j;
 	static_data->operand[i].is_address |= op_alt->is_address;
@@ -878,10 +873,7 @@ collect_non_operand_hard_regs (rtx_insn
 		if (curr->type != type)
 		  curr->type = OP_INOUT;
 		if (early_clobber)
-		  {
-		    curr->early_clobber = true;
-		    curr->early_clobber_alts = ALL_ALTERNATIVES;
-		  }
+		  curr->early_clobber_alts = ALL_ALTERNATIVES;
 		break;
 	      }
 	  if (curr == NULL)
@@ -897,7 +889,6 @@ collect_non_operand_hard_regs (rtx_insn
 			 && regno <= LAST_STACK_REG));
 #endif
 	      list = new_insn_reg (data->insn, regno, type, mode, subreg_p,
-				   early_clobber,
 				   early_clobber ? ALL_ALTERNATIVES : 0, list,
 				   clobber_high);
 	    }
@@ -1449,15 +1440,13 @@ lra_get_copy (int n)
 /* This page contains code dealing with info about registers in
    insns.  */
 
-/* Process X of INSN recursively and add info (operand type is
-   given by TYPE, flag of that it is early clobber is EARLY_CLOBBER)
-   about registers in X to the insn DATA.  If X can be early clobbered,
-   alternatives in which it can be early clobbered are given by
-   EARLY_CLOBBER_ALTS.  */
+/* Process X of INSN recursively and add info (operand type is given
+   by TYPE) about registers in X to the insn DATA.  If X can be early
+   clobbered, alternatives in which it can be early clobbered are given
+   by EARLY_CLOBBER_ALTS.  */
 static void
 add_regs_to_insn_regno_info (lra_insn_recog_data_t data, rtx x,
-			     rtx_insn *insn,
-			     enum op_type type, bool early_clobber,
+			     rtx_insn *insn, enum op_type type,
 			     alternative_mask early_clobber_alts)
 {
   int i, j, regno;
@@ -1487,8 +1476,7 @@ add_regs_to_insn_regno_info (lra_insn_re
       if (bitmap_set_bit (&lra_reg_info[regno].insn_bitmap, INSN_UID (insn)))
 	{
 	  data->regs = new_insn_reg (data->insn, regno, type, mode, subreg_p,
-				     early_clobber, early_clobber_alts,
-				     data->regs, false);
+				     early_clobber_alts, data->regs, false);
 	  return;
 	}
       else
@@ -1500,15 +1488,12 @@ add_regs_to_insn_regno_info (lra_insn_re
 		  /* The info cannot be integrated into the found
 		     structure.  */
 		  data->regs = new_insn_reg (data->insn, regno, type, mode,
-					     subreg_p, early_clobber,
-					     early_clobber_alts, data->regs,
-					     false);
+					     subreg_p, early_clobber_alts,
+					     data->regs, false);
 		else
 		  {
 		    if (curr->type != type)
 		      curr->type = OP_INOUT;
-		    if (curr->early_clobber != early_clobber)
-		      curr->early_clobber = true;
 		    curr->early_clobber_alts |= early_clobber_alts;
 		  }
 		return;
@@ -1520,23 +1505,23 @@ add_regs_to_insn_regno_info (lra_insn_re
   switch (code)
     {
     case SET:
-      add_regs_to_insn_regno_info (data, SET_DEST (x), insn, OP_OUT, false, 0);
-      add_regs_to_insn_regno_info (data, SET_SRC (x), insn, OP_IN, false, 0);
+      add_regs_to_insn_regno_info (data, SET_DEST (x), insn, OP_OUT, 0);
+      add_regs_to_insn_regno_info (data, SET_SRC (x), insn, OP_IN, 0);
       break;
     case CLOBBER:
       /* We treat clobber of non-operand hard registers as early
 	 clobber.  */
       add_regs_to_insn_regno_info (data, XEXP (x, 0), insn, OP_OUT,
-				   true, ALL_ALTERNATIVES);
+				   ALL_ALTERNATIVES);
       break;
     case CLOBBER_HIGH:
       gcc_unreachable ();
     case PRE_INC: case PRE_DEC: case POST_INC: case POST_DEC:
-      add_regs_to_insn_regno_info (data, XEXP (x, 0), insn, OP_INOUT, false, 0);
+      add_regs_to_insn_regno_info (data, XEXP (x, 0), insn, OP_INOUT, 0);
       break;
     case PRE_MODIFY: case POST_MODIFY:
-      add_regs_to_insn_regno_info (data, XEXP (x, 0), insn, OP_INOUT, false, 0);
-      add_regs_to_insn_regno_info (data, XEXP (x, 1), insn, OP_IN, false, 0);
+      add_regs_to_insn_regno_info (data, XEXP (x, 0), insn, OP_INOUT, 0);
+      add_regs_to_insn_regno_info (data, XEXP (x, 1), insn, OP_IN, 0);
       break;
     default:
       if ((code != PARALLEL && code != EXPR_LIST) || type != OP_OUT)
@@ -1557,12 +1542,12 @@ add_regs_to_insn_regno_info (lra_insn_re
       for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
 	{
 	  if (fmt[i] == 'e')
-	    add_regs_to_insn_regno_info (data, XEXP (x, i), insn, type, false, 0);
+	    add_regs_to_insn_regno_info (data, XEXP (x, i), insn, type, 0);
 	  else if (fmt[i] == 'E')
 	    {
 	      for (j = XVECLEN (x, i) - 1; j >= 0; j--)
 		add_regs_to_insn_regno_info (data, XVECEXP (x, i, j), insn,
-					     type, false, 0);
+					     type, 0);
 	    }
 	}
     }
@@ -1652,11 +1637,10 @@ lra_update_insn_regno_info (rtx_insn *in
   for (i = static_data->n_operands - 1; i >= 0; i--)
     add_regs_to_insn_regno_info (data, *data->operand_loc[i], insn,
 				 static_data->operand[i].type,
-				 static_data->operand[i].early_clobber,
 				 static_data->operand[i].early_clobber_alts);
   if ((code = GET_CODE (PATTERN (insn))) == CLOBBER || code == USE)
     add_regs_to_insn_regno_info (data, XEXP (PATTERN (insn), 0), insn,
-				 code == USE ? OP_IN : OP_OUT, false, 0);
+				 code == USE ? OP_IN : OP_OUT, 0);
   if (CALL_P (insn))
     /* On some targets call insns can refer to pseudos in memory in
        CALL_INSN_FUNCTION_USAGE list.  Process them in order to
@@ -1673,7 +1657,7 @@ lra_update_insn_regno_info (rtx_insn *in
 	if ((code == USE || code == CLOBBER)
 	    && MEM_P (XEXP (XEXP (link, 0), 0)))
 	  add_regs_to_insn_regno_info (data, XEXP (XEXP (link, 0), 0), insn,
-				       code == USE ? OP_IN : OP_OUT, false, 0);
+				       code == USE ? OP_IN : OP_OUT, 0);
       }
   if (NONDEBUG_INSN_P (insn))
     setup_insn_reg_info (data, freq);
Index: gcc/lra-constraints.c
===================================================================
--- gcc/lra-constraints.c	2019-07-29 09:39:49.750165306 +0100
+++ gcc/lra-constraints.c	2019-07-30 10:51:22.999621161 +0100
@@ -1866,11 +1866,12 @@ prohibited_class_reg_set_mode_p (enum re
    alternative.  */
 static unsigned int curr_small_class_check = 0;
 
-/* Update number of used inputs of class OP_CLASS for operand NOP.
-   Return true if we have more such class operands than the number of
-   available regs.  */
+/* Update number of used inputs of class OP_CLASS for operand NOP
+   of alternative NALT.  Return true if we have more such class operands
+   than the number of available regs.  */
 static bool
-update_and_check_small_class_inputs (int nop, enum reg_class op_class)
+update_and_check_small_class_inputs (int nop, int nalt,
+				     enum reg_class op_class)
 {
   static unsigned int small_class_check[LIM_REG_CLASSES];
   static int small_class_input_nums[LIM_REG_CLASSES];
@@ -1881,7 +1882,7 @@ update_and_check_small_class_inputs (int
       && hard_reg_set_intersect_p (reg_class_contents[op_class],
 				   ira_no_alloc_regs)
       && (curr_static_id->operand[nop].type != OP_OUT
-	  || curr_static_id->operand[nop].early_clobber))
+	  || TEST_BIT (curr_static_id->operand[nop].early_clobber_alts, nalt)))
     {
       if (small_class_check[op_class] == curr_small_class_check)
 	small_class_input_nums[op_class]++;
@@ -2150,7 +2151,8 @@ process_alt_operands (int only_alternati
 			/* We should reject matching of an early
 			   clobber operand if the matching operand is
 			   not dying in the insn.  */
-			if (! curr_static_id->operand[m].early_clobber
+			if (!TEST_BIT (curr_static_id->operand[m]
+				       .early_clobber_alts, nalt)
 			    || operand_reg[nop] == NULL_RTX
 			    || (find_regno_note (curr_insn, REG_DEAD,
 						 REGNO (op))
@@ -2234,7 +2236,8 @@ process_alt_operands (int only_alternati
 			   it results in less hard regs required for
 			   the insn than a non-matching earlyclobber
 			   alternative.  */
-			if (curr_static_id->operand[m].early_clobber)
+			if (TEST_BIT (curr_static_id->operand[m]
+				      .early_clobber_alts, nalt))
 			  {
 			    if (lra_dump_file != NULL)
 			      fprintf
@@ -2875,7 +2878,8 @@ process_alt_operands (int only_alternati
               goto fail;
             }
 
-	  if (update_and_check_small_class_inputs (nop, this_alternative))
+	  if (update_and_check_small_class_inputs (nop, nalt,
+						   this_alternative))
 	    {
 	      if (lra_dump_file != NULL)
 		fprintf (lra_dump_file,
Index: gcc/lra-lives.c
===================================================================
--- gcc/lra-lives.c	2019-07-10 19:41:22.591928492 +0100
+++ gcc/lra-lives.c	2019-07-30 10:51:22.999621161 +0100
@@ -624,10 +624,10 @@ check_pseudos_live_through_calls (int re
 static inline bool
 reg_early_clobber_p (const struct lra_insn_reg *reg, int n_alt)
 {
-  return (reg->early_clobber
-	  && (n_alt == LRA_UNKNOWN_ALT
-	      || (n_alt != LRA_NON_CLOBBERED_ALT
-		  && TEST_BIT (reg->early_clobber_alts, n_alt))));
+  return (n_alt == LRA_UNKNOWN_ALT
+	  ? reg->early_clobber_alts != 0
+	  : (n_alt != LRA_NON_CLOBBERED_ALT
+	     && TEST_BIT (reg->early_clobber_alts, n_alt)));
 }
 
 /* Return true if call instructions CALL1 and CALL2 use ABIs that

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: Make lra use per-alternative earlyclobber info
  2019-07-30 10:01 Make lra use per-alternative earlyclobber info Richard Sandiford
@ 2019-07-30 23:32 ` Vladimir Makarov
  0 siblings, 0 replies; 2+ messages in thread
From: Vladimir Makarov @ 2019-07-30 23:32 UTC (permalink / raw)
  To: gcc-patches, richard.sandiford


On 2019-07-30 5:58 a.m., Richard Sandiford wrote:
> lra_insn_reg and lra_operand_data have both a bitmask of earlyclobber
> alternatives and an overall boolean.  The danger is that we then test
> the overall boolean when really we should be testing for a particular
> alternative.  This patch gets rid of the boolean and tests the mask
> against zero when we really do need to test "any alternative might
> be earlyclobber".  (I think the only instance of that is the
> LRA_UNKNOWN_ALT handling in lra-lives.c:reg_early_clobber_p.)
>
> This is needed (and tested) by an upcoming SVE patch.
>
> Tested on aarch64-linux-gnu, aarch64_be-elf and x86_64-linux-gnu.
> OK to install?

Yes.  It looks good. Thank you for making the code more straightforward 
and accurate, Richard.


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2019-07-30 22:54 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-07-30 10:01 Make lra use per-alternative earlyclobber info Richard Sandiford
2019-07-30 23:32 ` Vladimir Makarov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).