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]

Re: [06/nn] Add VEC_SERIES_{CST,EXPR} and associated optab


Similarly to the update 05 patch, this patch just adds VEC_SERIES_EXPR,
since the VEC_SERIES_CST isn't needed with the new VECTOR_CST layout.
build_vec_series now uses the new VECTOR_CST layout, but otherwise
this is just the original patch with bits removed.

Tested on aarch64-linux-gnu, x86_64-linux-gnu and powerpc64-linux-gnu.
OK to install?

Richard


2017-12-15  Richard Sandiford  <richard.sandiford@linaro.org>
	    Alan Hayward  <alan.hayward@arm.com>
	    David Sherwood  <david.sherwood@arm.com>

gcc/
	* doc/generic.texi (VEC_SERIES_EXPR): Document.
	* doc/md.texi (vec_series@var{m}): Document.
	* tree.def (VEC_SERIES_EXPR): New tree code.
	* tree.h (build_vec_series): Declare.
	* tree.c (build_vec_series): New function.
	* cfgexpand.c (expand_debug_expr): Handle VEC_SERIES_EXPR.
	* tree-pretty-print.c (dump_generic_node): Likewise.
	* gimple-pretty-print.c (dump_binary_rhs): Likewise.
	* tree-inline.c (estimate_operator_cost): Likewise.
	* expr.c (expand_expr_real_2): Likewise.
	* optabs-tree.c (optab_for_tree_code): Likewise.
	* tree-cfg.c (verify_gimple_assign_binary): Likewise.
	* fold-const.c (const_binop): Fold VEC_SERIES_EXPRs of constants.
	* expmed.c (make_tree): Handle VEC_SERIES.
	* optabs.def (vec_series_optab): New optab.
	* optabs.h (expand_vec_series_expr): Declare.
	* optabs.c (expand_vec_series_expr): New function.
	* tree-vect-generic.c (expand_vector_operations_1): Check that
	the operands also have vector type.

Index: gcc/doc/generic.texi
===================================================================
--- gcc/doc/generic.texi	2017-12-15 00:30:46.596993903 +0000
+++ gcc/doc/generic.texi	2017-12-15 00:30:46.911991495 +0000
@@ -1769,6 +1769,7 @@ a value from @code{enum annot_expr_kind}
 @node Vectors
 @subsection Vectors
 @tindex VEC_DUPLICATE_EXPR
+@tindex VEC_SERIES_EXPR
 @tindex VEC_LSHIFT_EXPR
 @tindex VEC_RSHIFT_EXPR
 @tindex VEC_WIDEN_MULT_HI_EXPR
@@ -1788,6 +1789,14 @@ a value from @code{enum annot_expr_kind}
 This node has a single operand and represents a vector in which every
 element is equal to that operand.
 
+@item VEC_SERIES_EXPR
+This node represents a vector formed from a scalar base and step,
+given as the first and second operands respectively.  Element @var{i}
+of the result is equal to @samp{@var{base} + @var{i}*@var{step}}.
+
+This node is restricted to integral types, in order to avoid
+specifying the rounding behavior for floating-point types.
+
 @item VEC_LSHIFT_EXPR
 @itemx VEC_RSHIFT_EXPR
 These nodes represent whole vector left and right shifts, respectively.
Index: gcc/doc/md.texi
===================================================================
--- gcc/doc/md.texi	2017-12-15 00:30:46.596993903 +0000
+++ gcc/doc/md.texi	2017-12-15 00:30:46.912991487 +0000
@@ -4899,6 +4899,19 @@ vectors go through the @code{mov@var{m}}
 
 This pattern is not allowed to @code{FAIL}.
 
+@cindex @code{vec_series@var{m}} instruction pattern
+@item @samp{vec_series@var{m}}
+Initialize vector output operand 0 so that element @var{i} is equal to
+operand 1 plus @var{i} times operand 2.  In other words, create a linear
+series whose base value is operand 1 and whose step is operand 2.
+
+The vector output has mode @var{m} and the scalar inputs have the mode
+appropriate for one element of @var{m}.  This pattern is not used for
+floating-point vectors, in order to avoid having to specify the
+rounding behavior for @var{i} > 1.
+
+This pattern is not allowed to @code{FAIL}.
+
 @cindex @code{vec_cmp@var{m}@var{n}} instruction pattern
 @item @samp{vec_cmp@var{m}@var{n}}
 Output a vector comparison.  Operand 0 of mode @var{n} is the destination for
Index: gcc/tree.def
===================================================================
--- gcc/tree.def	2017-12-15 00:30:46.596993903 +0000
+++ gcc/tree.def	2017-12-15 00:30:46.919991433 +0000
@@ -540,6 +540,16 @@ DEFTREECODE (COND_EXPR, "cond_expr", tcc
 /* Represents a vector in which every element is equal to operand 0.  */
 DEFTREECODE (VEC_DUPLICATE_EXPR, "vec_duplicate_expr", tcc_unary, 1)
 
+/* Vector series created from a start (base) value and a step.
+
+   A = VEC_SERIES_EXPR (B, C)
+
+   means
+
+   for (i = 0; i < N; i++)
+     A[i] = B + C * i;  */
+DEFTREECODE (VEC_SERIES_EXPR, "vec_series_expr", tcc_binary, 2)
+
 /* Vector conditional expression. It is like COND_EXPR, but with
    vector operands.
 
Index: gcc/tree.h
===================================================================
--- gcc/tree.h	2017-12-15 00:30:46.596993903 +0000
+++ gcc/tree.h	2017-12-15 00:30:46.919991433 +0000
@@ -4052,6 +4052,7 @@ extern tree build_int_cst_type (tree, HO
 extern tree make_vector (unsigned, unsigned CXX_MEM_STAT_INFO);
 extern tree build_vector_from_ctor (tree, vec<constructor_elt, va_gc> *);
 extern tree build_vector_from_val (tree, tree);
+extern tree build_vec_series (tree, tree, tree);
 extern void recompute_constructor_flags (tree);
 extern void verify_constructor_flags (tree);
 extern tree build_constructor (tree, vec<constructor_elt, va_gc> *);
Index: gcc/tree.c
===================================================================
--- gcc/tree.c	2017-12-15 00:30:46.596993903 +0000
+++ gcc/tree.c	2017-12-15 00:30:46.918991441 +0000
@@ -1797,6 +1797,30 @@ build_vector_from_val (tree vectype, tre
     }
 }
 
+/* Build a vector series of type TYPE in which element I has the value
+   BASE + I * STEP.  The result is a constant if BASE and STEP are constant
+   and a VEC_SERIES_EXPR otherwise.  */
+
+tree
+build_vec_series (tree type, tree base, tree step)
+{
+  if (integer_zerop (step))
+    return build_vector_from_val (type, base);
+  if (TREE_CODE (base) == INTEGER_CST && TREE_CODE (step) == INTEGER_CST)
+    {
+      tree_vector_builder builder (type, 1, 3);
+      tree elt1 = wide_int_to_tree (TREE_TYPE (base),
+				    wi::to_wide (base) + wi::to_wide (step));
+      tree elt2 = wide_int_to_tree (TREE_TYPE (base),
+				    wi::to_wide (elt1) + wi::to_wide (step));
+      builder.quick_push (base);
+      builder.quick_push (elt1);
+      builder.quick_push (elt2);
+      return builder.build ();
+    }
+  return build2 (VEC_SERIES_EXPR, type, base, step);
+}
+
 /* Something has messed with the elements of CONSTRUCTOR C after it was built;
    calculate TREE_CONSTANT and TREE_SIDE_EFFECTS.  */
 
Index: gcc/cfgexpand.c
===================================================================
--- gcc/cfgexpand.c	2017-12-15 00:30:46.596993903 +0000
+++ gcc/cfgexpand.c	2017-12-15 00:30:46.911991495 +0000
@@ -5070,6 +5070,7 @@ expand_debug_expr (tree exp)
     case VEC_WIDEN_LSHIFT_LO_EXPR:
     case VEC_PERM_EXPR:
     case VEC_DUPLICATE_EXPR:
+    case VEC_SERIES_EXPR:
       return NULL;
 
     /* Misc codes.  */
Index: gcc/tree-pretty-print.c
===================================================================
--- gcc/tree-pretty-print.c	2017-12-15 00:30:46.596993903 +0000
+++ gcc/tree-pretty-print.c	2017-12-15 00:30:46.917991449 +0000
@@ -3162,6 +3162,7 @@ dump_generic_node (pretty_printer *pp, t
       is_expr = false;
       break;
 
+    case VEC_SERIES_EXPR:
     case VEC_WIDEN_MULT_HI_EXPR:
     case VEC_WIDEN_MULT_LO_EXPR:
     case VEC_WIDEN_MULT_EVEN_EXPR:
Index: gcc/gimple-pretty-print.c
===================================================================
--- gcc/gimple-pretty-print.c	2017-12-15 00:30:46.596993903 +0000
+++ gcc/gimple-pretty-print.c	2017-12-15 00:30:46.915991464 +0000
@@ -431,6 +431,7 @@ dump_binary_rhs (pretty_printer *buffer,
     case VEC_PACK_FIX_TRUNC_EXPR:
     case VEC_WIDEN_LSHIFT_HI_EXPR:
     case VEC_WIDEN_LSHIFT_LO_EXPR:
+    case VEC_SERIES_EXPR:
       for (p = get_tree_code_name (code); *p; p++)
 	pp_character (buffer, TOUPPER (*p));
       pp_string (buffer, " <");
Index: gcc/tree-inline.c
===================================================================
--- gcc/tree-inline.c	2017-12-15 00:30:46.596993903 +0000
+++ gcc/tree-inline.c	2017-12-15 00:30:46.917991449 +0000
@@ -3929,6 +3929,7 @@ estimate_operator_cost (enum tree_code c
     case VEC_WIDEN_LSHIFT_HI_EXPR:
     case VEC_WIDEN_LSHIFT_LO_EXPR:
     case VEC_DUPLICATE_EXPR:
+    case VEC_SERIES_EXPR:
 
       return 1;
 
Index: gcc/expr.c
===================================================================
--- gcc/expr.c	2017-12-15 00:30:46.596993903 +0000
+++ gcc/expr.c	2017-12-15 00:30:46.914991472 +0000
@@ -9586,6 +9586,10 @@ #define REDUCE_BIT_FIELD(expr)	(reduce_b
       gcc_assert (target);
       return target;
 
+    case VEC_SERIES_EXPR:
+      expand_operands (treeop0, treeop1, NULL_RTX, &op0, &op1, modifier);
+      return expand_vec_series_expr (mode, op0, op1, target);
+
     case BIT_INSERT_EXPR:
       {
 	unsigned bitpos = tree_to_uhwi (treeop2);
Index: gcc/optabs-tree.c
===================================================================
--- gcc/optabs-tree.c	2017-12-15 00:30:46.596993903 +0000
+++ gcc/optabs-tree.c	2017-12-15 00:30:46.915991464 +0000
@@ -202,6 +202,9 @@ optab_for_tree_code (enum tree_code code
     case VEC_DUPLICATE_EXPR:
       return vec_duplicate_optab;
 
+    case VEC_SERIES_EXPR:
+      return vec_series_optab;
+
     default:
       break;
     }
Index: gcc/tree-cfg.c
===================================================================
--- gcc/tree-cfg.c	2017-12-15 00:30:46.596993903 +0000
+++ gcc/tree-cfg.c	2017-12-15 00:30:46.917991449 +0000
@@ -4194,6 +4194,23 @@ verify_gimple_assign_binary (gassign *st
       /* Continue with generic binary expression handling.  */
       break;
 
+    case VEC_SERIES_EXPR:
+      if (!useless_type_conversion_p (rhs1_type, rhs2_type))
+	{
+	  error ("type mismatch in series expression");
+	  debug_generic_expr (rhs1_type);
+	  debug_generic_expr (rhs2_type);
+	  return true;
+	}
+      if (TREE_CODE (lhs_type) != VECTOR_TYPE
+	  || !useless_type_conversion_p (TREE_TYPE (lhs_type), rhs1_type))
+	{
+	  error ("vector type expected in series expression");
+	  debug_generic_expr (lhs_type);
+	  return true;
+	}
+      return false;
+
     default:
       gcc_unreachable ();
     }
Index: gcc/fold-const.c
===================================================================
--- gcc/fold-const.c	2017-12-15 00:30:46.596993903 +0000
+++ gcc/fold-const.c	2017-12-15 00:30:46.915991464 +0000
@@ -1527,6 +1527,12 @@ const_binop (enum tree_code code, tree t
      result as argument put those cases that need it here.  */
   switch (code)
     {
+    case VEC_SERIES_EXPR:
+      if (CONSTANT_CLASS_P (arg1)
+	  && CONSTANT_CLASS_P (arg2))
+	return build_vec_series (type, arg1, arg2);
+      return NULL_TREE;
+
     case COMPLEX_EXPR:
       if ((TREE_CODE (arg1) == REAL_CST
 	   && TREE_CODE (arg2) == REAL_CST)
Index: gcc/expmed.c
===================================================================
--- gcc/expmed.c	2017-12-15 00:30:46.596993903 +0000
+++ gcc/expmed.c	2017-12-15 00:30:46.913991479 +0000
@@ -5255,6 +5255,13 @@ make_tree (tree type, rtx x)
 	    tree elt_tree = make_tree (TREE_TYPE (type), XEXP (op, 0));
 	    return build_vector_from_val (type, elt_tree);
 	  }
+	if (GET_CODE (op) == VEC_SERIES)
+	  {
+	    tree itype = TREE_TYPE (type);
+	    tree base_tree = make_tree (itype, XEXP (op, 0));
+	    tree step_tree = make_tree (itype, XEXP (op, 1));
+	    return build_vec_series (type, base_tree, step_tree);
+	  }
 	return make_tree (type, op);
       }
 
Index: gcc/optabs.def
===================================================================
--- gcc/optabs.def	2017-12-15 00:30:46.596993903 +0000
+++ gcc/optabs.def	2017-12-15 00:30:46.916991456 +0000
@@ -365,3 +365,4 @@ OPTAB_D (get_thread_pointer_optab, "get_
 OPTAB_D (set_thread_pointer_optab, "set_thread_pointer$I$a")
 
 OPTAB_DC (vec_duplicate_optab, "vec_duplicate$a", VEC_DUPLICATE)
+OPTAB_DC (vec_series_optab, "vec_series$a", VEC_SERIES)
Index: gcc/optabs.h
===================================================================
--- gcc/optabs.h	2017-12-15 00:30:46.596993903 +0000
+++ gcc/optabs.h	2017-12-15 00:30:46.916991456 +0000
@@ -319,6 +319,9 @@ extern rtx expand_vec_cmp_expr (tree, tr
 /* Generate code for VEC_COND_EXPR.  */
 extern rtx expand_vec_cond_expr (tree, tree, tree, tree, rtx);
 
+/* Generate code for VEC_SERIES_EXPR.  */
+extern rtx expand_vec_series_expr (machine_mode, rtx, rtx, rtx);
+
 /* Generate code for MULT_HIGHPART_EXPR.  */
 extern rtx expand_mult_highpart (machine_mode, rtx, rtx, rtx, bool);
 
Index: gcc/optabs.c
===================================================================
--- gcc/optabs.c	2017-12-15 00:30:46.596993903 +0000
+++ gcc/optabs.c	2017-12-15 00:30:46.916991456 +0000
@@ -5768,6 +5768,27 @@ expand_vec_cond_expr (tree vec_cond_type
   return ops[0].value;
 }
 
+/* Generate VEC_SERIES_EXPR <OP0, OP1>, returning a value of mode VMODE.
+   Use TARGET for the result if nonnull and convenient.  */
+
+rtx
+expand_vec_series_expr (machine_mode vmode, rtx op0, rtx op1, rtx target)
+{
+  struct expand_operand ops[3];
+  enum insn_code icode;
+  machine_mode emode = GET_MODE_INNER (vmode);
+
+  icode = direct_optab_handler (vec_series_optab, vmode);
+  gcc_assert (icode != CODE_FOR_nothing);
+
+  create_output_operand (&ops[0], target, vmode);
+  create_input_operand (&ops[1], op0, emode);
+  create_input_operand (&ops[2], op1, emode);
+
+  expand_insn (icode, 3, ops);
+  return ops[0].value;
+}
+
 /* Generate insns for a vector comparison into a mask.  */
 
 rtx
Index: gcc/tree-vect-generic.c
===================================================================
--- gcc/tree-vect-generic.c	2017-12-15 00:30:46.596993903 +0000
+++ gcc/tree-vect-generic.c	2017-12-15 00:30:46.918991441 +0000
@@ -1594,7 +1594,8 @@ expand_vector_operations_1 (gimple_stmt_
   if (rhs_class == GIMPLE_BINARY_RHS)
     rhs2 = gimple_assign_rhs2 (stmt);
 
-  if (TREE_CODE (type) != VECTOR_TYPE)
+  if (!VECTOR_TYPE_P (type)
+      || !VECTOR_TYPE_P (TREE_TYPE (rhs1)))
     return;
 
   /* If the vector operation is operating on all same vector elements


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