From 953d0c90a2f0a98b6d860ecfbf1bc5672653a588 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Wed, 13 Jul 2011 11:16:36 +0000 Subject: tree.h (categorize_ctor_elements): Remove comment. gcc/ * tree.h (categorize_ctor_elements): Remove comment. Fix long line. (count_type_elements): Delete. (complete_ctor_at_level_p): Declare. * expr.c (flexible_array_member_p): New function, split out from... (count_type_elements): ...here. Make static. Replace allow_flexarr parameter with for_ctor_p. When for_ctor_p is true, return the number of elements that should appear in the top-level constructor, otherwise return an estimate of the number of scalars. (categorize_ctor_elements): Replace p_must_clear with p_complete. (categorize_ctor_elements_1): Likewise. Use complete_ctor_at_level_p. (complete_ctor_at_level_p): New function, borrowing union logic from old categorize_ctor_elements_1. (mostly_zeros_p): Return true if the constructor is not complete. (all_zeros_p): Update call to categorize_ctor_elements. * gimplify.c (gimplify_init_constructor): Update call to categorize_ctor_elements. Don't call count_type_elements. Unconditionally prevent clearing for variable-sized types, otherwise rely on categorize_ctor_elements to detect incomplete initializers. gcc/cp/ * typeck2.c (split_nonconstant_init_1): Pass the initializer directly, rather than a pointer to it. Return true if the whole of the value was initialized by the generated statements. Use complete_ctor_at_level_p instead of count_type_elements. gcc/testsuite/ 2011-07-12 Chung-Lin Tang * gcc.target/arm/pr48183.c: New test. From-SVN: r176228 --- gcc/gimplify.c | 44 +++++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 21 deletions(-) (limited to 'gcc/gimplify.c') diff --git a/gcc/gimplify.c b/gcc/gimplify.c index 5a928be..1d0b907 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -3731,9 +3731,8 @@ gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, case ARRAY_TYPE: { struct gimplify_init_ctor_preeval_data preeval_data; - HOST_WIDE_INT num_type_elements, num_ctor_elements; - HOST_WIDE_INT num_nonzero_elements; - bool cleared, valid_const_initializer; + HOST_WIDE_INT num_ctor_elements, num_nonzero_elements; + bool cleared, complete_p, valid_const_initializer; /* Aggregate types must lower constructors to initialization of individual elements. The exception is that a CONSTRUCTOR node @@ -3750,7 +3749,7 @@ gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, can only do so if it known to be a valid constant initializer. */ valid_const_initializer = categorize_ctor_elements (ctor, &num_nonzero_elements, - &num_ctor_elements, &cleared); + &num_ctor_elements, &complete_p); /* If a const aggregate variable is being initialized, then it should never be a lose to promote the variable to be static. */ @@ -3788,26 +3787,29 @@ gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, parts in, then generate code for the non-constant parts. */ /* TODO. There's code in cp/typeck.c to do this. */ - num_type_elements = count_type_elements (type, true); - - /* If count_type_elements could not determine number of type elements - for a constant-sized object, assume clearing is needed. - Don't do this for variable-sized objects, as store_constructor - will ignore the clearing of variable-sized objects. */ - if (num_type_elements < 0 && int_size_in_bytes (type) >= 0) + if (int_size_in_bytes (TREE_TYPE (ctor)) < 0) + /* store_constructor will ignore the clearing of variable-sized + objects. Initializers for such objects must explicitly set + every field that needs to be set. */ + cleared = false; + else if (!complete_p) + /* If the constructor isn't complete, clear the whole object + beforehand. + + ??? This ought not to be needed. For any element not present + in the initializer, we should simply set them to zero. Except + we'd need to *find* the elements that are not present, and that + requires trickery to avoid quadratic compile-time behavior in + large cases or excessive memory use in small cases. */ cleared = true; - /* If there are "lots" of zeros, then block clear the object first. */ - else if (num_type_elements - num_nonzero_elements + else if (num_ctor_elements - num_nonzero_elements > CLEAR_RATIO (optimize_function_for_speed_p (cfun)) - && num_nonzero_elements < num_type_elements/4) - cleared = true; - /* ??? This bit ought not be needed. For any element not present - in the initializer, we should simply set them to zero. Except - we'd need to *find* the elements that are not present, and that - requires trickery to avoid quadratic compile-time behavior in - large cases or excessive memory use in small cases. */ - else if (num_ctor_elements < num_type_elements) + && num_nonzero_elements < num_ctor_elements / 4) + /* If there are "lots" of zeros, it's more efficient to clear + the memory and then set the nonzero elements. */ cleared = true; + else + cleared = false; /* If there are "lots" of initialized elements, and all of them are valid address constants, then the entire initializer can -- cgit v1.1