This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [06/nn] Add VEC_SERIES_{CST,EXPR} and associated optab
- From: Richard Sandiford <richard dot sandiford at linaro dot org>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 15 Dec 2017 00:34:20 +0000
- Subject: Re: [06/nn] Add VEC_SERIES_{CST,EXPR} and associated optab
- Authentication-results: sourceware.org; auth=none
- References: <87wp3mxgir.fsf@linaro.org> <877evmxg8a.fsf@linaro.org>
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