aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2005-07-26 07:34:58 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2005-07-26 07:34:58 +0000
commit46c0a59dfb7e787766e70fae751b66e527a8932a (patch)
tree0c96be52bba7fbb40aef73b7e70cfd92198df875 /gcc
parent3e2844cb07459014e55308e43ec26dd75e280f30 (diff)
downloadgcc-46c0a59dfb7e787766e70fae751b66e527a8932a.zip
gcc-46c0a59dfb7e787766e70fae751b66e527a8932a.tar.gz
gcc-46c0a59dfb7e787766e70fae751b66e527a8932a.tar.bz2
re PR tree-optimization/22486 (Upcasts are not folded away)
2005-07-26 Richard Guenther <rguenther@suse.de> PR tree-optimization/22486 * fold-const.c (fold_unary): Fold away useless component references of the form (T *)&T.x, if the address doesn't change. * gcc.dg/tree-ssa/upcast-1.c: New testcase. From-SVN: r102381
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/fold-const.c23
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/upcast-1.c12
4 files changed, 47 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b3bf9d2..315a636 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2005-07-26 Richard Guenther <rguenther@suse.de>
+
+ PR tree-optimization/22486
+ * fold-const.c (fold_unary): Fold away useless component
+ references of the form (T *)&T.x, if the address
+ doesn't change.
+
2005-07-25 James E Wilson <wilson@specifixinc.com>
* dwarf2out.c (add_call_src_coords_attributes): New.
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 9a9ea22..bdda6001 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -6711,6 +6711,29 @@ fold_unary (enum tree_code code, tree type, tree op0)
return fold_build1 (code, type, TREE_OPERAND (op0, 0));
}
+ /* Handle (T *)&A.B.C for A being of type T and B and C
+ living at offset zero. This occours frequently in
+ C++ upcasting and then accessing the base. */
+ if (TREE_CODE (op0) == ADDR_EXPR
+ && POINTER_TYPE_P (type)
+ && handled_component_p (TREE_OPERAND (op0, 0)))
+ {
+ HOST_WIDE_INT bitsize, bitpos;
+ tree offset;
+ enum machine_mode mode;
+ int unsignedp, volatilep;
+ tree base = TREE_OPERAND (op0, 0);
+ base = get_inner_reference (base, &bitsize, &bitpos, &offset,
+ &mode, &unsignedp, &volatilep, false);
+ /* If the reference was to a (constant) zero offset, we can use
+ the address of the base if it has the same base type
+ as the result type. */
+ if (! offset && bitpos == 0
+ && TYPE_MAIN_VARIANT (TREE_TYPE (type))
+ == TYPE_MAIN_VARIANT (TREE_TYPE (base)))
+ return fold_convert (type, build_fold_addr_expr (base));
+ }
+
if (TREE_CODE (op0) == MODIFY_EXPR
&& TREE_CONSTANT (TREE_OPERAND (op0, 1))
/* Detect assigning a bitfield. */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index f82d239..693ddc9 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2005-07-26 Richard Guenther <rguenther@suse.de>
+
+ PR tree-optimization/22486
+ * gcc.dg/tree-ssa/upcast-1.c: New testcase.
+
2005-07-25 Andrew Pinski <pinskia@physics.uc.edu>
PR tree-opt/22484
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/upcast-1.c b/gcc/testsuite/gcc.dg/tree-ssa/upcast-1.c
new file mode 100644
index 0000000..12c2b91
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/upcast-1.c
@@ -0,0 +1,12 @@
+/* { do-go compile } */
+/* { dg-options "-fdump-tree-gimple" } */
+
+typedef struct { int i; } Foo;
+Foo foo;
+Foo *bar(void)
+{
+ return (Foo *)&foo.i;
+}
+
+/* { dg-final { scan-tree-dump "&foo;" "gimple" } } */
+/* { dg-final { cleanup-tree-dump "gimple" } } */