This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix PR optimization/7675


Hi,

This is a regression from gcc 2.95.3 present in all 3.x versions. The 
compiler ICEs when fixing the insns of a parent function after its child 
caused some registers to be put into the stack. See
	http://gcc.gnu.org/ml/gcc-patches/2002-12/msg00336.html
for the complete explanation.

Richard suggested that we compile the nested functions first, before 
beginning RTL expansion for the parent function. However, given that the 
problem can be triggered by an assignment via DECL_INITIAL for any automatic 
variable, I think this would imply that we would have to instantiate the 
automatic variables of the parent while compiling the child function, which 
appears convoluted to me.

I think we can use a simpler solution: instead of setting the DECL_NONLOCAL 
flag during RTL expansion of the nested functions, we can set it during 
parsing of the nested functions. Then we have the information during RTL 
expansion of the parent function and we put the automatic variables into the 
stack as needed.

Bootstrapped/regtested on i586-redhat-linux-gnu (c,c++,objc,f77 mainline).
Ok for mainline? Ok for 3.3 after similar testing?

-- 
Eric Botcazou


2003-04-15  Eric Botcazou  <ebotcazou at libertysurf dot fr>

        PR optimization/7675
	* c-typeck.c (build_external_ref): Set the DECL_NONLOCAL flag
	on VAR_DECL, PARM_DECL and FUNCTION_DECL from within
	nested functions if they refer to declarations from parent functions.
	* stmt.c (expand_decl): Don't put automatic variables in registers
	if the DECL_NONLOCAL flag is set.


2003-04-15  Eric Botcazou  <ebotcazou at libertysurf dot fr>

        * gcc.c-torture/compile/20030415-1.c: New test.
Index: c-typeck.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-typeck.c,v
retrieving revision 1.232
diff -u -p -r1.232 c-typeck.c
--- c-typeck.c	13 Apr 2003 03:31:09 -0000	1.232
+++ c-typeck.c	15 Apr 2003 18:41:55 -0000
@@ -1463,6 +1463,17 @@ build_external_ref (id, fun)
       ref = DECL_INITIAL (ref);
       TREE_CONSTANT (ref) = 1;
     }
+  else if (current_function_decl != 0
+	   && DECL_CONTEXT (current_function_decl) != 0
+	   && (TREE_CODE (ref) == VAR_DECL
+	       || TREE_CODE (ref) == PARM_DECL
+	       || TREE_CODE (ref) == FUNCTION_DECL))
+    {
+      tree context = decl_function_context (ref);
+    
+      if (context != 0 && context != current_function_decl)
+	DECL_NONLOCAL (ref) = 1;
+    }
 
   return ref;
 }
Index: stmt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/stmt.c,v
retrieving revision 1.297
diff -u -p -r1.297 stmt.c
--- stmt.c	24 Mar 2003 08:31:31 -0000	1.297
+++ stmt.c	15 Apr 2003 18:42:17 -0000
@@ -3924,6 +3924,7 @@ expand_decl (decl)
 	   && !(flag_float_store
 		&& TREE_CODE (type) == REAL_TYPE)
 	   && ! TREE_THIS_VOLATILE (decl)
+	   && ! DECL_NONLOCAL (decl)
 	   && (DECL_REGISTER (decl) || optimize))
     {
       /* Automatic variable that can go in a register.  */
/* PR optimization/7675 */
/* Contributed by Volker Reichelt */

/* Verify that we don't put automatic variables
   in registers too early.  */

extern int dummy (int *);

void foo(int i)
{
  int j=i;

  void bar() { int x=j, y=i; }

  dummy(&i);
}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]