fold-const.c (target.h): Include.
2008-03-26 Richard Guenther <rguenther@suse.de> * fold-const.c (target.h): Include. (fold_comparison): Fold comparison of addresses of two decls that bind locally. Consolidate address folding code. * gcc.dg/fold-addr-1.c: New testcase. From-SVN: r133599
This commit is contained in:
parent
813ab1d7df
commit
4990038def
@ -1,3 +1,9 @@
|
||||
2008-03-26 Richard Guenther <rguenther@suse.de>
|
||||
|
||||
* fold-const.c (target.h): Include.
|
||||
(fold_comparison): Fold comparison of addresses of two decls
|
||||
that bind locally. Consolidate address folding code.
|
||||
|
||||
2008-03-26 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
PR target/31232
|
||||
@ -577,8 +583,8 @@
|
||||
2008-03-19 Richard Guenther <rguenther@suse.de>
|
||||
|
||||
PR middle-end/35609
|
||||
* tree-ssa.c (always_executed): New global flag.
|
||||
(warn_uninitialized_var): If !always_executed warn with "maybe"
|
||||
* tree-ssa.c (walk_data): New structure.
|
||||
(warn_uninitialized_var): If not always_executed warn with "maybe"
|
||||
instead of "is".
|
||||
(execute_early_warn_uninitialized): Compute post-dominators.
|
||||
Initialize always_executed before processing each basic block.
|
||||
|
@ -58,6 +58,7 @@ along with GCC; see the file COPYING3. If not see
|
||||
#include "rtl.h"
|
||||
#include "expr.h"
|
||||
#include "tm_p.h"
|
||||
#include "target.h"
|
||||
#include "toplev.h"
|
||||
#include "intl.h"
|
||||
#include "ggc.h"
|
||||
@ -8481,11 +8482,12 @@ fold_comparison (enum tree_code code, tree type, tree op0, tree op1)
|
||||
HOST_WIDE_INT bitsize, bitpos0 = 0, bitpos1 = 0;
|
||||
enum machine_mode mode;
|
||||
int volatilep, unsignedp;
|
||||
bool indirect_base0 = false;
|
||||
bool indirect_base0 = false, indirect_base1 = false;
|
||||
|
||||
/* Get base and offset for the access. Strip ADDR_EXPR for
|
||||
get_inner_reference, but put it back by stripping INDIRECT_REF
|
||||
off the base object if possible. */
|
||||
off the base object if possible. indirect_baseN will be true
|
||||
if baseN is not an address but refers to the object itself. */
|
||||
base0 = arg0;
|
||||
if (TREE_CODE (arg0) == ADDR_EXPR)
|
||||
{
|
||||
@ -8509,24 +8511,19 @@ fold_comparison (enum tree_code code, tree type, tree op0, tree op1)
|
||||
base1 = get_inner_reference (TREE_OPERAND (arg1, 0),
|
||||
&bitsize, &bitpos1, &offset1, &mode,
|
||||
&unsignedp, &volatilep, false);
|
||||
/* We have to make sure to have an indirect/non-indirect base1
|
||||
just the same as we did for base0. */
|
||||
if (TREE_CODE (base1) == INDIRECT_REF
|
||||
&& !indirect_base0)
|
||||
if (TREE_CODE (base1) == INDIRECT_REF)
|
||||
base1 = TREE_OPERAND (base1, 0);
|
||||
else if (!indirect_base0)
|
||||
base1 = NULL_TREE;
|
||||
else
|
||||
indirect_base1 = true;
|
||||
}
|
||||
else if (TREE_CODE (arg1) == POINTER_PLUS_EXPR)
|
||||
{
|
||||
base1 = TREE_OPERAND (arg1, 0);
|
||||
offset1 = TREE_OPERAND (arg1, 1);
|
||||
}
|
||||
else if (indirect_base0)
|
||||
base1 = NULL_TREE;
|
||||
|
||||
/* If we have equivalent bases we might be able to simplify. */
|
||||
if (base0 && base1
|
||||
if (indirect_base0 == indirect_base1
|
||||
&& operand_equal_p (base0, base1, 0))
|
||||
{
|
||||
/* We can fold this expression to a constant if the non-constant
|
||||
@ -8581,6 +8578,37 @@ fold_comparison (enum tree_code code, tree type, tree op0, tree op1)
|
||||
return fold_build2 (code, type, offset0, offset1);
|
||||
}
|
||||
}
|
||||
/* For non-equal bases we can simplify if they are plain decls. */
|
||||
else if (!indirect_base0 && !indirect_base1
|
||||
&& TREE_CODE (arg0) == ADDR_EXPR
|
||||
&& TREE_CODE (arg1) == ADDR_EXPR
|
||||
&& DECL_P (base0) && DECL_P (base1)
|
||||
&& !operand_equal_p (base0, base1, 0)
|
||||
&& targetm.binds_local_p (base0)
|
||||
&& targetm.binds_local_p (base1))
|
||||
{
|
||||
if (code == EQ_EXPR)
|
||||
return omit_two_operands (type, boolean_false_node, arg0, arg1);
|
||||
else if (code == NE_EXPR)
|
||||
return omit_two_operands (type, boolean_true_node, arg0, arg1);
|
||||
}
|
||||
/* For equal offsets we can simplify to a comparison of the
|
||||
base addresses. */
|
||||
else if (bitpos0 == bitpos1
|
||||
&& (indirect_base0
|
||||
? base0 != TREE_OPERAND (arg0, 0) : base0 != arg0)
|
||||
&& (indirect_base1
|
||||
? base1 != TREE_OPERAND (arg1, 0) : base1 != arg1)
|
||||
&& ((offset0 == offset1)
|
||||
|| (offset0 && offset1
|
||||
&& operand_equal_p (offset0, offset1, 0))))
|
||||
{
|
||||
if (indirect_base0)
|
||||
base0 = fold_addr_expr (base0);
|
||||
if (indirect_base1)
|
||||
base1 = fold_addr_expr (base1);
|
||||
return fold_build2 (code, type, base0, base1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Transform comparisons of the form X +- C1 CMP Y +- C2 to
|
||||
@ -8927,27 +8955,6 @@ fold_comparison (enum tree_code code, tree type, tree op0, tree op1)
|
||||
}
|
||||
}
|
||||
|
||||
/* Fold a comparison of the address of COMPONENT_REFs with the same
|
||||
type and component to a comparison of the address of the base
|
||||
object. In short, &x->a OP &y->a to x OP y and
|
||||
&x->a OP &y.a to x OP &y */
|
||||
if (TREE_CODE (arg0) == ADDR_EXPR
|
||||
&& TREE_CODE (TREE_OPERAND (arg0, 0)) == COMPONENT_REF
|
||||
&& TREE_CODE (arg1) == ADDR_EXPR
|
||||
&& TREE_CODE (TREE_OPERAND (arg1, 0)) == COMPONENT_REF)
|
||||
{
|
||||
tree cref0 = TREE_OPERAND (arg0, 0);
|
||||
tree cref1 = TREE_OPERAND (arg1, 0);
|
||||
if (TREE_OPERAND (cref0, 1) == TREE_OPERAND (cref1, 1))
|
||||
{
|
||||
tree op0 = TREE_OPERAND (cref0, 0);
|
||||
tree op1 = TREE_OPERAND (cref1, 0);
|
||||
return fold_build2 (code, type,
|
||||
fold_addr_expr (op0),
|
||||
fold_addr_expr (op1));
|
||||
}
|
||||
}
|
||||
|
||||
/* We can fold X/C1 op C2 where C1 and C2 are integer constants
|
||||
into a single range test. */
|
||||
if ((TREE_CODE (arg0) == TRUNC_DIV_EXPR
|
||||
|
@ -1,3 +1,7 @@
|
||||
2008-03-26 Richard Guenther <rguenther@suse.de>
|
||||
|
||||
* gcc.dg/fold-addr-1.c: New testcase.
|
||||
|
||||
2008-03-26 Richard Guenther <rguenther@suse.de>
|
||||
|
||||
* gcc.dg/tree-ssa/20030731-2.c: Scan dce1 dump.
|
||||
|
10
gcc/testsuite/gcc.dg/fold-addr-1.c
Normal file
10
gcc/testsuite/gcc.dg/fold-addr-1.c
Normal file
@ -0,0 +1,10 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-fdump-tree-original" } */
|
||||
|
||||
int bar(char p1, char p2)
|
||||
{
|
||||
return &p1 == &p2;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-tree-dump "return 0;" "original" } } */
|
||||
/* { dg-final { cleanup-tree-dump "original" } } */
|
Loading…
Reference in New Issue
Block a user