Commit e756464b by DJ Delorie Committed by DJ Delorie

mep.c (machine_function): Add frame_locked flag.

* config/mep/mep.c (machine_function): Add frame_locked flag.  Set
it once we start generating the prologue or epilogue.
(mep_call_saves_register): If the frame is locked, re-use cached values.
(mep_assign_save_slots): New, broken out from mep_expand_prologue.
(mep_expand_prologue): Call it.
(mep_expand_epilogue): Likewise.
(mep_start_function): Use the same logic as mep_expand_prologue.
(mep_pass_by_reference): Make logic more readable.
(mep_return_in_memory): Zero-sized objects are passed in memory.
(mep_reorg_noframe): Make sure we have accurate REG_DEAD notes.

From-SVN: r151248
parent c8affb45
2009-08-31 DJ Delorie <dj@redhat.com>
* config/mep/mep.c (machine_function): Add frame_locked flag. Set
it once we start generating the prologue or epilogue.
(mep_call_saves_register): If the frame is locked, re-use cached values.
(mep_assign_save_slots): New, broken out from mep_expand_prologue.
(mep_expand_prologue): Call it.
(mep_expand_epilogue): Likewise.
(mep_start_function): Use the same logic as mep_expand_prologue.
(mep_pass_by_reference): Make logic more readable.
(mep_return_in_memory): Zero-sized objects are passed in memory.
(mep_reorg_noframe): Make sure we have accurate REG_DEAD notes.
2009-08-31 Richard Guenther <rguenther@suse.de> 2009-08-31 Richard Guenther <rguenther@suse.de>
* builtins.c (fold_builtin_memory_op): Use the alias oracle * builtins.c (fold_builtin_memory_op): Use the alias oracle
......
...@@ -87,6 +87,7 @@ struct GTY(()) machine_function ...@@ -87,6 +87,7 @@ struct GTY(()) machine_function
int arg_regs_to_save; int arg_regs_to_save;
int regsave_filler; int regsave_filler;
int frame_filler; int frame_filler;
int frame_locked;
/* Records __builtin_return address. */ /* Records __builtin_return address. */
rtx eh_stack_adjust; rtx eh_stack_adjust;
...@@ -2565,7 +2566,7 @@ mep_interrupt_saved_reg (int r) ...@@ -2565,7 +2566,7 @@ mep_interrupt_saved_reg (int r)
static bool static bool
mep_call_saves_register (int r) mep_call_saves_register (int r)
{ {
/* if (cfun->machine->reg_saved[r] == MEP_SAVES_UNKNOWN)*/ if (! cfun->machine->frame_locked)
{ {
int rv = MEP_SAVES_NO; int rv = MEP_SAVES_NO;
...@@ -2630,7 +2631,8 @@ mep_elimination_offset (int from, int to) ...@@ -2630,7 +2631,8 @@ mep_elimination_offset (int from, int to)
int frame_size = get_frame_size () + crtl->outgoing_args_size; int frame_size = get_frame_size () + crtl->outgoing_args_size;
int total_size; int total_size;
memset (cfun->machine->reg_saved, 0, sizeof (cfun->machine->reg_saved)); if (!cfun->machine->frame_locked)
memset (cfun->machine->reg_saved, 0, sizeof (cfun->machine->reg_saved));
/* We don't count arg_regs_to_save in the arg pointer offset, because /* We don't count arg_regs_to_save in the arg pointer offset, because
gcc thinks the arg pointer has moved along with the saved regs. gcc thinks the arg pointer has moved along with the saved regs.
...@@ -2790,31 +2792,17 @@ mep_reload_pointer (int regno, const char *symbol) ...@@ -2790,31 +2792,17 @@ mep_reload_pointer (int regno, const char *symbol)
emit_insn (gen_movsi_botsym_s (reg, reg, sym)); emit_insn (gen_movsi_botsym_s (reg, reg, sym));
} }
void /* Assign save slots for any register not already saved. DImode
mep_expand_prologue (void) registers go at the end of the reg save area; the rest go at the
beginning. This is for alignment purposes. Returns true if a frame
is really needed. */
static bool
mep_assign_save_slots (int reg_save_size)
{ {
int i, rss, sp_offset = 0; bool really_need_stack_frame = false;
int reg_save_size;
int frame_size;
int really_need_stack_frame = frame_size;
int di_ofs = 0; int di_ofs = 0;
int i;
/* We must not allow register renaming in interrupt functions,
because that invalidates the correctness of the set of call-used
registers we're going to save/restore. */
mep_set_leaf_registers (mep_interrupt_p () ? 0 : 1);
if (mep_disinterrupt_p ())
emit_insn (gen_mep_disable_int ());
cfun->machine->mep_frame_pointer_needed = frame_pointer_needed;
reg_save_size = mep_elimination_offset (ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM);
frame_size = mep_elimination_offset (FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM);
/* Assign save slots for any register not already saved. DImode
registers go at the end of the reg save area; the rest go at the
beginning. This is for alignment purposes. */
for (i=0; i<FIRST_PSEUDO_REGISTER; i++) for (i=0; i<FIRST_PSEUDO_REGISTER; i++)
if (mep_call_saves_register(i)) if (mep_call_saves_register(i))
{ {
...@@ -2822,7 +2810,7 @@ mep_expand_prologue (void) ...@@ -2822,7 +2810,7 @@ mep_expand_prologue (void)
if ((i != TP_REGNO && i != GP_REGNO && i != LP_REGNO) if ((i != TP_REGNO && i != GP_REGNO && i != LP_REGNO)
|| mep_reg_set_in_function (i)) || mep_reg_set_in_function (i))
really_need_stack_frame = 1; really_need_stack_frame = true;
if (cfun->machine->reg_save_slot[i]) if (cfun->machine->reg_save_slot[i])
continue; continue;
...@@ -2838,6 +2826,32 @@ mep_expand_prologue (void) ...@@ -2838,6 +2826,32 @@ mep_expand_prologue (void)
di_ofs += 8; di_ofs += 8;
} }
} }
cfun->machine->frame_locked = 1;
return really_need_stack_frame;
}
void
mep_expand_prologue (void)
{
int i, rss, sp_offset = 0;
int reg_save_size;
int frame_size;
int really_need_stack_frame = frame_size;
/* We must not allow register renaming in interrupt functions,
because that invalidates the correctness of the set of call-used
registers we're going to save/restore. */
mep_set_leaf_registers (mep_interrupt_p () ? 0 : 1);
if (mep_disinterrupt_p ())
emit_insn (gen_mep_disable_int ());
cfun->machine->mep_frame_pointer_needed = frame_pointer_needed;
reg_save_size = mep_elimination_offset (ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM);
frame_size = mep_elimination_offset (FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM);
really_need_stack_frame |= mep_assign_save_slots (reg_save_size);
sp_offset = reg_save_size; sp_offset = reg_save_size;
if (sp_offset + frame_size < 128) if (sp_offset + frame_size < 128)
...@@ -3005,7 +3019,12 @@ mep_start_function (FILE *file, HOST_WIDE_INT hwi_local) ...@@ -3005,7 +3019,12 @@ mep_start_function (FILE *file, HOST_WIDE_INT hwi_local)
int r = slot_map[i]; int r = slot_map[i];
int rss = cfun->machine->reg_save_slot[r]; int rss = cfun->machine->reg_save_slot[r];
if (!rss) if (!mep_call_saves_register (r))
continue;
if ((r == TP_REGNO || r == GP_REGNO || r == LP_REGNO)
&& (!mep_reg_set_in_function (r)
&& !mep_interrupt_p ()))
continue; continue;
rsize = mep_reg_size(r); rsize = mep_reg_size(r);
...@@ -3054,14 +3073,7 @@ mep_expand_epilogue (void) ...@@ -3054,14 +3073,7 @@ mep_expand_epilogue (void)
reg_save_size = mep_elimination_offset (ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM); reg_save_size = mep_elimination_offset (ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM);
frame_size = mep_elimination_offset (FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM); frame_size = mep_elimination_offset (FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM);
/* All save slots are set by mep_expand_prologue. */ really_need_stack_frame |= mep_assign_save_slots (reg_save_size);
for (i=0; i<FIRST_PSEUDO_REGISTER; i++)
if (mep_call_saves_register(i))
{
if ((i != TP_REGNO && i != GP_REGNO && i != LP_REGNO)
|| mep_reg_set_in_function (i))
really_need_stack_frame = 1;
}
if (frame_pointer_needed) if (frame_pointer_needed)
{ {
...@@ -3819,9 +3831,19 @@ mep_pass_by_reference (CUMULATIVE_ARGS * cum ATTRIBUTE_UNUSED, ...@@ -3819,9 +3831,19 @@ mep_pass_by_reference (CUMULATIVE_ARGS * cum ATTRIBUTE_UNUSED,
bool named ATTRIBUTE_UNUSED) bool named ATTRIBUTE_UNUSED)
{ {
int size = bytesize (type, mode); int size = bytesize (type, mode);
if (type && TARGET_IVC2 && cum->nregs < 4 && VECTOR_TYPE_P (type))
return size <= 0 || size > 8; /* This is non-obvious, but yes, large values passed after we've run
return size <= 0 || size > 4; out of registers are *still* passed by reference - we put the
address of the parameter on the stack, as well as putting the
parameter itself elsewhere on the stack. */
if (size <= 0 || size > 8)
return true;
if (size <= 4)
return false;
if (TARGET_IVC2 && cum->nregs < 4 && type != NULL_TREE && VECTOR_TYPE_P (type))
return false;
return true;
} }
void void
...@@ -3837,8 +3859,8 @@ mep_return_in_memory (const_tree type, const_tree decl ATTRIBUTE_UNUSED) ...@@ -3837,8 +3859,8 @@ mep_return_in_memory (const_tree type, const_tree decl ATTRIBUTE_UNUSED)
{ {
int size = bytesize (type, BLKmode); int size = bytesize (type, BLKmode);
if (TARGET_IVC2 && VECTOR_TYPE_P (type)) if (TARGET_IVC2 && VECTOR_TYPE_P (type))
return size >= 0 && size <= 8 ? 0 : 1; return size > 0 && size <= 8 ? 0 : 1;
return size >= 0 && size <= 4 ? 0 : 1; return size > 0 && size <= 4 ? 0 : 1;
} }
static bool static bool
...@@ -5879,6 +5901,12 @@ static void ...@@ -5879,6 +5901,12 @@ static void
mep_reorg (void) mep_reorg (void)
{ {
rtx insns = get_insns (); rtx insns = get_insns ();
/* We require accurate REG_DEAD notes. */
compute_bb_for_insn ();
df_note_add_problem ();
df_analyze ();
mep_reorg_addcombine (insns); mep_reorg_addcombine (insns);
#if EXPERIMENTAL_REGMOVE_REORG #if EXPERIMENTAL_REGMOVE_REORG
/* VLIW packing has been done already, so we can't just delete things. */ /* VLIW packing has been done already, so we can't just delete things. */
...@@ -5897,6 +5925,8 @@ mep_reorg (void) ...@@ -5897,6 +5925,8 @@ mep_reorg (void)
/* This may delete *insns so make sure it's last. */ /* This may delete *insns so make sure it's last. */
mep_reorg_noframe (insns); mep_reorg_noframe (insns);
df_finish_pass (false);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment