From: Richard Sandiford <richard.sandiford@linaro.org>
To: gcc-patches@gcc.gnu.org
Subject: [06/nn] Add VEC_SERIES_{CST,EXPR} and associated optab
Date: Mon, 23 Oct 2017 11:22:00 -0000 [thread overview]
Message-ID: <877evmxg8a.fsf@linaro.org> (raw)
In-Reply-To: <87wp3mxgir.fsf@linaro.org> (Richard Sandiford's message of "Mon, 23 Oct 2017 12:14:36 +0100")
Similarly to the VEC_DUPLICATE_{CST,EXPR}, this patch adds two
tree code equivalents of the VEC_SERIES rtx code. VEC_SERIES_EXPR
is for non-constant inputs and is a normal tcc_binary. VEC_SERIES_CST
is a tcc_constant.
Like VEC_DUPLICATE_CST, VEC_SERIES_CST is only used for variable-length
vectors. This avoids the need to handle combinations of VECTOR_CST
and VEC_SERIES_CST.
2017-10-23 Richard Sandiford <richard.sandiford@linaro.org>
Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com>
gcc/
* doc/generic.texi (VEC_SERIES_CST, VEC_SERIES_EXPR): Document.
* doc/md.texi (vec_series@var{m}): Document.
* tree.def (VEC_SERIES_CST, VEC_SERIES_EXPR): New tree codes.
* tree.h (TREE_OVERFLOW): Add VEC_SERIES_CST to the list of valid
codes.
(VEC_SERIES_CST_BASE, VEC_SERIES_CST_STEP): New macros.
(build_vec_series_cst, build_vec_series): Declare.
* tree.c (tree_node_structure_for_code, tree_code_size, tree_size)
(add_expr, walk_tree_1, drop_tree_overflow): Handle VEC_SERIES_CST.
(build_vec_series_cst, build_vec_series): New functions.
* cfgexpand.c (expand_debug_expr): Handle the new codes.
* tree-pretty-print.c (dump_generic_node): Likewise.
* dwarf2out.c (rtl_for_decl_init): Handle VEC_SERIES_CST.
* gimple-expr.h (is_gimple_constant): Likewise.
* gimplify.c (gimplify_expr): Likewise.
* graphite-scop-detection.c (scan_tree_for_params): Likewise.
* ipa-icf-gimple.c (func_checker::compare_cst_or_decl): Likewise.
(func_checker::compare_operand): Likewise.
* ipa-icf.c (sem_item::add_expr, sem_variable::equals): Likewise.
* print-tree.c (print_node): Likewise.
* tree-ssa-loop.c (for_each_index): Likewise.
* tree-ssa-pre.c (create_component_ref_by_pieces_1): Likewise.
* tree-ssa-sccvn.c (copy_reference_ops_from_ref): Likewise.
(ao_ref_init_from_vn_reference): Likewise.
* varasm.c (const_hash_1, compare_constant): Likewise.
* fold-const.c (negate_expr_p, fold_negate_expr_1, operand_equal_p)
(fold_checksum_tree): Likewise.
(vec_series_equivalent_p): New function.
(const_binop): Use it. Fold VEC_SERIES_EXPRs of constants.
* expmed.c (make_tree): Handle VEC_SERIES.
* gimple-pretty-print.c (dump_binary_rhs): Likewise.
* tree-inline.c (estimate_operator_cost): Likewise.
* expr.c (const_vector_element): Include VEC_SERIES_CST in comment.
(expand_expr_real_2): Handle VEC_SERIES_EXPR.
(expand_expr_real_1): Handle VEC_SERIES_CST.
* optabs.def (vec_series_optab): New optab.
* optabs.h (expand_vec_series_expr): Declare.
* optabs.c (expand_vec_series_expr): New function.
* optabs-tree.c (optab_for_tree_code): Handle VEC_SERIES_EXPR.
* tree-cfg.c (verify_gimple_assign_binary): Handle VEC_SERIES_EXPR.
(verify_gimple_assign_single): Handle VEC_SERIES_CST.
* 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-10-23 11:41:51.760448406 +0100
+++ gcc/doc/generic.texi 2017-10-23 11:42:34.910720660 +0100
@@ -1037,6 +1037,7 @@ As this example indicates, the operands
@tindex COMPLEX_CST
@tindex VECTOR_CST
@tindex VEC_DUPLICATE_CST
+@tindex VEC_SERIES_CST
@tindex STRING_CST
@findex TREE_STRING_LENGTH
@findex TREE_STRING_POINTER
@@ -1098,6 +1099,16 @@ instead. The scalar element value is gi
@code{VEC_DUPLICATE_CST_ELT} and has the same restrictions as the
element of a @code{VECTOR_CST}.
+@item VEC_SERIES_CST
+These nodes represent a vector constant in which element @var{i}
+has the value @samp{@var{base} + @var{i} * @var{step}}, for some
+constant @var{base} and @var{step}. The value of @var{base} is
+given by @code{VEC_SERIES_CST_BASE} and the value of @var{step} is
+given by @code{VEC_SERIES_CST_STEP}.
+
+These nodes are restricted to integral types, in order to avoid
+specifying the rounding behavior for floating-point types.
+
@item STRING_CST
These nodes represent string-constants. The @code{TREE_STRING_LENGTH}
returns the length of the string, as an @code{int}. The
@@ -1702,6 +1713,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
@@ -1721,6 +1733,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-10-23 11:41:51.761413027 +0100
+++ gcc/doc/md.texi 2017-10-23 11:42:34.911720660 +0100
@@ -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-10-23 11:41:51.774917721 +0100
+++ gcc/tree.def 2017-10-23 11:42:34.924720660 +0100
@@ -308,6 +308,10 @@ DEFTREECODE (VECTOR_CST, "vector_cst", t
VEC_DUPLICATE_CST_ELT. */
DEFTREECODE (VEC_DUPLICATE_CST, "vec_duplicate_cst", tcc_constant, 0)
+/* Represents a vector constant in which element i is equal to
+ VEC_SERIES_CST_BASE + i * VEC_SERIES_CST_STEP. */
+DEFTREECODE (VEC_SERIES_CST, "vec_series_cst", tcc_constant, 0)
+
/* Contents are TREE_STRING_LENGTH and the actual contents of the string. */
DEFTREECODE (STRING_CST, "string_cst", tcc_constant, 0)
@@ -541,6 +545,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-10-23 11:41:51.775882341 +0100
+++ gcc/tree.h 2017-10-23 11:42:34.925720660 +0100
@@ -730,8 +730,8 @@ #define TREE_SYMBOL_REFERENCED(NODE) \
#define TYPE_REF_CAN_ALIAS_ALL(NODE) \
(PTR_OR_REF_CHECK (NODE)->base.static_flag)
-/* In an INTEGER_CST, REAL_CST, COMPLEX_CST, VECTOR_CST or VEC_DUPLICATE_CST,
- this means there was an overflow in folding. */
+/* In an INTEGER_CST, REAL_CST, COMPLEX_CST, VECTOR_CST, VEC_DUPLICATE_CST
+ or VEC_SERES_CST, this means there was an overflow in folding. */
#define TREE_OVERFLOW(NODE) (CST_CHECK (NODE)->base.public_flag)
@@ -1034,6 +1034,12 @@ #define VECTOR_CST_ELT(NODE,IDX) (VECTOR
#define VEC_DUPLICATE_CST_ELT(NODE) \
(VEC_DUPLICATE_CST_CHECK (NODE)->vector.elts[0])
+/* In a VEC_SERIES_CST node. */
+#define VEC_SERIES_CST_BASE(NODE) \
+ (VEC_SERIES_CST_CHECK (NODE)->vector.elts[0])
+#define VEC_SERIES_CST_STEP(NODE) \
+ (VEC_SERIES_CST_CHECK (NODE)->vector.elts[1])
+
/* Define fields and accessors for some special-purpose tree nodes. */
#define IDENTIFIER_LENGTH(NODE) \
@@ -4030,9 +4036,11 @@ extern tree build_int_cstu (tree type, u
extern tree build_int_cst_type (tree, HOST_WIDE_INT);
extern tree make_vector (unsigned CXX_MEM_STAT_INFO);
extern tree build_vec_duplicate_cst (tree, tree CXX_MEM_STAT_INFO);
+extern tree build_vec_series_cst (tree, tree, tree CXX_MEM_STAT_INFO);
extern tree build_vector (tree, vec<tree> 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-10-23 11:41:51.774917721 +0100
+++ gcc/tree.c 2017-10-23 11:42:34.924720660 +0100
@@ -465,6 +465,7 @@ tree_node_structure_for_code (enum tree_
case COMPLEX_CST: return TS_COMPLEX;
case VECTOR_CST: return TS_VECTOR;
case VEC_DUPLICATE_CST: return TS_VECTOR;
+ case VEC_SERIES_CST: return TS_VECTOR;
case STRING_CST: return TS_STRING;
/* tcc_exceptional cases. */
case ERROR_MARK: return TS_COMMON;
@@ -818,6 +819,8 @@ tree_code_size (enum tree_code code)
case COMPLEX_CST: return sizeof (struct tree_complex);
case VECTOR_CST: return sizeof (struct tree_vector);
case VEC_DUPLICATE_CST: return sizeof (struct tree_vector);
+ case VEC_SERIES_CST:
+ return sizeof (struct tree_vector) + sizeof (tree);
case STRING_CST: gcc_unreachable ();
default:
return lang_hooks.tree_size (code);
@@ -880,6 +883,9 @@ tree_size (const_tree node)
case VEC_DUPLICATE_CST:
return sizeof (struct tree_vector);
+ case VEC_SERIES_CST:
+ return sizeof (struct tree_vector) + sizeof (tree);
+
case STRING_CST:
return TREE_STRING_LENGTH (node) + offsetof (struct tree_string, str) + 1;
@@ -1711,6 +1717,31 @@ build_vec_duplicate_cst (tree type, tree
return t;
}
+/* Build a new VEC_SERIES_CST with type TYPE, base BASE and step STEP.
+
+ Note that this function is only suitable for callers that specifically
+ need a VEC_SERIES_CST node. Use build_vec_series to build a general
+ series vector from a general base and step. */
+
+tree
+build_vec_series_cst (tree type, tree base, tree step MEM_STAT_DECL)
+{
+ int length = sizeof (struct tree_vector) + sizeof (tree);
+
+ record_node_allocation_statistics (VEC_SERIES_CST, length);
+
+ tree t = ggc_alloc_cleared_tree_node_stat (length PASS_MEM_STAT);
+
+ TREE_SET_CODE (t, VEC_SERIES_CST);
+ TREE_TYPE (t) = type;
+ t->base.u.nelts = 2;
+ VEC_SERIES_CST_BASE (t) = base;
+ VEC_SERIES_CST_STEP (t) = step;
+ TREE_CONSTANT (t) = 1;
+
+ return t;
+}
+
/* Build a newly constructed VECTOR_CST node of length LEN. */
tree
@@ -1821,6 +1852,19 @@ build_vector_from_val (tree vectype, tre
}
}
+/* Build a vector series of type TYPE in which element I has the value
+ BASE + I * STEP. */
+
+tree
+build_vec_series (tree type, tree base, tree step)
+{
+ if (integer_zerop (step))
+ return build_vector_from_val (type, base);
+ if (CONSTANT_CLASS_P (base) && CONSTANT_CLASS_P (step))
+ return build_vec_series_cst (type, base, step);
+ 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. */
@@ -7136,6 +7180,10 @@ add_expr (const_tree t, inchash::hash &h
case VEC_DUPLICATE_CST:
inchash::add_expr (VEC_DUPLICATE_CST_ELT (t), hstate);
return;
+ case VEC_SERIES_CST:
+ inchash::add_expr (VEC_SERIES_CST_BASE (t), hstate);
+ inchash::add_expr (VEC_SERIES_CST_STEP (t), hstate);
+ return;
case SSA_NAME:
/* We can just compare by pointer. */
hstate.add_wide_int (SSA_NAME_VERSION (t));
@@ -11150,6 +11198,7 @@ #define WALK_SUBTREE_TAIL(NODE) \
case FIXED_CST:
case VECTOR_CST:
case VEC_DUPLICATE_CST:
+ case VEC_SERIES_CST:
case STRING_CST:
case BLOCK:
case PLACEHOLDER_EXPR:
@@ -12442,6 +12491,15 @@ drop_tree_overflow (tree t)
if (TREE_OVERFLOW (*elt))
*elt = drop_tree_overflow (*elt);
}
+ if (TREE_CODE (t) == VEC_SERIES_CST)
+ {
+ tree *elt = &VEC_SERIES_CST_BASE (t);
+ if (TREE_OVERFLOW (*elt))
+ *elt = drop_tree_overflow (*elt);
+ elt = &VEC_SERIES_CST_STEP (t);
+ if (TREE_OVERFLOW (*elt))
+ *elt = drop_tree_overflow (*elt);
+ }
return t;
}
Index: gcc/cfgexpand.c
===================================================================
--- gcc/cfgexpand.c 2017-10-23 11:41:51.760448406 +0100
+++ gcc/cfgexpand.c 2017-10-23 11:42:34.909720660 +0100
@@ -5051,6 +5051,8 @@ expand_debug_expr (tree exp)
case VEC_PERM_EXPR:
case VEC_DUPLICATE_CST:
case VEC_DUPLICATE_EXPR:
+ case VEC_SERIES_CST:
+ case VEC_SERIES_EXPR:
return NULL;
/* Misc codes. */
Index: gcc/tree-pretty-print.c
===================================================================
--- gcc/tree-pretty-print.c 2017-10-23 11:41:51.772023858 +0100
+++ gcc/tree-pretty-print.c 2017-10-23 11:42:34.921720660 +0100
@@ -1808,6 +1808,14 @@ dump_generic_node (pretty_printer *pp, t
pp_string (pp, ", ... }");
break;
+ case VEC_SERIES_CST:
+ pp_string (pp, "{ ");
+ dump_generic_node (pp, VEC_SERIES_CST_BASE (node), spc, flags, false);
+ pp_string (pp, ", +, ");
+ dump_generic_node (pp, VEC_SERIES_CST_STEP (node), spc, flags, false);
+ pp_string (pp, "}");
+ break;
+
case FUNCTION_TYPE:
case METHOD_TYPE:
dump_generic_node (pp, TREE_TYPE (node), spc, flags, false);
@@ -3221,6 +3229,7 @@ dump_generic_node (pretty_printer *pp, t
pp_string (pp, " > ");
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/dwarf2out.c
===================================================================
--- gcc/dwarf2out.c 2017-10-23 11:41:51.763342269 +0100
+++ gcc/dwarf2out.c 2017-10-23 11:42:34.913720660 +0100
@@ -18863,6 +18863,7 @@ rtl_for_decl_init (tree init, tree type)
{
case VECTOR_CST:
case VEC_DUPLICATE_CST:
+ case VEC_SERIES_CST:
break;
case CONSTRUCTOR:
if (TREE_CONSTANT (init))
Index: gcc/gimple-expr.h
===================================================================
--- gcc/gimple-expr.h 2017-10-23 11:41:51.765271511 +0100
+++ gcc/gimple-expr.h 2017-10-23 11:42:34.916720660 +0100
@@ -135,6 +135,7 @@ is_gimple_constant (const_tree t)
case COMPLEX_CST:
case VECTOR_CST:
case VEC_DUPLICATE_CST:
+ case VEC_SERIES_CST:
case STRING_CST:
return true;
Index: gcc/gimplify.c
===================================================================
--- gcc/gimplify.c 2017-10-23 11:41:51.766236132 +0100
+++ gcc/gimplify.c 2017-10-23 11:42:34.917720660 +0100
@@ -11507,6 +11507,7 @@ gimplify_expr (tree *expr_p, gimple_seq
case COMPLEX_CST:
case VECTOR_CST:
case VEC_DUPLICATE_CST:
+ case VEC_SERIES_CST:
/* Drop the overflow flag on constants, we do not want
that in the GIMPLE IL. */
if (TREE_OVERFLOW_P (*expr_p))
Index: gcc/graphite-scop-detection.c
===================================================================
--- gcc/graphite-scop-detection.c 2017-10-23 11:41:51.767200753 +0100
+++ gcc/graphite-scop-detection.c 2017-10-23 11:42:34.917720660 +0100
@@ -1244,6 +1244,7 @@ scan_tree_for_params (sese_info_p s, tre
case COMPLEX_CST:
case VECTOR_CST:
case VEC_DUPLICATE_CST:
+ case VEC_SERIES_CST:
break;
default:
Index: gcc/ipa-icf-gimple.c
===================================================================
--- gcc/ipa-icf-gimple.c 2017-10-23 11:41:51.767200753 +0100
+++ gcc/ipa-icf-gimple.c 2017-10-23 11:42:34.917720660 +0100
@@ -334,6 +334,7 @@ func_checker::compare_cst_or_decl (tree
case COMPLEX_CST:
case VECTOR_CST:
case VEC_DUPLICATE_CST:
+ case VEC_SERIES_CST:
case STRING_CST:
case REAL_CST:
{
@@ -530,6 +531,7 @@ func_checker::compare_operand (tree t1,
case COMPLEX_CST:
case VECTOR_CST:
case VEC_DUPLICATE_CST:
+ case VEC_SERIES_CST:
case STRING_CST:
case REAL_CST:
case FUNCTION_DECL:
Index: gcc/ipa-icf.c
===================================================================
--- gcc/ipa-icf.c 2017-10-23 11:41:51.768165374 +0100
+++ gcc/ipa-icf.c 2017-10-23 11:42:34.918720660 +0100
@@ -1479,6 +1479,7 @@ sem_item::add_expr (const_tree exp, inch
case COMPLEX_CST:
case VECTOR_CST:
case VEC_DUPLICATE_CST:
+ case VEC_SERIES_CST:
inchash::add_expr (exp, hstate);
break;
case CONSTRUCTOR:
@@ -2034,6 +2035,11 @@ sem_variable::equals (tree t1, tree t2)
case VEC_DUPLICATE_CST:
return sem_variable::equals (VEC_DUPLICATE_CST_ELT (t1),
VEC_DUPLICATE_CST_ELT (t2));
+ case VEC_SERIES_CST:
+ return (sem_variable::equals (VEC_SERIES_CST_BASE (t1),
+ VEC_SERIES_CST_BASE (t2))
+ && sem_variable::equals (VEC_SERIES_CST_STEP (t1),
+ VEC_SERIES_CST_STEP (t2)));
case ARRAY_REF:
case ARRAY_RANGE_REF:
{
Index: gcc/print-tree.c
===================================================================
--- gcc/print-tree.c 2017-10-23 11:41:51.769129995 +0100
+++ gcc/print-tree.c 2017-10-23 11:42:34.919720660 +0100
@@ -787,6 +787,11 @@ print_node (FILE *file, const char *pref
print_node (file, "elt", VEC_DUPLICATE_CST_ELT (node), indent + 4);
break;
+ case VEC_SERIES_CST:
+ print_node (file, "base", VEC_SERIES_CST_BASE (node), indent + 4);
+ print_node (file, "step", VEC_SERIES_CST_STEP (node), indent + 4);
+ break;
+
case COMPLEX_CST:
print_node (file, "real", TREE_REALPART (node), indent + 4);
print_node (file, "imag", TREE_IMAGPART (node), indent + 4);
Index: gcc/tree-ssa-loop.c
===================================================================
--- gcc/tree-ssa-loop.c 2017-10-23 11:41:51.772023858 +0100
+++ gcc/tree-ssa-loop.c 2017-10-23 11:42:34.921720660 +0100
@@ -617,6 +617,7 @@ for_each_index (tree *addr_p, bool (*cbc
case RESULT_DECL:
case VECTOR_CST:
case VEC_DUPLICATE_CST:
+ case VEC_SERIES_CST:
case COMPLEX_CST:
case INTEGER_CST:
case REAL_CST:
Index: gcc/tree-ssa-pre.c
===================================================================
--- gcc/tree-ssa-pre.c 2017-10-23 11:41:51.772023858 +0100
+++ gcc/tree-ssa-pre.c 2017-10-23 11:42:34.922720660 +0100
@@ -2676,6 +2676,7 @@ create_component_ref_by_pieces_1 (basic_
case COMPLEX_CST:
case VECTOR_CST:
case VEC_DUPLICATE_CST:
+ case VEC_SERIES_CST:
case REAL_CST:
case CONSTRUCTOR:
case VAR_DECL:
Index: gcc/tree-ssa-sccvn.c
===================================================================
--- gcc/tree-ssa-sccvn.c 2017-10-23 11:41:51.773953100 +0100
+++ gcc/tree-ssa-sccvn.c 2017-10-23 11:42:34.922720660 +0100
@@ -859,6 +859,7 @@ copy_reference_ops_from_ref (tree ref, v
case COMPLEX_CST:
case VECTOR_CST:
case VEC_DUPLICATE_CST:
+ case VEC_SERIES_CST:
case REAL_CST:
case FIXED_CST:
case CONSTRUCTOR:
@@ -1052,6 +1053,7 @@ ao_ref_init_from_vn_reference (ao_ref *r
case COMPLEX_CST:
case VECTOR_CST:
case VEC_DUPLICATE_CST:
+ case VEC_SERIES_CST:
case REAL_CST:
case CONSTRUCTOR:
case CONST_DECL:
Index: gcc/varasm.c
===================================================================
--- gcc/varasm.c 2017-10-23 11:41:51.775882341 +0100
+++ gcc/varasm.c 2017-10-23 11:42:34.927720660 +0100
@@ -3065,6 +3065,10 @@ const_hash_1 (const tree exp)
return (const_hash_1 (TREE_OPERAND (exp, 0)) * 9
+ const_hash_1 (TREE_OPERAND (exp, 1)));
+ case VEC_SERIES_CST:
+ return (const_hash_1 (VEC_SERIES_CST_BASE (exp)) * 11
+ + const_hash_1 (VEC_SERIES_CST_STEP (exp)));
+
CASE_CONVERT:
return const_hash_1 (TREE_OPERAND (exp, 0)) * 7 + 2;
@@ -3165,6 +3169,12 @@ compare_constant (const tree t1, const t
return compare_constant (VEC_DUPLICATE_CST_ELT (t1),
VEC_DUPLICATE_CST_ELT (t2));
+ case VEC_SERIES_CST:
+ return (compare_constant (VEC_SERIES_CST_BASE (t1),
+ VEC_SERIES_CST_BASE (t2))
+ && compare_constant (VEC_SERIES_CST_STEP (t1),
+ VEC_SERIES_CST_STEP (t2)));
+
case CONSTRUCTOR:
{
vec<constructor_elt, va_gc> *v1, *v2;
Index: gcc/fold-const.c
===================================================================
--- gcc/fold-const.c 2017-10-23 11:41:51.765271511 +0100
+++ gcc/fold-const.c 2017-10-23 11:42:34.916720660 +0100
@@ -421,6 +421,10 @@ negate_expr_p (tree t)
case VEC_DUPLICATE_CST:
return negate_expr_p (VEC_DUPLICATE_CST_ELT (t));
+ case VEC_SERIES_CST:
+ return (negate_expr_p (VEC_SERIES_CST_BASE (t))
+ && negate_expr_p (VEC_SERIES_CST_STEP (t)));
+
case COMPLEX_EXPR:
return negate_expr_p (TREE_OPERAND (t, 0))
&& negate_expr_p (TREE_OPERAND (t, 1));
@@ -590,6 +594,17 @@ fold_negate_expr_1 (location_t loc, tree
return build_vector_from_val (type, sub);
}
+ case VEC_SERIES_CST:
+ {
+ tree neg_base = fold_negate_expr (loc, VEC_SERIES_CST_BASE (t));
+ if (!neg_base)
+ return NULL_TREE;
+ tree neg_step = fold_negate_expr (loc, VEC_SERIES_CST_STEP (t));
+ if (!neg_step)
+ return NULL_TREE;
+ return build_vec_series (type, neg_base, neg_step);
+ }
+
case COMPLEX_EXPR:
if (negate_expr_p (t))
return fold_build2_loc (loc, COMPLEX_EXPR, type,
@@ -1131,6 +1146,28 @@ int_const_binop (enum tree_code code, co
return int_const_binop_1 (code, arg1, arg2, 1);
}
+/* Return true if EXP is a VEC_DUPLICATE_CST or a VEC_SERIES_CST,
+ and if so express it as a linear series in *BASE_OUT and *STEP_OUT.
+ The step will be zero for VEC_DUPLICATE_CST. */
+
+static bool
+vec_series_equivalent_p (const_tree exp, tree *base_out, tree *step_out)
+{
+ if (TREE_CODE (exp) == VEC_SERIES_CST)
+ {
+ *base_out = VEC_SERIES_CST_BASE (exp);
+ *step_out = VEC_SERIES_CST_STEP (exp);
+ return true;
+ }
+ if (TREE_CODE (exp) == VEC_DUPLICATE_CST)
+ {
+ *base_out = VEC_DUPLICATE_CST_ELT (exp);
+ *step_out = build_zero_cst (TREE_TYPE (*base_out));
+ return true;
+ }
+ return false;
+}
+
/* Combine two constants ARG1 and ARG2 under operation CODE to produce a new
constant. We assume ARG1 and ARG2 have the same data type, or at least
are the same kind of constant and the same machine mode. Return zero if
@@ -1457,6 +1494,20 @@ const_binop (enum tree_code code, tree a
return build_vector_from_val (TREE_TYPE (arg1), sub);
}
+ tree base1, step1, base2, step2;
+ if ((code == PLUS_EXPR || code == MINUS_EXPR)
+ && vec_series_equivalent_p (arg1, &base1, &step1)
+ && vec_series_equivalent_p (arg2, &base2, &step2))
+ {
+ tree new_base = const_binop (code, base1, base2);
+ if (!new_base)
+ return NULL_TREE;
+ tree new_step = const_binop (code, step1, step2);
+ if (!new_step)
+ return NULL_TREE;
+ return build_vec_series (TREE_TYPE (arg1), new_base, new_step);
+ }
+
/* Shifts allow a scalar offset for a vector. */
if (TREE_CODE (arg1) == VECTOR_CST
&& TREE_CODE (arg2) == INTEGER_CST)
@@ -1505,6 +1556,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)
@@ -3008,6 +3065,12 @@ operand_equal_p (const_tree arg0, const_
return operand_equal_p (VEC_DUPLICATE_CST_ELT (arg0),
VEC_DUPLICATE_CST_ELT (arg1), flags);
+ case VEC_SERIES_CST:
+ return (operand_equal_p (VEC_SERIES_CST_BASE (arg0),
+ VEC_SERIES_CST_BASE (arg1), flags)
+ && operand_equal_p (VEC_SERIES_CST_STEP (arg0),
+ VEC_SERIES_CST_STEP (arg1), flags));
+
case COMPLEX_CST:
return (operand_equal_p (TREE_REALPART (arg0), TREE_REALPART (arg1),
flags)
@@ -12050,6 +12113,10 @@ fold_checksum_tree (const_tree expr, str
case VEC_DUPLICATE_CST:
fold_checksum_tree (VEC_DUPLICATE_CST_ELT (expr), ctx, ht);
break;
+ case VEC_SERIES_CST:
+ fold_checksum_tree (VEC_SERIES_CST_BASE (expr), ctx, ht);
+ fold_checksum_tree (VEC_SERIES_CST_STEP (expr), ctx, ht);
+ break;
default:
break;
}
Index: gcc/expmed.c
===================================================================
--- gcc/expmed.c 2017-10-23 11:41:39.186050437 +0100
+++ gcc/expmed.c 2017-10-23 11:42:34.914720660 +0100
@@ -5253,6 +5253,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/gimple-pretty-print.c
===================================================================
--- gcc/gimple-pretty-print.c 2017-10-23 11:41:25.500318672 +0100
+++ gcc/gimple-pretty-print.c 2017-10-23 11:42:34.916720660 +0100
@@ -438,6 +438,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-10-23 11:41:51.771059237 +0100
+++ gcc/tree-inline.c 2017-10-23 11:42:34.921720660 +0100
@@ -4003,6 +4003,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-10-23 11:41:51.764306890 +0100
+++ gcc/expr.c 2017-10-23 11:42:34.915720660 +0100
@@ -7704,7 +7704,7 @@ expand_operands (tree exp0, tree exp1, r
\f
/* Expand constant vector element ELT, which has mode MODE. This is used
- for members of VECTOR_CST and VEC_DUPLICATE_CST. */
+ for members of VECTOR_CST, VEC_DUPLICATE_CST and VEC_SERIES_CST. */
static rtx
const_vector_element (scalar_mode mode, const_tree elt)
@@ -9587,6 +9587,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);
@@ -10044,6 +10048,13 @@ expand_expr_real_1 (tree exp, rtx target
VEC_DUPLICATE_CST_ELT (exp));
return gen_const_vec_duplicate (mode, op0);
+ case VEC_SERIES_CST:
+ op0 = const_vector_element (GET_MODE_INNER (mode),
+ VEC_SERIES_CST_BASE (exp));
+ op1 = const_vector_element (GET_MODE_INNER (mode),
+ VEC_SERIES_CST_STEP (exp));
+ return gen_const_vec_series (mode, op0, op1);
+
case CONST_DECL:
if (modifier == EXPAND_WRITE)
{
Index: gcc/optabs.def
===================================================================
--- gcc/optabs.def 2017-10-23 11:41:51.769129995 +0100
+++ gcc/optabs.def 2017-10-23 11:42:34.919720660 +0100
@@ -366,3 +366,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-10-23 11:41:51.769129995 +0100
+++ gcc/optabs.h 2017-10-23 11:42:34.919720660 +0100
@@ -316,6 +316,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-10-23 11:41:51.769129995 +0100
+++ gcc/optabs.c 2017-10-23 11:42:34.919720660 +0100
@@ -5693,6 +5693,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/optabs-tree.c
===================================================================
--- gcc/optabs-tree.c 2017-10-23 11:41:51.768165374 +0100
+++ gcc/optabs-tree.c 2017-10-23 11:42:34.918720660 +0100
@@ -213,6 +213,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-10-23 11:41:51.770094616 +0100
+++ gcc/tree-cfg.c 2017-10-23 11:42:34.920720660 +0100
@@ -4119,6 +4119,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 ();
}
@@ -4485,6 +4502,7 @@ verify_gimple_assign_single (gassign *st
case COMPLEX_CST:
case VECTOR_CST:
case VEC_DUPLICATE_CST:
+ case VEC_SERIES_CST:
case STRING_CST:
return res;
Index: gcc/tree-vect-generic.c
===================================================================
--- gcc/tree-vect-generic.c 2017-10-23 11:41:51.773953100 +0100
+++ gcc/tree-vect-generic.c 2017-10-23 11:42:34.922720660 +0100
@@ -1595,7 +1595,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
next prev parent reply other threads:[~2017-10-23 11:21 UTC|newest]
Thread overview: 90+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-10-23 11:16 [00/nn] Patches preparing for runtime offsets and sizes Richard Sandiford
2017-10-23 11:17 ` [01/nn] Add gen_(const_)vec_duplicate helpers Richard Sandiford
2017-10-25 16:29 ` Jeff Law
2017-10-27 16:12 ` Richard Sandiford
2017-10-23 11:19 ` [03/nn] Allow vector CONSTs Richard Sandiford
2017-10-25 16:59 ` Jeff Law
2017-10-27 16:19 ` Richard Sandiford
2017-10-23 11:19 ` [02/nn] Add more vec_duplicate simplifications Richard Sandiford
2017-10-25 16:35 ` Jeff Law
2017-11-10 9:42 ` Christophe Lyon
2017-10-23 11:20 ` [04/nn] Add a VEC_SERIES rtl code Richard Sandiford
2017-10-26 11:49 ` Richard Biener
2017-10-23 11:21 ` [05/nn] Add VEC_DUPLICATE_{CST,EXPR} and associated optab Richard Sandiford
2017-10-26 11:53 ` Richard Biener
2017-11-06 15:09 ` Richard Sandiford
2017-11-07 10:37 ` Richard Biener
2017-12-15 0:29 ` Richard Sandiford
2017-12-15 8:58 ` Richard Biener
2017-12-15 12:52 ` Richard Sandiford
2017-12-15 13:20 ` Richard Biener
2017-10-23 11:22 ` [07/nn] Add unique CONSTs Richard Sandiford
2017-10-27 15:51 ` Jeff Law
2017-10-27 15:58 ` Richard Sandiford
2017-10-30 14:49 ` Jeff Law
2017-10-23 11:22 ` Richard Sandiford [this message]
2017-10-26 12:26 ` [06/nn] Add VEC_SERIES_{CST,EXPR} and associated optab Richard Biener
2017-10-26 12:43 ` Richard Biener
2017-11-06 15:21 ` Richard Sandiford
2017-11-07 10:38 ` Richard Biener
2017-12-15 0:34 ` Richard Sandiford
2017-12-15 9:03 ` Richard Biener
2017-10-23 11:22 ` [08/nn] Add a fixed_size_mode class Richard Sandiford
2017-10-26 11:57 ` Richard Biener
2017-10-23 11:23 ` [09/nn] Add a fixed_size_mode_pod class Richard Sandiford
2017-10-26 11:59 ` Richard Biener
2017-10-26 12:18 ` Richard Sandiford
2017-10-26 12:46 ` Richard Biener
2017-10-26 19:42 ` Eric Botcazou
2017-10-27 8:34 ` Richard Biener
2017-10-27 9:28 ` Eric Botcazou
2017-10-30 3:14 ` Trevor Saunders
2017-10-30 8:52 ` Richard Sandiford
2017-10-30 10:13 ` Eric Botcazou
2017-10-31 10:39 ` Trevor Saunders
2017-10-31 17:29 ` Eric Botcazou
2017-10-31 17:57 ` Jeff Law
2017-11-01 2:50 ` Trevor Saunders
2017-11-01 16:30 ` Jeff Law
2017-11-02 4:28 ` Trevor Saunders
2017-10-26 19:44 ` Richard Sandiford
2017-10-26 19:45 ` Jakub Jelinek
2017-10-27 8:43 ` Richard Biener
2017-10-27 8:45 ` Jakub Jelinek
2017-10-27 10:19 ` Pedro Alves
2017-10-27 15:23 ` Jeff Law
2017-10-23 11:24 ` [10/nn] Widening optab cleanup Richard Sandiford
2017-10-30 18:32 ` Jeff Law
2017-10-23 11:24 ` [11/nn] Add narrower_subreg_mode helper function Richard Sandiford
2017-10-30 15:06 ` Jeff Law
2017-10-23 11:25 ` [13/nn] More is_a <scalar_int_mode> Richard Sandiford
2017-10-26 12:03 ` Richard Biener
2017-10-23 11:25 ` [12/nn] Add an is_narrower_int_mode helper function Richard Sandiford
2017-10-26 11:59 ` Richard Biener
2017-10-23 11:26 ` [14/nn] Add helpers for shift count modes Richard Sandiford
2017-10-26 12:07 ` Richard Biener
2017-10-26 12:07 ` Richard Biener
2017-11-20 21:04 ` Richard Sandiford
2017-11-21 15:00 ` Richard Biener
2017-12-15 0:48 ` Richard Sandiford
2017-12-15 9:06 ` Richard Biener
2017-12-15 15:17 ` Richard Sandiford
2017-12-19 19:13 ` Richard Sandiford
2017-12-20 0:27 ` Jeff Law
2017-10-30 15:03 ` Jeff Law
2017-10-23 11:27 ` [16/nn] Factor out the mode handling in lower-subreg.c Richard Sandiford
2017-10-26 12:09 ` Richard Biener
2017-10-23 11:27 ` [15/nn] Use more specific hash functions in rtlhash.c Richard Sandiford
2017-10-26 12:08 ` Richard Biener
2017-10-23 11:28 ` [17/nn] Turn var-tracking.c:INT_MEM_OFFSET into a function Richard Sandiford
2017-10-26 12:10 ` Richard Biener
2017-10-23 11:29 ` [19/nn] Don't treat zero-sized ranges as overlapping Richard Sandiford
2017-10-26 12:14 ` Richard Biener
2017-10-23 11:29 ` [18/nn] Use (CONST_VECTOR|GET_MODE)_NUNITS in simplify-rtx.c Richard Sandiford
2017-10-26 12:13 ` Richard Biener
2017-10-23 11:30 ` [20/nn] Make tree-ssa-dse.c:normalize_ref return a bool Richard Sandiford
2017-10-30 17:49 ` Jeff Law
2017-10-23 11:31 ` [21/nn] Minor vn_reference_lookup_3 tweak Richard Sandiford
2017-10-26 12:18 ` Richard Biener
2017-10-23 11:45 ` [22/nn] Make dse.c use offset/width instead of start/end Richard Sandiford
2017-10-26 12:18 ` Richard Biener
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=877evmxg8a.fsf@linaro.org \
--to=richard.sandiford@linaro.org \
--cc=gcc-patches@gcc.gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).