[patch] PR32901: handle assignment from constructors better

Jakub Jelinek jakub@redhat.com
Wed Dec 12 16:03:00 GMT 2007


On Tue, Dec 11, 2007 at 08:36:49PM -0500, Diego Novillo wrote:
> On 12/11/07 6:15 PM, Aldy Hernandez wrote:
> 
> >        * gimplify.c (gimplify_modify_expr_rhs): Handle the case when we
> >        are assigning from a constant constructor.
> >        Fix wrapping in function comment.
> 
> Yes.  With ChangeLog entry for the test.

Sorry to chime in, but I'm afraid this needs some tuning.
Consider e.g.

struct foo {
  unsigned long int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10;
  unsigned long int b1, b2, b3, b4, b5, b6, b7, b8, b9, b10;
};

extern struct foo v1, v2, v3, v4;

void setup_foo(void)
{
  const struct foo init = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 };

  v1 = init;
  v2 = init;
  v3 = init;
  v4 = init;
}

Before this patch we got (*optimized dump):
setup_foo ()
{
  static const struct foo init = {.a1=1, .a2=2, .a3=3, .a4=4, .a5=5, .a6=6, .a7=7, .a8=8, .a9=9, .a10=10, .b1=11, .b2=12, .b3=13, .b4=14, .b5=15, .b6=16, .b7=17, .b8=18, .b9=19, .b10=20};
 
<bb 2>:
  v1 = init;
  v2 = init;
  v3 = init;
  v4 = init;
  return;

}

now we get:

setup_foo ()
{
  static const struct foo C.3 = {.a1=1, .a2=2, .a3=3, .a4=4, .a5=5, .a6=6, .a7=7, .a8=8, .a9=9, .a10=10, .b1=11, .b2=12, .b3=13, .b4=14, .b5=15, .b6=16, .b7=17, .b8=18, .b9=19, .b10=20};
  static const struct foo C.2 = {.a1=1, .a2=2, .a3=3, .a4=4, .a5=5, .a6=6, .a7=7, .a8=8, .a9=9, .a10=10, .b1=11, .b2=12, .b3=13, .b4=14, .b5=15, .b6=16, .b7=17, .b8=18, .b9=19, .b10=20};
  static const struct foo C.1 = {.a1=1, .a2=2, .a3=3, .a4=4, .a5=5, .a6=6, .a7=7, .a8=8, .a9=9, .a10=10, .b1=11, .b2=12, .b3=13, .b4=14, .b5=15, .b6=16, .b7=17, .b8=18, .b9=19, .b10=20};
  static const struct foo C.0 = {.a1=1, .a2=2, .a3=3, .a4=4, .a5=5, .a6=6, .a7=7, .a8=8, .a9=9, .a10=10, .b1=11, .b2=12, .b3=13, .b4=14, .b5=15, .b6=16, .b7=17, .b8=18, .b9=19, .b10=20};

<bb 2>:
  v1 = C.0;
  v2 = C.1;
  v3 = C.2;
  v4 = C.3;
  return;

}

There are several things which should be done IMHO:
1) this new gimplify_modify_expr_rhs optimization should do some checks
   that are done in gimplify_init_constructor, and not do this
   optimization if that would create a new C.* static constant.
   See that if (size > 0 && !can_move_by_pieces (size, align)) in
   gimplify_init_constructor.
2) independently from this optimization, we should set some flag
   on these create_tmp_var_name ("C") statics (not those when
   a const var with initializer is promoted to the static) and if
   -fmerge-constants (default at -O2) put them into mergeable sections,
   or at least remove duplicates within each TU.  As these C.* statics
   are only ever used by compiler generated code to initialize some vars,
   it really can be shared if the content is the same.
   2) should help if we have source like:
struct foo {
  unsigned long int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10;
  unsigned long int b1, b2, b3, b4, b5, b6, b7, b8, b9, b10;
};

extern struct foo v1, v2, v3, v4;

void setup_foo(void)
{
  v1 = (const struct foo) { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 };
  v2 = (const struct foo) { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 };
  v3 = (const struct foo) { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 };
  v4 = (const struct foo) { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 };
}

	Jakub



More information about the Gcc-patches mailing list