This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: RFA: Avoid unnecessary clearing in union initialisers


On Tue, Jul 12, 2011 at 9:34 AM, Richard Sandiford
<richard.sandiford@linaro.org> wrote:
> PR 48183 is caused by the fact that we don't really support integers
> (or least integer constants) wider than 2*HOST_BITS_PER_WIDE_INT:
>
> ? http://gcc.gnu.org/ml/gcc-patches/2011-03/msg01220.html
>
> However, such constants shouldn't be needed in normal use.
> They came from an unnecessary zero-initialisation of a union such as:
>
> ? union { a f1; b f2; } u = { init_f1 };
>
> where f1 and f2 are the full width of the union. ?The zero-initialisation
> gets optimised away for "real" insns, but persists in debug insns:
>
> ? http://gcc.gnu.org/ml/gcc-patches/2011-03/msg01585.html
>
> This patch takes up Richard's idea here:
>
> ? http://gcc.gnu.org/ml/gcc-patches/2011-03/msg01987.html
>
> categorize_ctor_elements currently tries to work out how many scalars a
> constructor initialises (IE) and how many of those scalars are zero (ZE).
> Callers can then call count_type_elements to find out how many scalars (TE)
> ought to be initialised if the constructor is "complete" (i.e. if it
> explicitly initialises every meaningful byte, rather than relying on
> default zero-initialisation). ?The constructor is complete if TE == ZE,
> except as noted in [A] below.
>
> However, count_type_elements can't return the required TE for unions,
> because it would need to know which of the union's fields was initialised
> by the constructor (if any). ?This choice of field is reflected in IE and
> ZE, so would need to be reflected in TE as well.
>
> count_type_elements therefore punts on unions. ?However, the caller
> can't easily tell whether it punts because of that, because of overflow,
> of because of variable-sized types.
>
> [A] One particular case of interest is when a union constructor initialises
> a field that is shorter than the union. ?In this case, the rest of the
> union must be zeroed in order to ensure that the other fields have
> predictable values. ?categorize_ctor_elements has a special out-parameter
> to reccord this situation.
>
> This leads to quite a complicated interface. ?The patch tries to
> simplify it by making categorize_ctor_elements keep track of whether
> a constructor is complete. ?This also has the minor advantage of
> avoiding double recursion: first through the constructor,
> then through its type tree.
>
> After this change, ZE and IE are only needed when deciding how best to
> implement "complete" initialisers (such as whether to do a bulk zero
> initialisation anyway, and just write the nonzero elements individually).
> For cases where a "leaf" constructor element is itself an aggregate with
> a union, we can therefore estimate the number of scalars in the union,
> and hopefully make the heuristic a bit more accurate than the current 1:
>
> ? ? ? ? ? ?HOST_WIDE_INT tc = count_type_elements (TREE_TYPE (value), true);
> ? ? ? ? ? ?if (tc < 1)
> ? ? ? ? ? ? ?tc = 1;
>
> cp/typeck2.c also wants to check whether the variable parts of a
> constructor are complete. ?The patch uses the approach to completeness
> there. ?This should make it a bit more general than the current code,
> which only deals with non-nested constructors.
>
> Tested on x86_64-linux-gnu (all languages, including Ada), and on
> arm-linux-gnueabi. ?OK to install?
>
> Richard
>
>
> 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 ?<cltang@codesourcery.com>
>
> ? ? ? ?* gcc.target/arm/pr48183.c: New test.
>

This caused:

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49736

-- 
H.J.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]