fold-const.c (distribute_bit_expr): Remove.
2015-07-10 Richard Biener <rguenther@suse.de> * fold-const.c (distribute_bit_expr): Remove. (fold_binary_loc): Move simplifying (A & C1) + (B & C2) to (A & C1) | (B & C2), distributing (A & B) | (A & C) to A & (B | C) and simplifying A << C1 << C2 to ... * match.pd: ... patterns here. From-SVN: r225670
This commit is contained in:
parent
53021678c5
commit
14ea9f9283
@ -1,3 +1,11 @@
|
||||
2015-07-10 Richard Biener <rguenther@suse.de>
|
||||
|
||||
* fold-const.c (distribute_bit_expr): Remove.
|
||||
(fold_binary_loc): Move simplifying (A & C1) + (B & C2)
|
||||
to (A & C1) | (B & C2), distributing (A & B) | (A & C)
|
||||
to A & (B | C) and simplifying A << C1 << C2 to ...
|
||||
* match.pd: ... patterns here.
|
||||
|
||||
2015-07-10 Jiong Wang <jiong.wang@arm.com>
|
||||
|
||||
* config/aarch64/aarch64.c (aarch64_load_symref_appropriately): Mark mem
|
||||
|
106
gcc/fold-const.c
106
gcc/fold-const.c
@ -118,7 +118,6 @@ static enum tree_code compcode_to_comparison (enum comparison_code);
|
||||
static int operand_equal_for_comparison_p (tree, tree, tree);
|
||||
static int twoval_comparison_p (tree, tree *, tree *, int *);
|
||||
static tree eval_subst (location_t, tree, tree, tree, tree, tree);
|
||||
static tree distribute_bit_expr (location_t, enum tree_code, tree, tree, tree);
|
||||
static tree make_bit_field_ref (location_t, tree, tree,
|
||||
HOST_WIDE_INT, HOST_WIDE_INT, int);
|
||||
static tree optimize_bit_field_compare (location_t, enum tree_code,
|
||||
@ -3550,62 +3549,6 @@ invert_truthvalue_loc (location_t loc, tree arg)
|
||||
type, arg);
|
||||
}
|
||||
|
||||
/* Given a bit-wise operation CODE applied to ARG0 and ARG1, see if both
|
||||
operands are another bit-wise operation with a common input. If so,
|
||||
distribute the bit operations to save an operation and possibly two if
|
||||
constants are involved. For example, convert
|
||||
(A | B) & (A | C) into A | (B & C)
|
||||
Further simplification will occur if B and C are constants.
|
||||
|
||||
If this optimization cannot be done, 0 will be returned. */
|
||||
|
||||
static tree
|
||||
distribute_bit_expr (location_t loc, enum tree_code code, tree type,
|
||||
tree arg0, tree arg1)
|
||||
{
|
||||
tree common;
|
||||
tree left, right;
|
||||
|
||||
if (TREE_CODE (arg0) != TREE_CODE (arg1)
|
||||
|| TREE_CODE (arg0) == code
|
||||
|| (TREE_CODE (arg0) != BIT_AND_EXPR
|
||||
&& TREE_CODE (arg0) != BIT_IOR_EXPR))
|
||||
return 0;
|
||||
|
||||
if (operand_equal_p (TREE_OPERAND (arg0, 0), TREE_OPERAND (arg1, 0), 0))
|
||||
{
|
||||
common = TREE_OPERAND (arg0, 0);
|
||||
left = TREE_OPERAND (arg0, 1);
|
||||
right = TREE_OPERAND (arg1, 1);
|
||||
}
|
||||
else if (operand_equal_p (TREE_OPERAND (arg0, 0), TREE_OPERAND (arg1, 1), 0))
|
||||
{
|
||||
common = TREE_OPERAND (arg0, 0);
|
||||
left = TREE_OPERAND (arg0, 1);
|
||||
right = TREE_OPERAND (arg1, 0);
|
||||
}
|
||||
else if (operand_equal_p (TREE_OPERAND (arg0, 1), TREE_OPERAND (arg1, 0), 0))
|
||||
{
|
||||
common = TREE_OPERAND (arg0, 1);
|
||||
left = TREE_OPERAND (arg0, 0);
|
||||
right = TREE_OPERAND (arg1, 1);
|
||||
}
|
||||
else if (operand_equal_p (TREE_OPERAND (arg0, 1), TREE_OPERAND (arg1, 1), 0))
|
||||
{
|
||||
common = TREE_OPERAND (arg0, 1);
|
||||
left = TREE_OPERAND (arg0, 0);
|
||||
right = TREE_OPERAND (arg1, 0);
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
|
||||
common = fold_convert_loc (loc, type, common);
|
||||
left = fold_convert_loc (loc, type, left);
|
||||
right = fold_convert_loc (loc, type, right);
|
||||
return fold_build2_loc (loc, TREE_CODE (arg0), type, common,
|
||||
fold_build2_loc (loc, code, type, left, right));
|
||||
}
|
||||
|
||||
/* Knowing that ARG0 and ARG1 are both RDIV_EXPRs, simplify a binary operation
|
||||
with code CODE. This optimization is unsafe. */
|
||||
static tree
|
||||
@ -9575,21 +9518,6 @@ fold_binary_loc (location_t loc,
|
||||
|
||||
if (! FLOAT_TYPE_P (type))
|
||||
{
|
||||
/* If we are adding two BIT_AND_EXPR's, both of which are and'ing
|
||||
with a constant, and the two constants have no bits in common,
|
||||
we should treat this as a BIT_IOR_EXPR since this may produce more
|
||||
simplifications. */
|
||||
if (TREE_CODE (arg0) == BIT_AND_EXPR
|
||||
&& TREE_CODE (arg1) == BIT_AND_EXPR
|
||||
&& TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST
|
||||
&& TREE_CODE (TREE_OPERAND (arg1, 1)) == INTEGER_CST
|
||||
&& wi::bit_and (TREE_OPERAND (arg0, 1),
|
||||
TREE_OPERAND (arg1, 1)) == 0)
|
||||
{
|
||||
code = BIT_IOR_EXPR;
|
||||
goto bit_ior;
|
||||
}
|
||||
|
||||
/* Reassociate (plus (plus (mult) (foo)) (mult)) as
|
||||
(plus (plus (mult) (mult)) (foo)) so that we can
|
||||
take advantage of the factoring cases below. */
|
||||
@ -10423,7 +10351,6 @@ fold_binary_loc (location_t loc,
|
||||
goto associate;
|
||||
|
||||
case BIT_IOR_EXPR:
|
||||
bit_ior:
|
||||
/* Canonicalize (X & C1) | C2. */
|
||||
if (TREE_CODE (arg0) == BIT_AND_EXPR
|
||||
&& TREE_CODE (arg1) == INTEGER_CST
|
||||
@ -10494,10 +10421,6 @@ fold_binary_loc (location_t loc,
|
||||
return fold_build2_loc (loc, BIT_XOR_EXPR, type, l0, n1);
|
||||
}
|
||||
|
||||
t1 = distribute_bit_expr (loc, code, type, arg0, arg1);
|
||||
if (t1 != NULL_TREE)
|
||||
return t1;
|
||||
|
||||
/* See if this can be simplified into a rotate first. If that
|
||||
is unsuccessful continue in the association code. */
|
||||
goto bit_rotate;
|
||||
@ -10760,9 +10683,6 @@ fold_binary_loc (location_t loc,
|
||||
}
|
||||
}
|
||||
|
||||
t1 = distribute_bit_expr (loc, code, type, arg0, arg1);
|
||||
if (t1 != NULL_TREE)
|
||||
return t1;
|
||||
/* Simplify ((int)c & 0377) into (int)c, if c is unsigned char. */
|
||||
if (TREE_CODE (arg1) == INTEGER_CST && TREE_CODE (arg0) == NOP_EXPR
|
||||
&& TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (arg0, 0))))
|
||||
@ -11111,32 +11031,6 @@ fold_binary_loc (location_t loc,
|
||||
|
||||
prec = element_precision (type);
|
||||
|
||||
/* Turn (a OP c1) OP c2 into a OP (c1+c2). */
|
||||
if (TREE_CODE (op0) == code && tree_fits_uhwi_p (arg1)
|
||||
&& tree_to_uhwi (arg1) < prec
|
||||
&& tree_fits_uhwi_p (TREE_OPERAND (arg0, 1))
|
||||
&& tree_to_uhwi (TREE_OPERAND (arg0, 1)) < prec)
|
||||
{
|
||||
unsigned int low = (tree_to_uhwi (TREE_OPERAND (arg0, 1))
|
||||
+ tree_to_uhwi (arg1));
|
||||
|
||||
/* Deal with a OP (c1 + c2) being undefined but (a OP c1) OP c2
|
||||
being well defined. */
|
||||
if (low >= prec)
|
||||
{
|
||||
if (code == LROTATE_EXPR || code == RROTATE_EXPR)
|
||||
low = low % prec;
|
||||
else if (TYPE_UNSIGNED (type) || code == LSHIFT_EXPR)
|
||||
return omit_one_operand_loc (loc, type, build_zero_cst (type),
|
||||
TREE_OPERAND (arg0, 0));
|
||||
else
|
||||
low = prec - 1;
|
||||
}
|
||||
|
||||
return fold_build2_loc (loc, code, type, TREE_OPERAND (arg0, 0),
|
||||
build_int_cst (TREE_TYPE (arg1), low));
|
||||
}
|
||||
|
||||
/* Transform (x >> c) << c into x & (-1<<c), or transform (x << c) >> c
|
||||
into x & ((unsigned)-1 >> c) for unsigned types. */
|
||||
if (((code == LSHIFT_EXPR && TREE_CODE (arg0) == RSHIFT_EXPR)
|
||||
|
51
gcc/match.pd
51
gcc/match.pd
@ -419,17 +419,18 @@ along with GCC; see the file COPYING3. If not see
|
||||
&& tree_nop_conversion_p (type, TREE_TYPE (@1)))
|
||||
(bit_not (rop (convert @0) (convert @1))))))
|
||||
|
||||
/* If we are XORing two BIT_AND_EXPR's, both of which are and'ing
|
||||
/* If we are XORing or adding two BIT_AND_EXPR's, both of which are and'ing
|
||||
with a constant, and the two constants have no bits in common,
|
||||
we should treat this as a BIT_IOR_EXPR since this may produce more
|
||||
simplifications. */
|
||||
(simplify
|
||||
(bit_xor (convert1? (bit_and@4 @0 INTEGER_CST@1))
|
||||
(convert2? (bit_and@5 @2 INTEGER_CST@3)))
|
||||
(if (tree_nop_conversion_p (type, TREE_TYPE (@0))
|
||||
&& tree_nop_conversion_p (type, TREE_TYPE (@2))
|
||||
&& wi::bit_and (@1, @3) == 0)
|
||||
(bit_ior (convert @4) (convert @5))))
|
||||
(for op (bit_xor plus)
|
||||
(simplify
|
||||
(op (convert1? (bit_and@4 @0 INTEGER_CST@1))
|
||||
(convert2? (bit_and@5 @2 INTEGER_CST@3)))
|
||||
(if (tree_nop_conversion_p (type, TREE_TYPE (@0))
|
||||
&& tree_nop_conversion_p (type, TREE_TYPE (@2))
|
||||
&& wi::bit_and (@1, @3) == 0)
|
||||
(bit_ior (convert @4) (convert @5)))))
|
||||
|
||||
/* (X | Y) ^ X -> Y & ~ X*/
|
||||
(simplify
|
||||
@ -455,6 +456,19 @@ along with GCC; see the file COPYING3. If not see
|
||||
(bit_xor:c (bit_and:c @0 @1) @1)
|
||||
(bit_and (bit_not @0) @1))
|
||||
|
||||
/* Given a bit-wise operation CODE applied to ARG0 and ARG1, see if both
|
||||
operands are another bit-wise operation with a common input. If so,
|
||||
distribute the bit operations to save an operation and possibly two if
|
||||
constants are involved. For example, convert
|
||||
(A | B) & (A | C) into A | (B & C)
|
||||
Further simplification will occur if B and C are constants. */
|
||||
(for op (bit_and bit_ior)
|
||||
rop (bit_ior bit_and)
|
||||
(simplify
|
||||
(op (convert? (rop:c @0 @1)) (convert? (rop @0 @2)))
|
||||
(if (tree_nop_conversion_p (type, TREE_TYPE (@0)))
|
||||
(rop (convert @0) (op (convert @1) (convert @2))))))
|
||||
|
||||
|
||||
(simplify
|
||||
(abs (abs@1 @0))
|
||||
@ -880,6 +894,27 @@ along with GCC; see the file COPYING3. If not see
|
||||
build_int_cst (TREE_TYPE (@1),
|
||||
element_precision (type)), @1); }))
|
||||
|
||||
/* Turn (a OP c1) OP c2 into a OP (c1+c2). */
|
||||
(for op (lrotate rrotate rshift lshift)
|
||||
(simplify
|
||||
(op (op @0 INTEGER_CST@1) INTEGER_CST@2)
|
||||
(with { unsigned int prec = element_precision (type); }
|
||||
(if (wi::ge_p (@1, 0, TYPE_SIGN (TREE_TYPE (@1)))
|
||||
&& wi::lt_p (@1, prec, TYPE_SIGN (TREE_TYPE (@1)))
|
||||
&& wi::ge_p (@2, 0, TYPE_SIGN (TREE_TYPE (@2)))
|
||||
&& wi::lt_p (@2, prec, TYPE_SIGN (TREE_TYPE (@2))))
|
||||
(with { unsigned int low = wi::add (@1, @2).to_uhwi (); }
|
||||
/* Deal with a OP (c1 + c2) being undefined but (a OP c1) OP c2
|
||||
being well defined. */
|
||||
(if (low >= prec)
|
||||
(if (op == LROTATE_EXPR || op == RROTATE_EXPR)
|
||||
(op @0 { build_int_cst (TREE_TYPE (@1), low % prec); }))
|
||||
(if (TYPE_UNSIGNED (type) || code == LSHIFT_EXPR)
|
||||
{ build_zero_cst (type); })
|
||||
(op @0 { build_int_cst (TREE_TYPE (@1), prec - 1); }))
|
||||
(op @0 { build_int_cst (TREE_TYPE (@1), low); }))))))
|
||||
|
||||
|
||||
/* ((1 << A) & 1) != 0 -> A == 0
|
||||
((1 << A) & 1) == 0 -> A != 0 */
|
||||
(for cmp (ne eq)
|
||||
|
Loading…
Reference in New Issue
Block a user