diff options
author | Richard Guenther <rguenther@suse.de> | 2008-03-26 12:37:29 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2008-03-26 12:37:29 +0000 |
commit | 4990038deffbd5f5e6453c42d82d23d030cc0634 (patch) | |
tree | 009a3001e6db5ff029f1ffacd768d9ef6a24e51a /gcc | |
parent | 813ab1d7df3a0c7c2de2c8e5c30ce6be69e0a6dd (diff) | |
download | gcc-4990038deffbd5f5e6453c42d82d23d030cc0634.zip gcc-4990038deffbd5f5e6453c42d82d23d030cc0634.tar.gz gcc-4990038deffbd5f5e6453c42d82d23d030cc0634.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/fold-const.c | 71 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/fold-addr-1.c | 10 |
4 files changed, 61 insertions, 34 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d31e6ad..e1f0e34 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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. diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 3bfe52e..4964ef7 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 6c8c190..64ffcb0 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,9 @@ 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. * gcc.dg/tree-ssa/20030917-1.c: Scan optimized dump. * gcc.dg/tree-ssa/20030917-3.c: Scan ccp1 dump. diff --git a/gcc/testsuite/gcc.dg/fold-addr-1.c b/gcc/testsuite/gcc.dg/fold-addr-1.c new file mode 100644 index 0000000..7323ffd --- /dev/null +++ b/gcc/testsuite/gcc.dg/fold-addr-1.c @@ -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" } } */ |