aboutsummaryrefslogtreecommitdiff
path: root/gcc/fold-const.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/fold-const.c')
-rw-r--r--gcc/fold-const.c107
1 files changed, 25 insertions, 82 deletions
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 0004f789d53..8aabe2155fa 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -836,11 +836,10 @@ split_tree (location_t loc, tree in, tree type, enum tree_code code,
*minus_litp = *litp, *litp = 0;
if (neg_conp_p)
*conp = negate_expr (*conp);
- if (neg_var_p)
+ if (neg_var_p && var)
{
- /* Convert to TYPE before negating a pointer type expr. */
- if (var && POINTER_TYPE_P (TREE_TYPE (var)))
- var = fold_convert_loc (loc, type, var);
+ /* Convert to TYPE before negating. */
+ var = fold_convert_loc (loc, type, var);
var = negate_expr (var);
}
}
@@ -863,10 +862,12 @@ split_tree (location_t loc, tree in, tree type, enum tree_code code,
else if (*minus_litp)
*litp = *minus_litp, *minus_litp = 0;
*conp = negate_expr (*conp);
- /* Convert to TYPE before negating a pointer type expr. */
- if (var && POINTER_TYPE_P (TREE_TYPE (var)))
- var = fold_convert_loc (loc, type, var);
- var = negate_expr (var);
+ if (var)
+ {
+ /* Convert to TYPE before negating. */
+ var = fold_convert_loc (loc, type, var);
+ var = negate_expr (var);
+ }
}
return var;
@@ -2758,8 +2759,8 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
if (arg0 != arg1)
{
inchash::hash hstate0 (0), hstate1 (0);
- inchash::add_expr (arg0, hstate0, flags);
- inchash::add_expr (arg1, hstate1, flags);
+ inchash::add_expr (arg0, hstate0, flags | OEP_HASH_CHECK);
+ inchash::add_expr (arg1, hstate1, flags | OEP_HASH_CHECK);
hashval_t h0 = hstate0.end ();
hashval_t h1 = hstate1.end ();
gcc_assert (h0 == h1);
@@ -11719,9 +11720,7 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type,
gcc_unreachable ();
case BIT_FIELD_REF:
- if ((TREE_CODE (arg0) == VECTOR_CST
- || (TREE_CODE (arg0) == CONSTRUCTOR
- && TREE_CODE (TREE_TYPE (arg0)) == VECTOR_TYPE))
+ if (TREE_CODE (arg0) == VECTOR_CST
&& (type == TREE_TYPE (TREE_TYPE (arg0))
|| (TREE_CODE (type) == VECTOR_TYPE
&& TREE_TYPE (type) == TREE_TYPE (TREE_TYPE (arg0)))))
@@ -11749,88 +11748,32 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type,
vals[i] = VECTOR_CST_ELT (arg0, idx + i);
return build_vector (type, vals);
}
-
- /* Constructor elements can be subvectors. */
- unsigned HOST_WIDE_INT k = 1;
- if (CONSTRUCTOR_NELTS (arg0) != 0)
- {
- tree cons_elem = TREE_TYPE (CONSTRUCTOR_ELT (arg0, 0)->value);
- if (TREE_CODE (cons_elem) == VECTOR_TYPE)
- k = TYPE_VECTOR_SUBPARTS (cons_elem);
- }
-
- /* We keep an exact subset of the constructor elements. */
- if ((idx % k) == 0 && (n % k) == 0)
- {
- if (CONSTRUCTOR_NELTS (arg0) == 0)
- return build_constructor (type, NULL);
- idx /= k;
- n /= k;
- if (n == 1)
- {
- if (idx < CONSTRUCTOR_NELTS (arg0))
- return CONSTRUCTOR_ELT (arg0, idx)->value;
- return build_zero_cst (type);
- }
-
- vec<constructor_elt, va_gc> *vals;
- vec_alloc (vals, n);
- for (unsigned i = 0;
- i < n && idx + i < CONSTRUCTOR_NELTS (arg0);
- ++i)
- CONSTRUCTOR_APPEND_ELT (vals, NULL_TREE,
- CONSTRUCTOR_ELT
- (arg0, idx + i)->value);
- return build_constructor (type, vals);
- }
- /* The bitfield references a single constructor element. */
- else if (idx + n <= (idx / k + 1) * k)
- {
- if (CONSTRUCTOR_NELTS (arg0) <= idx / k)
- return build_zero_cst (type);
- else if (n == k)
- return CONSTRUCTOR_ELT (arg0, idx / k)->value;
- else
- return fold_build3_loc (loc, code, type,
- CONSTRUCTOR_ELT (arg0, idx / k)->value, op1,
- build_int_cst (TREE_TYPE (op2), (idx % k) * width));
- }
}
}
- /* A bit-field-ref that referenced the full argument can be stripped. */
- if (INTEGRAL_TYPE_P (TREE_TYPE (arg0))
- && TYPE_PRECISION (TREE_TYPE (arg0)) == tree_to_uhwi (arg1)
- && integer_zerop (op2))
- return fold_convert_loc (loc, type, arg0);
-
/* On constants we can use native encode/interpret to constant
fold (nearly) all BIT_FIELD_REFs. */
if (CONSTANT_CLASS_P (arg0)
&& can_native_interpret_type_p (type)
- && tree_fits_uhwi_p (TYPE_SIZE_UNIT (TREE_TYPE (arg0)))
- /* This limitation should not be necessary, we just need to
- round this up to mode size. */
- && tree_to_uhwi (op1) % BITS_PER_UNIT == 0
- /* Need bit-shifting of the buffer to relax the following. */
- && tree_to_uhwi (op2) % BITS_PER_UNIT == 0)
+ && BITS_PER_UNIT == 8)
{
unsigned HOST_WIDE_INT bitpos = tree_to_uhwi (op2);
unsigned HOST_WIDE_INT bitsize = tree_to_uhwi (op1);
- unsigned HOST_WIDE_INT clen;
- clen = tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (arg0)));
- /* ??? We cannot tell native_encode_expr to start at
- some random byte only. So limit us to a reasonable amount
- of work. */
- if (clen <= 4096)
+ /* Limit us to a reasonable amount of work. To relax the
+ other limitations we need bit-shifting of the buffer
+ and rounding up the size. */
+ if (bitpos % BITS_PER_UNIT == 0
+ && bitsize % BITS_PER_UNIT == 0
+ && bitsize <= MAX_BITSIZE_MODE_ANY_MODE)
{
- unsigned char *b = XALLOCAVEC (unsigned char, clen);
- unsigned HOST_WIDE_INT len = native_encode_expr (arg0, b, clen);
+ unsigned char b[MAX_BITSIZE_MODE_ANY_MODE / BITS_PER_UNIT];
+ unsigned HOST_WIDE_INT len
+ = native_encode_expr (arg0, b, bitsize / BITS_PER_UNIT,
+ bitpos / BITS_PER_UNIT);
if (len > 0
- && len * BITS_PER_UNIT >= bitpos + bitsize)
+ && len * BITS_PER_UNIT >= bitsize)
{
- tree v = native_interpret_expr (type,
- b + bitpos / BITS_PER_UNIT,
+ tree v = native_interpret_expr (type, b,
bitsize / BITS_PER_UNIT);
if (v)
return v;