From 4990038deffbd5f5e6453c42d82d23d030cc0634 Mon Sep 17 00:00:00 2001 From: Richard Guenther Date: Wed, 26 Mar 2008 12:37:29 +0000 Subject: [PATCH] fold-const.c (target.h): Include. 2008-03-26 Richard Guenther * 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 --- gcc/ChangeLog | 10 ++++- gcc/fold-const.c | 71 ++++++++++++++++-------------- gcc/testsuite/ChangeLog | 4 ++ gcc/testsuite/gcc.dg/fold-addr-1.c | 10 +++++ 4 files changed, 61 insertions(+), 34 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/fold-addr-1.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d31e6adbe14..e1f0e34f2eb 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2008-03-26 Richard Guenther + + * 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 PR target/31232 @@ -577,8 +583,8 @@ 2008-03-19 Richard Guenther 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 3bfe52e0081..4964ef7b525 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 6c8c1902efd..64ffcb07fca 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2008-03-26 Richard Guenther + + * gcc.dg/fold-addr-1.c: New testcase. + 2008-03-26 Richard Guenther * gcc.dg/tree-ssa/20030731-2.c: Scan dce1 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 00000000000..7323ffdabf7 --- /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" } } */ -- 2.30.2