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] Add 'OS_main' attribute. (Need middle-end approval.)


Hello.

This patch adds an 'OS_main' attribute to the AVR port. The 'main' functions
with 'OS_main' attribute do not save any "call-saved" registers, requiring
less stack space.

  This patch add the 'prologue_contains' function in 'function.c' file.
Please consider this for approval.

2008-04-03  Anatoly Sokolov <aesok@post.ru>

        * rtl.h (prologue_contains): New declaration.
        * function.c (prologue_contains):  New function.
        * config/avr/avr.h (machine_function): Add 'is_OS_main' field.
        * config/avr/avr.c (avr_OS_main_function_p): Add new function.
        (avr_attribute_table): Add 'OS_main' function attribute.
        (avr_regs_to_save, expand_prologue, expand_epilogue, output_movhi): 
        Handle functions with 'OS_main' attribute.

Index: gcc/function.c
===================================================================
--- gcc/function.c      (revision 133869)
+++ gcc/function.c      (working copy)
@@ -4698,6 +4698,14 @@
 }
 
 int
+prologue_contains (const_rtx insn)
+{
+  if (contains (insn, &prologue))
+    return 1;
+  return 0;
+}
+
+int
 prologue_epilogue_contains (const_rtx insn)
 {
   if (contains (insn, &prologue))
Index: gcc/rtl.h
===================================================================
--- gcc/rtl.h   (revision 133869)
+++ gcc/rtl.h   (working copy)
@@ -2128,6 +2128,7 @@
 
 /* In function.c */
 extern void reposition_prologue_and_epilogue_notes (void);
+extern int prologue_contains (const_rtx);
 extern int prologue_epilogue_contains (const_rtx);
 extern int sibcall_epilogue_contains (const_rtx);
 extern void mark_temp_addr_taken (rtx);
Index: gcc/config/avr/avr.c
===================================================================
--- gcc/config/avr/avr.c        (revision 133869)
+++ gcc/config/avr/avr.c        (working copy)
@@ -52,6 +52,7 @@
 static int interrupt_function_p (tree);
 static int signal_function_p (tree);
 static int avr_OS_task_function_p (tree);
+static int avr_OS_main_function_p (tree);
 static int avr_regs_to_save (HARD_REG_SET *);
 static int sequent_regs_live (void);
 static const char *ptrreg_to_str (int);
@@ -465,6 +466,19 @@
   return a != NULL_TREE;
 }
 
+/* Return nonzero if FUNC is a OS_main function.  */
+
+static int
+avr_OS_main_function_p (tree func)
+{
+  tree a;
+
+  gcc_assert (TREE_CODE (func) == FUNCTION_DECL);
+  
+  a = lookup_attribute ("OS_main", TYPE_ATTRIBUTES (TREE_TYPE (func)));
+  return a != NULL_TREE;
+}
+
 /* Return the number of hard registers to push/pop in the prologue/epilogue
    of the current function, and optionally store these registers in SET.  */
 
@@ -481,9 +495,10 @@
   count = 0;
 
   /* No need to save any registers if the function never returns or 
-     is have "OS_task" attribute.  */
+     is have "OS_task" or "OS_main" attribute.  */
   if (TREE_THIS_VOLATILE (current_function_decl)
-      || cfun->machine->is_OS_task)
+      || cfun->machine->is_OS_task
+      || cfun->machine->is_OS_main)
     return 0;
 
   for (reg = 0; reg < 32; reg++)
@@ -610,6 +625,7 @@
   cfun->machine->is_interrupt = interrupt_function_p (current_function_decl);
   cfun->machine->is_signal = signal_function_p (current_function_decl);
   cfun->machine->is_OS_task = avr_OS_task_function_p (current_function_decl);
+  cfun->machine->is_OS_main = avr_OS_main_function_p (current_function_decl);
   
   /* Prologue: naked.  */
   if (cfun->machine->is_naked)
@@ -623,6 +639,7 @@
              && !cfun->machine->is_interrupt
              && !cfun->machine->is_signal
              && !cfun->machine->is_OS_task
+             && !cfun->machine->is_OS_main
              && live_seq);
 
   if (cfun->machine->is_interrupt || cfun->machine->is_signal)
@@ -692,7 +709,7 @@
         }
       if (frame_pointer_needed)
         {
-         if(!cfun->machine->is_OS_task)
+         if (!(cfun->machine->is_OS_task || cfun->machine->is_OS_main))
            {
               /* Push frame pointer.  */
              insn = emit_move_insn (pushword, frame_pointer_rtx);
@@ -846,6 +863,7 @@
              && !cfun->machine->is_interrupt
              && !cfun->machine->is_signal
              && !cfun->machine->is_OS_task
+             && !cfun->machine->is_OS_main
              && live_seq);
   
   if (minimize && (frame_pointer_needed || live_seq > 4))
@@ -908,7 +926,7 @@
                   emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
                 }
             }
-         if(!cfun->machine->is_OS_task)
+         if (!(cfun->machine->is_OS_task || cfun->machine->is_OS_main))
            {
               /* Restore previous frame_pointer.  */
              emit_insn (gen_pophi (frame_pointer_rtx));
@@ -1684,7 +1702,10 @@
              else if (TARGET_NO_INTERRUPTS 
                         || (reload_completed 
                             && cfun->machine->is_signal 
-                            && prologue_epilogue_contains (insn)))
+                            && prologue_epilogue_contains (insn))
+                       || (reload_completed 
+                            && cfun->machine->is_OS_main 
+                            && prologue_contains (insn)))
                 {
                   *l = 2;
                   return (AS2 (out,__SP_H__,%B1) CR_TAB
@@ -4610,6 +4631,7 @@
   { "interrupt", 0, 0, true,  false, false,  avr_handle_fndecl_attribute },
   { "naked",     0, 0, false, true,  true,   avr_handle_fntype_attribute },
   { "OS_task",   0, 0, false, true,  true,   avr_handle_fntype_attribute },
+  { "OS_main",   0, 0, false, true,  true,   avr_handle_fntype_attribute },
   { NULL,        0, 0, false, false, false, NULL }
 };
 
Index: gcc/config/avr/avr.h
===================================================================
--- gcc/config/avr/avr.h        (revision 133869)
+++ gcc/config/avr/avr.h        (working copy)
@@ -1039,7 +1039,11 @@
      as specified by the "signal" attribute.  */
   int is_signal;
   
-  /* 'true' - if current function is a signal function 
+  /* 'true' - if current function is a task function 
      as specified by the "OS_task" attribute.  */
   int is_OS_task;
+
+  /* 'true' - if current function is a 'main' function 
+     as specified by the "OS_main" attribute.  */
+  int is_OS_main;
 };


 Anatoly


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