This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[AVR][commited][4.4,4.3] Save all call-used registers in interrupt handler routine if it is not leaf function
- From: Anatoly Sokolov <aesok at post dot ru>
- To: gcc-patches at gcc dot gnu dot org
- Cc: aesok at post dot ru, eweddington at cso dot atmel dot com, hutchinsonandy at aim dot com
- Date: Mon, 12 May 2008 23:50:16 +0400
- Subject: [AVR][commited][4.4,4.3] Save all call-used registers in interrupt handler routine if it is not leaf function
Hello.
Now avr-gcc don't save all call-used registers in interrupt handler routine
if it do function call, but should. The reason is in 'leaf_function_p'
function, it not always returns correct value. Comment from arm.c:
/* We need to know if we are a leaf function. Unfortunately, it
is possible to be called after start_sequence has been called,
which causes get_insns to return the insns for the sequence,
not the function, which will cause leaf_function_p to return
the incorrect result.
to know about leaf functions once reload has completed, and the
frame size cannot be changed after that time, so we can safely
use the cached value. */
This patch save result of 'leaf_function_p' function before reload, and use
cached value after.
2008-05-12 Anatoly Sokolov <aesok@post.ru>
* config/avr/avr.h (machine_function): Add 'is_leaf' field.
* config/avr/avr.c (avr_regs_to_save): Compute 'machine->is_leaf'.
Use 'machine->is_leaf' instead of 'leaf_func_p'.
Index: gcc/config/avr/avr.c
===================================================================
--- gcc/config/avr/avr.c (revision 134897)
+++ gcc/config/avr/avr.c (working copy)
@@ -471,8 +471,10 @@
int reg, count;
int int_or_sig_p = (interrupt_function_p (current_function_decl)
|| signal_function_p (current_function_decl));
- int leaf_func_p = leaf_function_p ();
+ if (!reload_completed)
+ cfun->machine->is_leaf = leaf_function_p ();
+
if (set)
CLEAR_HARD_REG_SET (*set);
count = 0;
@@ -490,7 +492,7 @@
if (fixed_regs[reg])
continue;
- if ((int_or_sig_p && !leaf_func_p && call_used_regs[reg])
+ if ((int_or_sig_p && !cfun->machine->is_leaf && call_used_regs[reg])
|| (df_regs_ever_live_p (reg)
&& (int_or_sig_p || !call_used_regs[reg])
&& !(frame_pointer_needed
Index: gcc/config/avr/avr.h
===================================================================
--- gcc/config/avr/avr.h (revision 134897)
+++ gcc/config/avr/avr.h (working copy)
@@ -1026,6 +1026,9 @@
This is added to the cfun structure. */
struct machine_function GTY(())
{
+ /* 'true' - if the current function is a leaf function. */
+ int is_leaf;
+
/* 'true' - if current function is a naked function. */
int is_naked;
Anatoly.