This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Another code generation bug in EGCS-1.0.1
- To: egcs at cygnus dot com
- Subject: Another code generation bug in EGCS-1.0.1
- From: Gary Thomas <g dot thomas at opengroup dot org>
- Date: Sun, 08 Feb 1998 10:10:02 +0100 (MET)
- Cc: Michael Meissner <meissner at cygnus dot com>, David Edelsohn <dje at watson dot ibm dot com>
- Organization: The Open Group / Research Institute
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