------- Comment #6 from jakub at gcc dot gnu dot org 2007-08-23 20:36 ------- It is unfortunate that gimple can only initialize the whole array, unless __builtin_memcpy is used. Unfortunately __builtin_memcpy has a different drawback - the var will be forced to be TREE_ADDRESSABLE even when it otherwise wouldn't have to be. So, we have the option to add some flag to count_type_elements etc., so that they will behave one way for expr.c etc. and one way for the gimplifier - there it would need to count whole arrays as units if they are initialized from string literals, etc. The other option is IMHO to hint during expansion expand_assignment that the memory is already cleared by previous var = {} and so it can avoid storing zeros. Or teach some RTL pass to remove the redundant zero stores. If the big clear_storage is done through clearing by pieces, DSE will already handle this to some extent (will remove redundant stores from the big clear_storage), but if it is done through a special insn (like rep stosb) or through memset call, nothing will remove it.
While looking at this, I have noticed that a simple struct A { char c[10]; }; void foo (void) { struct A a = { "abcdefghi" }; baz (&a); } void bar (void) { struct A a; __builtin_strcpy (&a.c[0], "abcdefghi"); baz (&a); } is not as efficient as it ought to be in the foo function - while strcpy/memcpy can and in this case will use store_by_pieces, store_expr will always emit the string literal to memory and then emit a block move from it to target followed optionally by clear_storage of the rest of the memory. I'm testing a patch to improve this ATM. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31150