Use tree_vector_builder::new_unary_operation for folding
Richard Biener
richard.guenther@gmail.com
Thu Dec 7 11:06:00 GMT 2017
On Wed, Dec 6, 2017 at 4:23 PM, Richard Sandiford
<richard.sandiford@linaro.org> wrote:
> This patch makes fold-const.c operate directly on the VECTOR_CST
> encoding when folding an operation that has a single VECTOR_CST input.
>
> Tested on aarch64-linux-gnu, x86_64-linux-gnu and powerpc64le-linux-gnu.
> Also spot-checked on sparc64-linux-gnu. OK to install?
Ok.
Richard.
> Thanks,
> Richard
>
> 2017-12-06 Richard Sandiford <richard.sandiford@linaro.org>
>
> gcc/
> * fold-const.c (fold_negate_expr_1): Use tree_vector_builder and
> new_unary_operation, operating only on the encoded elements.
> (const_unop): Likewise.
> (exact_inverse): Likewise.
> (distributes_over_addition_p): New function.
> (const_binop): Use tree_vector_builder and new_unary_operation
> for combinations of VECTOR_CST and INTEGER_CST. Operate only
> on the encoded elements unless the encoding is strided and the
> operation does not distribute over addition.
> (fold_convert_const): Use tree_vector_builder and
> new_unary_operation. Operate only on the encoded elements
> for truncating integer conversions, or for non-stepped encodings.
>
> Index: gcc/fold-const.c
> ===================================================================
> --- gcc/fold-const.c 2017-12-06 14:48:52.887162217 +0000
> +++ gcc/fold-const.c 2017-12-06 14:48:56.997993407 +0000
> @@ -566,10 +566,10 @@ fold_negate_expr_1 (location_t loc, tree
>
> case VECTOR_CST:
> {
> - int count = VECTOR_CST_NELTS (t), i;
> -
> - auto_vec<tree, 32> elts (count);
> - for (i = 0; i < count; i++)
> + tree_vector_builder elts;
> + elts.new_unary_operation (type, t, true);
> + unsigned int count = elts.encoded_nelts ();
> + for (unsigned int i = 0; i < count; ++i)
> {
> tree elt = fold_negate_expr (loc, VECTOR_CST_ELT (t, i));
> if (elt == NULL_TREE)
> @@ -577,7 +577,7 @@ fold_negate_expr_1 (location_t loc, tree
> elts.quick_push (elt);
> }
>
> - return build_vector (type, elts);
> + return elts.build ();
> }
>
> case COMPLEX_EXPR:
> @@ -1121,6 +1121,27 @@ int_const_binop (enum tree_code code, co
> return int_const_binop_1 (code, arg1, arg2, 1);
> }
>
> +/* Return true if binary operation OP distributes over addition in operand
> + OPNO, with the other operand being held constant. OPNO counts from 1. */
> +
> +static bool
> +distributes_over_addition_p (tree_code op, int opno)
> +{
> + switch (op)
> + {
> + case PLUS_EXPR:
> + case MINUS_EXPR:
> + case MULT_EXPR:
> + return true;
> +
> + case LSHIFT_EXPR:
> + return opno == 1;
> +
> + default:
> + 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
> @@ -1442,10 +1463,12 @@ const_binop (enum tree_code code, tree a
> && TREE_CODE (arg2) == INTEGER_CST)
> {
> tree type = TREE_TYPE (arg1);
> - int count = VECTOR_CST_NELTS (arg1), i;
> -
> - auto_vec<tree, 32> elts (count);
> - for (i = 0; i < count; i++)
> + bool step_ok_p = distributes_over_addition_p (code, 1);
> + tree_vector_builder elts;
> + if (!elts.new_unary_operation (type, arg1, step_ok_p))
> + return NULL_TREE;
> + unsigned int count = elts.encoded_nelts ();
> + for (unsigned int i = 0; i < count; ++i)
> {
> tree elem1 = VECTOR_CST_ELT (arg1, i);
>
> @@ -1458,7 +1481,7 @@ const_binop (enum tree_code code, tree a
> elts.quick_push (elt);
> }
>
> - return build_vector (type, elts);
> + return elts.build ();
> }
> return NULL_TREE;
> }
> @@ -1649,10 +1672,12 @@ const_unop (enum tree_code code, tree ty
> else if (TREE_CODE (arg0) == VECTOR_CST)
> {
> tree elem;
> - unsigned count = VECTOR_CST_NELTS (arg0), i;
>
> - auto_vec<tree, 32> elements (count);
> - for (i = 0; i < count; i++)
> + /* This can cope with stepped encodings because ~x == -1 - x. */
> + tree_vector_builder elements;
> + elements.new_unary_operation (type, arg0, true);
> + unsigned int i, count = elements.encoded_nelts ();
> + for (i = 0; i < count; ++i)
> {
> elem = VECTOR_CST_ELT (arg0, i);
> elem = const_unop (BIT_NOT_EXPR, TREE_TYPE (type), elem);
> @@ -1661,7 +1686,7 @@ const_unop (enum tree_code code, tree ty
> elements.quick_push (elem);
> }
> if (i == count)
> - return build_vector (type, elements);
> + return elements.build ();
> }
> break;
>
> @@ -2135,10 +2160,19 @@ fold_convert_const (enum tree_code code,
> if (TREE_CODE (arg1) == VECTOR_CST
> && TYPE_VECTOR_SUBPARTS (type) == VECTOR_CST_NELTS (arg1))
> {
> - int len = VECTOR_CST_NELTS (arg1);
> tree elttype = TREE_TYPE (type);
> - auto_vec<tree, 32> v (len);
> - for (int i = 0; i < len; ++i)
> + tree arg1_elttype = TREE_TYPE (TREE_TYPE (arg1));
> + /* We can't handle steps directly when extending, since the
> + values need to wrap at the original precision first. */
> + bool step_ok_p
> + = (INTEGRAL_TYPE_P (elttype)
> + && INTEGRAL_TYPE_P (arg1_elttype)
> + && TYPE_PRECISION (elttype) <= TYPE_PRECISION (arg1_elttype));
> + tree_vector_builder v;
> + if (!v.new_unary_operation (type, arg1, step_ok_p))
> + return NULL_TREE;
> + unsigned int len = v.encoded_nelts ();
> + for (unsigned int i = 0; i < len; ++i)
> {
> tree elt = VECTOR_CST_ELT (arg1, i);
> tree cvt = fold_convert_const (code, elttype, elt);
> @@ -2146,7 +2180,7 @@ fold_convert_const (enum tree_code code,
> return NULL_TREE;
> v.quick_push (cvt);
> }
> - return build_vector (type, v);
> + return v.build ();
> }
> }
> return NULL_TREE;
> @@ -8832,7 +8866,6 @@ exact_inverse (tree type, tree cst)
> REAL_VALUE_TYPE r;
> tree unit_type;
> machine_mode mode;
> - unsigned vec_nelts, i;
>
> switch (TREE_CODE (cst))
> {
> @@ -8846,12 +8879,14 @@ exact_inverse (tree type, tree cst)
>
> case VECTOR_CST:
> {
> - vec_nelts = VECTOR_CST_NELTS (cst);
> unit_type = TREE_TYPE (type);
> mode = TYPE_MODE (unit_type);
>
> - auto_vec<tree, 32> elts (vec_nelts);
> - for (i = 0; i < vec_nelts; i++)
> + tree_vector_builder elts;
> + if (!elts.new_unary_operation (type, cst, false))
> + return NULL_TREE;
> + unsigned int count = elts.encoded_nelts ();
> + for (unsigned int i = 0; i < count; ++i)
> {
> r = TREE_REAL_CST (VECTOR_CST_ELT (cst, i));
> if (!exact_real_inverse (mode, &r))
> @@ -8859,7 +8894,7 @@ exact_inverse (tree type, tree cst)
> elts.quick_push (build_real (unit_type, r));
> }
>
> - return build_vector (type, elts);
> + return elts.build ();
> }
>
> default:
More information about the Gcc-patches
mailing list