This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[patch] Improve gimplification of constructors
- From: Eric Botcazou <ebotcazou at adacore dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 9 Apr 2010 22:46:23 +0200
- Subject: [patch] Improve gimplification of constructors
Hi,
attached is a couple of patches to improve gimplification of constructors:
1. We don't need to pre-evaluate anything if it's a real init (INIT_EXPR).
2. categorize_ctor_elements doesn't correctly count the number of scalars
when the constructor is not constant, so
/* ??? 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)
cleared = true;
unnecessarily triggers and causes useless clearing, for example on
procedure P is
type Arr is array (1..2) of Character;
function F return Arr;
pragma Import (Ada, F);
type Rec is record
A : Arr;
end record;
A : Rec := (A => F);
begin
null;
end;
Bootstrapped/regtested on x86_64-suse-linux, OK for mainline?
2010-04-09 Eric Botcazou <ebotcazou@adacore.com>
* gimplify.c (gimplify_init_constructor): Do not pre-evaluate if this
is a real initialization.
* expr.c (categorize_ctor_elements_1): Properly count sub-elements of
non-constant aggregate elements.
--
Eric Botcazou
Index: expr.c
===================================================================
--- expr.c (revision 158148)
+++ expr.c (working copy)
@@ -4861,9 +4861,8 @@ categorize_ctor_elements_1 (const_tree c
FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), idx, purpose, value)
{
- HOST_WIDE_INT mult;
+ HOST_WIDE_INT mult = 1;
- mult = 1;
if (TREE_CODE (purpose) == RANGE_EXPR)
{
tree lo_index = TREE_OPERAND (purpose, 0);
@@ -4925,12 +4924,17 @@ categorize_ctor_elements_1 (const_tree c
break;
default:
- nz_elts += mult;
- elt_count += mult;
+ {
+ HOST_WIDE_INT tc = count_type_elements (TREE_TYPE (value), true);
+ if (tc < 1)
+ tc = 1;
+ nz_elts += mult * tc;
+ elt_count += mult * tc;
- if (const_from_elts_p && const_p)
- const_p = initializer_constant_valid_p (value, TREE_TYPE (value))
- != NULL_TREE;
+ if (const_from_elts_p && const_p)
+ const_p = initializer_constant_valid_p (value, TREE_TYPE (value))
+ != NULL_TREE;
+ }
break;
}
}
Index: gimplify.c
===================================================================
--- gimplify.c (revision 158148)
+++ gimplify.c (working copy)
@@ -3793,10 +3793,10 @@ gimplify_init_constructor (tree *expr_p,
if (notify_temp_creation)
return GS_OK;
- /* If there are nonzero elements, pre-evaluate to capture elements
- overlapping with the lhs into temporaries. We must do this before
- clearing to fetch the values before they are zeroed-out. */
- if (num_nonzero_elements > 0)
+ /* If there are nonzero elements and if needed, pre-evaluate to capture
+ elements overlapping with the lhs into temporaries. We must do this
+ before clearing to fetch the values before they are zeroed-out. */
+ if (num_nonzero_elements > 0 && TREE_CODE (*expr_p) != INIT_EXPR)
{
preeval_data.lhs_base_decl = get_base_address (object);
if (!DECL_P (preeval_data.lhs_base_decl))