This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[AVR][committed] Remove duplicate code in expand_prologue/expand_epilogue
- From: Anatoly Sokolov <aesok at post dot ru>
- To: gcc-patches <gcc-patches at gcc dot gnu dot org>
- Cc: aesok at post dot ru, hutchinsonandy at aim dot com
- Date: Thu, 22 May 2008 22:54:03 +0400
- Subject: [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.