From 489f2598af821da1157ec21cd484fcb32a5193e9 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Mon, 29 Oct 2007 23:26:59 +0100 Subject: [PATCH] re PR tree-optimization/33723 (Inefficient code with compound literals) PR tree-optimization/33723 * c-gimplify.c (c_gimplify_expr): Optimize INIT_EXPR or MODIFY_EXPR with non-addressable COMPOUND_LITERAL_EXPR as source. * gcc.c-torture/execute/20071029-1.c: New test. * gcc.dg/tree-ssa/pr33723.c: New test. From-SVN: r129743 --- gcc/ChangeLog | 6 ++ gcc/c-gimplify.c | 23 ++++++ gcc/testsuite/ChangeLog | 6 ++ .../gcc.c-torture/execute/20071029-1.c | 56 ++++++++++++++ gcc/testsuite/gcc.dg/tree-ssa/pr33723.c | 74 +++++++++++++++++++ 5 files changed, 165 insertions(+) create mode 100644 gcc/testsuite/gcc.c-torture/execute/20071029-1.c create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr33723.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a8d26816d8c..ab0ee0fa5c8 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2007-10-29 Jakub Jelinek + + PR tree-optimization/33723 + * c-gimplify.c (c_gimplify_expr): Optimize INIT_EXPR or + MODIFY_EXPR with non-addressable COMPOUND_LITERAL_EXPR as source. + 2007-10-29 Richard Sandiford PR tree-optimization/33614 diff --git a/gcc/c-gimplify.c b/gcc/c-gimplify.c index 9721b67008b..a1ee27bfb70 100644 --- a/gcc/c-gimplify.c +++ b/gcc/c-gimplify.c @@ -233,6 +233,29 @@ c_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p ATTRIBUTE_UNUSED) case COMPOUND_LITERAL_EXPR: return gimplify_compound_literal_expr (expr_p, pre_p); + case INIT_EXPR: + case MODIFY_EXPR: + if (TREE_CODE (TREE_OPERAND (*expr_p, 1)) == COMPOUND_LITERAL_EXPR) + { + tree complit = TREE_OPERAND (*expr_p, 1); + tree decl_s = COMPOUND_LITERAL_EXPR_DECL_STMT (complit); + tree decl = DECL_EXPR_DECL (decl_s); + tree init = DECL_INITIAL (decl); + + /* struct T x = (struct T) { 0, 1, 2 } can be optimized + into struct T x = { 0, 1, 2 } if the address of the + compound literal has never been taken. */ + if (!TREE_ADDRESSABLE (complit) + && !TREE_ADDRESSABLE (decl) + && init) + { + *expr_p = copy_node (*expr_p); + TREE_OPERAND (*expr_p, 1) = init; + return GS_OK; + } + } + return GS_UNHANDLED; + default: return GS_UNHANDLED; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index db874d34f06..b60bf928784 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2007-10-29 Jakub Jelinek + + PR tree-optimization/33723 + * gcc.c-torture/execute/20071029-1.c: New test. + * gcc.dg/tree-ssa/pr33723.c: New test. + 2007-10-29 Richard Sandiford PR tree-optimization/33614 diff --git a/gcc/testsuite/gcc.c-torture/execute/20071029-1.c b/gcc/testsuite/gcc.c-torture/execute/20071029-1.c new file mode 100644 index 00000000000..6b895d60a5e --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/20071029-1.c @@ -0,0 +1,56 @@ +extern void exit (int); +extern void abort (void); + +typedef union +{ + struct + { + int f1, f2, f3, f4, f5, f6, f7, f8; + long int f9, f10; + int f11; + } f; + char s[56]; + long int a; +} T; + +__attribute__((noinline)) +void +test (T *t) +{ + static int i = 11; + if (t->f.f1 != i++) + abort (); + if (t->f.f2 || t->f.f3 || t->f.f4 || t->f.f5 || t->f.f6 + || t->f.f7 || t->f.f8 || t->f.f9 || t->f.f10 || t->f.f11) + abort (); + if (i == 20) + exit (0); +} + +__attribute__((noinline)) +void +foo (int i) +{ + T t; +again: + t = (T) { { ++i, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }; + test (&t); + goto again; +} + +int +main (void) +{ + T *t1, *t2; + int cnt = 0; + t1 = (T *) 0; +loop: + t2 = t1; + t1 = & (T) { .f.f9 = cnt++ }; + if (cnt < 3) + goto loop; + if (t1 != t2 || t1->f.f9 != 2) + abort (); + foo (10); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr33723.c b/gcc/testsuite/gcc.dg/tree-ssa/pr33723.c new file mode 100644 index 00000000000..b11623fbb63 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr33723.c @@ -0,0 +1,74 @@ +/* PR tree-optimization/33723 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-gimple" } */ + +typedef union +{ + struct + { + int f1, f2, f3, f4, f5, f6, f7, f8; + long int f9, f10; + int f11; + } f; + char s[56]; + long int a; +} T; + +void +foo1 (void) +{ + T t; + t = (T) { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }; + test (&t); +} + +void +bar1 (void) +{ + T t = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }; + test (&t); +} + +void +baz1 (void) +{ + T t; + t = (const T) { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }; + test (&t); +} + +void +foo2 (void) +{ + T t; + t = (T) { { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 } }; + test (&t); +} + +void +bar2 (void) +{ + T t = { { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 } }; + test (&t); +} + +void +baz2 (void) +{ + T t; + t = (const T) { { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 } }; + test (&t); +} + +void +baz3 (void) +{ + T t; + t = (const T) (T) { { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 } }; + test (&t); +} + +/* { dg-final { scan-tree-dump-times "t = {}" 3 "gimple"} } */ +/* { dg-final { scan-tree-dump-times "t.f.f1 = 1" 4 "gimple"} } */ +/* { dg-final { scan-tree-dump-times "t.f.f8 = 8" 4 "gimple"} } */ +/* { dg-final { cleanup-tree-dump "gimple" } } */