diff mbox

[[Boolean,Vector,5/5] Support boolean vectors in vector lowering

Message ID 20151002141102.GI26618@msticlxl57.ims.intel.com
State New
Headers show

Commit Message

Ilya Enkovich Oct. 2, 2015, 2:11 p.m. UTC
Hi,

This patch supports boolean vectors in vector lowering.  Main change is to lower vector comparison into comparisons, not cond_exprs.

Thanks,
Ilya
--
2015-10-02  Ilya Enkovich  <enkovich.gnu@gmail.com>

	* tree-vect-generic.c (elem_op_func): Add new operand to hold
	vector type.
	(do_unop): Adjust to modified function type.
	(do_binop): Likewise.
	(do_plus_minus): Likewise.
	(do_negate); Likewise.
	(expand_vector_piecewise): Likewise.
	(do_cond): Likewise.
	(do_compare): Use comparison instead of condition.
	(expand_vector_divmod): Use boolean vector type for comparison.
	(expand_vector_operations_1): Skip scalar mask operations.

Comments

Jeff Law Oct. 9, 2015, 9:01 p.m. UTC | #1
On 10/02/2015 08:11 AM, Ilya Enkovich wrote:
> Hi,
>
> This patch supports boolean vectors in vector lowering.  Main change is to lower vector comparison into comparisons, not cond_exprs.
>
> Thanks,
> Ilya
> --
> 2015-10-02  Ilya Enkovich  <enkovich.gnu@gmail.com>
>
> 	* tree-vect-generic.c (elem_op_func): Add new operand to hold
> 	vector type.
> 	(do_unop): Adjust to modified function type.
> 	(do_binop): Likewise.
> 	(do_plus_minus): Likewise.
> 	(do_negate); Likewise.
> 	(expand_vector_piecewise): Likewise.
> 	(do_cond): Likewise.
> 	(do_compare): Use comparison instead of condition.
> 	(expand_vector_divmod): Use boolean vector type for comparison.
> 	(expand_vector_operations_1): Skip scalar mask operations.
This is fine too.

So my question for the series as a whole is whether or not we need to do 
something for the other languages, particularly Fortran.  I was a bit 
surprised to see this stuff bleed into the C/C++ front-ends and 
obviously wonder if it's bled into Fortran, Ada, Java, etc.


jeff
Alan Lawrence Oct. 12, 2015, 10:37 a.m. UTC | #2
On 09/10/15 22:01, Jeff Law wrote:

> So my question for the series as a whole is whether or not we need to do
> something for the other languages, particularly Fortran.  I was a bit
> surprised to see this stuff bleed into the C/C++ front-ends and
> obviously wonder if it's bled into Fortran, Ada, Java, etc.

Isn't that just because, we have GNU extensions to C/C++, for vectors? I admit I 
don't know enough Ada/Fortran to know whether we've added GNU extensions to 
those languages as well...

A.
Ilya Enkovich Oct. 13, 2015, 2:56 p.m. UTC | #3
2015-10-12 13:37 GMT+03:00 Alan Lawrence <alan.lawrence@arm.com>:
> On 09/10/15 22:01, Jeff Law wrote:
>
>> So my question for the series as a whole is whether or not we need to do
>> something for the other languages, particularly Fortran.  I was a bit
>> surprised to see this stuff bleed into the C/C++ front-ends and
>> obviously wonder if it's bled into Fortran, Ada, Java, etc.
>
>
> Isn't that just because, we have GNU extensions to C/C++, for vectors? I
> admit I don't know enough Ada/Fortran to know whether we've added GNU
> extensions to those languages as well...
>
> A.

I also got an impression only GNU vector extensions should be
affected. And those are for C/C++ only.

Thanks,
Ilya
Jeff Law Oct. 13, 2015, 3:35 p.m. UTC | #4
On 10/13/2015 08:56 AM, Ilya Enkovich wrote:
> 2015-10-12 13:37 GMT+03:00 Alan Lawrence <alan.lawrence@arm.com>:
>> On 09/10/15 22:01, Jeff Law wrote:
>>
>>> So my question for the series as a whole is whether or not we need to do
>>> something for the other languages, particularly Fortran.  I was a bit
>>> surprised to see this stuff bleed into the C/C++ front-ends and
>>> obviously wonder if it's bled into Fortran, Ada, Java, etc.
>>
>>
>> Isn't that just because, we have GNU extensions to C/C++, for vectors? I
>> admit I don't know enough Ada/Fortran to know whether we've added GNU
>> extensions to those languages as well...
>>
>> A.
>
> I also got an impression only GNU vector extensions should be
> affected. And those are for C/C++ only.
I'd be surprised if Fortran doesn't have vector capabilities.  I think 
some sanity checking in there would be wise.

jeff
Ilya Enkovich Oct. 13, 2015, 3:48 p.m. UTC | #5
2015-10-13 18:35 GMT+03:00 Jeff Law <law@redhat.com>:
> On 10/13/2015 08:56 AM, Ilya Enkovich wrote:
>>
>> 2015-10-12 13:37 GMT+03:00 Alan Lawrence <alan.lawrence@arm.com>:
>>>
>>> On 09/10/15 22:01, Jeff Law wrote:
>>>
>>>> So my question for the series as a whole is whether or not we need to do
>>>> something for the other languages, particularly Fortran.  I was a bit
>>>> surprised to see this stuff bleed into the C/C++ front-ends and
>>>> obviously wonder if it's bled into Fortran, Ada, Java, etc.
>>>
>>>
>>>
>>> Isn't that just because, we have GNU extensions to C/C++, for vectors? I
>>> admit I don't know enough Ada/Fortran to know whether we've added GNU
>>> extensions to those languages as well...
>>>
>>> A.
>>
>>
>> I also got an impression only GNU vector extensions should be
>> affected. And those are for C/C++ only.
>
> I'd be surprised if Fortran doesn't have vector capabilities.  I think some
> sanity checking in there would be wise.

Vector type in language doesn't mean SIMD. AFAIK OpenMP is used in
Fortran for SIMD features. Also I would get a lot of Fortran
regressions in case such feature exists due to fixed IL checker.

Thanks,
Ilya

>
> jeff
Andreas Schwab Oct. 23, 2015, 7:22 a.m. UTC | #6
../../gcc/tree-vect-generic.c: In member function 'virtual unsigned int {anonymous}::pass_lower_vector_ssa::execute(function*)':
../../gcc/tree-vect-generic.c:127:70: error: 'a2' may be used uninitialized in this function [-Werror=maybe-uninitialized]
  return gimplify_build3 (gsi, BIT_FIELD_REF, type, t, bitsize, bitpos);
                                                                      ^
../../gcc/tree-vect-generic.c:847:8: note: 'a2' was declared here
   tree a2;
        ^

Andreas.
diff mbox

Patch

diff --git a/gcc/tree-vect-generic.c b/gcc/tree-vect-generic.c
index dad38a2..a20b9af 100644
--- a/gcc/tree-vect-generic.c
+++ b/gcc/tree-vect-generic.c
@@ -105,14 +105,27 @@  build_word_mode_vector_type (int nunits)
 }
 
 typedef tree (*elem_op_func) (gimple_stmt_iterator *,
-			      tree, tree, tree, tree, tree, enum tree_code);
+			      tree, tree, tree, tree, tree, enum tree_code,
+			      tree);
 
 static inline tree
 tree_vec_extract (gimple_stmt_iterator *gsi, tree type,
 		  tree t, tree bitsize, tree bitpos)
 {
   if (bitpos)
-    return gimplify_build3 (gsi, BIT_FIELD_REF, type, t, bitsize, bitpos);
+    {
+      if (TREE_CODE (type) == BOOLEAN_TYPE)
+	{
+	  tree itype
+	    = build_nonstandard_integer_type (tree_to_uhwi (bitsize), 0);
+	  tree field = gimplify_build3 (gsi, BIT_FIELD_REF, itype, t,
+					bitsize, bitpos);
+	  return gimplify_build2 (gsi, NE_EXPR, type, field,
+				  build_zero_cst (itype));
+	}
+      else
+	return gimplify_build3 (gsi, BIT_FIELD_REF, type, t, bitsize, bitpos);
+    }
   else
     return gimplify_build1 (gsi, VIEW_CONVERT_EXPR, type, t);
 }
@@ -120,7 +133,7 @@  tree_vec_extract (gimple_stmt_iterator *gsi, tree type,
 static tree
 do_unop (gimple_stmt_iterator *gsi, tree inner_type, tree a,
 	 tree b ATTRIBUTE_UNUSED, tree bitpos, tree bitsize,
-	 enum tree_code code)
+	 enum tree_code code, tree type ATTRIBUTE_UNUSED)
 {
   a = tree_vec_extract (gsi, inner_type, a, bitsize, bitpos);
   return gimplify_build1 (gsi, code, inner_type, a);
@@ -128,7 +141,8 @@  do_unop (gimple_stmt_iterator *gsi, tree inner_type, tree a,
 
 static tree
 do_binop (gimple_stmt_iterator *gsi, tree inner_type, tree a, tree b,
-	  tree bitpos, tree bitsize, enum tree_code code)
+	  tree bitpos, tree bitsize, enum tree_code code,
+	  tree type ATTRIBUTE_UNUSED)
 {
   if (TREE_CODE (TREE_TYPE (a)) == VECTOR_TYPE)
     a = tree_vec_extract (gsi, inner_type, a, bitsize, bitpos);
@@ -145,20 +159,12 @@  do_binop (gimple_stmt_iterator *gsi, tree inner_type, tree a, tree b,
    size equal to the size of INNER_TYPE.  */
 static tree
 do_compare (gimple_stmt_iterator *gsi, tree inner_type, tree a, tree b,
-	  tree bitpos, tree bitsize, enum tree_code code)
+	    tree bitpos, tree bitsize, enum tree_code code, tree type)
 {
-  tree comp_type;
-
   a = tree_vec_extract (gsi, inner_type, a, bitsize, bitpos);
   b = tree_vec_extract (gsi, inner_type, b, bitsize, bitpos);
 
-  comp_type = build_nonstandard_integer_type
-		      (GET_MODE_BITSIZE (TYPE_MODE (inner_type)), 0);
-
-  return gimplify_build3 (gsi, COND_EXPR, comp_type,
-			  fold_build2 (code, boolean_type_node, a, b),
-			  build_int_cst (comp_type, -1),
-			  build_int_cst (comp_type, 0));
+  return gimplify_build2 (gsi, code, TREE_TYPE (type), a, b);
 }
 
 /* Expand vector addition to scalars.  This does bit twiddling
@@ -177,7 +183,7 @@  do_compare (gimple_stmt_iterator *gsi, tree inner_type, tree a, tree b,
 static tree
 do_plus_minus (gimple_stmt_iterator *gsi, tree word_type, tree a, tree b,
 	       tree bitpos ATTRIBUTE_UNUSED, tree bitsize ATTRIBUTE_UNUSED,
-	       enum tree_code code)
+	       enum tree_code code, tree type ATTRIBUTE_UNUSED)
 {
   tree inner_type = TREE_TYPE (TREE_TYPE (a));
   unsigned HOST_WIDE_INT max;
@@ -209,7 +215,8 @@  static tree
 do_negate (gimple_stmt_iterator *gsi, tree word_type, tree b,
 	   tree unused ATTRIBUTE_UNUSED, tree bitpos ATTRIBUTE_UNUSED,
 	   tree bitsize ATTRIBUTE_UNUSED,
-	   enum tree_code code ATTRIBUTE_UNUSED)
+	   enum tree_code code ATTRIBUTE_UNUSED,
+	   tree type ATTRIBUTE_UNUSED)
 {
   tree inner_type = TREE_TYPE (TREE_TYPE (b));
   HOST_WIDE_INT max;
@@ -255,7 +262,7 @@  expand_vector_piecewise (gimple_stmt_iterator *gsi, elem_op_func f,
   for (i = 0; i < nunits;
        i += delta, index = int_const_binop (PLUS_EXPR, index, part_width))
     {
-      tree result = f (gsi, inner_type, a, b, index, part_width, code);
+      tree result = f (gsi, inner_type, a, b, index, part_width, code, type);
       constructor_elt ce = {NULL_TREE, result};
       v->quick_push (ce);
     }
@@ -298,7 +305,7 @@  expand_vector_parallel (gimple_stmt_iterator *gsi, elem_op_func f, tree type,
       /* Use a single scalar operation with a mode no wider than word_mode.  */
       mode = mode_for_size (tree_to_uhwi (TYPE_SIZE (type)), MODE_INT, 0);
       compute_type = lang_hooks.types.type_for_mode (mode, 1);
-      result = f (gsi, compute_type, a, b, NULL_TREE, NULL_TREE, code);
+      result = f (gsi, compute_type, a, b, NULL_TREE, NULL_TREE, code, type);
       warning_at (loc, OPT_Wvector_operation_performance,
 	          "vector operation will be expanded with a "
 		  "single scalar operation");
@@ -615,11 +622,12 @@  expand_vector_divmod (gimple_stmt_iterator *gsi, tree type, tree op0,
 	  if (addend == NULL_TREE
 	      && expand_vec_cond_expr_p (type, type))
 	    {
-	      tree zero, cst, cond;
+	      tree zero, cst, cond, mask_type;
 	      gimple *stmt;
 
+	      mask_type = build_same_sized_truth_vector_type (type);
 	      zero = build_zero_cst (type);
-	      cond = build2 (LT_EXPR, type, op0, zero);
+	      cond = build2 (LT_EXPR, mask_type, op0, zero);
 	      for (i = 0; i < nunits; i++)
 		vec[i] = build_int_cst (TREE_TYPE (type),
 					((unsigned HOST_WIDE_INT) 1
@@ -1386,7 +1394,8 @@  count_type_subparts (tree type)
 
 static tree
 do_cond (gimple_stmt_iterator *gsi, tree inner_type, tree a, tree b,
-	 tree bitpos, tree bitsize, enum tree_code code)
+	 tree bitpos, tree bitsize, enum tree_code code,
+	 tree type ATTRIBUTE_UNUSED)
 {
   if (TREE_CODE (TREE_TYPE (a)) == VECTOR_TYPE)
     a = tree_vec_extract (gsi, inner_type, a, bitsize, bitpos);
@@ -1496,6 +1505,12 @@  expand_vector_operations_1 (gimple_stmt_iterator *gsi)
   if (TREE_CODE (type) != VECTOR_TYPE)
     return;
 
+  /* A scalar operation pretending to be a vector one.  */
+  if (VECTOR_BOOLEAN_TYPE_P (type)
+      && !VECTOR_MODE_P (TYPE_MODE (type))
+      && TYPE_MODE (type) != BLKmode)
+    return;
+
   if (CONVERT_EXPR_CODE_P (code)
       || code == FLOAT_EXPR
       || code == FIX_TRUNC_EXPR