From: Richard Guenther Date: Tue, 26 Jul 2005 07:34:58 +0000 (+0000) Subject: re PR tree-optimization/22486 (Upcasts are not folded away) X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=46c0a59dfb7e787766e70fae751b66e527a8932a;p=platform%2Fupstream%2Fgcc.git re PR tree-optimization/22486 (Upcasts are not folded away) 2005-07-26 Richard Guenther 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 --- 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 + + 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 * dwarf2out.c (add_call_src_coords_attributes): New. diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 9a9ea22..bdda600 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 + + PR tree-optimization/22486 + * gcc.dg/tree-ssa/upcast-1.c: New testcase. + 2005-07-25 Andrew Pinski 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" } } */