Patchwork bit_field_ref of constructor of vectors

login
register
mail settings
Submitter Marc Glisse
Date Nov. 27, 2012, 5:10 p.m.
Message ID <alpine.DEB.2.02.1211271758300.332@stedding.saclay.inria.fr>
Download mbox | patch
Permalink /patch/202266/
State New
Headers show

Comments

Marc Glisse - Nov. 27, 2012, 5:10 p.m.
On Tue, 27 Nov 2012, Marc Glisse wrote:

> On Tue, 27 Nov 2012, Richard Biener wrote:
>
>>> It passes bootstrap+testsuite.
>
> ... on x86_64-linux-gnu, sorry for the lack of precision (default languages, 
> Xeon E5520, graphite enabled).
[...]
>> Boostrapped and tested on ... ?
>> 
>> Ok if bootstrap / testing passes.
>
> Thanks, I'll retest it to make sure it still works.

Duh, it uses VEC, of course it doesn't work anymore...
Here is what I tested instead (I copied the 2 vec lines from somewhere 
else in the file). I'll probably commit it later today.

>>> 2012-11-12  Marc Glisse  <marc.glisse@inria.fr>
>>>
>>>         * fold-const.c (fold_ternary_loc) [BIT_FIELD_REF]: Handle
>>>         CONSTRUCTOR with vector elements.
>>>         * tree-ssa-propagate.c (valid_gimple_rhs_p): Handle CONSTRUCTOR
>>>         and BIT_FIELD_REF.

Patch

Index: gcc/fold-const.c

===================================================================
--- gcc/fold-const.c	(revision 193847)

+++ gcc/fold-const.c	(working copy)

@@ -14074,66 +14074,76 @@  fold_ternary_loc (location_t loc, enum t

 	  unsigned HOST_WIDE_INT n = tree_low_cst (arg1, 1);
 	  unsigned HOST_WIDE_INT idx = tree_low_cst (op2, 1);
 
 	  if (n != 0
 	      && (idx % width) == 0
 	      && (n % width) == 0
 	      && ((idx + n) / width) <= TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0)))
 	    {
 	      idx = idx / width;
 	      n = n / width;
-	      if (TREE_CODE (type) == VECTOR_TYPE)

+

+	      if (TREE_CODE (arg0) == VECTOR_CST)

 		{
-		  if (TREE_CODE (arg0) == VECTOR_CST)

-		    {

-		      tree *vals = XALLOCAVEC (tree, n);

-		      unsigned i;

-		      for (i = 0; i < n; ++i)

-			vals[i] = VECTOR_CST_ELT (arg0, idx + i);

-		      return build_vector (type, vals);

-		    }

-		  else

-		    {

-		      vec<constructor_elt, va_gc> *vals;

-		      unsigned i;

-		      if (CONSTRUCTOR_NELTS (arg0) == 0)

-			return build_constructor (type,

-					      NULL);

-		      if (TREE_CODE (TREE_TYPE (CONSTRUCTOR_ELT (arg0,

-								 0)->value))

-			  != VECTOR_TYPE)

-			{

-			  vec_alloc (vals, n);

-			  for (i = 0;

-			       i < n && idx + i < CONSTRUCTOR_NELTS (arg0);

-			       ++i)

-			    CONSTRUCTOR_APPEND_ELT (vals, NULL_TREE,

-						    CONSTRUCTOR_ELT

-						      (arg0, idx + i)->value);

-			  return build_constructor (type, vals);

-			}

-		    }

+		  if (n == 1)

+		    return VECTOR_CST_ELT (arg0, idx);

+

+		  tree *vals = XALLOCAVEC (tree, n);

+		  for (unsigned i = 0; i < n; ++i)

+		    vals[i] = VECTOR_CST_ELT (arg0, idx + i);

+		  return build_vector (type, vals);

 		}
-	      else if (n == 1)

+

+	      /* Constructor elements can be subvectors.  */

+	      unsigned HOST_WIDE_INT k = 1;

+	      if (CONSTRUCTOR_NELTS (arg0) != 0)

 		{
-		  if (TREE_CODE (arg0) == VECTOR_CST)

-		    return VECTOR_CST_ELT (arg0, idx);

-		  else if (CONSTRUCTOR_NELTS (arg0) == 0)

-		    return build_zero_cst (type);

-		  else if (TREE_CODE (TREE_TYPE (CONSTRUCTOR_ELT (arg0,

-								  0)->value))

-			   != VECTOR_TYPE)

+		  tree cons_elem = TREE_TYPE (CONSTRUCTOR_ELT (arg0, 0)->value);

+		  if (TREE_CODE (cons_elem) == VECTOR_TYPE)

+		    k = TYPE_VECTOR_SUBPARTS (cons_elem);

+		}

+

+	      /* We keep an exact subset of the constructor elements.  */

+	      if ((idx % k) == 0 && (n % k) == 0)

+		{

+		  if (CONSTRUCTOR_NELTS (arg0) == 0)

+		    return build_constructor (type, NULL);

+		  idx /= k;

+		  n /= k;

+		  if (n == 1)

 		    {
 		      if (idx < CONSTRUCTOR_NELTS (arg0))
 			return CONSTRUCTOR_ELT (arg0, idx)->value;
 		      return build_zero_cst (type);
 		    }
+

+		  vec<constructor_elt, va_gc> *vals;

+		  vec_alloc (vals, n);

+		  for (unsigned i = 0;

+		       i < n && idx + i < CONSTRUCTOR_NELTS (arg0);

+		       ++i)

+		    CONSTRUCTOR_APPEND_ELT (vals, NULL_TREE,

+					    CONSTRUCTOR_ELT

+					      (arg0, idx + i)->value);

+		  return build_constructor (type, vals);

+		}

+	      /* The bitfield references a single constructor element.  */

+	      else if (idx + n <= (idx / k + 1) * k)

+		{

+		  if (CONSTRUCTOR_NELTS (arg0) <= idx / k)

+		    return build_zero_cst (type);

+		  else if (n == k)

+		    return CONSTRUCTOR_ELT (arg0, idx / k)->value;

+		  else

+		    return fold_build3_loc (loc, code, type,

+		      CONSTRUCTOR_ELT (arg0, idx / k)->value, op1,

+		      build_int_cst (TREE_TYPE (op2), (idx % k) * width));

 		}
 	    }
 	}
 
       /* A bit-field-ref that referenced the full argument can be stripped.  */
       if (INTEGRAL_TYPE_P (TREE_TYPE (arg0))
 	  && TYPE_PRECISION (TREE_TYPE (arg0)) == tree_low_cst (arg1, 1)
 	  && integer_zerop (op2))
 	return fold_convert_loc (loc, type, arg0);
 
Index: gcc/tree-ssa-propagate.c

===================================================================
--- gcc/tree-ssa-propagate.c	(revision 193847)

+++ gcc/tree-ssa-propagate.c	(working copy)

@@ -604,24 +604,38 @@  valid_gimple_rhs_p (tree expr)

 	      break;
 	    }
 	  return false;
 	}
       break;
 
     case tcc_vl_exp:
       return false;
 
     case tcc_exceptional:
+      if (code == CONSTRUCTOR)

+	{

+	  unsigned i;

+	  tree elt;

+	  FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (expr), i, elt)

+	    if (!is_gimple_val (elt))

+	      return false;

+	  return true;

+	}

       if (code != SSA_NAME)
         return false;
       break;
 
+    case tcc_reference:

+      if (code == BIT_FIELD_REF)

+	return is_gimple_val (TREE_OPERAND (expr, 0));

+      return false;

+

     default:
       return false;
     }
 
   return true;
 }
 
 
 /* Return true if EXPR is a CALL_EXPR suitable for representation
    as a single GIMPLE_CALL statement.  If the arguments require