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][committed] Remove duplicate code in expand_prologue/expand_epilogue


Hi.

  Now for the frame pointer setup code the insn's is generated twice, first
for calculation length of code and then when shorter variant of code are
emitted in function.

  This patch remove duplicate generation of the insn's by making two insn's
sequence for each variants of frame pointer setup code and emitting shorter
sequence. 

2008-05-22  Anatoly Sokolov <aesok@post.ru>

        * config/avr/avr.c (get_sequence_length): Add new function.
        (expand_prologue, expand_epilogue): Remove duplicate code


Index: gcc/config/avr/avr.c
===================================================================
--- gcc/config/avr/avr.c        (revision 135767)
+++ gcc/config/avr/avr.c        (working copy)
@@ -54,6 +54,7 @@
 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 get_sequence_length (rtx insns);
 static int sequent_regs_live (void);
 static const char *ptrreg_to_str (int);
 static const char *cond_string (enum rtx_code);
@@ -585,6 +586,20 @@
   return (cur_seq == live_seq) ? live_seq : 0;
 }
 
+/* Obtain the length sequence of insns.  */
+
+int
+get_sequence_length (rtx insns)
+{
+  rtx insn;
+  int length;
+  
+  for (insn = insns, length = 0; insn; insn = NEXT_INSN (insn))
+    length += get_attr_length (insn);
+               
+  return length;
+}
+
 /*  Output function prologue.  */
 
 void
@@ -718,12 +733,11 @@
               To avoid a complex logic, both methods are tested and shortest
               is selected.  */
               rtx myfp;
-              /*  First method.  */
+             rtx fp_plus_insns; 
+             rtx sp_plus_insns = NULL_RTX;
+
               if (TARGET_TINY_STACK)
                 {
-                  if (size < -63 || size > 63)
-                    warning (0, "large frame pointer change (%d) with -mtiny-stack", size);
-                    
                   /* The high byte (r29) doesn't change - prefer 'subi' (1 cycle)
                      over 'sbiw' (2 cycles, same size).  */
                   myfp = gen_rtx_REG (QImode, REGNO (frame_pointer_rtx));
@@ -733,51 +747,53 @@
                   /*  Normal sized addition.  */
                   myfp = frame_pointer_rtx;
                 }
-              /* Calculate length.  */ 
-              int method1_length;
-              method1_length =
-               get_attr_length (gen_move_insn (frame_pointer_rtx, stack_pointer_rtx));
-              method1_length +=
-               get_attr_length (gen_move_insn (myfp, 
-                                                gen_rtx_PLUS (GET_MODE(myfp), myfp,
-                                                              gen_int_mode (-size, 
-                                                                           GET_MODE(myfp)))));
-              method1_length += 
-               get_attr_length (gen_move_insn (stack_pointer_rtx, frame_pointer_rtx));
-              
+
+             /* Method 1-Adjust frame pointer.  */
+             start_sequence ();
+
+              insn = emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
+              RTX_FRAME_RELATED_P (insn) = 1;
+
+              insn = 
+               emit_move_insn (myfp,
+                               gen_rtx_PLUS (GET_MODE(myfp), myfp, 
+                                             gen_int_mode (-size, 
+                                                           GET_MODE(myfp))));
+              RTX_FRAME_RELATED_P (insn) = 1;
+
+              insn = emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
+              RTX_FRAME_RELATED_P (insn) = 1;
+
+             fp_plus_insns = get_insns ();
+             end_sequence ();
+
              /* Method 2-Adjust Stack pointer.  */
-              int sp_plus_length = 0;
               if (size <= 6)
                 {
-                  sp_plus_length = 
-                   get_attr_length (gen_move_insn (stack_pointer_rtx,
-                                                    gen_rtx_PLUS (HImode, stack_pointer_rtx,
-                                                                  gen_int_mode (-size, 
-                                                                               HImode))));
-                 sp_plus_length += 
-                   get_attr_length (gen_move_insn (frame_pointer_rtx, stack_pointer_rtx));
+                 start_sequence ();
+
+                 insn = 
+                   emit_move_insn (stack_pointer_rtx,
+                                   gen_rtx_PLUS (HImode, 
+                                                 stack_pointer_rtx, 
+                                                 gen_int_mode (-size, 
+                                                               HImode)));
+                 RTX_FRAME_RELATED_P (insn) = 1;
+                 
+                 insn = 
+                   emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
+                 RTX_FRAME_RELATED_P (insn) = 1;
+
+                 sp_plus_insns = get_insns ();
+                 end_sequence ();
                 }
+
               /* Use shortest method.  */
-              if (size <= 6 && (sp_plus_length < method1_length))
-                {
-                  insn = emit_move_insn (stack_pointer_rtx,
-                                         gen_rtx_PLUS (HImode, stack_pointer_rtx, 
-                                                       gen_int_mode (-size, HImode)));
-                  RTX_FRAME_RELATED_P (insn) = 1;
-                 insn = emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
-                  RTX_FRAME_RELATED_P (insn) = 1;
-                }
+              if (size <= 6 && (get_sequence_length (sp_plus_insns) 
+                                < get_sequence_length (fp_plus_insns)))
+               emit_insn (sp_plus_insns);
               else
-                {              
-                  insn = emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
-                  RTX_FRAME_RELATED_P (insn) = 1;
-                  insn = emit_move_insn (myfp,
-                                         gen_rtx_PLUS (GET_MODE(myfp), myfp, 
-                                                       gen_int_mode (-size, GET_MODE(myfp))));
-                  RTX_FRAME_RELATED_P (insn) = 1;
-                  insn = emit_move_insn ( stack_pointer_rtx, frame_pointer_rtx);
-                  RTX_FRAME_RELATED_P (insn) = 1;
-                }
+               emit_insn (fp_plus_insns);
             }
         }
     }
@@ -872,42 +888,56 @@
          if (size)
            {
               /* Try two methods to adjust stack and select shortest.  */
-              int fp_plus_length;
+             rtx myfp;
+             rtx fp_plus_insns;
+             rtx sp_plus_insns = NULL_RTX;
+             
+             if (TARGET_TINY_STACK)
+                {
+                  /* The high byte (r29) doesn't change - prefer 'subi' 
+                     (1 cycle) over 'sbiw' (2 cycles, same size).  */
+                  myfp = gen_rtx_REG (QImode, REGNO (frame_pointer_rtx));
+                }
+              else 
+                {
+                  /* Normal sized addition.  */
+                  myfp = frame_pointer_rtx;
+                }
+             
               /* Method 1-Adjust frame pointer.  */
-              fp_plus_length = 
-               get_attr_length (gen_move_insn (frame_pointer_rtx,
-                                                gen_rtx_PLUS (HImode, frame_pointer_rtx,
-                                                              gen_int_mode (size,
-                                                                           HImode))));
-              /* Copy to stack pointer.  */
-              fp_plus_length += 
-               get_attr_length (gen_move_insn (stack_pointer_rtx, frame_pointer_rtx));    
-          
+             start_sequence ();
+
+             emit_move_insn (myfp,
+                             gen_rtx_PLUS (HImode, myfp,
+                                           gen_int_mode (size, 
+                                                         GET_MODE(myfp))));
+
+             /* Copy to stack pointer.  */
+             emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
+
+             fp_plus_insns = get_insns ();
+             end_sequence ();        
+
               /* Method 2-Adjust Stack pointer.  */
-              int sp_plus_length = 0;
               if (size <= 5)
                 {
-                  sp_plus_length = 
-                   get_attr_length (gen_move_insn (stack_pointer_rtx,
-                                                    gen_rtx_PLUS (HImode, stack_pointer_rtx,
-                                                                  gen_int_mode (size,
-                                                                               HImode))));
+                 start_sequence ();
+
+                 emit_move_insn (stack_pointer_rtx,
+                                 gen_rtx_PLUS (HImode, stack_pointer_rtx,
+                                               gen_int_mode (size, 
+                                                             HImode)));
+
+                 sp_plus_insns = get_insns ();
+                 end_sequence ();
                 }
+
               /* Use shortest method.  */
-              if (size <= 5 && (sp_plus_length < fp_plus_length))
-                {
-                  emit_move_insn (stack_pointer_rtx,
-                                  gen_rtx_PLUS (HImode, stack_pointer_rtx,
-                                                gen_int_mode (size, HImode)));
-                }
+              if (size <= 5 && (get_sequence_length (sp_plus_insns) 
+                                < get_sequence_length (fp_plus_insns)))
+               emit_insn (sp_plus_insns);
               else
-                {
-                  emit_move_insn (frame_pointer_rtx,
-                                  gen_rtx_PLUS (HImode, frame_pointer_rtx,
-                                                gen_int_mode (size, HImode)));
-                  /* Copy to stack pointer.  */
-                  emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
-                }
+               emit_insn (fp_plus_insns);
             }
          if (!(cfun->machine->is_OS_task || cfun->machine->is_OS_main))
            {


Anatoly.


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