Patchwork Forward port Steven's PR middle-end/52640 patch

login
register
mail settings
Submitter Jakub Jelinek
Date Dec. 11, 2012, 9:30 p.m.
Message ID <20121211213035.GX2315@tucnak.redhat.com>
Download mbox | patch
Permalink /patch/205302/
State New
Headers show

Comments

Jakub Jelinek - Dec. 11, 2012, 9:30 p.m.
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?

2012-12-11  Steven Bosscher  <steven@gcc.gnu.org>
	    Jakub Jelinek  <jakub@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.


	Jakub
Richard Guenther - Dec. 12, 2012, 9:20 a.m.
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  <steven@gcc.gnu.org>
> 	    Jakub Jelinek  <jakub@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
> 
>

Patch

--- 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
+};