This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: avoid unnecessary register saves for setjmp
On Fri, 2003-11-21 at 12:11, Geoff Keating wrote:
> I've looked at this some time in the past (I don't remember the exact
> circumstances). I came to the same conclusion as you, except in the
> case when NON_SAVING_SETJMP is defined, when we do need to save any
> call-saved registers.
This is an attempt to make NON_SAVING_SETJMP work again, as I offered to do a
week ago before I caught the flu.
As mentioned before, the current code which sets regs_ever_live in
final_start_function only works if there is no register elimination, and if
the prologue/epilogue are emitted as assembly language. This makes the code
work again by moving the code to reload. The result is similar to the code
I deleted a week ago, except that it is only enabled if NON_SAVING_SETMP is
true.
There is only one port that defines NON_SAVING_SETJMP: i386-sysv. It won't
build because of bit-rot, and it is on the list of targets to be obsoleted, and
I don't have access to it anyways. So there is no good way to test this
change.
I tested this by building a i386-linux toolchain, with NON_SAVING_SETJMP set to
true and compiling a small testcase. No registers are saved without this
patch. With this patch, all call-saved regs are saved in the prologue and
restored in the epilogue. There is code in function.c to avoid using registers
for locals in a function that calls setjmp when NON_SAVING_SETJMP is true, so
this is sufficient to ensure that gcc works even if setjmp doesn't save
registers.
To make sure I didn't introduce a stupid typo, I did 3 x86-linux bootstraps
with --enable-languages=c, one with NON_SAVING_SETMP undefined, one with it
defined to 0, and one with it defined to 1.
2003-11-29 James E Wilson <wilson@specifixinc.com>
* final.c (final_start_function): Delete code for NON_SAVING_SETJMP.
* reload1.c (reload): Re-add it here.
Index: reload1.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/reload1.c,v
retrieving revision 1.413
diff -p -r1.413 reload1.c
*** reload1.c 21 Nov 2003 05:49:05 -0000 1.413
--- reload1.c 30 Nov 2003 05:12:16 -0000
*************** reload (rtx first, int global)
*** 673,678 ****
--- 673,689 ----
if (! call_used_regs[i] && ! fixed_regs[i] && ! LOCAL_REGNO (i))
regs_ever_live[i] = 1;
+ #ifdef NON_SAVING_SETJMP
+ /* A function that calls setjmp should save and restore all the
+ call-saved registers on a system where longjmp clobbers them. */
+ if (NON_SAVING_SETJMP && current_function_calls_setjmp)
+ {
+ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+ if (! call_used_regs[i])
+ regs_ever_live[i] = 1;
+ }
+ #endif
+
/* Find all the pseudo registers that didn't get hard regs
but do have known equivalent constants or memory slots.
These include parameters (known equivalent to parameter slots)
Index: final.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/final.c,v
retrieving revision 1.294
diff -p -r1.294 final.c
*** final.c 1 Nov 2003 00:48:50 -0000 1.294
--- final.c 30 Nov 2003 05:12:19 -0000
*************** final_start_function (rtx first ATTRIBUT
*** 1336,1354 ****
this_is_asm_operands = 0;
- #ifdef NON_SAVING_SETJMP
- /* A function that calls setjmp should save and restore all the
- call-saved registers on a system where longjmp clobbers them. */
- if (NON_SAVING_SETJMP && current_function_calls_setjmp)
- {
- int i;
-
- for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
- if (!call_used_regs[i])
- regs_ever_live[i] = 1;
- }
- #endif
-
last_filename = locator_file (prologue_locator);
last_linenum = locator_line (prologue_locator);
--- 1336,1341 ----
--
Jim Wilson, GNU Tools Support, http://www.SpecifixInc.com