public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [AVR][committed] Remove duplicate code in expand_prologue/expand_epilogue
@ 2008-05-22 19:25 Anatoly Sokolov
  0 siblings, 0 replies; only message in thread
From: Anatoly Sokolov @ 2008-05-22 19:25 UTC (permalink / raw)
  To: gcc-patches; +Cc: aesok, hutchinsonandy

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.

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2008-05-22 18:54 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-05-22 19:25 [AVR][committed] Remove duplicate code in expand_prologue/expand_epilogue Anatoly Sokolov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).