Commit ffed8a01 by Aldy Hernandez Committed by Aldy Hernandez

re PR tree-optimization/34448 (ICE in declare_inline_vars, at tree-inline.c:3243)

        PR tree-optimization/34448
        PR tree-optimization/34465
        * gimplify.c (gimplify_init_constructor): Add new parameter
        notify_temp_creation.  Use it.
        (gimplify_modify_expr_rhs): Take volatiles into account when
        optimizing constructors.
        Do not optimize constructors if gimplify_init_constructor will dump to
        memory.
        * gcc.dg/tree-ssa/pr32901.c: Tests const volatiles.
        * gcc.c-torture/compile/pr34448.c: New.

From-SVN: r131323
parent b5ca517c
2008-01-04 Aldy Hernandez <aldyh@redhat.com>
PR tree-optimization/34448
PR tree-optimization/34465
* gimplify.c (gimplify_init_constructor): Add new parameter
notify_temp_creation. Use it.
(gimplify_modify_expr_rhs): Take volatiles into account when
optimizing constructors.
Do not optimize constructors if gimplify_init_constructor will dump to
memory.
* gcc.dg/tree-ssa/pr32901.c: Tests const volatiles.
* gcc.c-torture/compile/pr34448.c: New.
2008-01-04 Jakub Jelinek <jakub@redhat.com> 2008-01-04 Jakub Jelinek <jakub@redhat.com>
PR gcov-profile/34609 PR gcov-profile/34609
...@@ -3119,11 +3119,18 @@ gimplify_init_ctor_eval (tree object, VEC(constructor_elt,gc) *elts, ...@@ -3119,11 +3119,18 @@ gimplify_init_ctor_eval (tree object, VEC(constructor_elt,gc) *elts,
Note that we still need to clear any elements that don't have explicit Note that we still need to clear any elements that don't have explicit
initializers, so if not all elements are initialized we keep the initializers, so if not all elements are initialized we keep the
original MODIFY_EXPR, we just remove all of the constructor elements. */ original MODIFY_EXPR, we just remove all of the constructor elements.
If NOTIFY_TEMP_CREATION is true, do not gimplify, just return
GS_ERROR if we would have to create a temporary when gimplifying
this constructor. Otherwise, return GS_OK.
If NOTIFY_TEMP_CREATION is false, just do the gimplification. */
static enum gimplify_status static enum gimplify_status
gimplify_init_constructor (tree *expr_p, tree *pre_p, gimplify_init_constructor (tree *expr_p, tree *pre_p,
tree *post_p, bool want_value) tree *post_p, bool want_value,
bool notify_temp_creation)
{ {
tree object; tree object;
tree ctor = GENERIC_TREE_OPERAND (*expr_p, 1); tree ctor = GENERIC_TREE_OPERAND (*expr_p, 1);
...@@ -3134,10 +3141,13 @@ gimplify_init_constructor (tree *expr_p, tree *pre_p, ...@@ -3134,10 +3141,13 @@ gimplify_init_constructor (tree *expr_p, tree *pre_p,
if (TREE_CODE (ctor) != CONSTRUCTOR) if (TREE_CODE (ctor) != CONSTRUCTOR)
return GS_UNHANDLED; return GS_UNHANDLED;
ret = gimplify_expr (&GENERIC_TREE_OPERAND (*expr_p, 0), pre_p, post_p, if (!notify_temp_creation)
is_gimple_lvalue, fb_lvalue); {
if (ret == GS_ERROR) ret = gimplify_expr (&GENERIC_TREE_OPERAND (*expr_p, 0), pre_p, post_p,
return ret; is_gimple_lvalue, fb_lvalue);
if (ret == GS_ERROR)
return ret;
}
object = GENERIC_TREE_OPERAND (*expr_p, 0); object = GENERIC_TREE_OPERAND (*expr_p, 0);
elts = CONSTRUCTOR_ELTS (ctor); elts = CONSTRUCTOR_ELTS (ctor);
...@@ -3159,7 +3169,11 @@ gimplify_init_constructor (tree *expr_p, tree *pre_p, ...@@ -3159,7 +3169,11 @@ gimplify_init_constructor (tree *expr_p, tree *pre_p,
individual elements. The exception is that a CONSTRUCTOR node individual elements. The exception is that a CONSTRUCTOR node
with no elements indicates zero-initialization of the whole. */ with no elements indicates zero-initialization of the whole. */
if (VEC_empty (constructor_elt, elts)) if (VEC_empty (constructor_elt, elts))
break; {
if (notify_temp_creation)
return GS_OK;
break;
}
/* Fetch information about the constructor to direct later processing. /* Fetch information about the constructor to direct later processing.
We might want to make static versions of it in various cases, and We might want to make static versions of it in various cases, and
...@@ -3175,6 +3189,8 @@ gimplify_init_constructor (tree *expr_p, tree *pre_p, ...@@ -3175,6 +3189,8 @@ gimplify_init_constructor (tree *expr_p, tree *pre_p,
&& TREE_READONLY (object) && TREE_READONLY (object)
&& TREE_CODE (object) == VAR_DECL) && TREE_CODE (object) == VAR_DECL)
{ {
if (notify_temp_creation)
return GS_ERROR;
DECL_INITIAL (object) = ctor; DECL_INITIAL (object) = ctor;
TREE_STATIC (object) = 1; TREE_STATIC (object) = 1;
if (!DECL_NAME (object)) if (!DECL_NAME (object))
...@@ -3251,7 +3267,12 @@ gimplify_init_constructor (tree *expr_p, tree *pre_p, ...@@ -3251,7 +3267,12 @@ gimplify_init_constructor (tree *expr_p, tree *pre_p,
if (size > 0 && !can_move_by_pieces (size, align)) if (size > 0 && !can_move_by_pieces (size, align))
{ {
tree new = create_tmp_var_raw (type, "C"); tree new;
if (notify_temp_creation)
return GS_ERROR;
new = create_tmp_var_raw (type, "C");
gimple_add_tmp_var (new); gimple_add_tmp_var (new);
TREE_STATIC (new) = 1; TREE_STATIC (new) = 1;
...@@ -3273,6 +3294,9 @@ gimplify_init_constructor (tree *expr_p, tree *pre_p, ...@@ -3273,6 +3294,9 @@ gimplify_init_constructor (tree *expr_p, tree *pre_p,
} }
} }
if (notify_temp_creation)
return GS_OK;
/* If there are nonzero elements, pre-evaluate to capture elements /* If there are nonzero elements, pre-evaluate to capture elements
overlapping with the lhs into temporaries. We must do this before overlapping with the lhs into temporaries. We must do this before
clearing to fetch the values before they are zeroed-out. */ clearing to fetch the values before they are zeroed-out. */
...@@ -3312,6 +3336,9 @@ gimplify_init_constructor (tree *expr_p, tree *pre_p, ...@@ -3312,6 +3336,9 @@ gimplify_init_constructor (tree *expr_p, tree *pre_p,
{ {
tree r, i; tree r, i;
if (notify_temp_creation)
return GS_OK;
/* Extract the real and imaginary parts out of the ctor. */ /* Extract the real and imaginary parts out of the ctor. */
gcc_assert (VEC_length (constructor_elt, elts) == 2); gcc_assert (VEC_length (constructor_elt, elts) == 2);
r = VEC_index (constructor_elt, elts, 0)->value; r = VEC_index (constructor_elt, elts, 0)->value;
...@@ -3348,6 +3375,9 @@ gimplify_init_constructor (tree *expr_p, tree *pre_p, ...@@ -3348,6 +3375,9 @@ gimplify_init_constructor (tree *expr_p, tree *pre_p,
unsigned HOST_WIDE_INT ix; unsigned HOST_WIDE_INT ix;
constructor_elt *ce; constructor_elt *ce;
if (notify_temp_creation)
return GS_OK;
/* Go ahead and simplify constant constructors to VECTOR_CST. */ /* Go ahead and simplify constant constructors to VECTOR_CST. */
if (TREE_CONSTANT (ctor)) if (TREE_CONSTANT (ctor))
{ {
...@@ -3488,10 +3518,27 @@ gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p, tree *pre_p, ...@@ -3488,10 +3518,27 @@ gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p, tree *pre_p,
constructor expression to the RHS of the MODIFY_EXPR. */ constructor expression to the RHS of the MODIFY_EXPR. */
if (DECL_INITIAL (*from_p) if (DECL_INITIAL (*from_p)
&& TYPE_READONLY (TREE_TYPE (*from_p)) && TYPE_READONLY (TREE_TYPE (*from_p))
&& !TREE_THIS_VOLATILE (*from_p)
&& TREE_CODE (DECL_INITIAL (*from_p)) == CONSTRUCTOR) && TREE_CODE (DECL_INITIAL (*from_p)) == CONSTRUCTOR)
{ {
*from_p = DECL_INITIAL (*from_p); tree old_from = *from_p;
ret = GS_OK;
/* Move the constructor into the RHS. */
*from_p = unshare_expr (DECL_INITIAL (*from_p));
/* Let's see if gimplify_init_constructor will need to put
it in memory. If so, revert the change. */
ret = gimplify_init_constructor (expr_p, NULL, NULL, false, true);
if (ret == GS_ERROR)
{
*from_p = old_from;
/* Fall through. */
}
else
{
ret = GS_OK;
break;
}
} }
ret = GS_UNHANDLED; ret = GS_UNHANDLED;
break; break;
...@@ -3551,7 +3598,8 @@ gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p, tree *pre_p, ...@@ -3551,7 +3598,8 @@ gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p, tree *pre_p,
case CONSTRUCTOR: case CONSTRUCTOR:
/* If we're initializing from a CONSTRUCTOR, break this into /* If we're initializing from a CONSTRUCTOR, break this into
individual MODIFY_EXPRs. */ individual MODIFY_EXPRs. */
return gimplify_init_constructor (expr_p, pre_p, post_p, want_value); return gimplify_init_constructor (expr_p, pre_p, post_p, want_value,
false);
case COND_EXPR: case COND_EXPR:
/* If we're assigning to a non-register type, push the assignment /* If we're assigning to a non-register type, push the assignment
......
/* { dg-do compile } */
/* { dg-options "-O" } */
typedef struct chunk_t chunk_t;
struct chunk_t
{
unsigned char *ptr;
long unsigned int len;
};
extern chunk_t asn1_wrap (chunk_t c, ...);
typedef struct linked_list_t linked_list_t;
chunk_t ietfAttr_list_encode (linked_list_t * list);
extern linked_list_t *groups;
static unsigned char ASN1_group_oid_str[] = {
0x06
};
static const chunk_t ASN1_group_oid = {
ASN1_group_oid_str, sizeof (ASN1_group_oid_str)
};
static chunk_t
build_attribute_type (const chunk_t type, chunk_t content)
{
return type;
}
static chunk_t
build_attributes (void)
{
return asn1_wrap (build_attribute_type (ASN1_group_oid,
ietfAttr_list_encode (groups)));
}
void build_attr_cert (void)
{
asn1_wrap (build_attributes ());
}
...@@ -7,7 +7,7 @@ struct foo { ...@@ -7,7 +7,7 @@ struct foo {
unsigned : 4; unsigned : 4;
}; };
extern struct foo thefoo; extern struct foo thefoo, theotherfoo;
void setup_foo(void) void setup_foo(void)
{ {
...@@ -15,10 +15,16 @@ void setup_foo(void) ...@@ -15,10 +15,16 @@ void setup_foo(void)
.a1 = 1, .a1 = 1,
.a2 = 5, .a2 = 5,
}; };
volatile const struct foo volinit = {
.a1 = 0,
.a2 = 6
};
thefoo = init; thefoo = init;
theotherfoo = volinit;
} }
/* { dg-final { scan-tree-dump-times "thefoo.0 = \{\}" 1 "gimple"} } */ /* { dg-final { scan-tree-dump-times "thefoo.* = {}" 1 "gimple"} } */
/* { dg-final { scan-tree-dump-times "thefoo.0.a1 = 1" 1 "gimple"} } */ /* { dg-final { scan-tree-dump-times "thefoo.* = 1" 1 "gimple"} } */
/* { dg-final { scan-tree-dump-times "thefoo.0.a2 = 5" 1 "gimple"} } */ /* { dg-final { scan-tree-dump-times "thefoo.* = 5" 1 "gimple"} } */
/* { dg-final { scan-tree-dump-times "theotherfoo = volinit" 1 "gimple"} } */
/* { dg-final { cleanup-tree-dump "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