This is the mail archive of the gcc@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]

Another code generation bug in EGCS-1.0.1


EGCS-1.0.1 (and GCC-2.8.0) can generate bad code when configured
for PowerPC and SYSV4-ABI (Linux/PPC).  In this configuration, the
stack is managed differently when varargs are present (a stack space
optimization).  However, for inlined functions that end up not
generated inline and nested functions, this optimization is lost and
the generated functions generate incorrect preamble code which will
destroy the runtime stack.

Code exists in the current version to try and address this for the nested
functions case, but it was a little wrong (patch to "function.c").  Also,
the case of inline functions was not present at all.

A patch is attached which solves both problems.

------------------------------------------------------------------------
Gary Thomas                              |
The Open Group / Research Institute      | "Fine wine is a necessity of
2 Avenue de Vignate                      |        life for me"
38610 Gieres - FRANCE                    |
+33 4 76 63 48 74                        |      Thomas Jefferson
email: g.thomas@opengroup.org            |
<http://www.opengroup.org/~gdt>          |
   ... opinions expressed here are mine  |
       and no one else would claim them! |
------------------------------------------------------------------------


* This patch fixes problems with the RS6000/PowerPC compilers.
  Nested functions and inline functions which have varargs will
  generate incorrect code (for SYSV4 ABI only).  This is because
  the code generation 'back end' tries to optimize information about
  stack usage.  'varargs' functions need very different stack layouts
  and without the patch, the fact that a function contains 'varargs'
  get's lost.  
  Note: Mike Meissner already had some of this support in the code for
  nested functions, but it wasn't correct (see change to "function.c").
  I couldn't see how to use those changes for inline functions, so I
  mimicked them in the changes in "integrate.c".

--- egcs-1.0/gcc/config/rs6000/rs6000.c.orig	Sun Feb  8 07:41:41 1998
+++ egcs-1.0/gcc/config/rs6000/rs6000.c	Sun Feb  8 07:43:43 1998
@@ -38,6 +38,7 @@
 #include "tree.h"
 #include "except.h"
 #include "function.h"
+#include "integrate.h"
 
 #ifndef TARGET_NO_PROTOTYPE
 #define TARGET_NO_PROTOTYPE 0
@@ -2385,6 +2386,32 @@
   p->machine = (struct machine_function *)0;
 }
 
+void *
+rs6000_save_machine_context(void)
+{
+  struct machine_function *machine =
+    (struct machine_function *) xmalloc (sizeof (struct machine_function));
+
+  machine->sysv_varargs_p = rs6000_sysv_varargs_p;
+  machine->fpmem_size     = rs6000_fpmem_size;
+  machine->fpmem_offset   = rs6000_fpmem_offset;
+  machine->pic_offset_table_rtx = pic_offset_table_rtx;
+  return((void *)machine);
+}
+
+void
+rs6000_restore_machine_context(void *p)
+{
+  struct machine_function *machine = p;
+
+  rs6000_sysv_varargs_p = machine->sysv_varargs_p;
+  rs6000_fpmem_size     = machine->fpmem_size;
+  rs6000_fpmem_offset   = machine->fpmem_offset;
+  pic_offset_table_rtx  = machine->pic_offset_table_rtx;
+
+  free (machine);
+}
+
 /* Do anything needed before RTL is emitted for each function.  */
 
 void
@@ -2399,6 +2426,9 @@
   /* Arrange to save and restore machine status around nested functions.  */
   save_machine_status = rs6000_save_machine_status;
   restore_machine_status = rs6000_restore_machine_status;
+  /* And for inline routines */
+  save_machine_context = rs6000_save_machine_context;
+  restore_machine_context = rs6000_restore_machine_context;
 }
 
  
--- egcs-1.0/gcc/integrate.c.orig	Sat Oct 25 18:23:10 1997
+++ egcs-1.0/gcc/integrate.c	Sun Feb  8 07:43:30 1998
@@ -76,6 +76,13 @@
 static void set_block_abstract_flags PROTO((tree, int));
 
 void set_decl_abstract_flags	PROTO((tree, int));
+
+/* These variables hold pointers to functions to
+   save and restore machine-specific context data,
+   used to properly handle inline function code generation */
+void *(*save_machine_context) PROTO((void));
+void (*restore_machine_context) PROTO((void *));
+
  
 /* Zero if the current function (whose FUNCTION_DECL is FNDECL)
    is safe and reasonable to integrate into other functions.
@@ -251,6 +258,10 @@
   rtvec arg_vector;
   tree parms;
 
+  /* Save context specific for this function */
+  if (save_machine_context)
+    fndecl->decl.machine_context = (*save_machine_context)();
+
   /* Compute the values of any flags we must restore when inlining this.  */
 
   function_flags
@@ -3183,6 +3194,10 @@
 
   /* This call is only used to initialize global variables.  */
   init_function_start (fndecl, "lossage", 1);
+
+  /* Restore context - maybe instead of 'init_function_start()' */
+  if (restore_machine_context)
+    (*restore_machine_context)(fndecl->decl.machine_context);
 
   /* Redo parameter determinations in case the FUNCTION_...
      macros took machine-specific actions that need to be redone.  */
--- egcs-1.0/gcc/integrate.h.orig	Mon Aug 11 17:57:10 1997
+++ egcs-1.0/gcc/integrate.h	Sun Feb  8 07:43:30 1998
@@ -128,3 +128,9 @@
 
 extern rtx *global_const_equiv_map;
 extern int global_const_equiv_map_size;
+
+/* These variables hold pointers to functions to
+   save and restore machine-specific context data,
+   used to properly handle inline function code generation */
+extern void *(*save_machine_context) PROTO((void));
+extern void (*restore_machine_context) PROTO((void *));
--- egcs-1.0/gcc/tree.h.orig	Wed Oct 15 19:19:40 1997
+++ egcs-1.0/gcc/tree.h	Sun Feb  8 07:43:30 1998
@@ -1165,6 +1165,7 @@
   union tree_node *assembler_name;
   union tree_node *section_name;
   union tree_node *machine_attributes;
+  void *machine_context;
   struct rtx_def *rtl;	/* acts as link to register transfer language
 				   (rtl) info */
   /* For FUNCTION_DECLs: points to insn that constitutes its definition

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