Message ID | 20151021190529.GB92763@kam.mff.cuni.cz |
---|---|
State | New |
Headers | show |
On Wed, 21 Oct 2015, Jan Hubicka wrote: > Hi, > this is updated patch I am going to commit. As discussed, we also need to match > non-empty CONSTRUCTOR of vectors, but those should never be having CONSTANT flags > set, so they need care in the other path trhough operand_equal_p, so I will post > separate patch for that. > > I updated the comment per Richard's comment and added a testcase. Vuriously > enoug we fold "val? (struct a){} : (struct a){}" only in PRE (tailmerging). > W/o the patch even .optimized dump has the test and we fold it away only after > lowering to RTL: > ret (int val) > { > struct a D.1764; > > <bb 2>: > if (val_2(D) != 0) > goto <bb 3>; > else > goto <bb 4>; > > <bb 3>: > D.1764 = {}; > goto <bb 5>; > > <bb 4>: > D.1764 = {}; > > <bb 5>: > return D.1764; > > } > > ret: > .LFB0: > .cfi_startproc > xorl %eax, %eax > ret > .cfi_endproc > > With the patch we get: > > ret (int val) > { > struct a D.1764; > > <bb 2>: > D.1764 = {}; > return D.1764; > > } But only via GENERIC folding I suppose. Yes, we don't value-number aggregates and generally PRE (and DOM via excessive jump-threading) is the only pass that remotely handles this kind of situation. code hoisting/sinking would maybe catch this but as this involves memory I'm not sure the implementation ontop of PRE that is stuck in some PR would catch it. Richard. > Honza > > * fold-const.c (operand_equal_p): Add code matching empty > constructors. > * gcc.dg/tree-ssa/operand-equal-1.c: Verify that empty constructors > are matched. > > Index: fold-const.c > =================================================================== > --- fold-const.c (revision 229133) > +++ fold-const.c (working copy) > @@ -2892,6 +2892,11 @@ operand_equal_p (const_tree arg0, const_ > return operand_equal_p (TREE_OPERAND (arg0, 0), TREE_OPERAND (arg1, 0), > flags | OEP_ADDRESS_OF > | OEP_CONSTANT_ADDRESS_OF); > + case CONSTRUCTOR: > + /* In GIMPLE empty constructors are allowed in initializers of > + aggregates. */ > + return (!vec_safe_length (CONSTRUCTOR_ELTS (arg0)) > + && !vec_safe_length (CONSTRUCTOR_ELTS (arg1))); > default: > break; > } > Index: testsuite/gcc.dg/tree-ssa/operand-equal-1.c > =================================================================== > --- testsuite/gcc.dg/tree-ssa/operand-equal-1.c (revision 0) > +++ testsuite/gcc.dg/tree-ssa/operand-equal-1.c (revision 0) > @@ -0,0 +1,8 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -fdump-tree-pre" } */ > +struct a {int a,b;}; > +struct a ret(int val) > +{ > + return val? (struct a){} : (struct a){}; > +} > +/* { dg-final { scan-tree-dump-not "if " "pre"} } */ > >
> > But only via GENERIC folding I suppose. Yes, we don't value-number > aggregates and generally PRE (and DOM via excessive jump-threading) > is the only pass that remotely handles this kind of situation. I actually think it is tail merging unifying the code, but I did not really look too deep into it. Honza > > code hoisting/sinking would maybe catch this but as this involves > memory I'm not sure the implementation ontop of PRE that is stuck > in some PR would catch it. > > Richard. > > > Honza > > > > * fold-const.c (operand_equal_p): Add code matching empty > > constructors. > > * gcc.dg/tree-ssa/operand-equal-1.c: Verify that empty constructors > > are matched. > > > > Index: fold-const.c > > =================================================================== > > --- fold-const.c (revision 229133) > > +++ fold-const.c (working copy) > > @@ -2892,6 +2892,11 @@ operand_equal_p (const_tree arg0, const_ > > return operand_equal_p (TREE_OPERAND (arg0, 0), TREE_OPERAND (arg1, 0), > > flags | OEP_ADDRESS_OF > > | OEP_CONSTANT_ADDRESS_OF); > > + case CONSTRUCTOR: > > + /* In GIMPLE empty constructors are allowed in initializers of > > + aggregates. */ > > + return (!vec_safe_length (CONSTRUCTOR_ELTS (arg0)) > > + && !vec_safe_length (CONSTRUCTOR_ELTS (arg1))); > > default: > > break; > > } > > Index: testsuite/gcc.dg/tree-ssa/operand-equal-1.c > > =================================================================== > > --- testsuite/gcc.dg/tree-ssa/operand-equal-1.c (revision 0) > > +++ testsuite/gcc.dg/tree-ssa/operand-equal-1.c (revision 0) > > @@ -0,0 +1,8 @@ > > +/* { dg-do compile } */ > > +/* { dg-options "-O2 -fdump-tree-pre" } */ > > +struct a {int a,b;}; > > +struct a ret(int val) > > +{ > > + return val? (struct a){} : (struct a){}; > > +} > > +/* { dg-final { scan-tree-dump-not "if " "pre"} } */ > > > > > > -- > Richard Biener <rguenther@suse.de> > SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nuernberg)
Index: fold-const.c =================================================================== --- fold-const.c (revision 229133) +++ fold-const.c (working copy) @@ -2892,6 +2892,11 @@ operand_equal_p (const_tree arg0, const_ return operand_equal_p (TREE_OPERAND (arg0, 0), TREE_OPERAND (arg1, 0), flags | OEP_ADDRESS_OF | OEP_CONSTANT_ADDRESS_OF); + case CONSTRUCTOR: + /* In GIMPLE empty constructors are allowed in initializers of + aggregates. */ + return (!vec_safe_length (CONSTRUCTOR_ELTS (arg0)) + && !vec_safe_length (CONSTRUCTOR_ELTS (arg1))); default: break; } Index: testsuite/gcc.dg/tree-ssa/operand-equal-1.c =================================================================== --- testsuite/gcc.dg/tree-ssa/operand-equal-1.c (revision 0) +++ testsuite/gcc.dg/tree-ssa/operand-equal-1.c (revision 0) @@ -0,0 +1,8 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-pre" } */ +struct a {int a,b;}; +struct a ret(int val) +{ + return val? (struct a){} : (struct a){}; +} +/* { dg-final { scan-tree-dump-not "if " "pre"} } */