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]

More contant folding of vectors


Hi,
as promised, here is code to constant-fold some other vector expression
(relational and if-then-else operations are still missing,  I will take
a look at these later)

Honza

Sun Feb  9 15:36:20 CET 2003  Jan Hubicka  <jh@suse.cz>
	* simplify-rtx.c (simplify_unary_operation,
	simplify_binary_operation):  Deal with vector modes
	(simplify_ternary_operation):  Deal with no-op VEC_MERGE.
Index: simplify-rtx.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/simplify-rtx.c,v
retrieving revision 1.135
diff -c -3 -p -r1.135 simplify-rtx.c
*** simplify-rtx.c	9 Feb 2003 12:35:27 -0000	1.135
--- simplify-rtx.c	9 Feb 2003 14:36:15 -0000
*************** simplify_unary_operation (code, mode, op
*** 410,415 ****
--- 410,440 ----
  	}
      }
  
+   if (VECTOR_MODE_P (mode) && GET_CODE (trueop) == CONST_VECTOR)
+     {
+       int elt_size = GET_MODE_SIZE (GET_MODE_INNER (mode));
+       unsigned n_elts = (GET_MODE_SIZE (mode) / elt_size);
+       enum machine_mode opmode = GET_MODE (trueop);
+       int op_elt_size = GET_MODE_SIZE (GET_MODE_INNER (opmode));
+       unsigned op_n_elts = (GET_MODE_SIZE (opmode) / op_elt_size);
+       rtvec v = rtvec_alloc (n_elts);
+       unsigned int i;
+ 
+       if (op_n_elts != n_elts)
+ 	abort ();
+ 
+       for (i = 0; i < n_elts; i++)
+ 	{
+ 	  rtx x = simplify_unary_operation (code, GET_MODE_INNER (mode),
+ 					    CONST_VECTOR_ELT (trueop, i),
+ 					    GET_MODE_INNER (opmode));
+ 	  if (!x)
+ 	    return 0;
+ 	  RTVEC_ELT (v, i) = x;
+ 	}
+       return gen_rtx_CONST_VECTOR (mode, v);
+     }
+ 
    /* The order of these tests is critical so that, for example, we don't
       check the wrong mode (input vs. output) for a conversion operation,
       such as FIX.  At some point, this should be simplified.  */
*************** simplify_binary_operation (code, mode, o
*** 875,880 ****
--- 900,936 ----
        tem = trueop0, trueop0 = trueop1, trueop1 = tem;
      }
  
+   if (VECTOR_MODE_P (mode)
+       && GET_CODE (trueop0) == CONST_VECTOR
+       && GET_CODE (trueop1) == CONST_VECTOR)
+     {
+       int elt_size = GET_MODE_SIZE (GET_MODE_INNER (mode));
+       unsigned n_elts = (GET_MODE_SIZE (mode) / elt_size);
+       enum machine_mode op0mode = GET_MODE (trueop0);
+       int op0_elt_size = GET_MODE_SIZE (GET_MODE_INNER (op0mode));
+       unsigned op0_n_elts = (GET_MODE_SIZE (op0mode) / op0_elt_size);
+       enum machine_mode op1mode = GET_MODE (trueop1);
+       int op1_elt_size = GET_MODE_SIZE (GET_MODE_INNER (op1mode));
+       unsigned op1_n_elts = (GET_MODE_SIZE (op1mode) / op1_elt_size);
+       rtvec v = rtvec_alloc (n_elts);
+       unsigned int i;
+ 
+       if (op0_n_elts != n_elts || op1_n_elts != n_elts)
+ 	abort ();
+ 
+       for (i = 0; i < n_elts; i++)
+ 	{
+ 	  rtx x = simplify_binary_operation (code, GET_MODE_INNER (mode),
+ 					     CONST_VECTOR_ELT (trueop0, i),
+ 					     CONST_VECTOR_ELT (trueop1, i));
+ 	  if (!x)
+ 	    return 0;
+ 	  RTVEC_ELT (v, i) = x;
+ 	}
+ 
+       return gen_rtx_CONST_VECTOR (mode, v);
+     }
+ 
    if (GET_MODE_CLASS (mode) == MODE_FLOAT
        && GET_CODE (trueop0) == CONST_DOUBLE
        && GET_CODE (trueop1) == CONST_DOUBLE
*************** simplify_binary_operation (code, mode, o
*** 1515,1521 ****
--- 1571,1684 ----
  	  return 0;
  
  	case VEC_SELECT:
+ 	  if (!VECTOR_MODE_P (mode))
+ 	    {
+ 	      if (!VECTOR_MODE_P (GET_MODE (trueop0))
+ 		  || (mode
+ 		      != GET_MODE_INNER (GET_MODE (trueop0)))
+ 		  || GET_CODE (trueop1) != PARALLEL
+ 		  || XVECLEN (trueop1, 0) != 1
+ 		  || GET_CODE (XVECEXP (trueop1, 0, 0)) != CONST_INT)
+ 		abort ();
+ 
+ 	      if (GET_CODE (trueop0) == CONST_VECTOR)
+ 		return CONST_VECTOR_ELT (trueop0, INTVAL (XVECEXP (trueop1, 0, 0)));
+ 	    }
+ 	  else
+ 	    {
+ 	      if (!VECTOR_MODE_P (GET_MODE (trueop0))
+ 		  || (GET_MODE_INNER (mode)
+ 		      != GET_MODE_INNER (GET_MODE (trueop0)))
+ 		  || GET_CODE (trueop1) != PARALLEL)
+ 		abort ();
+ 
+ 	      if (GET_CODE (trueop0) == CONST_VECTOR)
+ 		{
+ 		  int elt_size = GET_MODE_SIZE (GET_MODE_INNER (mode));
+ 		  unsigned n_elts = (GET_MODE_SIZE (mode) / elt_size);
+ 		  rtvec v = rtvec_alloc (n_elts);
+ 		  unsigned int i;
+ 
+ 		  if (XVECLEN (trueop1, 0) != (int)n_elts)
+ 		    abort ();
+ 		  for (i = 0; i < n_elts; i++)
+ 		    {
+ 		       rtx x = XVECEXP (trueop1, 0, i);
+ 
+ 		       if (GET_CODE (x) != CONST_INT)
+ 			 abort ();
+ 		       RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop0, INTVAL (x));
+ 		    }
+ 
+ 		  return gen_rtx_CONST_VECTOR (mode, v);
+ 		}
+ 	    }
+ 	  return 0;
  	case VEC_CONCAT:
+ 	  {
+ 	    enum machine_mode op0_mode = (GET_MODE (trueop0) != VOIDmode
+ 					  ? GET_MODE (trueop0)
+ 					  : GET_MODE_INNER (mode));
+ 	    enum machine_mode op1_mode = (GET_MODE (trueop1) != VOIDmode
+ 					  ? GET_MODE (trueop1)
+ 					  : GET_MODE_INNER (mode));
+ 
+ 	    if (!VECTOR_MODE_P (mode)
+ 		|| (GET_MODE_SIZE (op0_mode) + GET_MODE_SIZE (op1_mode)
+ 		    != GET_MODE_SIZE (mode)))
+ 	      abort ();
+ 
+ 	    if ((VECTOR_MODE_P (op0_mode)
+ 		 && (GET_MODE_INNER (mode)
+ 		     != GET_MODE_INNER (op0_mode)))
+ 		|| (!VECTOR_MODE_P (op0_mode)
+ 		    && GET_MODE_INNER (mode) != op0_mode))
+ 	      abort ();
+ 
+ 	    if ((VECTOR_MODE_P (op1_mode)
+ 		 && (GET_MODE_INNER (mode)
+ 		     != GET_MODE_INNER (op1_mode)))
+ 		|| (!VECTOR_MODE_P (op1_mode)
+ 		    && GET_MODE_INNER (mode) != op1_mode))
+ 	      abort ();
+ 
+ 	    if ((GET_CODE (trueop0) == CONST_VECTOR
+ 		 || GET_CODE (trueop0) == CONST_INT
+ 		 || GET_CODE (trueop0) == CONST_DOUBLE)
+ 		&& (GET_CODE (trueop1) == CONST_VECTOR
+ 		    || GET_CODE (trueop1) == CONST_INT
+ 		    || GET_CODE (trueop1) == CONST_DOUBLE))
+ 	      {
+ 		int elt_size = GET_MODE_SIZE (GET_MODE_INNER (mode));
+ 		unsigned n_elts = (GET_MODE_SIZE (mode) / elt_size);
+ 		rtvec v = rtvec_alloc (n_elts);
+ 		unsigned int i;
+ 		unsigned in_n_elts = 1;
+ 
+ 		if (VECTOR_MODE_P (op0_mode))
+ 		  in_n_elts = (GET_MODE_SIZE (op0_mode) / elt_size);
+ 		for (i = 0; i < n_elts; i++)
+ 		  {
+ 		    if (i < in_n_elts)
+ 		      {
+ 			if (!VECTOR_MODE_P (op0_mode))
+ 			  RTVEC_ELT (v, i) = trueop0;
+ 			else
+ 			  RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop0, i);
+ 		      }
+ 		    else
+ 		      {
+ 			if (!VECTOR_MODE_P (op1_mode))
+ 			  RTVEC_ELT (v, i) = trueop1;
+ 			else
+ 			  RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop1,
+ 							       i - in_n_elts);
+ 		      }
+ 		  }
+ 
+ 		return gen_rtx_CONST_VECTOR (mode, v);
+ 	      }
+ 	    }
  	  return 0;
  
  	default:
*************** simplify_ternary_operation (code, mode, 
*** 2379,2401 ****
  	  || GET_MODE (op1) != mode
  	  || !VECTOR_MODE_P (mode))
  	abort ();
-       op0 = avoid_constant_pool_reference (op0);
-       op1 = avoid_constant_pool_reference (op1);
        op2 = avoid_constant_pool_reference (op2);
!       if (GET_CODE (op0) == CONST_VECTOR
! 	  && GET_CODE (op1) == CONST_VECTOR
! 	  && GET_CODE (op2) == CONST_INT)
  	{
            int elt_size = GET_MODE_SIZE (GET_MODE_INNER (mode));
  	  unsigned n_elts = (GET_MODE_SIZE (mode) / elt_size);
! 	  rtvec v = rtvec_alloc (n_elts);
! 	  unsigned int i;
  
! 	  for (i = 0; i < n_elts; i++)
! 	    RTVEC_ELT (v, i) = (INTVAL (op2) & (1 << i)
! 				? CONST_VECTOR_ELT (op0, i)
! 				: CONST_VECTOR_ELT (op1, i));
! 	  return gen_rtx_CONST_VECTOR (mode, v);
  	}
        break;
  
--- 2542,2573 ----
  	  || GET_MODE (op1) != mode
  	  || !VECTOR_MODE_P (mode))
  	abort ();
        op2 = avoid_constant_pool_reference (op2);
!       if (GET_CODE (op2) == CONST_INT)
  	{
            int elt_size = GET_MODE_SIZE (GET_MODE_INNER (mode));
  	  unsigned n_elts = (GET_MODE_SIZE (mode) / elt_size);
! 	  int mask = (1<<n_elts) - 1;
  
! 	  if (!(INTVAL (op2) & mask))
! 	    return op1;
! 	  if ((INTVAL (op2) & mask) == mask)
! 	    return op0;
! 
! 	  op0 = avoid_constant_pool_reference (op0);
! 	  op1 = avoid_constant_pool_reference (op1);
! 	  if (GET_CODE (op0) == CONST_VECTOR
! 	      && GET_CODE (op1) == CONST_VECTOR)
! 	    {
! 	      rtvec v = rtvec_alloc (n_elts);
! 	      unsigned int i;
! 
! 	      for (i = 0; i < n_elts; i++)
! 		RTVEC_ELT (v, i) = (INTVAL (op2) & (1 << i)
! 				    ? CONST_VECTOR_ELT (op0, i)
! 				    : CONST_VECTOR_ELT (op1, i));
! 	      return gen_rtx_CONST_VECTOR (mode, v);
! 	    }
  	}
        break;
  


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