Commit 7ef249e5 by Jakub Jelinek Committed by Jakub Jelinek

re PR c/34146 (Inefficient code with compound literals inside a CONSTRUCTO)

	PR c/34146
	* c-gimplify.c (optimize_compound_literals_in_ctor): New function.
	(c_gimplify_expr): Use it.

	PR c/34146
	* gcc.dg/tree-ssa/pr34146.c: New test.

	PR testsuite/33978
	* gcc.dg/tree-ssa/pr33723.c: Adjust scan pattern to make it less
	dependent on target settings like move_by_pieces etc.

From-SVN: r130311
parent cae85ca9
2007-11-20 Jakub Jelinek <jakub@redhat.com>
PR c/34146
* c-gimplify.c (optimize_compound_literals_in_ctor): New function.
(c_gimplify_expr): Use it.
2007-11-20 Ben Elliston <bje@au.ibm.com>
* config/spu/spu_mfcio.h: Fix typo.
......@@ -208,6 +208,47 @@ gimplify_compound_literal_expr (tree *expr_p, tree *pre_p)
return GS_OK;
}
/* Optimize embedded COMPOUND_LITERAL_EXPRs within a CONSTRUCTOR,
return a new CONSTRUCTOR if something changed. */
static tree
optimize_compound_literals_in_ctor (tree orig_ctor)
{
tree ctor = orig_ctor;
VEC(constructor_elt,gc) *elts = CONSTRUCTOR_ELTS (ctor);
unsigned int idx, num = VEC_length (constructor_elt, elts);
for (idx = 0; idx < num; idx++)
{
tree value = VEC_index (constructor_elt, elts, idx)->value;
tree newval = value;
if (TREE_CODE (value) == CONSTRUCTOR)
newval = optimize_compound_literals_in_ctor (value);
else if (TREE_CODE (value) == COMPOUND_LITERAL_EXPR)
{
tree decl_s = COMPOUND_LITERAL_EXPR_DECL_STMT (value);
tree decl = DECL_EXPR_DECL (decl_s);
tree init = DECL_INITIAL (decl);
if (!TREE_ADDRESSABLE (value)
&& !TREE_ADDRESSABLE (decl)
&& init)
newval = init;
}
if (newval == value)
continue;
if (ctor == orig_ctor)
{
ctor = copy_node (orig_ctor);
CONSTRUCTOR_ELTS (ctor) = VEC_copy (constructor_elt, gc, elts);
elts = CONSTRUCTOR_ELTS (ctor);
}
VEC_index (constructor_elt, elts, idx)->value = newval;
}
return ctor;
}
/* Do C-specific gimplification. Args are as for gimplify_expr. */
int
......@@ -254,6 +295,18 @@ c_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p ATTRIBUTE_UNUSED)
return GS_OK;
}
}
else if (TREE_CODE (TREE_OPERAND (*expr_p, 1)) == CONSTRUCTOR)
{
tree ctor
= optimize_compound_literals_in_ctor (TREE_OPERAND (*expr_p, 1));
if (ctor != TREE_OPERAND (*expr_p, 1))
{
*expr_p = copy_node (*expr_p);
TREE_OPERAND (*expr_p, 1) = ctor;
return GS_OK;
}
}
return GS_UNHANDLED;
default:
......
2007-11-20 Jakub Jelinek <jakub@redhat.com>
PR c/34146
* gcc.dg/tree-ssa/pr34146.c: New test.
PR testsuite/33978
* gcc.dg/tree-ssa/pr33723.c: Adjust scan pattern to make it less
dependent on target settings like move_by_pieces etc.
PR c++/28879
* g++.dg/template/vla2.C: New test.
......@@ -68,7 +68,5 @@ baz3 (void)
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 { scan-tree-dump-not "t = D" "gimple"} } */
/* { dg-final { cleanup-tree-dump "gimple" } } */
/* PR c/34146 */
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-gimple" } */
struct A
{
int f1, f2, f3;
};
struct B
{
struct A g1, g2;
};
struct C
{
struct B h1, h2;
};
typedef union
{
struct C c;
char s[4];
long int a;
} T;
void
foo (void)
{
T t = { { { { 0, 0, 0 }, { 0, 0, 0 } }, { { 0, 0, 0 }, { 0, 0, 0 } } } };
test (&t);
}
void
bar (void)
{
T t = { { { { 0, 0, 0 }, (struct A) { 0, 0, 0 } },
(struct B) { (struct A) { 0, 0, 0 }, { 0, 0, 0 } } } };
test (&t);
}
void
baz (void)
{
T t = { { { { 0, 0, 0 }, (struct A) { 1, 1, 1 } },
(struct B) { (struct A) { 0, 0, 0 }, { 1, 1, 1 } } } };
test (&t);
}
/* { dg-final { scan-tree-dump-not "t = D" "gimple"} } */
/* { dg-final { scan-tree-dump-not "t\.c\.h\[12\] = D" "gimple"} } */
/* { dg-final { scan-tree-dump-not "\.g\[12\] = D" "gimple"} } */
/* { dg-final { cleanup-tree-dump "gimple" } } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment