]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
mep.c (machine_function): Add frame_locked flag.
authorDJ Delorie <dj@redhat.com>
Mon, 31 Aug 2009 21:37:49 +0000 (17:37 -0400)
committerDJ Delorie <dj@gcc.gnu.org>
Mon, 31 Aug 2009 21:37:49 +0000 (17:37 -0400)
* 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

gcc/ChangeLog
gcc/config/mep/mep.c

index 928235524fabd8b82e52dc9ac95869fc854e3003..e8f83027bf2eb98000ea64725220d0b22d70c562 100644 (file)
@@ -1,3 +1,16 @@
+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>
 
        * builtins.c (fold_builtin_memory_op): Use the alias oracle
index b255339bfc37ad326da26288c7832e6d04156f04..a473328254d61295b140167f6a84a9687e59efac 100644 (file)
@@ -87,6 +87,7 @@ struct GTY(()) machine_function
   int arg_regs_to_save;
   int regsave_filler;
   int frame_filler;
+  int frame_locked;
   
   /* Records __builtin_return address.  */
   rtx eh_stack_adjust;
@@ -2565,7 +2566,7 @@ mep_interrupt_saved_reg (int r)
 static bool
 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;
 
@@ -2630,7 +2631,8 @@ mep_elimination_offset (int from, int to)
   int frame_size = get_frame_size () + crtl->outgoing_args_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
      gcc thinks the arg pointer has moved along with the saved regs.
@@ -2790,31 +2792,17 @@ mep_reload_pointer (int regno, const char *symbol)
   emit_insn (gen_movsi_botsym_s (reg, reg, sym));
 }
 
-void
-mep_expand_prologue (void)
+/* 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.  Returns true if a frame
+   is really needed.  */
+static bool
+mep_assign_save_slots (int reg_save_size)
 {
-  int i, rss, sp_offset = 0;
-  int reg_save_size;
-  int frame_size;
-  int really_need_stack_frame = frame_size;
+  bool really_need_stack_frame = false;
   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++)
     if (mep_call_saves_register(i))
       {
@@ -2822,7 +2810,7 @@ mep_expand_prologue (void)
 
        if ((i != TP_REGNO && i != GP_REGNO && i != LP_REGNO)
            || mep_reg_set_in_function (i))
-         really_need_stack_frame = 1;
+         really_need_stack_frame = true;
 
        if (cfun->machine->reg_save_slot[i])
          continue;
@@ -2838,6 +2826,32 @@ mep_expand_prologue (void)
            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;
   if (sp_offset + frame_size < 128)
@@ -3005,7 +3019,12 @@ mep_start_function (FILE *file, HOST_WIDE_INT hwi_local)
       int r = slot_map[i];
       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;
 
       rsize = mep_reg_size(r);
@@ -3054,14 +3073,7 @@ mep_expand_epilogue (void)
   reg_save_size = mep_elimination_offset (ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM);
   frame_size = mep_elimination_offset (FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM);
 
-  /* All save slots are set by mep_expand_prologue.  */
-  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;
-      }
+  really_need_stack_frame |= mep_assign_save_slots (reg_save_size);
 
   if (frame_pointer_needed)
     {
@@ -3819,9 +3831,19 @@ mep_pass_by_reference (CUMULATIVE_ARGS * cum ATTRIBUTE_UNUSED,
                       bool              named ATTRIBUTE_UNUSED)
 {
   int size = bytesize (type, mode);
-  if (type && TARGET_IVC2 && cum->nregs < 4 && VECTOR_TYPE_P (type))
-    return size <= 0 || size > 8;
-  return size <= 0 || size > 4;
+
+  /* This is non-obvious, but yes, large values passed after we've run
+     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
@@ -3837,8 +3859,8 @@ mep_return_in_memory (const_tree type, const_tree decl ATTRIBUTE_UNUSED)
 {
   int size = bytesize (type, BLKmode);
   if (TARGET_IVC2 && VECTOR_TYPE_P (type))
-    return size >= 0 && size <= 8 ? 0 : 1;
-  return size >= 0 && size <= 4 ? 0 : 1;
+    return size > 0 && size <= 8 ? 0 : 1;
+  return size > 0 && size <= 4 ? 0 : 1;
 }
 
 static bool
@@ -5879,6 +5901,12 @@ static void
 mep_reorg (void)
 {
   rtx insns = get_insns ();
+
+  /* We require accurate REG_DEAD notes.  */
+  compute_bb_for_insn ();
+  df_note_add_problem ();
+  df_analyze ();
+
   mep_reorg_addcombine (insns);
 #if EXPERIMENTAL_REGMOVE_REORG
   /* VLIW packing has been done already, so we can't just delete things.  */
@@ -5897,6 +5925,8 @@ mep_reorg (void)
 
   /* This may delete *insns so make sure it's last.  */
   mep_reorg_noframe (insns);
+
+  df_finish_pass (false);
 }
 
 \f