OSDN Git Service

* sibcall.c (uses_addressof): Accept both addressof and
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 12 Aug 2000 16:28:10 +0000 (16:28 +0000)
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 12 Aug 2000 16:28:10 +0000 (16:28 +0000)
        current_function_internal_arg_pointer inside a mem.
        (optimize_sibling_and_tail_recursive_call): Fail tail recursion
        if current_function_uses_addressof.
        * stmt.c (expand_return): Kill tail recursion and HAVE_return
        optimizations.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@35657 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/sibcall.c
gcc/stmt.c

index ac510fa..402fe22 100644 (file)
@@ -1,3 +1,12 @@
+2000-08-12  Richard Henderson  <rth@cygnus.com>
+
+       * sibcall.c (uses_addressof): Accept both addressof and
+       current_function_internal_arg_pointer inside a mem.
+       (optimize_sibling_and_tail_recursive_call): Fail tail recursion
+       if current_function_uses_addressof.
+       * stmt.c (expand_return): Kill tail recursion and HAVE_return
+       optimizations.
+
 2000-08-11  Richard Henderson  <rth@cygnus.com>
 
        * config/ia64/ia64.md (addsi3): Remove expander.
index 78e855e..42a9d70 100644 (file)
@@ -37,7 +37,7 @@ static rtx skip_copy_to_return_value  PARAMS ((rtx, rtx, rtx));
 static rtx skip_use_of_return_value    PARAMS ((rtx, enum rtx_code));
 static rtx skip_stack_adjustment       PARAMS ((rtx));
 static rtx skip_jump_insn              PARAMS ((rtx));
-static int uses_addressof              PARAMS ((rtx, int));
+static int uses_addressof              PARAMS ((rtx));
 static int sequence_uses_addressof     PARAMS ((rtx));
 static void purge_reg_equiv_notes      PARAMS ((void));
 
@@ -237,16 +237,12 @@ skip_jump_insn (orig_insn)
 
 /* Scan the rtx X for ADDRESSOF expressions or
    current_function_internal_arg_pointer registers.
-   INMEM argument should be 1 if we're looking at inner part of some
-   MEM expression, otherwise 0.
-   Return nonzero if an ADDRESSOF expresion is found or if
-   current_function_internal_arg_pointer is found outside of some MEM
-   expression, else return zero.  */
+   Return nonzero if an ADDRESSOF or current_function_internal_arg_pointer
+   is found outside of some MEM expression, else return zero.  */
 
 static int
-uses_addressof (x, inmem)
+uses_addressof (x)
      rtx x;
-     int inmem;
 {
   RTX_CODE code;
   int i, j;
@@ -257,14 +253,11 @@ uses_addressof (x, inmem)
 
   code = GET_CODE (x);
 
-  if (code == ADDRESSOF)
-    return 1;
-
-  if (x == current_function_internal_arg_pointer && ! inmem)
+  if (code == ADDRESSOF || x == current_function_internal_arg_pointer)
     return 1;
 
   if (code == MEM)
-    return uses_addressof (XEXP (x, 0), 1);
+    return 0;
 
   /* Scan all subexpressions. */
   fmt = GET_RTX_FORMAT (code);
@@ -272,13 +265,13 @@ uses_addressof (x, inmem)
     {
       if (*fmt == 'e')
        {
-         if (uses_addressof (XEXP (x, i), inmem))
+         if (uses_addressof (XEXP (x, i)))
            return 1;
        }
       else if (*fmt == 'E')
        {
          for (j = 0; j < XVECLEN (x, i); j++)
-           if (uses_addressof (XVECEXP (x, i, j), inmem))
+           if (uses_addressof (XVECEXP (x, i, j)))
              return 1;
        }
     }
@@ -318,8 +311,8 @@ sequence_uses_addressof (seq)
                && sequence_uses_addressof (XEXP (PATTERN (insn), 2)))
              return 1;
          }
-       else if (uses_addressof (PATTERN (insn), 0)
-                || (REG_NOTES (insn) && uses_addressof (REG_NOTES (insn), 0)))
+       else if (uses_addressof (PATTERN (insn))
+                || (REG_NOTES (insn) && uses_addressof (REG_NOTES (insn))))
          return 1;
       }
   return 0;
@@ -490,14 +483,16 @@ optimize_sibling_and_tail_recursive_calls ()
          if (frame_offset)
            goto failure;
 
+         /* Taking the address of a local variable is fatal to tail
+            recursion if the address is used by the recursive call.  */
+         if (current_function_uses_addressof)
+           goto failure;
+
          /* alloca (until we have stack slot life analysis) inhibits
             sibling call optimizations, but not tail recursion.
-
-            Similarly if we have ADDRESSOF expressions.
-
             Similarly if we use varargs or stdarg since they implicitly
             may take the address of an argument.  */
-         if (current_function_calls_alloca || current_function_uses_addressof
+         if (current_function_calls_alloca
              || current_function_varargs || current_function_stdarg)
            sibcall = 0;
 
index 47431f6..38572ca 100644 (file)
@@ -2809,9 +2809,6 @@ expand_return (retval)
   rtx last_insn = 0;
   rtx result_rtl = DECL_RTL (DECL_RESULT (current_function_decl));
   register rtx val = 0;
-#ifdef HAVE_return
-  register rtx op0;
-#endif
   tree retval_rhs;
   int cleanups;
 
@@ -2885,82 +2882,6 @@ expand_return (retval)
       return;
     }
 
-  /* Attempt to optimize the call if it is tail recursive.  */
-  if (flag_optimize_sibling_calls
-      && retval_rhs != NULL_TREE
-      && frame_offset == 0
-      && TREE_CODE (retval_rhs) == CALL_EXPR
-      && TREE_CODE (TREE_OPERAND (retval_rhs, 0)) == ADDR_EXPR
-      && (TREE_OPERAND (TREE_OPERAND (retval_rhs, 0), 0)
-         == current_function_decl)
-      && optimize_tail_recursion (TREE_OPERAND (retval_rhs, 1), last_insn))
-    return;
-
-#ifdef HAVE_return
-  /* This optimization is safe if there are local cleanups
-     because expand_null_return takes care of them.
-     ??? I think it should also be safe when there is a cleanup label,
-     because expand_null_return takes care of them, too.
-     Any reason why not?  */
-  if (HAVE_return && cleanup_label == 0
-      && ! current_function_returns_pcc_struct
-      && BRANCH_COST <= 1)
-    {
-      /* If this is  return x == y;  then generate
-        if (x == y) return 1; else return 0;
-        if we can do it with explicit return insns and branches are cheap,
-        but not if we have the corresponding scc insn.  */
-      int has_scc = 0;
-      if (retval_rhs)
-       switch (TREE_CODE (retval_rhs))
-         {
-         case EQ_EXPR:
-#ifdef HAVE_seq
-           has_scc = HAVE_seq;
-#endif
-         case NE_EXPR:
-#ifdef HAVE_sne
-           has_scc = HAVE_sne;
-#endif
-         case GT_EXPR:
-#ifdef HAVE_sgt
-           has_scc = HAVE_sgt;
-#endif
-         case GE_EXPR:
-#ifdef HAVE_sge
-           has_scc = HAVE_sge;
-#endif
-         case LT_EXPR:
-#ifdef HAVE_slt
-           has_scc = HAVE_slt;
-#endif
-         case LE_EXPR:
-#ifdef HAVE_sle
-           has_scc = HAVE_sle;
-#endif
-         case TRUTH_ANDIF_EXPR:
-         case TRUTH_ORIF_EXPR:
-         case TRUTH_AND_EXPR:
-         case TRUTH_OR_EXPR:
-         case TRUTH_NOT_EXPR:
-         case TRUTH_XOR_EXPR:
-           if (! has_scc)
-             {
-               op0 = gen_label_rtx ();
-               jumpifnot (retval_rhs, op0);
-               expand_value_return (const1_rtx);
-               emit_label (op0);
-               expand_value_return (const0_rtx);
-               return;
-             }
-           break;
-
-         default:
-           break;
-         }
-    }
-#endif /* HAVE_return */
-
   /* If the result is an aggregate that is being returned in one (or more)
      registers, load the registers here.  The compiler currently can't handle
      copying a BLKmode value into registers.  We could put this code in a