[RFC] rs6000 rtx_costs (take 3)

David Edelsohn dje@watson.ibm.com
Wed Jul 28 08:54:00 GMT 2004


	The main difference here is treating the cost of FP CONST_DOULE as
MEM. 

David

Index: rs6000.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.670
diff -c -p -r1.670 rs6000.c
*** rs6000.c	20 Jul 2004 07:27:13 -0000	1.670
--- rs6000.c	27 Jul 2004 19:24:32 -0000
*************** rs6000_rtx_costs (rtx x, int code, int o
*** 16506,16526 ****
        /* On the RS/6000, if it is valid in the insn, it is free.
  	 So this always returns 0.  */
      case CONST_INT:
      case CONST:
      case LABEL_REF:
      case SYMBOL_REF:
!     case CONST_DOUBLE:
!     case HIGH:
!       *total = 0;
        return true;
  
      case PLUS:
        if (mode == DFmode)
! 	*total = GET_CODE (XEXP (x, 0)) == MULT
! 		 ? rs6000_cost->dmul
! 		 : rs6000_cost->fp;
        else if (mode == SFmode)
! 	*total = rs6000_cost->fp;
        else if (GET_CODE (XEXP (x, 0)) == MULT)
  	{
  	  /* The rs6000 doesn't have shift-and-add instructions.  */
--- 16511,16592 ----
        /* On the RS/6000, if it is valid in the insn, it is free.
  	 So this always returns 0.  */
      case CONST_INT:
+       if ((outer_code == PLUS && add_operand (x, VOIDmode))
+ 	  || (outer_code == MINUS && add_operand (x, VOIDmode))
+ 	  || (outer_code == AND
+ 	      && (logical_operand (x, VOIDmode) || mask_operand (x, VOIDmode)))
+ 	  || (outer_code == IOR && logical_operand (x, VOIDmode))
+ 	  || (outer_code == XOR && logical_operand (x, VOIDmode)))
+ 	{
+ 	  *total = 0;
+ 	  return true;
+ 	}
+       else if ((outer_code == PLUS
+ 		&& reg_or_add_cint64_operand (x, VOIDmode))
+ 	       || (outer_code == MINUS
+ 		   && reg_or_sub_cint64_operand (x, VOIDmode))
+ 	       || (outer_code == IOR
+ 		   && reg_or_logical_cint_operand (x, VOIDmode))
+ 	       || (outer_code == XOR
+ 		   && reg_or_logical_cint_operand (x, VOIDmode)))
+ 	{
+ 	  *total = COSTS_N_INSNS (1);
+ 	  return true;
+ 	}
+       /* FALLTHRU */
+ 
+     case CONST_DOUBLE:
+       if ((outer_code == AND
+ 	   && (logical_operand (x, VOIDmode)) || mask_operand (x, VOIDmode))
+ 	  || (outer_code == IOR && logical_operand (x, VOIDmode))
+ 	  || (outer_code == XOR && logical_operand (x, VOIDmode)))
+ 	{
+ 	  *total = 0;
+ 	  return true;
+ 	}
+       else if ((outer_code == IOR
+ 		&& reg_or_logical_cint_operand (x, VOIDmode))
+ 	       || (outer_code == XOR
+ 		   && reg_or_logical_cint_operand (x, VOIDmode)))
+ 	{
+ 	  *total = COSTS_N_INSNS (1);
+ 	  return true;
+ 	}
+       /* FALLTHRU */
+ 
      case CONST:
+     case HIGH:
      case LABEL_REF:
      case SYMBOL_REF:
!     case MEM:
!       /* When optimizing for size, MEM should be slightly more expensive
! 	 than generating address, e.g., (plus (reg) (const)).
! 	 L1 cache latecy is about two instructions.  */
!       *total = optimize_size ? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
        return true;
  
      case PLUS:
        if (mode == DFmode)
! 	{
! 	  if (GET_CODE (XEXP (x, 0)) == MULT)
! 	    {
! 	      /* FNMA accounted in outer NEG.  */
! 	      if (outer_code == NEG)
! 		*total = rs6000_cost->dmul - rs6000_cost->fp;
! 	      else
! 		*total = rs6000_cost->dmul;
! 	    }
! 	  else
! 	    *total = rs6000_cost->fp;
! 	}
        else if (mode == SFmode)
! 	{
! 	  /* FNMA accounted in outer NEG.  */
! 	  if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
! 	    *total = 0;
! 	  else
! 	    *total = rs6000_cost->fp;
! 	}
        else if (GET_CODE (XEXP (x, 0)) == MULT)
  	{
  	  /* The rs6000 doesn't have shift-and-add instructions.  */
*************** rs6000_rtx_costs (rtx x, int code, int o
*** 16528,16548 ****
  	  *total += COSTS_N_INSNS (1);
  	}
        else
! 	*total = ((GET_CODE (XEXP (x, 1)) == CONST_INT
! 		  && ((unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1))
! 						+ 0x8000) >= 0x10000)
! 		  && ((INTVAL (XEXP (x, 1)) & 0xffff) != 0))
! 		 ? COSTS_N_INSNS (2)
! 		 : COSTS_N_INSNS (1));
!       return true;
  
      case MINUS:
        if (mode == DFmode)
! 	*total = GET_CODE (XEXP (x, 0)) == MULT
! 		 ? rs6000_cost->dmul
! 		 : rs6000_cost->fp;
        else if (mode == SFmode)
! 	*total = rs6000_cost->fp;
        else if (GET_CODE (XEXP (x, 0)) == MULT)
  	{
  	  /* The rs6000 doesn't have shift-and-sub instructions.  */
--- 16594,16624 ----
  	  *total += COSTS_N_INSNS (1);
  	}
        else
! 	*total = COSTS_N_INSNS (1);
!       return false;
  
      case MINUS:
        if (mode == DFmode)
! 	{
! 	  if (GET_CODE (XEXP (x, 0)) == MULT)
! 	    {
! 	      /* FNMA accounted in outer NEG.  */
! 	      if (outer_code == NEG)
! 		*total = 0;
! 	      else
! 		*total = rs6000_cost->dmul;
! 	    }
! 	  else
! 	    *total = rs6000_cost->fp;
! 	}
        else if (mode == SFmode)
! 	{
! 	  /* FNMA accounted in outer NEG.  */
! 	  if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
! 	    *total = 0;
! 	  else
! 	    *total = rs6000_cost->fp;
! 	}
        else if (GET_CODE (XEXP (x, 0)) == MULT)
  	{
  	  /* The rs6000 doesn't have shift-and-sub instructions.  */
*************** rs6000_rtx_costs (rtx x, int code, int o
*** 16551,16567 ****
  	}
        else
          *total = COSTS_N_INSNS (1);
!       return true;
! 
!     case AND:
!     case IOR:
!     case XOR:
!       *total = ((GET_CODE (XEXP (x, 1)) == CONST_INT
! 		 && (INTVAL (XEXP (x, 1)) & (~ (HOST_WIDE_INT) 0xffff)) != 0
! 		 && ((INTVAL (XEXP (x, 1)) & 0xffff) != 0))
! 		? COSTS_N_INSNS (2)
! 		: COSTS_N_INSNS (1));
!       return true;
  
      case MULT:
        if (GET_CODE (XEXP (x, 1)) == CONST_INT)
--- 16627,16633 ----
  	}
        else
          *total = COSTS_N_INSNS (1);
!       return false;
  
      case MULT:
        if (GET_CODE (XEXP (x, 1)) == CONST_INT)
*************** rs6000_rtx_costs (rtx x, int code, int o
*** 16572,16577 ****
--- 16638,16647 ----
  	  else
  	    *total = rs6000_cost->mulsi_const;
  	}
+       /* FMA accounted in outer PLUS/MINUS.  */
+       else if ((mode == DFmode || mode == SFmode)
+ 	       && (outer_code == PLUS || outer_code == MINUS))
+ 	*total = 0;
        else if (mode == DFmode)
  	*total = rs6000_cost->dmul;
        else if (mode == SFmode)
*************** rs6000_rtx_costs (rtx x, int code, int o
*** 16580,16586 ****
  	*total = rs6000_cost->muldi;
        else
  	*total = rs6000_cost->mulsi;
!       return true;
  
      case DIV:
      case MOD:
--- 16650,16656 ----
  	*total = rs6000_cost->muldi;
        else
  	*total = rs6000_cost->mulsi;
!       return false;
  
      case DIV:
      case MOD:
*************** rs6000_rtx_costs (rtx x, int code, int o
*** 16588,16600 ****
  	{
  	  *total = mode == DFmode ? rs6000_cost->ddiv
  				  : rs6000_cost->sdiv;
! 	  return true;
  	}
        if (GET_CODE (XEXP (x, 1)) == CONST_INT
  	  && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
  	{
  	  *total = COSTS_N_INSNS (2);
! 	  return true;
  	}
        /* FALLTHRU */
  
--- 16658,16670 ----
  	{
  	  *total = mode == DFmode ? rs6000_cost->ddiv
  				  : rs6000_cost->sdiv;
! 	  return false;
  	}
        if (GET_CODE (XEXP (x, 1)) == CONST_INT
  	  && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
  	{
  	  *total = COSTS_N_INSNS (2);
! 	  return false;
  	}
        /* FALLTHRU */
  
*************** rs6000_rtx_costs (rtx x, int code, int o
*** 16604,16638 ****
  	*total = rs6000_cost->divdi;
        else
  	*total = rs6000_cost->divsi;
!       return true;
  
      case FFS:
        *total = COSTS_N_INSNS (4);
!       return true;
! 
!     case NEG:
!     case ABS:
!       if (FLOAT_MODE_P (mode))
! 	*total = rs6000_cost->fp;
!       else
! 	*total = COSTS_N_INSNS (1);
!       return true;
! 
!     case MEM:
!       /* MEM should be slightly more expensive than (plus (reg) (const)).  */
!       *total = COSTS_N_INSNS (1) + 1;
!       return true;
  
      case NOT:
      case SIGN_EXTEND:
      case ZERO_EXTEND:
-     case COMPARE:
        *total = COSTS_N_INSNS (1);
!       break;
  
      case FLOAT_TRUNCATE:
        *total = rs6000_cost->fp;
!       return true;
  
      case UNSPEC:
        switch (XINT (x, 1))
--- 16674,16724 ----
  	*total = rs6000_cost->divdi;
        else
  	*total = rs6000_cost->divsi;
!       return false;
  
      case FFS:
        *total = COSTS_N_INSNS (4);
!       return false;
  
      case NOT:
+       if (outer_code == AND || outer_code == IOR || outer_code == XOR)
+ 	{
+ 	  *total = 0;
+ 	  return false;
+ 	}
+       /* FALLTHRU */
+ 
+     case AND:
+     case IOR:
+     case XOR:
+     case ASHIFT:
+     case ASHIFTRT:
+     case LSHIFTRT:
+     case ROTATE:
+     case ROTATERT:
      case SIGN_EXTEND:
      case ZERO_EXTEND:
        *total = COSTS_N_INSNS (1);
!       return false;
! 
!     case COMPARE:
!     case NEG:
!     case ABS:
!       if (!FLOAT_MODE_P (mode))
! 	{
! 	  *total = COSTS_N_INSNS (1);
! 	  return false;
! 	}
!       /* FALLTHRU */
  
+     case FLOAT:
+     case UNSIGNED_FLOAT:
+     case FIX:
+     case UNSIGNED_FIX:
+     case FLOAT_EXTEND:
      case FLOAT_TRUNCATE:
        *total = rs6000_cost->fp;
!       return false;
  
      case UNSPEC:
        switch (XINT (x, 1))
*************** rs6000_rtx_costs (rtx x, int code, int o
*** 16653,16658 ****
--- 16739,16751 ----
  	  *total = COSTS_N_INSNS (1);
  	  return true;
  	}
+       else if (FLOAT_MODE_P (x)
+ 	       && TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS)
+ 	{
+ 	  *total = rs6000_cost->fp;
+ 	  return false;
+ 	}
+ 
        break;
  
      default:



More information about the Gcc-patches mailing list