On Tue, 11 Dec 2012, Jakub Jelinek wrote: > Hi! > > As discussed in the PR, this patch forward ports Steven's patch from 4.7 > branch to trunk. No need to include pointer-set.h (already included), > I've moved the var definition into the #ifdef so that it isn't an unused > static var and tweaked the comment a little bit. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
Ok. Thanks, Richard. > 2012-12-11 Steven Bosscher <ste...@gcc.gnu.org> > Jakub Jelinek <ja...@redhat.com> > > PR middle-end/52640 > * varasm.c (pending_assemble_externals_set): New pointer set. > (process_pending_assemble_externals): Destroy the pointer set. > (assemble_external): See if decl is in pending_assemble_externals_set, > and add it to pending_assemble_externals if necessary. > (init_varasm_once): Allocate pending_assemble_externals_set. > > * gcc.c-torture/compile/limits-externdecl.c: New test. > > --- gcc/varasm.c.jj 2012-12-11 13:05:36.099732106 +0100 > +++ gcc/varasm.c 2012-12-11 18:01:52.454620513 +0100 > @@ -2089,6 +2089,10 @@ contains_pointers_p (tree type) > static GTY(()) tree pending_assemble_externals; > > #ifdef ASM_OUTPUT_EXTERNAL > +/* Avoid O(external_decls**2) lookups in the pending_assemble_externals > + TREE_LIST in assemble_external. */ > +static struct pointer_set_t *pending_assemble_externals_set; > + > /* True if DECL is a function decl for which no out-of-line copy exists. > It is assumed that DECL's assembler name has been set. */ > > @@ -2140,6 +2144,7 @@ process_pending_assemble_externals (void > assemble_external_real (TREE_VALUE (list)); > > pending_assemble_externals = 0; > + pointer_set_destroy (pending_assemble_externals_set); > #endif > } > > @@ -2191,7 +2196,7 @@ assemble_external (tree decl ATTRIBUTE_U > weak_decls = tree_cons (NULL, decl, weak_decls); > > #ifdef ASM_OUTPUT_EXTERNAL > - if (value_member (decl, pending_assemble_externals) == NULL_TREE) > + if (! pointer_set_insert (pending_assemble_externals_set, decl)) > pending_assemble_externals = tree_cons (NULL, decl, > pending_assemble_externals); > #endif > @@ -5904,6 +5909,10 @@ init_varasm_once (void) > > if (readonly_data_section == NULL) > readonly_data_section = text_section; > + > +#ifdef ASM_OUTPUT_EXTERNAL > + pending_assemble_externals_set = pointer_set_create (); > +#endif > } > > enum tls_model > --- gcc/testsuite/gcc.c-torture/compile/limits-externdecl.c.jj > 2012-12-11 17:59:03.130578361 +0100 > +++ gcc/testsuite/gcc.c-torture/compile/limits-externdecl.c 2012-12-11 > 17:59:03.130578361 +0100 > @@ -0,0 +1,55 @@ > +/* Inspired by the test case for PR middle-end/52640. */ > + > +typedef struct > +{ > + char *value; > +} REFERENCE; > + > +/* Add a few "extern int Xxxxxx ();" declarations. */ > +#undef DEF > +#undef LIM1 > +#undef LIM2 > +#undef LIM3 > +#undef LIM4 > +#undef LIM5 > +#undef LIM6 > +#define DEF(x) extern int x () > +#define LIM1(x) DEF(x##0); DEF(x##1); DEF(x##2); DEF(x##3); DEF(x##4); \ > + DEF(x##5); DEF(x##6); DEF(x##7); DEF(x##8); DEF(x##9); > +#define LIM2(x) LIM1(x##0) LIM1(x##1) LIM1(x##2) LIM1(x##3) LIM1(x##4) \ > + LIM1(x##5) LIM1(x##6) LIM1(x##7) LIM1(x##8) LIM1(x##9) > +#define LIM3(x) LIM2(x##0) LIM2(x##1) LIM2(x##2) LIM2(x##3) LIM2(x##4) \ > + LIM2(x##5) LIM2(x##6) LIM2(x##7) LIM2(x##8) LIM2(x##9) > +#define LIM4(x) LIM3(x##0) LIM3(x##1) LIM3(x##2) LIM3(x##3) LIM3(x##4) \ > + LIM3(x##5) LIM3(x##6) LIM3(x##7) LIM3(x##8) LIM3(x##9) > +#define LIM5(x) LIM4(x##0) LIM4(x##1) LIM4(x##2) LIM4(x##3) LIM4(x##4) \ > + LIM4(x##5) LIM4(x##6) LIM4(x##7) LIM4(x##8) LIM4(x##9) > +#define LIM6(x) LIM5(x##0) LIM5(x##1) LIM5(x##2) LIM5(x##3) LIM5(x##4) \ > + LIM5(x##5) LIM5(x##6) LIM5(x##7) LIM5(x##8) LIM5(x##9) > +LIM5 (X); > + > +/* Add references to them, or GCC will simply ignore the extern decls. */ > +#undef DEF > +#undef LIM1 > +#undef LIM2 > +#undef LIM3 > +#undef LIM4 > +#undef LIM5 > +#undef LIM6 > +#define DEF(x) (char *) x > +#define LIM1(x) DEF(x##0), DEF(x##1), DEF(x##2), DEF(x##3), DEF(x##4), \ > + DEF(x##5), DEF(x##6), DEF(x##7), DEF(x##8), DEF(x##9), > +#define LIM2(x) LIM1(x##0) LIM1(x##1) LIM1(x##2) LIM1(x##3) LIM1(x##4) \ > + LIM1(x##5) LIM1(x##6) LIM1(x##7) LIM1(x##8) LIM1(x##9) > +#define LIM3(x) LIM2(x##0) LIM2(x##1) LIM2(x##2) LIM2(x##3) LIM2(x##4) \ > + LIM2(x##5) LIM2(x##6) LIM2(x##7) LIM2(x##8) LIM2(x##9) > +#define LIM4(x) LIM3(x##0) LIM3(x##1) LIM3(x##2) LIM3(x##3) LIM3(x##4) \ > + LIM3(x##5) LIM3(x##6) LIM3(x##7) LIM3(x##8) LIM3(x##9) > +#define LIM5(x) LIM4(x##0) LIM4(x##1) LIM4(x##2) LIM4(x##3) LIM4(x##4) \ > + LIM4(x##5) LIM4(x##6) LIM4(x##7) LIM4(x##8) LIM4(x##9) > +#define LIM6(x) LIM5(x##0) LIM5(x##1) LIM5(x##2) LIM5(x##3) LIM5(x##4) \ > + LIM5(x##5) LIM5(x##6) LIM5(x##7) LIM5(x##8) LIM5(x##9) > +REFERENCE references[] = { > + LIM5 (X) > + 0 > +}; > > Jakub > > -- Richard Biener <rguent...@suse.de> SUSE / SUSE Labs SUSE LINUX Products GmbH - Nuernberg - AG Nuernberg - HRB 16746 GF: Jeff Hawn, Jennifer Guild, Felix Imend