mips.c (epilogue_reg_mentioned_p): Delete unused function.
authorJeff Law <law@gcc.gnu.org>
Fri, 11 Jul 1997 15:48:51 +0000 (09:48 -0600)
committerJeff Law <law@gcc.gnu.org>
Fri, 11 Jul 1997 15:48:51 +0000 (09:48 -0600)
        * mips.c (epilogue_reg_mentioned_p): Delete unused function.
        (mips_epilogue_delay_slots): Likewise.
        (function_epilogue): Greatly simplify.
        (mips_expand_epilogue): If we have a null prologue/epilogue,
        then use a normal return insn.  Emit blockage insns before
        stack pointer adjustments.
        (mips_can_use_return_insn): Renamed from simple_epilogue_p.  All
        callers changed.  Do not use return insns if $31 is live in the
        function or if generating profiling information.
        * mips.h (DELAY_SLOTS_FOR_EPILOGUE): Delete.
        (ELIGIBLE_FOR_EPILOGUE_DELAY): Likewise.
        * mips.md (return): Remove expander and change the pattern to
        look like a standard "return" insn.
        (return_internal): Show use of $31 explictly.
        (epilogue expander): Enable.

From-SVN: r14412

gcc/config/mips/mips.c
gcc/config/mips/mips.h
gcc/config/mips/mips.md

index 584de95a0846f16bc4deba6203a212870d00efb3..7ebb50836484311c3a0c6fee22d96aa8fc792646 100644 (file)
@@ -4729,71 +4729,6 @@ mips_output_float (stream, value)
 #endif
 }
 
-\f
-/* Return TRUE if any register used in the epilogue is used.  This to insure
-   any insn put into the epilogue delay slots is safe.  */
-
-int
-epilogue_reg_mentioned_p (insn)
-     rtx insn;
-{
-  register char *fmt;
-  register int i;
-  register enum rtx_code code;
-  register int regno;
-
-  if (insn == (rtx)0)
-    return 0;
-
-  if (GET_CODE (insn) == LABEL_REF)
-    return 0;
-
-  code = GET_CODE (insn);
-  switch (code)
-    {
-    case REG:
-      regno = REGNO (insn);
-      if (regno == STACK_POINTER_REGNUM)
-       return 1;
-
-      if (regno == FRAME_POINTER_REGNUM && frame_pointer_needed)
-       return 1;
-
-      if (!call_used_regs[regno])
-       return 1;
-
-      if (regno != MIPS_TEMP1_REGNUM && regno != MIPS_TEMP2_REGNUM)
-       return 0;
-
-      if (!current_frame_info.initialized)
-       compute_frame_size (get_frame_size ());
-
-      return (current_frame_info.total_size >= 32768);
-
-    case SCRATCH:
-    case CC0:
-    case PC:
-    case CONST_INT:
-    case CONST_DOUBLE:
-      return 0;
-    }
-
-  fmt = GET_RTX_FORMAT (code);
-  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
-    {
-      if (fmt[i] == 'E')
-       {
-         register int j;
-         for (j = XVECLEN (insn, i) - 1; j >= 0; j--)
-           if (epilogue_reg_mentioned_p (XVECEXP (insn, i, j)))
-             return 1;
-       }
-      else if (fmt[i] == 'e' && epilogue_reg_mentioned_p (XEXP (insn, i)))
-       return 1;
-    }
-
-  return 0;
-}
 \f
 /* Return the bytes needed to compute the frame pointer from the current
    stack pointer.
@@ -5525,170 +5460,6 @@ function_epilogue (file, size)
      int size;
 {
   char *fnname;
-  long tsize;
-  char *sp_str = reg_names[STACK_POINTER_REGNUM];
-  char *t1_str = reg_names[MIPS_TEMP1_REGNUM];
-  rtx epilogue_delay = current_function_epilogue_delay_list;
-  int noreorder = (epilogue_delay != 0);
-  int noepilogue = FALSE;
-  int load_nop = FALSE;
-  int load_only_r31;
-  rtx tmp_rtx = (rtx)0;
-  rtx restore_rtx;
-  int i;
-
-  /* The epilogue does not depend on any registers, but the stack
-     registers, so we assume that if we have 1 pending nop, it can be
-     ignored, and 2 it must be filled (2 nops occur for integer
-     multiply and divide).  */
-
-  if (dslots_number_nops > 0)
-    {
-      if (dslots_number_nops == 1)
-       {
-         dslots_number_nops = 0;
-         dslots_load_filled++;
-       }
-      else
-       {
-         while (--dslots_number_nops > 0)
-           fputs ("\t#nop\n", asm_out_file);
-       }
-    }
-
-  if (set_noat != 0)
-    {
-      set_noat = 0;
-      fputs ("\t.set\tat\n", file);
-      error ("internal gcc error: .set noat left on in epilogue");
-    }
-
-  if (set_nomacro != 0)
-    {
-      set_nomacro = 0;
-      fputs ("\t.set\tmacro\n", file);
-      error ("internal gcc error: .set nomacro left on in epilogue");
-    }
-
-  if (set_noreorder != 0)
-    {
-      set_noreorder = 0;
-      fputs ("\t.set\treorder\n", file);
-      error ("internal gcc error: .set noreorder left on in epilogue");
-    }
-
-  if (set_volatile != 0)
-    {
-      set_volatile = 0;
-      fprintf (file, "\t%s.set\tnovolatile\n", (TARGET_MIPS_AS) ? "" : "#");
-      error ("internal gcc error: .set volatile left on in epilogue");
-    }
-
-  size = MIPS_STACK_ALIGN (size);
-  tsize = (!current_frame_info.initialized)
-               ? compute_frame_size (size)
-               : current_frame_info.total_size;
-
-  if (tsize == 0 && epilogue_delay == 0)
-    {
-      rtx insn = get_last_insn ();
-
-      /* If the last insn was a BARRIER, we don't have to write any code
-        because a jump (aka return) was put there.  */
-      if (GET_CODE (insn) == NOTE)
-       insn = prev_nonnote_insn (insn);
-      if (insn && GET_CODE (insn) == BARRIER)
-       noepilogue = TRUE;
-
-      noreorder = FALSE;
-    }
-
-  if (!noepilogue)
-    {
-      /* In the reload sequence, we don't need to fill the load delay
-        slots for most of the loads, also see if we can fill the final
-        delay slot if not otherwise filled by the reload sequence.  */
-
-      if (noreorder)
-       fprintf (file, "\t.set\tnoreorder\n");
-
-      if (tsize > 32767)
-       {
-         fprintf (file, "\tli\t%s,0x%.08lx\t# %ld\n", t1_str, (long)tsize, (long)tsize);
-         tmp_rtx = gen_rtx (REG, Pmode, MIPS_TEMP1_REGNUM);
-       }
-
-      if (frame_pointer_needed)
-       fprintf (file, "\tmove\t%s,%s\t\t\t# sp not trusted here\n",
-                sp_str, reg_names[FRAME_POINTER_REGNUM]);
-
-      save_restore_insns (FALSE, tmp_rtx, tsize, file);
-
-      load_only_r31 = (((current_frame_info.mask
-                        & ~ (TARGET_ABICALLS && mips_abi == ABI_32
-                             ? PIC_OFFSET_TABLE_MASK : 0))
-                       == RA_MASK)
-                      && current_frame_info.fmask == 0);
-
-      if (noreorder)
-       {
-         /* If the only register saved is the return address, we need a
-            nop, unless we have an instruction to put into it.  Otherwise
-            we don't since reloading multiple registers doesn't reference
-            the register being loaded.  */
-
-         if (load_only_r31)
-           {
-             if (epilogue_delay)
-                 final_scan_insn (XEXP (epilogue_delay, 0),
-                                  file,
-                                  1,                   /* optimize */
-                                  -2,                  /* prescan */
-                                  1);                  /* nopeepholes */
-             else
-               {
-                 fprintf (file, "\tnop\n");
-                 load_nop = TRUE;
-               }
-           }
-
-         fprintf (file, "\tj\t%s\n", reg_names[GP_REG_FIRST + 31]);
-
-         if (tsize > 32767)
-           fprintf (file, "\t%s\t%s,%s,%s\n",
-                    TARGET_LONG64 ? "daddu" : "addu",
-                    sp_str, sp_str, t1_str);
-
-         else if (tsize > 0)
-           fprintf (file, "\t%s\t%s,%s,%d\n",
-                    TARGET_LONG64 ? "daddu" : "addu",
-                    sp_str, sp_str, tsize);
-
-         else if (!load_only_r31 && epilogue_delay != 0)
-           final_scan_insn (XEXP (epilogue_delay, 0),
-                            file,
-                            1,                 /* optimize */
-                            -2,                /* prescan */
-                            1);                /* nopeepholes */
-
-         fprintf (file, "\t.set\treorder\n");
-       }
-
-      else
-       {
-         if (tsize > 32767)
-           fprintf (file, "\t%s\t%s,%s,%s\n",
-                    TARGET_LONG64 ? "daddu" : "addu",
-                    sp_str, sp_str, t1_str);
-
-         else if (tsize > 0)
-           fprintf (file, "\t%s\t%s,%s,%d\n",
-                    TARGET_LONG64 ? "daddu" : "addu",
-                    sp_str, sp_str, tsize);
-
-         fprintf (file, "\tj\t%s\n", reg_names[GP_REG_FIRST + 31]);
-       }
-    }
 
 #ifndef FUNCTION_NAME_ALREADY_DECLARED
   /* Get the function name the same way that toplev.c does before calling
@@ -5713,23 +5484,6 @@ function_epilogue (file, size)
 
       dslots_load_total += num_regs;
 
-      if (!noepilogue)
-       dslots_jump_total++;
-
-      if (noreorder)
-       {
-         dslots_load_filled += num_regs;
-
-         /* If the only register saved is the return register, we
-            can't fill this register's delay slot.  */
-
-         if (load_only_r31 && epilogue_delay == 0)
-           dslots_load_filled--;
-
-         if (tsize > 0 || (!load_only_r31 && epilogue_delay != 0))
-           dslots_jump_filled++;
-       }
-
       fprintf (stderr,
               "%-20s fp=%c leaf=%c alloca=%c setjmp=%c stack=%4ld arg=%3ld reg=%2d/%d delay=%3d/%3dL %3d/%3dJ refs=%3d/%3d/%3d",
               name,
@@ -5791,6 +5545,12 @@ mips_expand_epilogue ()
   rtx tsize_rtx = GEN_INT (tsize);
   rtx tmp_rtx = (rtx)0;
 
+  if (mips_can_use_return_insn ())
+    {
+      emit_insn (gen_return ());
+      return;
+    }
+
   if (tsize > 32767)
     {
       tmp_rtx = gen_rtx (REG, Pmode, MIPS_TEMP1_REGNUM);
@@ -5802,6 +5562,7 @@ mips_expand_epilogue ()
     {
       if (frame_pointer_needed)
        {
+         emit_insn (gen_blockage ());
          if (TARGET_LONG64)
            emit_insn (gen_movdi (stack_pointer_rtx, frame_pointer_rtx));
          else
@@ -5810,6 +5571,7 @@ mips_expand_epilogue ()
 
       save_restore_insns (FALSE, tmp_rtx, tsize, (FILE *)0);
 
+      emit_insn (gen_blockage ());
       if (TARGET_LONG64)
        emit_insn (gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx,
                               tsize_rtx));
@@ -5818,28 +5580,7 @@ mips_expand_epilogue ()
                               tsize_rtx));
     }
 
-  emit_jump_insn (gen_return_internal (gen_rtx (REG, Pmode, GP_REG_FIRST+31)));
-}
-
-\f
-/* Define the number of delay slots needed for the function epilogue.
-
-   On the mips, we need a slot if either no stack has been allocated,
-   or the only register saved is the return register.  */
-
-int
-mips_epilogue_delay_slots ()
-{
-  if (!current_frame_info.initialized)
-    (void) compute_frame_size (get_frame_size ());
-
-  if (current_frame_info.total_size == 0)
-    return 1;
-
-  if (current_frame_info.mask == RA_MASK && current_frame_info.fmask == 0)
-    return 1;
-
-  return 0;
+  emit_jump_insn (gen_return_internal ());
 }
 
 \f
@@ -5848,11 +5589,14 @@ mips_epilogue_delay_slots ()
    was created.  */
 
 int
-simple_epilogue_p ()
+mips_can_use_return_insn ()
 {
   if (!reload_completed)
     return 0;
 
+  if (regs_ever_live[31] || profile_flag)
+    return 0;
+
   if (current_frame_info.initialized)
     return current_frame_info.total_size == 0;
 
index 6aa3402c22ce3e8057a936b4059fef545f6e891b..74068d4497b4f420cbcc16c6da52226e6b8a6b91 100644 (file)
@@ -2241,22 +2241,6 @@ typedef struct mips_args {
 
 #define FUNCTION_EPILOGUE(FILE, SIZE) function_epilogue(FILE, SIZE)
 
-/* Define the number of delay slots needed for the function epilogue.
-
-   On the mips, we need a slot if either no stack has been allocated,
-   or the only register saved is the return register.  */
-
-#define DELAY_SLOTS_FOR_EPILOGUE mips_epilogue_delay_slots ()
-
-/* Define whether INSN can be placed in delay slot N for the epilogue.
-   No references to the stack must be made, since on the MIPS, the
-   delay slot is done after the stack has been cleaned up.  */
-
-#define ELIGIBLE_FOR_EPILOGUE_DELAY(INSN,N)                            \
-  (get_attr_dslot (INSN) == DSLOT_NO                                   \
-   && get_attr_length (INSN) == 1                                      \
-   && ! epilogue_reg_mentioned_p (PATTERN (INSN)))
-
 /* Tell prologue and epilogue if register REGNO should be saved / restored.  */
 
 #define MUST_SAVE_REGISTER(regno) \
index 36f97910ffdd80a78619cdf340703987a960e727..770a91c97a3566deeb2c6cfaec1311dbf5c4c11a 100644 (file)
@@ -6315,29 +6315,6 @@ move\\t%0,%z4\\n\\
    (set_attr "mode"    "none")
    (set_attr "length"  "1")])
 
-;; Function return, only allow after optimization, so that we can
-;; eliminate jumps to jumps if no stack space is used.
-
-;; (define_expand "return"
-;;   [(set (pc) (reg:SI 31))]
-;;   "simple_epilogue_p ()"
-;;   "")
-
-(define_expand "return"
-  [(parallel [(return)
-             (use (reg:SI 31))])]
-  "simple_epilogue_p ()"
-  "")
-
-(define_insn "return_internal"
-  [(parallel [(return)
-              (use (match_operand:SI 0 "register_operand" "d"))])]
-  ""
-  "%*j\\t%0"
-  [(set_attr "type"    "jump")
-   (set_attr "mode"    "none")
-   (set_attr "length"  "1")])
-
 ;; Implement a switch statement when generating embedded PIC code.
 ;; Switches are implemented by `tablejump' when not using -membedded-pic.
 
@@ -6448,21 +6425,38 @@ move\\t%0,%z4\\n\\
    (set_attr "mode"    "none")
    (set_attr "length"  "0")])
 
-;; At present, don't expand the epilogue, reorg.c will clobber the
-;; return register in compiling gen_lowpart (emit-rtl.c).
-;; 
-;; (define_expand "epilogue"
-;;   [(const_int 2)]
-;;   ""
-;;   "
-;; {
-;;   if (mips_isa >= 0)            /* avoid unused code warnings */
-;;     {
-;;       mips_expand_epilogue ();
-;;       DONE;
-;;     }
-;; }")
+(define_expand "epilogue"
+  [(const_int 2)]
+  ""
+  "
+{
+  if (mips_isa >= 0)            /* avoid unused code warnings */
+    {
+      mips_expand_epilogue ();
+      DONE;
+    }
+}")
 
+;; Trivial return.  Make it look like a normal return insn as that
+;; allows jump optimizations to work better .
+(define_insn "return"
+  [(return)]
+  "mips_can_use_return_insn ()"
+  "%*j\\t$31"
+  [(set_attr "type"    "jump")
+   (set_attr "mode"    "none")
+   (set_attr "length"  "1")])
+
+;; Normal return.
+(define_insn "return_internal"
+  [(use (reg:SI 31))
+   (return)]
+  ""
+  "%*j\\t$31"
+  [(set_attr "type"    "jump")
+   (set_attr "mode"    "none")
+   (set_attr "length"  "1")])
+  
 ;; When generating embedded PIC code we need to get the address of the
 ;; current function.  This specialized instruction does just that.