On Wed, Sep 7, 2011 at 7:18 PM, Martin Jambor <mjam...@suse.cz> wrote: > Hi, > > the patch below should fix PR 50287 (and its many duplicates) by > simply never attempting to create new default-defs for unused > non-register parameters and using their DECL when calling the split > function. Note that all of this is relevant only in the case when > there is some other reason why we cannot change the function's > signature (typically because there are function attributes). > Otherwise, parameters that are not used or referenced in any way are > not passed on to the split function. > > This is correct because it does not really matter what actual value we > pass to the split function for any non-register parameter because all > statements that are going to end up in the split function are checked > by mark_nonssa_use which makes sure it does not use, store or take > address of any such PARM_DECL. > > The patch passes bootstrap and testing on x86_64-linux, it has > successfully LTO-built Firefox and I'm LTO-building a few SPEC 2006 > benchmarks with it right now. Of course it fixes the ICE when > compiling the testcase (and I have verified that the 4.6 version also > fixes the ICE when compiling the reduced testcase of PR 50295). OK for > trunk (and then for the 4.6 branch)?
Ok. Thanks, Richard. > Thanks, > > Martin > > > 2011-09-06 Martin Jambor <mjam...@suse.cz> > > PR tree-optimization/50287 > * ipa-split.c (split_function): Do not create SSA names for > non-gimple-registers. > > * testsuite/gcc.dg/torture/pr50287.c: New test. > > > Index: src/gcc/testsuite/gcc.dg/torture/pr50287.c > =================================================================== > --- /dev/null > +++ src/gcc/testsuite/gcc.dg/torture/pr50287.c > @@ -0,0 +1,109 @@ > +/* { dg-do compile } */ > + > +struct PMC { > + unsigned flags; > +}; > + > +struct PVC { > + unsigned flags, other_stuff; > +}; > + > + > +typedef struct Pcc_cell > +{ > + struct PMC *p; > + long bla; > + long type; > +} Pcc_cell; > + > +int gi; > +int cond; > + > +struct PVC g_pvc; > + > +extern void abort (); > +extern void never_ever(int interp, struct PMC *pmc) > + __attribute__((noinline,noclone)); > + > +void never_ever (int interp, struct PMC *pmc) > +{ > + abort (); > +} > + > +static void mark_cell(int * interp, Pcc_cell *c, struct PVC pvc) > + __attribute__((__nonnull__(1))); > + > +static void > +mark_cell(int * interp, Pcc_cell *c, struct PVC pvc) > +{ > + if (!cond) > + return; > + > + if (c && c->type == 4 && c->p > + && !(c->p->flags & (1<<8))) > + never_ever(gi + 1, c->p); > + if (c && c->type == 4 && c->p > + && !(c->p->flags & (1<<7))) > + never_ever(gi + 2, c->p); > + if (c && c->type == 4 && c->p > + && !(c->p->flags & (1<<6))) > + never_ever(gi + 3, c->p); > + if (c && c->type == 4 && c->p > + && !(c->p->flags & (1<<5))) > + never_ever(gi + 4, c->p); > + if (c && c->type == 4 && c->p > + && !(c->p->flags & (1<<4))) > + never_ever(gi + 5, c->p); > + if (c && c->type == 4 && c->p > + && !(c->p->flags & (1<<3))) > + never_ever(gi + 6, c->p); > + if (c && c->type == 4 && c->p > + && !(c->p->flags & (1<<2))) > + never_ever(gi + 7, c->p); > + if (c && c->type == 4 && c->p > + && !(c->p->flags & (1<<1))) > + never_ever(gi + 8, c->p); > + if (c && c->type == 4 && c->p > + && !(c->p->flags & (1<<9))) > + never_ever(gi + 9, c->p); > +} > + > +static void > +foo(int * interp, Pcc_cell *c) > +{ > + mark_cell(interp, c, g_pvc); > +} > + > +static struct Pcc_cell * > +__attribute__((noinline,noclone)) > +getnull(void) > +{ > + return (struct Pcc_cell *) 0; > +} > + > + > +int main() > +{ > + int i; > + > + cond = 1; > + for (i = 0; i < 100; i++) > + foo (&gi, getnull ()); > + return 0; > +} > + > + > +void > +bar_1 (int * interp, Pcc_cell *c) > +{ > + c->bla += 1; > + mark_cell(interp, c, g_pvc); > +} > + > +void > +bar_2 (int * interp, Pcc_cell *c, struct PVC pvc) > +{ > + c->bla += 2; > + mark_cell(interp, c, pvc); > +} > + > Index: src/gcc/ipa-split.c > =================================================================== > --- src.orig/gcc/ipa-split.c > +++ src/gcc/ipa-split.c > @@ -985,15 +985,20 @@ split_function (struct split_point *spli > bitmap_set_bit (args_to_skip, num); > else > { > - arg = gimple_default_def (cfun, parm); > - if (!arg) > + /* This parm might not have been used up to now, but is going to be > + used, hence register it. */ > + add_referenced_var (parm); > + if (is_gimple_reg (parm)) > { > - /* This parm wasn't used up to now, but is going to be used, > - hence register it. */ > - add_referenced_var (parm); > - arg = make_ssa_name (parm, gimple_build_nop ()); > - set_default_def (parm, arg); > + arg = gimple_default_def (cfun, parm); > + if (!arg) > + { > + arg = make_ssa_name (parm, gimple_build_nop ()); > + set_default_def (parm, arg); > + } > } > + else > + arg = parm; > > if (TYPE_MAIN_VARIANT (DECL_ARG_TYPE (parm)) > != TYPE_MAIN_VARIANT (TREE_TYPE (arg))) >