aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@linaro.org>2017-09-14 15:25:57 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2017-09-14 15:25:57 +0000
commit9e822269364f5268b2bdc82530fd6c871f47b1bc (patch)
treec7de33f186c199c790259d0bdb8d0d743b5309da /gcc
parent2a94be35291a8564154cd213f73b7e302e3f3b80 (diff)
downloadgcc-9e822269364f5268b2bdc82530fd6c871f47b1bc.zip
gcc-9e822269364f5268b2bdc82530fd6c871f47b1bc.tar.gz
gcc-9e822269364f5268b2bdc82530fd6c871f47b1bc.tar.bz2
Store VECTOR_CST_NELTS directly in tree_node
Previously VECTOR_CST_NELTS (t) read the number of elements from TYPE_VECTOR_SUBPARTS (TREE_TYPE (t)). There were two ways of handling this with variable TYPE_VECTOR_SUBPARTS: either forcibly convert the number to a constant (which is doable) or store the number directly in the VECTOR_CST. The latter seemed better, since it involves less pointer chasing and since the tree_node u field is otherwise unused for VECTOR_CST. It would still be easy to switch to the former in future if we need to free up the field for someting else. The patch also changes various bits of VECTOR_CST code to use VECTOR_CST_NELTS instead of TYPE_VECTOR_SUBPARTS when iterating over VECTOR_CST_ELTs. Also, when the two are checked for equality, the patch prefers to read VECTOR_CST_NELTS (which must be constant) and check against TYPE_VECTOR_SUBPARTS, instead of the other way around. 2017-09-14 Richard Sandiford <richard.sandiford@linaro.org> Alan Hayward <alan.hayward@arm.com> David Sherwood <david.sherwood@arm.com> gcc/ * tree-core.h (tree_base::u): Add an "nelts" field. (tree_vector): Use VECTOR_CST_NELTS as the length. * tree.c (tree_size): Likewise. (make_vector): Initialize VECTOR_CST_NELTS. * tree.h (VECTOR_CST_NELTS): Use the u.nelts field. * cfgexpand.c (expand_debug_expr): Use VECTOR_CST_NELTS instead of TYPE_VECTOR_SUBPARTS. * expr.c (const_vector_mask_from_tree): Consistently use "units" as the number of units, setting it from VECTOR_CST_NELTS. (const_vector_from_tree): Likewise. * fold-const.c (negate_expr_p): Use VECTOR_CST_NELTS instead of TYPE_VECTOR_SUBPARTS for the number of elements in a VECTOR_CST. (fold_negate_expr_1): Likewise. (fold_convert_const): Likewise. (const_binop): Likewise. Differentiate the number of output and input elements. (const_unop): Likewise. (fold_ternary_loc): Use VECTOR_CST_NELTS for the number of elements in a VECTOR_CST, asserting that it is the same as TYPE_VECTOR_SUBPARTS in cases that did the opposite. Co-Authored-By: Alan Hayward <alan.hayward@arm.com> Co-Authored-By: David Sherwood <david.sherwood@arm.com> From-SVN: r252758
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog25
-rw-r--r--gcc/cfgexpand.c8
-rw-r--r--gcc/expr.c14
-rw-r--r--gcc/fold-const.c76
-rw-r--r--gcc/tree-core.h5
-rw-r--r--gcc/tree.c3
-rw-r--r--gcc/tree.h2
7 files changed, 84 insertions, 49 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 3925e46..fb9c448 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,28 @@
+2017-09-14 Richard Sandiford <richard.sandiford@linaro.org>
+ Alan Hayward <alan.hayward@arm.com>
+ David Sherwood <david.sherwood@arm.com>
+
+ * tree-core.h (tree_base::u): Add an "nelts" field.
+ (tree_vector): Use VECTOR_CST_NELTS as the length.
+ * tree.c (tree_size): Likewise.
+ (make_vector): Initialize VECTOR_CST_NELTS.
+ * tree.h (VECTOR_CST_NELTS): Use the u.nelts field.
+ * cfgexpand.c (expand_debug_expr): Use VECTOR_CST_NELTS instead of
+ TYPE_VECTOR_SUBPARTS.
+ * expr.c (const_vector_mask_from_tree): Consistently use "units"
+ as the number of units, setting it from VECTOR_CST_NELTS.
+ (const_vector_from_tree): Likewise.
+ * fold-const.c (negate_expr_p): Use VECTOR_CST_NELTS instead of
+ TYPE_VECTOR_SUBPARTS for the number of elements in a VECTOR_CST.
+ (fold_negate_expr_1): Likewise.
+ (fold_convert_const): Likewise.
+ (const_binop): Likewise. Differentiate the number of output and
+ input elements.
+ (const_unop): Likewise.
+ (fold_ternary_loc): Use VECTOR_CST_NELTS for the number of elements
+ in a VECTOR_CST, asserting that it is the same as TYPE_VECTOR_SUBPARTS
+ in cases that did the opposite.
+
2017-09-14 Richard Biener <rguenther@suse.de>
* tree-ssa-sccvn.c (visit_phi): Merge undefined values similar
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index 7657a65..bd3312e 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -4921,12 +4921,12 @@ expand_debug_expr (tree exp)
case VECTOR_CST:
{
- unsigned i;
+ unsigned i, nelts;
- op0 = gen_rtx_CONCATN
- (mode, rtvec_alloc (TYPE_VECTOR_SUBPARTS (TREE_TYPE (exp))));
+ nelts = VECTOR_CST_NELTS (exp);
+ op0 = gen_rtx_CONCATN (mode, rtvec_alloc (nelts));
- for (i = 0; i < VECTOR_CST_NELTS (exp); ++i)
+ for (i = 0; i < nelts; ++i)
{
op1 = expand_debug_expr (VECTOR_CST_ELT (exp, i));
if (!op1)
diff --git a/gcc/expr.c b/gcc/expr.c
index 989badc..a9689a6 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -11700,18 +11700,17 @@ static rtx
const_vector_mask_from_tree (tree exp)
{
rtvec v;
- unsigned i;
- int units;
+ unsigned i, units;
tree elt;
machine_mode inner, mode;
mode = TYPE_MODE (TREE_TYPE (exp));
- units = GET_MODE_NUNITS (mode);
+ units = VECTOR_CST_NELTS (exp);
inner = GET_MODE_INNER (mode);
v = rtvec_alloc (units);
- for (i = 0; i < VECTOR_CST_NELTS (exp); ++i)
+ for (i = 0; i < units; ++i)
{
elt = VECTOR_CST_ELT (exp, i);
@@ -11756,8 +11755,7 @@ static rtx
const_vector_from_tree (tree exp)
{
rtvec v;
- unsigned i;
- int units;
+ unsigned i, units;
tree elt;
machine_mode inner, mode;
@@ -11769,12 +11767,12 @@ const_vector_from_tree (tree exp)
if (VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (exp)))
return const_vector_mask_from_tree (exp);
- units = GET_MODE_NUNITS (mode);
+ units = VECTOR_CST_NELTS (exp);
inner = GET_MODE_INNER (mode);
v = rtvec_alloc (units);
- for (i = 0; i < VECTOR_CST_NELTS (exp); ++i)
+ for (i = 0; i < units; ++i)
{
elt = VECTOR_CST_ELT (exp, i);
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 16bf456..66e7cc7 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -410,7 +410,7 @@ negate_expr_p (tree t)
if (FLOAT_TYPE_P (TREE_TYPE (type)) || TYPE_OVERFLOW_WRAPS (type))
return true;
- int count = TYPE_VECTOR_SUBPARTS (type), i;
+ int count = VECTOR_CST_NELTS (t), i;
for (i = 0; i < count; i++)
if (!negate_expr_p (VECTOR_CST_ELT (t, i)))
@@ -564,7 +564,7 @@ fold_negate_expr_1 (location_t loc, tree t)
case VECTOR_CST:
{
- int count = TYPE_VECTOR_SUBPARTS (type), i;
+ int count = VECTOR_CST_NELTS (t), i;
tree *elts = XALLOCAVEC (tree, count);
for (i = 0; i < count; i++)
@@ -1413,7 +1413,7 @@ const_binop (enum tree_code code, tree arg1, tree arg2)
&& TREE_CODE (arg2) == VECTOR_CST)
{
tree type = TREE_TYPE (arg1);
- int count = TYPE_VECTOR_SUBPARTS (type), i;
+ int count = VECTOR_CST_NELTS (arg1), i;
tree *elts = XALLOCAVEC (tree, count);
for (i = 0; i < count; i++)
@@ -1437,7 +1437,7 @@ const_binop (enum tree_code code, tree arg1, tree arg2)
&& TREE_CODE (arg2) == INTEGER_CST)
{
tree type = TREE_TYPE (arg1);
- int count = TYPE_VECTOR_SUBPARTS (type), i;
+ int count = VECTOR_CST_NELTS (arg1), i;
tree *elts = XALLOCAVEC (tree, count);
for (i = 0; i < count; i++)
@@ -1481,21 +1481,24 @@ const_binop (enum tree_code code, tree type, tree arg1, tree arg2)
case VEC_PACK_TRUNC_EXPR:
case VEC_PACK_FIX_TRUNC_EXPR:
{
- unsigned int nelts = TYPE_VECTOR_SUBPARTS (type), i;
tree *elts;
+ unsigned int out_nelts, in_nelts, i;
- gcc_assert (TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg1)) == nelts / 2
- && TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg2)) == nelts / 2);
if (TREE_CODE (arg1) != VECTOR_CST
|| TREE_CODE (arg2) != VECTOR_CST)
return NULL_TREE;
- elts = XALLOCAVEC (tree, nelts);
+ in_nelts = VECTOR_CST_NELTS (arg1);
+ out_nelts = in_nelts * 2;
+ gcc_assert (in_nelts == VECTOR_CST_NELTS (arg2)
+ && out_nelts == TYPE_VECTOR_SUBPARTS (type));
+
+ elts = XALLOCAVEC (tree, out_nelts);
if (!vec_cst_ctor_to_array (arg1, elts)
- || !vec_cst_ctor_to_array (arg2, elts + nelts / 2))
+ || !vec_cst_ctor_to_array (arg2, elts + in_nelts))
return NULL_TREE;
- for (i = 0; i < nelts; i++)
+ for (i = 0; i < out_nelts; i++)
{
elts[i] = fold_convert_const (code == VEC_PACK_TRUNC_EXPR
? NOP_EXPR : FIX_TRUNC_EXPR,
@@ -1512,33 +1515,35 @@ const_binop (enum tree_code code, tree type, tree arg1, tree arg2)
case VEC_WIDEN_MULT_EVEN_EXPR:
case VEC_WIDEN_MULT_ODD_EXPR:
{
- unsigned int nelts = TYPE_VECTOR_SUBPARTS (type);
- unsigned int out, ofs, scale;
+ unsigned int out_nelts, in_nelts, out, ofs, scale;
tree *elts;
- gcc_assert (TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg1)) == nelts * 2
- && TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg2)) == nelts * 2);
if (TREE_CODE (arg1) != VECTOR_CST || TREE_CODE (arg2) != VECTOR_CST)
return NULL_TREE;
- elts = XALLOCAVEC (tree, nelts * 4);
+ in_nelts = VECTOR_CST_NELTS (arg1);
+ out_nelts = in_nelts / 2;
+ gcc_assert (in_nelts == VECTOR_CST_NELTS (arg2)
+ && out_nelts == TYPE_VECTOR_SUBPARTS (type));
+
+ elts = XALLOCAVEC (tree, in_nelts * 2);
if (!vec_cst_ctor_to_array (arg1, elts)
- || !vec_cst_ctor_to_array (arg2, elts + nelts * 2))
+ || !vec_cst_ctor_to_array (arg2, elts + in_nelts))
return NULL_TREE;
if (code == VEC_WIDEN_MULT_LO_EXPR)
- scale = 0, ofs = BYTES_BIG_ENDIAN ? nelts : 0;
+ scale = 0, ofs = BYTES_BIG_ENDIAN ? out_nelts : 0;
else if (code == VEC_WIDEN_MULT_HI_EXPR)
- scale = 0, ofs = BYTES_BIG_ENDIAN ? 0 : nelts;
+ scale = 0, ofs = BYTES_BIG_ENDIAN ? 0 : out_nelts;
else if (code == VEC_WIDEN_MULT_EVEN_EXPR)
scale = 1, ofs = 0;
else /* if (code == VEC_WIDEN_MULT_ODD_EXPR) */
scale = 1, ofs = 1;
- for (out = 0; out < nelts; out++)
+ for (out = 0; out < out_nelts; out++)
{
unsigned int in1 = (out << scale) + ofs;
- unsigned int in2 = in1 + nelts * 2;
+ unsigned int in2 = in1 + in_nelts;
tree t1, t2;
t1 = fold_convert_const (NOP_EXPR, TREE_TYPE (type), elts[in1]);
@@ -1671,28 +1676,31 @@ const_unop (enum tree_code code, tree type, tree arg0)
case VEC_UNPACK_FLOAT_LO_EXPR:
case VEC_UNPACK_FLOAT_HI_EXPR:
{
- unsigned int nelts = TYPE_VECTOR_SUBPARTS (type), i;
+ unsigned int out_nelts, in_nelts, i;
tree *elts;
enum tree_code subcode;
- gcc_assert (TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0)) == nelts * 2);
if (TREE_CODE (arg0) != VECTOR_CST)
return NULL_TREE;
- elts = XALLOCAVEC (tree, nelts * 2);
+ in_nelts = VECTOR_CST_NELTS (arg0);
+ out_nelts = in_nelts / 2;
+ gcc_assert (out_nelts == TYPE_VECTOR_SUBPARTS (type));
+
+ elts = XALLOCAVEC (tree, in_nelts);
if (!vec_cst_ctor_to_array (arg0, elts))
return NULL_TREE;
if ((!BYTES_BIG_ENDIAN) ^ (code == VEC_UNPACK_LO_EXPR
|| code == VEC_UNPACK_FLOAT_LO_EXPR))
- elts += nelts;
+ elts += out_nelts;
if (code == VEC_UNPACK_LO_EXPR || code == VEC_UNPACK_HI_EXPR)
subcode = NOP_EXPR;
else
subcode = FLOAT_EXPR;
- for (i = 0; i < nelts; i++)
+ for (i = 0; i < out_nelts; i++)
{
elts[i] = fold_convert_const (subcode, TREE_TYPE (type), elts[i]);
if (elts[i] == NULL_TREE || !CONSTANT_CLASS_P (elts[i]))
@@ -1712,7 +1720,7 @@ const_unop (enum tree_code code, tree type, tree arg0)
if (TREE_CODE (arg0) != VECTOR_CST)
return NULL_TREE;
- nelts = TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0));
+ nelts = VECTOR_CST_NELTS (arg0);
elts = XALLOCAVEC (tree, nelts);
if (!vec_cst_ctor_to_array (arg0, elts))
@@ -2153,7 +2161,7 @@ fold_convert_const (enum tree_code code, tree type, tree arg1)
if (TREE_CODE (arg1) == VECTOR_CST
&& TYPE_VECTOR_SUBPARTS (type) == VECTOR_CST_NELTS (arg1))
{
- int len = TYPE_VECTOR_SUBPARTS (type);
+ int len = VECTOR_CST_NELTS (arg1);
tree elttype = TREE_TYPE (type);
tree *v = XALLOCAVEC (tree, len);
for (int i = 0; i < len; ++i)
@@ -11311,9 +11319,9 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type,
&& (TREE_CODE (arg2) == VECTOR_CST
|| TREE_CODE (arg2) == CONSTRUCTOR))
{
- unsigned int nelts = TYPE_VECTOR_SUBPARTS (type), i;
+ unsigned int nelts = VECTOR_CST_NELTS (arg0), i;
unsigned char *sel = XALLOCAVEC (unsigned char, nelts);
- gcc_assert (nelts == VECTOR_CST_NELTS (arg0));
+ gcc_assert (nelts == TYPE_VECTOR_SUBPARTS (type));
for (i = 0; i < nelts; i++)
{
tree val = VECTOR_CST_ELT (arg0, i);
@@ -11642,7 +11650,7 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type,
case VEC_PERM_EXPR:
if (TREE_CODE (arg2) == VECTOR_CST)
{
- unsigned int nelts = TYPE_VECTOR_SUBPARTS (type), i, mask, mask2;
+ unsigned int nelts = VECTOR_CST_NELTS (arg2), i, mask, mask2;
unsigned char *sel = XALLOCAVEC (unsigned char, 2 * nelts);
unsigned char *sel2 = sel + nelts;
bool need_mask_canon = false;
@@ -11655,7 +11663,7 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type,
mask2 = 2 * nelts - 1;
mask = single_arg ? (nelts - 1) : mask2;
- gcc_assert (nelts == VECTOR_CST_NELTS (arg2));
+ gcc_assert (nelts == TYPE_VECTOR_SUBPARTS (type));
for (i = 0; i < nelts; i++)
{
tree val = VECTOR_CST_ELT (arg2, i);
@@ -11766,9 +11774,9 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type,
return arg0;
else
{
- tree *elts = XALLOCAVEC (tree, TYPE_VECTOR_SUBPARTS (type));
- memcpy (elts, VECTOR_CST_ELTS (arg0),
- sizeof (tree) * TYPE_VECTOR_SUBPARTS (type));
+ unsigned int nelts = VECTOR_CST_NELTS (arg0);
+ tree *elts = XALLOCAVEC (tree, nelts);
+ memcpy (elts, VECTOR_CST_ELTS (arg0), sizeof (tree) * nelts);
elts[k] = arg1;
return build_vector (type, elts);
}
diff --git a/gcc/tree-core.h b/gcc/tree-core.h
index dc358e8..b34080e 100644
--- a/gcc/tree-core.h
+++ b/gcc/tree-core.h
@@ -975,6 +975,9 @@ struct GTY(()) tree_base {
/* VEC length. This field is only used with TREE_VEC. */
int length;
+ /* Number of elements. This field is only used with VECTOR_CST. */
+ unsigned int nelts;
+
/* SSA version number. This field is only used with SSA_NAME. */
unsigned int version;
@@ -1326,7 +1329,7 @@ struct GTY(()) tree_complex {
struct GTY(()) tree_vector {
struct tree_typed typed;
- tree GTY ((length ("TYPE_VECTOR_SUBPARTS (TREE_TYPE ((tree)&%h))"))) elts[1];
+ tree GTY ((length ("VECTOR_CST_NELTS ((tree) &%h)"))) elts[1];
};
struct GTY(()) tree_identifier {
diff --git a/gcc/tree.c b/gcc/tree.c
index 721330a..0f505c2 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -873,7 +873,7 @@ tree_size (const_tree node)
case VECTOR_CST:
return (sizeof (struct tree_vector)
- + (TYPE_VECTOR_SUBPARTS (TREE_TYPE (node)) - 1) * sizeof (tree));
+ + (VECTOR_CST_NELTS (node) - 1) * sizeof (tree));
case STRING_CST:
return TREE_STRING_LENGTH (node) + offsetof (struct tree_string, str) + 1;
@@ -1696,6 +1696,7 @@ make_vector (unsigned len MEM_STAT_DECL)
TREE_SET_CODE (t, VECTOR_CST);
TREE_CONSTANT (t) = 1;
+ VECTOR_CST_NELTS (t) = len;
return t;
}
diff --git a/gcc/tree.h b/gcc/tree.h
index 19dd807..490c3b6 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -1026,7 +1026,7 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int,
#define TREE_IMAGPART(NODE) (COMPLEX_CST_CHECK (NODE)->complex.imag)
/* In a VECTOR_CST node. */
-#define VECTOR_CST_NELTS(NODE) (TYPE_VECTOR_SUBPARTS (TREE_TYPE (NODE)))
+#define VECTOR_CST_NELTS(NODE) (VECTOR_CST_CHECK (NODE)->base.u.nelts)
#define VECTOR_CST_ELTS(NODE) (VECTOR_CST_CHECK (NODE)->vector.elts)
#define VECTOR_CST_ELT(NODE,IDX) (VECTOR_CST_CHECK (NODE)->vector.elts[IDX])