+2017-12-07 Richard Sandiford <richard.sandiford@linaro.org>
+
+ * config/sparc/sparc.c: Include tree-vector-builder.h.
+ (sparc_fold_builtin): Use tree_vector_builder instead of build_vector.
+ * expmed.c: Include tree-vector-builder.h.
+ (make_tree): Use tree_vector_builder instead of build_vector.
+ * fold-const.c: Include tree-vector-builder.h.
+ (const_binop): Use tree_vector_builder instead of build_vector.
+ (const_unop): Likewise.
+ (native_interpret_vector): Likewise.
+ (fold_vec_perm): Likewise.
+ (fold_ternary_loc): Likewise.
+ * gimple-fold.c: Include tree-vector-builder.h.
+ (gimple_fold_stmt_to_constant_1): Use tree_vector_builder instead
+ of build_vector.
+ * tree-ssa-forwprop.c: Include tree-vector-builder.h.
+ (simplify_vector_constructor): Use tree_vector_builder instead
+ of build_vector.
+ * tree-vect-generic.c: Include tree-vector-builder.h.
+ (add_rshift): Use tree_vector_builder instead of build_vector.
+ (expand_vector_divmod): Likewise.
+ (optimize_vector_constructor): Likewise.
+ * tree-vect-loop.c: Include tree-vector-builder.h.
+ (vect_create_epilog_for_reduction): Use tree_vector_builder instead
+ of build_vector. Explicitly use a stepped encoding for
+ { 1, 2, 3, ... }.
+ * tree-vect-slp.c: Include tree-vector-builder.h.
+ (vect_get_constant_vectors): Use tree_vector_builder instead
+ of build_vector.
+ (vect_transform_slp_perm_load): Likewise.
+ (vect_schedule_slp_instance): Likewise.
+ * tree-vect-stmts.c: Include tree-vector-builder.h.
+ (vectorizable_bswap): Use tree_vector_builder instead of build_vector.
+ (vect_gen_perm_mask_any): Likewise.
+ (vectorizable_call): Likewise. Explicitly use a stepped encoding.
+ * tree.c: (build_vector_from_ctor): Use tree_vector_builder instead
+ of build_vector.
+ (build_vector_from_val): Likewise. Explicitly use a duplicate
+ encoding.
+
2017-12-07 Richard Sandiford <richard.sandiford@arm.com>
* doc/generic.texi (VECTOR_CST): Describe new representation of
#include "tree-pass.h"
#include "context.h"
#include "builtins.h"
+#include "tree-vector-builder.h"
/* This file should be included last. */
#include "target-def.h"
tree inner_type = TREE_TYPE (rtype);
unsigned i;
- auto_vec<tree, 32> n_elts (VECTOR_CST_NELTS (arg0));
+ tree_vector_builder n_elts (rtype, VECTOR_CST_NELTS (arg0), 1);
for (i = 0; i < VECTOR_CST_NELTS (arg0); ++i)
{
unsigned HOST_WIDE_INT val
= TREE_INT_CST_LOW (VECTOR_CST_ELT (arg0, i));
n_elts.quick_push (build_int_cst (inner_type, val << 4));
}
- return build_vector (rtype, n_elts);
+ return n_elts.build ();
}
break;
if (TREE_CODE (arg0) == VECTOR_CST && TREE_CODE (arg1) == VECTOR_CST)
{
tree inner_type = TREE_TYPE (rtype);
- auto_vec<tree, 32> n_elts (VECTOR_CST_NELTS (arg0));
+ tree_vector_builder n_elts (rtype, VECTOR_CST_NELTS (arg0), 1);
sparc_handle_vis_mul8x16 (&n_elts, code, inner_type, arg0, arg1);
- return build_vector (rtype, n_elts);
+ return n_elts.build ();
}
break;
if (TREE_CODE (arg0) == VECTOR_CST && TREE_CODE (arg1) == VECTOR_CST)
{
- auto_vec<tree, 32> n_elts (2 * VECTOR_CST_NELTS (arg0));
+ tree_vector_builder n_elts (rtype, 2 * VECTOR_CST_NELTS (arg0), 1);
unsigned i;
for (i = 0; i < VECTOR_CST_NELTS (arg0); ++i)
{
n_elts.quick_push (VECTOR_CST_ELT (arg1, i));
}
- return build_vector (rtype, n_elts);
+ return n_elts.build ();
}
break;
#include "explow.h"
#include "expr.h"
#include "langhooks.h"
+#include "tree-vector-builder.h"
struct target_expmed default_target_expmed;
#if SWITCHABLE_TARGET
int i;
/* Build a tree with vector elements. */
- auto_vec<tree, 32> elts (units);
+ tree_vector_builder elts (type, units, 1);
for (i = 0; i < units; ++i)
{
rtx elt = CONST_VECTOR_ELT (x, i);
elts.quick_push (make_tree (itype, elt));
}
- return build_vector (type, elts);
+ return elts.build ();
}
case PLUS:
#include "selftest.h"
#include "stringpool.h"
#include "attribs.h"
+#include "tree-vector-builder.h"
/* Nonzero if we are folding constants inside an initializer; zero
otherwise. */
gcc_assert (in_nelts == VECTOR_CST_NELTS (arg2)
&& out_nelts == TYPE_VECTOR_SUBPARTS (type));
- auto_vec<tree, 32> elts (out_nelts);
+ tree_vector_builder elts (type, out_nelts, 1);
for (i = 0; i < out_nelts; i++)
{
tree elt = (i < in_nelts
elts.quick_push (elt);
}
- return build_vector (type, elts);
+ return elts.build ();
}
case VEC_WIDEN_MULT_LO_EXPR:
else /* if (code == VEC_WIDEN_MULT_ODD_EXPR) */
scale = 1, ofs = 1;
- auto_vec<tree, 32> elts (out_nelts);
+ tree_vector_builder elts (type, out_nelts, 1);
for (out = 0; out < out_nelts; out++)
{
unsigned int in = (out << scale) + ofs;
elts.quick_push (elt);
}
- return build_vector (type, elts);
+ return elts.build ();
}
default:;
else
subcode = FLOAT_EXPR;
- auto_vec<tree, 32> elts (out_nelts);
+ tree_vector_builder elts (type, out_nelts, 1);
for (i = 0; i < out_nelts; i++)
{
tree elt = fold_convert_const (subcode, TREE_TYPE (type),
elts.quick_push (elt);
}
- return build_vector (type, elts);
+ return elts.build ();
}
default:
if (size * count > len)
return NULL_TREE;
- auto_vec<tree, 32> elements (count);
+ tree_vector_builder elements (type, count, 1);
for (i = 0; i < count; ++i)
{
elem = native_interpret_expr (etype, ptr+(i*size), size);
return NULL_TREE;
elements.quick_push (elem);
}
- return build_vector (type, elements);
+ return elements.build ();
}
|| !vec_cst_ctor_to_array (arg1, nelts, in_elts + nelts))
return NULL_TREE;
- auto_vec<tree, 32> out_elts (nelts);
+ tree_vector_builder out_elts (type, nelts, 1);
for (i = 0; i < nelts; i++)
{
if (!CONSTANT_CLASS_P (in_elts[sel[i]]))
return build_constructor (type, v);
}
else
- return build_vector (type, out_elts);
+ return out_elts.build ();
}
/* Try to fold a pointer difference of type TYPE two address expressions of
if (n == 1)
return VECTOR_CST_ELT (arg0, idx);
- auto_vec<tree, 32> vals (n);
+ tree_vector_builder vals (type, n, 1);
for (unsigned i = 0; i < n; ++i)
vals.quick_push (VECTOR_CST_ELT (arg0, idx + i));
- return build_vector (type, vals);
+ return vals.build ();
}
}
}
if (need_mask_canon && arg2 == op2)
{
tree eltype = TREE_TYPE (TREE_TYPE (arg2));
- auto_vec<tree, 32> tsel (nelts);
+ tree_vector_builder tsel (TREE_TYPE (arg2), nelts, 1);
for (i = 0; i < nelts; i++)
tsel.quick_push (build_int_cst (eltype, sel[i]));
- op2 = build_vector (TREE_TYPE (arg2), tsel);
+ op2 = tsel.build ();
changed = true;
}
else
{
unsigned int nelts = VECTOR_CST_NELTS (arg0);
- auto_vec<tree, 32> elts (nelts);
+ tree_vector_builder elts (type, nelts, 1);
elts.quick_grow (nelts);
- for (unsigned int i = 0; i < VECTOR_CST_NELTS (arg0); ++i)
+ for (unsigned int i = 0; i < nelts; ++i)
elts[i] = (i == k ? arg1 : VECTOR_CST_ELT (arg0, i));
- return build_vector (type, elts);
+ return elts.build ();
}
}
}
#include "diagnostic-core.h"
#include "intl.h"
#include "calls.h"
+#include "tree-vector-builder.h"
/* Return true when DECL can be referenced from current unit.
FROM_DECL (if non-null) specify constructor of variable DECL was taken from.
tree val;
nelts = TYPE_VECTOR_SUBPARTS (TREE_TYPE (rhs));
- auto_vec<tree, 32> vec (nelts);
+ tree_vector_builder vec (TREE_TYPE (rhs), nelts, 1);
FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (rhs), i, val)
{
val = (*valueize) (val);
return NULL_TREE;
}
- return build_vector (TREE_TYPE (rhs), vec);
+ return vec.build ();
}
if (subcode == OBJ_TYPE_REF)
{
#include "tree-cfgcleanup.h"
#include "cfganal.h"
#include "optabs-tree.h"
+#include "tree-vector-builder.h"
/* This pass propagates the RHS of assignment statements into use
sites of the LHS of the assignment. It's basically a specialized
|| GET_MODE_SIZE (TYPE_MODE (mask_type))
!= GET_MODE_SIZE (TYPE_MODE (type)))
return false;
- auto_vec<tree, 32> mask_elts (nelts);
+ tree_vector_builder mask_elts (mask_type, nelts, 1);
for (i = 0; i < nelts; i++)
mask_elts.quick_push (build_int_cst (TREE_TYPE (mask_type), sel[i]));
- op2 = build_vector (mask_type, mask_elts);
+ op2 = mask_elts.build ();
if (conv_code == ERROR_MARK)
gimple_assign_set_rhs_with_ops (gsi, VEC_PERM_EXPR, orig, orig, op2);
else
#include "gimplify-me.h"
#include "gimplify.h"
#include "tree-cfg.h"
+#include "tree-vector-builder.h"
static void expand_vector_operations_1 (gimple_stmt_iterator *);
if (op != unknown_optab
&& optab_handler (op, TYPE_MODE (type)) != CODE_FOR_nothing)
{
- auto_vec<tree, 32> vec (nunits);
+ tree_vector_builder vec (type, nunits, 1);
for (i = 0; i < nunits; i++)
vec.quick_push (build_int_cst (TREE_TYPE (type), shiftcnts[i]));
- return gimplify_build2 (gsi, RSHIFT_EXPR, type, op0,
- build_vector (type, vec));
+ return gimplify_build2 (gsi, RSHIFT_EXPR, type, op0, vec.build ());
}
return NULL_TREE;
mask_type = build_same_sized_truth_vector_type (type);
zero = build_zero_cst (type);
cond = build2 (LT_EXPR, mask_type, op0, zero);
- auto_vec<tree, 32> vec (nunits);
+ tree_vector_builder vec (type, nunits, 1);
for (i = 0; i < nunits; i++)
vec.quick_push (build_int_cst (TREE_TYPE (type),
(HOST_WIDE_INT_1U
<< shifts[i]) - 1));
- cst = build_vector (type, vec);
+ cst = vec.build ();
addend = make_ssa_name (type);
stmt = gimple_build_assign (addend, VEC_COND_EXPR, cond,
cst, zero);
else
{
tree mask;
- auto_vec<tree, 32> vec (nunits);
+ tree_vector_builder vec (type, nunits, 1);
for (i = 0; i < nunits; i++)
vec.quick_push (build_int_cst (TREE_TYPE (type),
(HOST_WIDE_INT_1U
<< shifts[i]) - 1));
- mask = build_vector (type, vec);
+ mask = vec.build ();
op = optab_for_tree_code (BIT_AND_EXPR, type, optab_default);
if (op != unknown_optab
&& optab_handler (op, TYPE_MODE (type)) != CODE_FOR_nothing)
return NULL_TREE;
}
- auto_vec<tree, 32> vec (nunits);
+ tree_vector_builder vec (type, nunits, 1);
for (i = 0; i < nunits; i++)
vec.quick_push (build_int_cst (TREE_TYPE (type), mulc[i]));
- mulcst = build_vector (type, vec);
+ mulcst = vec.build ();
cur_op = gimplify_build2 (gsi, MULT_HIGHPART_EXPR, type, cur_op, mulcst);
}
if (all_same)
return;
- auto_vec<tree, 32> cst (nelts);
+ tree_vector_builder cst (type, nelts, 1);
for (i = 0; i < nelts; i++)
{
tree this_base = CONSTRUCTOR_ELT (rhs, i)->value;
g = gimple_build_assign (make_ssa_name (type), rhs);
gsi_insert_before (gsi, g, GSI_SAME_STMT);
g = gimple_build_assign (lhs, PLUS_EXPR, gimple_assign_lhs (g),
- build_vector (type, cst));
+ cst.build ());
gsi_replace (gsi, g, false);
}
\f
#include "tree-cfg.h"
#include "tree-if-conv.h"
#include "internal-fn.h"
+#include "tree-vector-builder.h"
/* Loop Vectorization Pass.
vector size (STEP). */
/* Create a {1,2,3,...} vector. */
- auto_vec<tree, 32> vtemp (nunits_out);
- for (k = 0; k < nunits_out; ++k)
+ tree_vector_builder vtemp (cr_index_vector_type, 1, 3);
+ for (k = 0; k < 3; ++k)
vtemp.quick_push (build_int_cst (cr_index_scalar_type, k + 1));
- tree series_vect = build_vector (cr_index_vector_type, vtemp);
+ tree series_vect = vtemp.build ();
/* Create a vector of the step value. */
tree step = build_int_cst (cr_index_scalar_type, nunits_out);
#include "langhooks.h"
#include "gimple-walk.h"
#include "dbgcnt.h"
+#include "tree-vector-builder.h"
/* Recursively free the memory allocated for the SLP tree rooted at NODE. */
number_of_places_left_in_vector = nunits;
constant_p = true;
- auto_vec<tree, 32> elts (nunits);
+ tree_vector_builder elts (vector_type, nunits, 1);
elts.quick_grow (nunits);
bool place_after_defs = false;
for (j = 0; j < number_of_copies; j++)
if (number_of_places_left_in_vector == 0)
{
if (constant_p)
- vec_cst = build_vector (vector_type, elts);
+ vec_cst = elts.build ();
else
{
vec<constructor_elt, va_gc> *v;
place_after_defs = false;
number_of_places_left_in_vector = nunits;
constant_p = true;
+ elts.new_vector (vector_type, nunits, 1);
+ elts.quick_grow (nunits);
}
}
}
if (! noop_p)
{
- auto_vec<tree, 32> mask_elts (nunits);
+ tree_vector_builder mask_elts (mask_type, nunits, 1);
for (int l = 0; l < nunits; ++l)
mask_elts.quick_push (build_int_cst (mask_element_type,
mask[l]));
- mask_vec = build_vector (mask_type, mask_elts);
+ mask_vec = mask_elts.build ();
}
if (second_vec_index == -1)
for (j = 0; j < v0.length (); ++j)
{
unsigned int nunits = TYPE_VECTOR_SUBPARTS (vectype);
- auto_vec<tree, 32> melts (nunits);
+ tree_vector_builder melts (mvectype, nunits, 1);
for (l = 0; l < nunits; ++l)
{
if (k >= group_size)
tree t = build_int_cst (meltype, mask[k++] * nunits + l);
melts.quick_push (t);
}
- tmask = build_vector (mvectype, melts);
+ tmask = melts.build ();
/* ??? Not all targets support a VEC_PERM_EXPR with a
constant mask that would translate to a vec_merge RTX
#include "tree-vectorizer.h"
#include "builtins.h"
#include "internal-fn.h"
+#include "tree-vector-builder.h"
/* For lang_hooks.types.type_for_mode. */
#include "langhooks.h"
return true;
}
- auto_vec<tree, 32> telts (num_bytes);
+ tree_vector_builder telts (char_vectype, num_bytes, 1);
for (unsigned i = 0; i < num_bytes; ++i)
telts.quick_push (build_int_cst (char_type_node, elts[i]));
- tree bswap_vconst = build_vector (char_vectype, telts);
+ tree bswap_vconst = telts.build ();
/* Transform. */
vec<tree> vec_oprnds = vNULL;
if (gimple_call_internal_p (stmt)
&& gimple_call_internal_fn (stmt) == IFN_GOMP_SIMD_LANE)
{
- auto_vec<tree, 32> v (nunits_out);
- for (int k = 0; k < nunits_out; ++k)
+ tree_vector_builder v (vectype_out, 1, 3);
+ for (int k = 0; k < 3; ++k)
v.quick_push (build_int_cst (unsigned_type_node,
j * nunits_out + k));
- tree cst = build_vector (vectype_out, v);
+ tree cst = v.build ();
tree new_var
= vect_get_new_ssa_name (vectype_out, vect_simple_var, "cst_");
gimple *init_stmt = gimple_build_assign (new_var, cst);
tree
vect_gen_perm_mask_any (tree vectype, vec_perm_indices sel)
{
- tree mask_elt_type, mask_type, mask_vec;
+ tree mask_elt_type, mask_type;
unsigned int nunits = sel.length ();
gcc_checking_assert (nunits == TYPE_VECTOR_SUBPARTS (vectype));
(int_mode_for_mode (TYPE_MODE (TREE_TYPE (vectype))).require (), 1);
mask_type = get_vectype_for_scalar_type (mask_elt_type);
- auto_vec<tree, 32> mask_elts (nunits);
+ tree_vector_builder mask_elts (mask_type, nunits, 1);
for (unsigned int i = 0; i < nunits; ++i)
mask_elts.quick_push (build_int_cst (mask_elt_type, sel[i]));
- mask_vec = build_vector (mask_type, mask_elts);
-
- return mask_vec;
+ return mask_elts.build ();
}
/* Checked version of vect_gen_perm_mask_any. Asserts can_vec_perm_p,
unsigned HOST_WIDE_INT idx;
tree value;
- auto_vec<tree, 32> vec (nelts);
+ tree_vector_builder vec (type, nelts, 1);
FOR_EACH_CONSTRUCTOR_VALUE (v, idx, value)
{
if (TREE_CODE (value) == VECTOR_CST)
while (vec.length () < nelts)
vec.quick_push (build_zero_cst (TREE_TYPE (type)));
- return build_vector (type, vec);
+ return vec.build ();
}
/* Build a vector of type VECTYPE where all the elements are SCs. */
if (CONSTANT_CLASS_P (sc))
{
- auto_vec<tree, 32> v (nunits);
- for (i = 0; i < nunits; ++i)
- v.quick_push (sc);
- return build_vector (vectype, v);
+ tree_vector_builder v (vectype, 1, 1);
+ v.quick_push (sc);
+ return v.build ();
}
else
{