This is the mail archive of the gcc-patches@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]
Other format: [Raw text]

[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.


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