[PATCH] If ctor has at most one non-zero element, don't force it into memory (PR c++/38253)

Jakub Jelinek jakub@redhat.com
Wed Dec 10 15:03:00 GMT 2008


g++.dg/ipa/iinline-1.C fails to match a dump regexp on ppc, because
unlike say i386/x86_64 the { fn, 0 } ctor for pointer-to-member
is forced in gimplify_init_constructor into a static const var (C.*)
and thus IPA doesn't notice that the member function is being called.
esra makes things even worse, so it is hard to find it out at IPA inline

But, for { fn, 0 } ctor I don't think it makes sense on any arch to
force it into memory.  can_move_by_pieces is certainly a wrong thing to
call in gimplify_init_constructor, we want to find out if initializing
by pieces is cheap enough (speed wise or size wise), not if copying two
memory blocks of certain size and alignment will be copied using
mov[qhsd]i insns into regs and back to the other memory, or using say
movmem[qhsd]i.  That is something that depends on the types of the ctor
elements (e.g. is much more expensive if there are bitfields) and for const
initializer is definitely closer to can_store_by_pieces with some callback.

Anyway, changing that seems to be too radical this late in 4.4 cycle, so
I'm considering just special casing one non-zero element (if cleared is
false, then clearing the whole var by pieces can't be too expensive, and
setting just one non-zero field instead of one 0 store shouldn't be much
more expensive.  On the iinline1.C testcase with funcOne being extern
this patch generates better code on both ppc32 and ppc64.

Will bootstrap/regtest this on x86_64-linux and powerpc64-linux.

2008-12-10  Jakub Jelinek  <jakub@redhat.com>

	PR c++/38253
	* gimplify.c (gimplify_init_constructor): Don't force constructor
	into memory if there is just one nonzero element.

--- gcc/gimplify.c.jj	2008-12-10 14:01:34.000000000 +0100
+++ gcc/gimplify.c	2008-12-10 15:14:01.000000000 +0100
@@ -3610,7 +3610,9 @@ gimplify_init_constructor (tree *expr_p,
 	      align = TYPE_ALIGN (type);
-	    if (size > 0 && !can_move_by_pieces (size, align))
+	    if (size > 0
+		&& num_nonzero_elements > 1
+		&& !can_move_by_pieces (size, align))
 		tree new_tree;


More information about the Gcc-patches mailing list