Patchwork [RFA] Avoid non-static&external vars in varpool

login
register
mail settings
Submitter Jan Hubicka
Date Sept. 2, 2010, 7:28 p.m.
Message ID <20100902192815.GN1664@kam.mff.cuni.cz>
Download mbox | patch
Permalink /patch/63518/
State New
Headers show

Comments

Jan Hubicka - Sept. 2, 2010, 7:28 p.m.
Hi,
this patch fixes problem with gfortran adding local var into varpool.  I first considered
it to be bug in the frontend, but rest_of_decl_compilation comment seems to agree with fortran's
behaviour:

   This is called from various places for FUNCTION_DECL, VAR_DECL,
   and TYPE_DECL nodes.

   This does nothing for local (non-static) variables, unless the
   variable is a register variable with DECL_ASSEMBLER_NAME set.  In
   that case, or if the variable is not an automatic, it sets up the
   RTL and outputs any assembler code (label definition, storage
   allocation and initialization).

So this patch makes it really no-op on local vars and also adds sanity check to varpool.

Bootstrapped and regtested x86_64-linux, OK?

Honza

	* passes.c (rest_of_decl_compilation): Do not add local vars into varpol.
	* varpool.c (varpool_get_node, varpool_node): Sanity check that only
	static or extern vars are in varpool.
	(varpool_finalize_decl): Sanity check that only static vars are finalized.
Richard Henderson - Sept. 2, 2010, 7:35 p.m.
On 09/02/2010 12:28 PM, Jan Hubicka wrote:
> 	* passes.c (rest_of_decl_compilation): Do not add local vars into varpol.
> 	* varpool.c (varpool_get_node, varpool_node): Sanity check that only
> 	static or extern vars are in varpool.
> 	(varpool_finalize_decl): Sanity check that only static vars are finalized.

Looks good.


r~
H.J. Lu - Jan. 15, 2011, 4:53 p.m.
On Thu, Sep 2, 2010 at 12:28 PM, Jan Hubicka <hubicka@ucw.cz> wrote:
> Hi,
> this patch fixes problem with gfortran adding local var into varpool.  I first considered
> it to be bug in the frontend, but rest_of_decl_compilation comment seems to agree with fortran's
> behaviour:
>
>   This is called from various places for FUNCTION_DECL, VAR_DECL,
>   and TYPE_DECL nodes.
>
>   This does nothing for local (non-static) variables, unless the
>   variable is a register variable with DECL_ASSEMBLER_NAME set.  In
>   that case, or if the variable is not an automatic, it sets up the
>   RTL and outputs any assembler code (label definition, storage
>   allocation and initialization).
>
> So this patch makes it really no-op on local vars and also adds sanity check to varpool.
>
> Bootstrapped and regtested x86_64-linux, OK?
>
> Honza
>
>        * passes.c (rest_of_decl_compilation): Do not add local vars into varpol.
>        * varpool.c (varpool_get_node, varpool_node): Sanity check that only
>        static or extern vars are in varpool.
>        (varpool_finalize_decl): Sanity check that only static vars are finalized.

This caused:

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47303

Patch

Index: passes.c
===================================================================
--- passes.c	(revision 163779)
+++ passes.c	(working copy)
@@ -219,7 +219,8 @@  rest_of_decl_compilation (tree decl,
   /* Let cgraph know about the existence of variables.  */
   if (in_lto_p && !at_end)
     ;
-  else if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl))
+  else if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl)
+	   && TREE_STATIC (decl))
     varpool_node (decl);
 }
 
Index: varpool.c
===================================================================
--- varpool.c	(revision 163779)
+++ varpool.c	(working copy)
@@ -111,7 +111,8 @@  varpool_get_node (tree decl)
 {
   struct varpool_node key, **slot;
 
-  gcc_assert (DECL_P (decl) && TREE_CODE (decl) != FUNCTION_DECL);
+  gcc_assert (TREE_CODE (decl) == VAR_DECL
+	      && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)));
 
   if (!varpool_hash)
     return NULL;
@@ -129,7 +130,8 @@  varpool_node (tree decl)
 {
   struct varpool_node key, *node, **slot;
 
-  gcc_assert (DECL_P (decl) && TREE_CODE (decl) != FUNCTION_DECL);
+  gcc_assert (TREE_CODE (decl) == VAR_DECL
+	      && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)));
 
   if (!varpool_hash)
     varpool_hash = htab_create_ggc (10, hash_varpool_node,
@@ -365,6 +398,8 @@  varpool_finalize_decl (tree decl)
 {
   struct varpool_node *node = varpool_node (decl);
 
+  gcc_assert (TREE_STATIC (decl));
+
   /* The first declaration of a variable that comes through this function
      decides whether it is global (in C, has external linkage)
      or local (in C, has internal linkage).  So do nothing more