------- Comment #20 from jakub at gcc dot gnu dot org 2007-08-29 08:52 ------- typedef struct { int abi; unsigned nargs; void **arg_types; void *rtype; unsigned bytes; unsigned flags; } ffi_cif;
void ffi_java_raw_to_ptrarray (ffi_cif *cif, void *raw, void **args); void ffi_java_rvalue_to_raw (ffi_cif *cif, void *rvalue); void ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue); void ffi_java_raw_call (ffi_cif *cif, void (*fn)(), void *rvalue, void *raw) { void **avalue = (void**) __builtin_alloca (cif->nargs * sizeof (void*)); ffi_java_raw_to_ptrarray (cif, raw, avalue); ffi_call (cif, fn, rvalue, avalue); ffi_java_rvalue_to_raw (cif, rvalue); } -m32 -O2 -fexceptions -fno-dce vs. -m32 -O2 -fexceptions -fdce shows the same difference. The assignment of stack pointer to hard frame pointer is removed during *.peephole2. Although the hard frame pointer is never referenced directly in the function, it is really necessary for proper unwind info, given that the function uses alloca and stack pointer is decreased by some non-constant value. Here is an executable testcase for inclusion in the testsuite. Fails with both ppc -m32 and -m64 at -O2 -fexceptions, doesn't fail with -O2 -fno-dce -fexceptions. /* HP-UX libunwind.so doesn't provide _UA_END_OF_STACK */ /* { dg-do run } */ /* { dg-options "-O2 -fexceptions" } */ /* { dg-skip-if "" { "ia64-*-hpux11.*" } { "*" } { "" } } */ /* Verify unwind info in presence of alloca. */ #include <unwind.h> #include <stdlib.h> #include <string.h> static _Unwind_Reason_Code force_unwind_stop (int version, _Unwind_Action actions, _Unwind_Exception_Class exc_class, struct _Unwind_Exception *exc_obj, struct _Unwind_Context *context, void *stop_parameter) { if (actions & _UA_END_OF_STACK) abort (); return _URC_NO_REASON; } static void force_unwind (void) { struct _Unwind_Exception *exc = malloc (sizeof (*exc)); memset (&exc->exception_class, 0, sizeof (exc->exception_class)); exc->exception_cleanup = 0; #ifndef __USING_SJLJ_EXCEPTIONS__ _Unwind_ForcedUnwind (exc, force_unwind_stop, 0); #else _Unwind_SjLj_ForcedUnwind (exc, force_unwind_stop, 0); #endif abort (); } __attribute__((noinline)) void foo (void *x __attribute__((unused))) { force_unwind (); } __attribute__((noinline)) int bar (unsigned int x) { void *y = __builtin_alloca (x); foo (y); return 1; } static void handler (void *p __attribute__((unused))) { exit (0); } __attribute__((noinline)) static void doit () { char dummy __attribute__((cleanup (handler))); bar (1024); } int main () { doit (); abort (); } -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=32758