fold-const.h (const_unop): Declare.
2014-11-26 Richard Biener <rguenther@suse.de> * fold-const.h (const_unop): Declare. (const_binop): Likewise. * fold-const.c (const_binop): Export overload that expects a type parameter and dispatches to fold_relational_const as well. Check both operand kinds for guarding the transforms. (const_unop): New function, with constant folding from fold_unary_loc. (fold_unary_loc): Dispatch to const_unop for tcc_constant operand. Remove constant folding done there from the simplifications. (fold_binary_loc): Check for constants using CONSTANT_CLASS_P. (fold_negate_expr): Remove dead code from the REAL_CST case. Avoid building garbage in the COMPLEX_CST case. * gimple-match-head.c (gimple_resimplify1): Dispatch to const_unop. (gimple_resimplify2): Dispatch to const_binop. (gimple_simplify): Likewise. From-SVN: r218086
This commit is contained in:
parent
4186636315
commit
8006f46bdd
@ -1,3 +1,21 @@
|
||||
2014-11-26 Richard Biener <rguenther@suse.de>
|
||||
|
||||
* fold-const.h (const_unop): Declare.
|
||||
(const_binop): Likewise.
|
||||
* fold-const.c (const_binop): Export overload that expects
|
||||
a type parameter and dispatches to fold_relational_const as well.
|
||||
Check both operand kinds for guarding the transforms.
|
||||
(const_unop): New function, with constant folding from fold_unary_loc.
|
||||
(fold_unary_loc): Dispatch to const_unop for tcc_constant operand.
|
||||
Remove constant folding done there from the simplifications.
|
||||
(fold_binary_loc): Check for constants using CONSTANT_CLASS_P.
|
||||
(fold_negate_expr): Remove dead code from the REAL_CST case.
|
||||
Avoid building garbage in the COMPLEX_CST case.
|
||||
* gimple-match-head.c (gimple_resimplify1): Dispatch to
|
||||
const_unop.
|
||||
(gimple_resimplify2): Dispatch to const_binop.
|
||||
(gimple_simplify): Likewise.
|
||||
|
||||
2014-11-26 Ilya Enkovich <ilya.enkovich@intel.com>
|
||||
|
||||
PR bootstrap/63995
|
||||
|
355
gcc/fold-const.c
355
gcc/fold-const.c
@ -115,7 +115,6 @@ static bool negate_expr_p (tree);
|
||||
static tree negate_expr (tree);
|
||||
static tree split_tree (tree, enum tree_code, tree *, tree *, tree *, int);
|
||||
static tree associate_trees (location_t, tree, tree, enum tree_code, tree);
|
||||
static tree const_binop (enum tree_code, tree, tree);
|
||||
static enum comparison_code comparison_to_compcode (enum tree_code);
|
||||
static enum tree_code compcode_to_comparison (enum comparison_code);
|
||||
static int operand_equal_for_comparison_p (tree, tree, tree);
|
||||
@ -156,6 +155,9 @@ static tree fold_negate_const (tree, tree);
|
||||
static tree fold_not_const (const_tree, tree);
|
||||
static tree fold_relational_const (enum tree_code, tree, tree, tree);
|
||||
static tree fold_convert_const (enum tree_code, tree, tree);
|
||||
static tree fold_view_convert_expr (tree, tree);
|
||||
static bool vec_cst_ctor_to_array (tree, tree *);
|
||||
|
||||
|
||||
/* Return EXPR_LOCATION of T if it is not UNKNOWN_LOCATION.
|
||||
Otherwise, return LOC. */
|
||||
@ -564,10 +566,7 @@ fold_negate_expr (location_t loc, tree t)
|
||||
|
||||
case REAL_CST:
|
||||
tem = fold_negate_const (t, type);
|
||||
/* Two's complement FP formats, such as c4x, may overflow. */
|
||||
if (!TREE_OVERFLOW (tem) || !flag_trapping_math)
|
||||
return tem;
|
||||
break;
|
||||
return tem;
|
||||
|
||||
case FIXED_CST:
|
||||
tem = fold_negate_const (t, type);
|
||||
@ -575,13 +574,9 @@ fold_negate_expr (location_t loc, tree t)
|
||||
|
||||
case COMPLEX_CST:
|
||||
{
|
||||
tree rpart = negate_expr (TREE_REALPART (t));
|
||||
tree ipart = negate_expr (TREE_IMAGPART (t));
|
||||
|
||||
if ((TREE_CODE (rpart) == REAL_CST
|
||||
&& TREE_CODE (ipart) == REAL_CST)
|
||||
|| (TREE_CODE (rpart) == INTEGER_CST
|
||||
&& TREE_CODE (ipart) == INTEGER_CST))
|
||||
tree rpart = fold_negate_expr (loc, TREE_REALPART (t));
|
||||
tree ipart = fold_negate_expr (loc, TREE_IMAGPART (t));
|
||||
if (rpart && ipart)
|
||||
return build_complex (type, rpart, ipart);
|
||||
}
|
||||
break;
|
||||
@ -1138,10 +1133,10 @@ const_binop (enum tree_code code, tree arg1, tree arg2)
|
||||
STRIP_NOPS (arg1);
|
||||
STRIP_NOPS (arg2);
|
||||
|
||||
if (TREE_CODE (arg1) == INTEGER_CST)
|
||||
if (TREE_CODE (arg1) == INTEGER_CST && TREE_CODE (arg2) == INTEGER_CST)
|
||||
return int_const_binop (code, arg1, arg2);
|
||||
|
||||
if (TREE_CODE (arg1) == REAL_CST)
|
||||
if (TREE_CODE (arg1) == REAL_CST && TREE_CODE (arg2) == REAL_CST)
|
||||
{
|
||||
machine_mode mode;
|
||||
REAL_VALUE_TYPE d1;
|
||||
@ -1219,7 +1214,7 @@ const_binop (enum tree_code code, tree arg1, tree arg2)
|
||||
return t;
|
||||
}
|
||||
|
||||
if (TREE_CODE (arg1) == FIXED_CST)
|
||||
if (TREE_CODE (arg1) == FIXED_CST && TREE_CODE (arg2) == FIXED_CST)
|
||||
{
|
||||
FIXED_VALUE_TYPE f1;
|
||||
FIXED_VALUE_TYPE f2;
|
||||
@ -1263,7 +1258,7 @@ const_binop (enum tree_code code, tree arg1, tree arg2)
|
||||
return t;
|
||||
}
|
||||
|
||||
if (TREE_CODE (arg1) == COMPLEX_CST)
|
||||
if (TREE_CODE (arg1) == COMPLEX_CST && TREE_CODE (arg2) == COMPLEX_CST)
|
||||
{
|
||||
tree type = TREE_TYPE (arg1);
|
||||
tree r1 = TREE_REALPART (arg1);
|
||||
@ -1440,6 +1435,179 @@ const_binop (enum tree_code code, tree arg1, tree arg2)
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
/* Overload that adds a TYPE parameter to be able to dispatch
|
||||
to fold_relational_const. */
|
||||
|
||||
tree
|
||||
const_binop (enum tree_code code, tree type, tree arg1, tree arg2)
|
||||
{
|
||||
if (TREE_CODE_CLASS (code) == tcc_comparison)
|
||||
return fold_relational_const (code, type, arg1, arg2);
|
||||
else
|
||||
return const_binop (code, arg1, arg2);
|
||||
}
|
||||
|
||||
/* Compute CODE ARG1 with resulting type TYPE with ARG1 being constant.
|
||||
Return zero if computing the constants is not possible. */
|
||||
|
||||
tree
|
||||
const_unop (enum tree_code code, tree type, tree arg0)
|
||||
{
|
||||
switch (code)
|
||||
{
|
||||
CASE_CONVERT:
|
||||
case FLOAT_EXPR:
|
||||
case FIX_TRUNC_EXPR:
|
||||
case FIXED_CONVERT_EXPR:
|
||||
return fold_convert_const (code, type, arg0);
|
||||
|
||||
case ADDR_SPACE_CONVERT_EXPR:
|
||||
if (integer_zerop (arg0))
|
||||
return fold_convert_const (code, type, arg0);
|
||||
break;
|
||||
|
||||
case VIEW_CONVERT_EXPR:
|
||||
return fold_view_convert_expr (type, arg0);
|
||||
|
||||
case NEGATE_EXPR:
|
||||
{
|
||||
/* Can't call fold_negate_const directly here as that doesn't
|
||||
handle all cases and we might not be able to negate some
|
||||
constants. */
|
||||
tree tem = fold_negate_expr (UNKNOWN_LOCATION, arg0);
|
||||
if (tem && CONSTANT_CLASS_P (tem))
|
||||
return tem;
|
||||
break;
|
||||
}
|
||||
|
||||
case ABS_EXPR:
|
||||
return fold_abs_const (arg0, type);
|
||||
|
||||
case CONJ_EXPR:
|
||||
if (TREE_CODE (arg0) == COMPLEX_CST)
|
||||
{
|
||||
tree ipart = fold_negate_const (TREE_IMAGPART (arg0),
|
||||
TREE_TYPE (type));
|
||||
return build_complex (type, TREE_REALPART (arg0), ipart);
|
||||
}
|
||||
break;
|
||||
|
||||
case BIT_NOT_EXPR:
|
||||
if (TREE_CODE (arg0) == INTEGER_CST)
|
||||
return fold_not_const (arg0, type);
|
||||
/* Perform BIT_NOT_EXPR on each element individually. */
|
||||
else if (TREE_CODE (arg0) == VECTOR_CST)
|
||||
{
|
||||
tree *elements;
|
||||
tree elem;
|
||||
unsigned count = VECTOR_CST_NELTS (arg0), i;
|
||||
|
||||
elements = XALLOCAVEC (tree, count);
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
elem = VECTOR_CST_ELT (arg0, i);
|
||||
elem = const_unop (BIT_NOT_EXPR, TREE_TYPE (type), elem);
|
||||
if (elem == NULL_TREE)
|
||||
break;
|
||||
elements[i] = elem;
|
||||
}
|
||||
if (i == count)
|
||||
return build_vector (type, elements);
|
||||
}
|
||||
break;
|
||||
|
||||
case TRUTH_NOT_EXPR:
|
||||
if (TREE_CODE (arg0) == INTEGER_CST)
|
||||
return constant_boolean_node (integer_zerop (arg0), type);
|
||||
break;
|
||||
|
||||
case REALPART_EXPR:
|
||||
if (TREE_CODE (arg0) == COMPLEX_CST)
|
||||
return fold_convert (type, TREE_REALPART (arg0));
|
||||
break;
|
||||
|
||||
case IMAGPART_EXPR:
|
||||
if (TREE_CODE (arg0) == COMPLEX_CST)
|
||||
return fold_convert (type, TREE_IMAGPART (arg0));
|
||||
break;
|
||||
|
||||
case VEC_UNPACK_LO_EXPR:
|
||||
case VEC_UNPACK_HI_EXPR:
|
||||
case VEC_UNPACK_FLOAT_LO_EXPR:
|
||||
case VEC_UNPACK_FLOAT_HI_EXPR:
|
||||
{
|
||||
unsigned int nelts = TYPE_VECTOR_SUBPARTS (type), 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);
|
||||
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;
|
||||
|
||||
if (code == VEC_UNPACK_LO_EXPR || code == VEC_UNPACK_HI_EXPR)
|
||||
subcode = NOP_EXPR;
|
||||
else
|
||||
subcode = FLOAT_EXPR;
|
||||
|
||||
for (i = 0; i < nelts; i++)
|
||||
{
|
||||
elts[i] = fold_convert_const (subcode, TREE_TYPE (type), elts[i]);
|
||||
if (elts[i] == NULL_TREE || !CONSTANT_CLASS_P (elts[i]))
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
return build_vector (type, elts);
|
||||
}
|
||||
|
||||
case REDUC_MIN_EXPR:
|
||||
case REDUC_MAX_EXPR:
|
||||
case REDUC_PLUS_EXPR:
|
||||
{
|
||||
unsigned int nelts, i;
|
||||
tree *elts;
|
||||
enum tree_code subcode;
|
||||
|
||||
if (TREE_CODE (arg0) != VECTOR_CST)
|
||||
return NULL_TREE;
|
||||
nelts = TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0));
|
||||
|
||||
elts = XALLOCAVEC (tree, nelts);
|
||||
if (!vec_cst_ctor_to_array (arg0, elts))
|
||||
return NULL_TREE;
|
||||
|
||||
switch (code)
|
||||
{
|
||||
case REDUC_MIN_EXPR: subcode = MIN_EXPR; break;
|
||||
case REDUC_MAX_EXPR: subcode = MAX_EXPR; break;
|
||||
case REDUC_PLUS_EXPR: subcode = PLUS_EXPR; break;
|
||||
default: gcc_unreachable ();
|
||||
}
|
||||
|
||||
for (i = 1; i < nelts; i++)
|
||||
{
|
||||
elts[0] = const_binop (subcode, elts[0], elts[i]);
|
||||
if (elts[0] == NULL_TREE || !CONSTANT_CLASS_P (elts[0]))
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
return elts[0];
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
/* Create a sizetype INT_CST node with NUMBER sign extended. KIND
|
||||
indicates which particular sizetype to create. */
|
||||
|
||||
@ -7507,8 +7675,6 @@ build_fold_addr_expr_loc (location_t loc, tree t)
|
||||
return build_fold_addr_expr_with_type_loc (loc, t, ptrtype);
|
||||
}
|
||||
|
||||
static bool vec_cst_ctor_to_array (tree, tree *);
|
||||
|
||||
/* Fold a unary expression of code CODE and type TYPE with operand
|
||||
OP0. Return the folded expression if folding is successful.
|
||||
Otherwise, return NULL_TREE. */
|
||||
@ -7523,10 +7689,6 @@ fold_unary_loc (location_t loc, enum tree_code code, tree type, tree op0)
|
||||
gcc_assert (IS_EXPR_CODE_CLASS (kind)
|
||||
&& TREE_CODE_LENGTH (code) == 1);
|
||||
|
||||
tem = generic_simplify (loc, code, type, op0);
|
||||
if (tem)
|
||||
return tem;
|
||||
|
||||
arg0 = op0;
|
||||
if (arg0)
|
||||
{
|
||||
@ -7552,8 +7714,23 @@ fold_unary_loc (location_t loc, enum tree_code code, tree type, tree op0)
|
||||
constant folder. */
|
||||
STRIP_NOPS (arg0);
|
||||
}
|
||||
|
||||
if (CONSTANT_CLASS_P (arg0))
|
||||
{
|
||||
tree tem = const_unop (code, type, arg0);
|
||||
if (tem)
|
||||
{
|
||||
if (TREE_TYPE (tem) != type)
|
||||
tem = fold_convert_loc (loc, type, tem);
|
||||
return tem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tem = generic_simplify (loc, code, type, op0);
|
||||
if (tem)
|
||||
return tem;
|
||||
|
||||
if (TREE_CODE_CLASS (code) == tcc_unary)
|
||||
{
|
||||
if (TREE_CODE (arg0) == COMPOUND_EXPR)
|
||||
@ -7790,24 +7967,14 @@ fold_unary_loc (location_t loc, enum tree_code code, tree type, tree op0)
|
||||
}
|
||||
}
|
||||
|
||||
tem = fold_convert_const (code, type, arg0);
|
||||
return tem ? tem : NULL_TREE;
|
||||
|
||||
case ADDR_SPACE_CONVERT_EXPR:
|
||||
if (integer_zerop (arg0))
|
||||
return fold_convert_const (code, type, arg0);
|
||||
return NULL_TREE;
|
||||
|
||||
case FIXED_CONVERT_EXPR:
|
||||
tem = fold_convert_const (code, type, arg0);
|
||||
return tem ? tem : NULL_TREE;
|
||||
|
||||
case VIEW_CONVERT_EXPR:
|
||||
if (TREE_CODE (op0) == MEM_REF)
|
||||
return fold_build2_loc (loc, MEM_REF, type,
|
||||
TREE_OPERAND (op0, 0), TREE_OPERAND (op0, 1));
|
||||
|
||||
return fold_view_convert_expr (type, op0);
|
||||
return NULL_TREE;
|
||||
|
||||
case NEGATE_EXPR:
|
||||
tem = fold_negate_expr (loc, arg0);
|
||||
@ -7816,11 +7983,9 @@ fold_unary_loc (location_t loc, enum tree_code code, tree type, tree op0)
|
||||
return NULL_TREE;
|
||||
|
||||
case ABS_EXPR:
|
||||
if (TREE_CODE (arg0) == INTEGER_CST || TREE_CODE (arg0) == REAL_CST)
|
||||
return fold_abs_const (arg0, type);
|
||||
/* Convert fabs((double)float) into (double)fabsf(float). */
|
||||
else if (TREE_CODE (arg0) == NOP_EXPR
|
||||
&& TREE_CODE (type) == REAL_TYPE)
|
||||
if (TREE_CODE (arg0) == NOP_EXPR
|
||||
&& TREE_CODE (type) == REAL_TYPE)
|
||||
{
|
||||
tree targ0 = strip_float_extensions (arg0);
|
||||
if (targ0 != arg0)
|
||||
@ -7854,22 +8019,13 @@ fold_unary_loc (location_t loc, enum tree_code code, tree type, tree op0)
|
||||
return fold_build2_loc (loc, COMPLEX_EXPR, type, rpart,
|
||||
negate_expr (ipart));
|
||||
}
|
||||
if (TREE_CODE (arg0) == COMPLEX_CST)
|
||||
{
|
||||
tree itype = TREE_TYPE (type);
|
||||
tree rpart = fold_convert_loc (loc, itype, TREE_REALPART (arg0));
|
||||
tree ipart = fold_convert_loc (loc, itype, TREE_IMAGPART (arg0));
|
||||
return build_complex (type, rpart, negate_expr (ipart));
|
||||
}
|
||||
if (TREE_CODE (arg0) == CONJ_EXPR)
|
||||
return fold_convert_loc (loc, type, TREE_OPERAND (arg0, 0));
|
||||
return NULL_TREE;
|
||||
|
||||
case BIT_NOT_EXPR:
|
||||
if (TREE_CODE (arg0) == INTEGER_CST)
|
||||
return fold_not_const (arg0, type);
|
||||
/* Convert ~ (-A) to A - 1. */
|
||||
else if (INTEGRAL_TYPE_P (type) && TREE_CODE (arg0) == NEGATE_EXPR)
|
||||
if (INTEGRAL_TYPE_P (type) && TREE_CODE (arg0) == NEGATE_EXPR)
|
||||
return fold_build2_loc (loc, MINUS_EXPR, type,
|
||||
fold_convert_loc (loc, type, TREE_OPERAND (arg0, 0)),
|
||||
build_int_cst (type, 1));
|
||||
@ -7897,25 +8053,6 @@ fold_unary_loc (location_t loc, enum tree_code code, tree type, tree op0)
|
||||
return fold_build2_loc (loc, BIT_XOR_EXPR, type,
|
||||
fold_convert_loc (loc, type,
|
||||
TREE_OPERAND (arg0, 0)), tem);
|
||||
/* Perform BIT_NOT_EXPR on each element individually. */
|
||||
else if (TREE_CODE (arg0) == VECTOR_CST)
|
||||
{
|
||||
tree *elements;
|
||||
tree elem;
|
||||
unsigned count = VECTOR_CST_NELTS (arg0), i;
|
||||
|
||||
elements = XALLOCAVEC (tree, count);
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
elem = VECTOR_CST_ELT (arg0, i);
|
||||
elem = fold_unary_loc (loc, BIT_NOT_EXPR, TREE_TYPE (type), elem);
|
||||
if (elem == NULL_TREE)
|
||||
break;
|
||||
elements[i] = elem;
|
||||
}
|
||||
if (i == count)
|
||||
return build_vector (type, elements);
|
||||
}
|
||||
|
||||
return NULL_TREE;
|
||||
|
||||
@ -7932,8 +8069,6 @@ fold_unary_loc (location_t loc, enum tree_code code, tree type, tree op0)
|
||||
case REALPART_EXPR:
|
||||
if (TREE_CODE (TREE_TYPE (arg0)) != COMPLEX_TYPE)
|
||||
return fold_convert_loc (loc, type, arg0);
|
||||
if (TREE_CODE (arg0) == COMPLEX_CST)
|
||||
return fold_convert_loc (loc, type, TREE_REALPART (arg0));
|
||||
if (TREE_CODE (arg0) == PLUS_EXPR || TREE_CODE (arg0) == MINUS_EXPR)
|
||||
{
|
||||
tree itype = TREE_TYPE (TREE_TYPE (arg0));
|
||||
@ -7972,8 +8107,6 @@ fold_unary_loc (location_t loc, enum tree_code code, tree type, tree op0)
|
||||
case IMAGPART_EXPR:
|
||||
if (TREE_CODE (TREE_TYPE (arg0)) != COMPLEX_TYPE)
|
||||
return build_zero_cst (type);
|
||||
if (TREE_CODE (arg0) == COMPLEX_CST)
|
||||
return fold_convert_loc (loc, type, TREE_IMAGPART (arg0));
|
||||
if (TREE_CODE (arg0) == PLUS_EXPR || TREE_CODE (arg0) == MINUS_EXPR)
|
||||
{
|
||||
tree itype = TREE_TYPE (TREE_TYPE (arg0));
|
||||
@ -8021,76 +8154,6 @@ fold_unary_loc (location_t loc, enum tree_code code, tree type, tree op0)
|
||||
}
|
||||
return NULL_TREE;
|
||||
|
||||
case VEC_UNPACK_LO_EXPR:
|
||||
case VEC_UNPACK_HI_EXPR:
|
||||
case VEC_UNPACK_FLOAT_LO_EXPR:
|
||||
case VEC_UNPACK_FLOAT_HI_EXPR:
|
||||
{
|
||||
unsigned int nelts = TYPE_VECTOR_SUBPARTS (type), 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);
|
||||
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;
|
||||
|
||||
if (code == VEC_UNPACK_LO_EXPR || code == VEC_UNPACK_HI_EXPR)
|
||||
subcode = NOP_EXPR;
|
||||
else
|
||||
subcode = FLOAT_EXPR;
|
||||
|
||||
for (i = 0; i < nelts; i++)
|
||||
{
|
||||
elts[i] = fold_convert_const (subcode, TREE_TYPE (type), elts[i]);
|
||||
if (elts[i] == NULL_TREE || !CONSTANT_CLASS_P (elts[i]))
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
return build_vector (type, elts);
|
||||
}
|
||||
|
||||
case REDUC_MIN_EXPR:
|
||||
case REDUC_MAX_EXPR:
|
||||
case REDUC_PLUS_EXPR:
|
||||
{
|
||||
unsigned int nelts, i;
|
||||
tree *elts;
|
||||
enum tree_code subcode;
|
||||
|
||||
if (TREE_CODE (op0) != VECTOR_CST)
|
||||
return NULL_TREE;
|
||||
nelts = TYPE_VECTOR_SUBPARTS (TREE_TYPE (op0));
|
||||
|
||||
elts = XALLOCAVEC (tree, nelts);
|
||||
if (!vec_cst_ctor_to_array (op0, elts))
|
||||
return NULL_TREE;
|
||||
|
||||
switch (code)
|
||||
{
|
||||
case REDUC_MIN_EXPR: subcode = MIN_EXPR; break;
|
||||
case REDUC_MAX_EXPR: subcode = MAX_EXPR; break;
|
||||
case REDUC_PLUS_EXPR: subcode = PLUS_EXPR; break;
|
||||
default: gcc_unreachable ();
|
||||
}
|
||||
|
||||
for (i = 1; i < nelts; i++)
|
||||
{
|
||||
elts[0] = const_binop (subcode, elts[0], elts[i]);
|
||||
if (elts[0] == NULL_TREE || !CONSTANT_CLASS_P (elts[0]))
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
return elts[0];
|
||||
}
|
||||
|
||||
default:
|
||||
return NULL_TREE;
|
||||
} /* switch (code) */
|
||||
@ -9689,19 +9752,13 @@ fold_binary_loc (location_t loc,
|
||||
|
||||
/* Note that TREE_CONSTANT isn't enough: static var addresses are
|
||||
constant but we can't do arithmetic on them. */
|
||||
if ((TREE_CODE (arg0) == INTEGER_CST && TREE_CODE (arg1) == INTEGER_CST)
|
||||
|| (TREE_CODE (arg0) == REAL_CST && TREE_CODE (arg1) == REAL_CST)
|
||||
|| (TREE_CODE (arg0) == FIXED_CST && TREE_CODE (arg1) == FIXED_CST)
|
||||
|| (TREE_CODE (arg0) == FIXED_CST && TREE_CODE (arg1) == INTEGER_CST)
|
||||
|| (TREE_CODE (arg0) == COMPLEX_CST && TREE_CODE (arg1) == COMPLEX_CST)
|
||||
|| (TREE_CODE (arg0) == VECTOR_CST && TREE_CODE (arg1) == VECTOR_CST)
|
||||
|| (TREE_CODE (arg0) == VECTOR_CST && TREE_CODE (arg1) == INTEGER_CST))
|
||||
if (CONSTANT_CLASS_P (arg0) && CONSTANT_CLASS_P (arg1))
|
||||
{
|
||||
if (kind == tcc_binary)
|
||||
{
|
||||
/* Make sure type and arg0 have the same saturating flag. */
|
||||
gcc_assert (TYPE_SATURATING (type)
|
||||
== TYPE_SATURATING (TREE_TYPE (arg0)));
|
||||
gcc_checking_assert (TYPE_SATURATING (type)
|
||||
== TYPE_SATURATING (TREE_TYPE (arg0)));
|
||||
tem = const_binop (code, arg0, arg1);
|
||||
}
|
||||
else if (kind == tcc_comparison)
|
||||
|
@ -169,5 +169,7 @@ extern bool merge_ranges (int *, tree *, tree *, int, tree, tree, int,
|
||||
tree, tree);
|
||||
extern tree sign_bit_p (tree, const_tree);
|
||||
extern tree exact_inverse (tree, tree);
|
||||
extern tree const_unop (enum tree_code, tree, tree);
|
||||
extern tree const_binop (enum tree_code, tree, tree, tree);
|
||||
|
||||
#endif // GCC_FOLD_CONST_H
|
||||
|
@ -94,7 +94,7 @@ gimple_resimplify1 (gimple_seq *seq,
|
||||
{
|
||||
tree tem = NULL_TREE;
|
||||
if (res_code->is_tree_code ())
|
||||
tem = fold_unary_to_constant (*res_code, type, res_ops[0]);
|
||||
tem = const_unop (*res_code, type, res_ops[0]);
|
||||
else
|
||||
{
|
||||
tree decl = builtin_decl_implicit (*res_code);
|
||||
@ -150,8 +150,7 @@ gimple_resimplify2 (gimple_seq *seq,
|
||||
{
|
||||
tree tem = NULL_TREE;
|
||||
if (res_code->is_tree_code ())
|
||||
tem = fold_binary_to_constant (*res_code, type,
|
||||
res_ops[0], res_ops[1]);
|
||||
tem = const_binop (*res_code, type, res_ops[0], res_ops[1]);
|
||||
else
|
||||
{
|
||||
tree decl = builtin_decl_implicit (*res_code);
|
||||
@ -386,7 +385,7 @@ gimple_simplify (enum tree_code code, tree type,
|
||||
{
|
||||
if (constant_for_folding (op0))
|
||||
{
|
||||
tree res = fold_unary_to_constant (code, type, op0);
|
||||
tree res = const_unop (code, type, op0);
|
||||
if (res != NULL_TREE
|
||||
&& CONSTANT_CLASS_P (res))
|
||||
return res;
|
||||
@ -409,7 +408,7 @@ gimple_simplify (enum tree_code code, tree type,
|
||||
{
|
||||
if (constant_for_folding (op0) && constant_for_folding (op1))
|
||||
{
|
||||
tree res = fold_binary_to_constant (code, type, op0, op1);
|
||||
tree res = const_binop (code, type, op0, op1);
|
||||
if (res != NULL_TREE
|
||||
&& CONSTANT_CLASS_P (res))
|
||||
return res;
|
||||
|
Loading…
x
Reference in New Issue
Block a user