diff mbox

[RFC,i386] : Implement ix86_set_reg_reg_cost, fix PR 53250 "Splitting reg" failure.

Message ID CAFULd4ZRpB=396y0dtr8TMwLHM3vx0-8bV8q8tLepHK90PbNdw@mail.gmail.com
State New
Headers show

Commit Message

Uros Bizjak May 7, 2012, 8:40 p.m. UTC
On Mon, May 7, 2012 at 10:35 PM, Uros Bizjak <ubizjak@gmail.com> wrote:

Now with a patch and ChangeLog:

2012-05-07  Uros Bizjak  <ubizjak@gmail.com>

	PR target/53250
	* config/i386/i386.c (ix86_set_reg_reg_cost): New function.
	(ix86_rtx_costs): Handle SET.

> Patch was tested on x86_64-pc-linux-gnu {,-m32}.
>
> I have also #define LOG_COST 1 temporarily and looked at generated
> cost calculations for various -msse* settings.
>
> I will wait for a day for possible comments on the implementation
> before the patch will be committed to mainline SVN.

Uros.

Comments

Uros Bizjak May 8, 2012, 4:02 p.m. UTC | #1
On Mon, May 7, 2012 at 10:40 PM, Uros Bizjak <ubizjak@gmail.com> wrote:

> 2012-05-07  Uros Bizjak  <ubizjak@gmail.com>
>
>        PR target/53250
>        * config/i386/i386.c (ix86_set_reg_reg_cost): New function.
>        (ix86_rtx_costs): Handle SET.
>
>> Patch was tested on x86_64-pc-linux-gnu {,-m32}.
>>
>> I have also #define LOG_COST 1 temporarily and looked at generated
>> cost calculations for various -msse* settings.
>>
>> I will wait for a day for possible comments on the implementation
>> before the patch will be committed to mainline SVN.

Committed to mainline SVN at r187289.

Uros.
diff mbox

Patch

Index: config/i386/i386.c
===================================================================
--- config/i386/i386.c	(revision 187259)
+++ config/i386/i386.c	(working copy)
@@ -31861,6 +31861,52 @@  ix86_modes_tieable_p (enum machine_mode mode1, enu
   return false;
 }
 
+/* Return the cost of moving between two registers of mode MODE.  */
+
+static int
+ix86_set_reg_reg_cost (enum machine_mode mode)
+{
+  unsigned int units = UNITS_PER_WORD;
+
+  switch (GET_MODE_CLASS (mode))
+    {
+    default:
+      break;
+
+    case MODE_CC:
+      units = GET_MODE_SIZE (CCmode);
+      break;
+
+    case MODE_FLOAT:
+      if ((TARGET_SSE2 && mode == TFmode)
+	  || (TARGET_80387 && mode == XFmode)
+	  || ((TARGET_80387 || TARGET_SSE2) && mode == DFmode)
+	  || ((TARGET_80387 || TARGET_SSE) && mode == SFmode))
+	units = GET_MODE_SIZE (mode);
+      break;
+
+    case MODE_COMPLEX_FLOAT:
+      if ((TARGET_SSE2 && mode == TCmode)
+	  || (TARGET_80387 && mode == XCmode)
+	  || ((TARGET_80387 || TARGET_SSE2) && mode == DCmode)
+	  || ((TARGET_80387 || TARGET_SSE) && mode == SCmode))
+	units = GET_MODE_SIZE (mode);
+      break;
+
+    case MODE_VECTOR_INT:
+    case MODE_VECTOR_FLOAT:
+      if ((TARGET_AVX && VALID_AVX256_REG_MODE (mode))
+	  || (TARGET_SSE2 && VALID_SSE2_REG_MODE (mode))
+	  || (TARGET_SSE && VALID_SSE_REG_MODE (mode))
+	  || (TARGET_MMX && VALID_MMX_REG_MODE (mode)))
+	units = GET_MODE_SIZE (mode);
+    }
+
+  /* Return the cost of moving between two registers of mode MODE,
+     assuming that the move will be in pieces of at most UNITS bytes.  */
+  return COSTS_N_INSNS ((GET_MODE_SIZE (mode) + units - 1) / units);
+}
+
 /* Compute a (partial) cost for rtx X.  Return true if the complete
    cost has been computed, and false if subexpressions should be
    scanned.  In either case, *TOTAL contains the cost result.  */
@@ -31875,6 +31921,15 @@  ix86_rtx_costs (rtx x, int code, int outer_code_i,
 
   switch (code)
     {
+    case SET:
+      if (register_operand (SET_DEST (x), VOIDmode)
+	  && reg_or_0_operand (SET_SRC (x), VOIDmode))
+	{
+	  *total = ix86_set_reg_reg_cost (GET_MODE (SET_DEST (x)));
+	  return true;
+	}
+      return false;
+
     case CONST_INT:
     case CONST:
     case LABEL_REF: