stmt.c (optimize_tail_recursion): New function, extracted from ...
authorJeffrey A Law <law@cygnus.com>
Fri, 8 Jan 1999 12:05:20 +0000 (05:05 -0700)
committerJeff Law <law@gcc.gnu.org>
Fri, 8 Jan 1999 12:05:20 +0000 (05:05 -0700)
        * stmt.c (optimize_tail_recursion): New function, extracted from ...
        (expand_return): Use optimize_tail_recursion.
        * tree.h (optimize_tail_recursion): Declare.

From-SVN: r24574

gcc/ChangeLog
gcc/stmt.c
gcc/tree.h

index 92498dc0ba30e2cae9dfb7de146b17b9d7da5480..ef257fe82bfbff501960c23b3ee867b31c40fbc7 100644 (file)
@@ -1,8 +1,3 @@
-Thu Jan  7 19:52:53 1999  Gerald Pfeifer  <pfeifer@dbai.tuwien.ac.at>
-
-       * system.h (abort): Supply more detailed information on how to
-       report an Internal Compiler Error.
-
 Fri Jan  8 10:51:13 1999  Andreas Schwab  <schwab@issan.cs.uni-dortmund.de>
 
        * config/m68k/m68k.h: Declare output_function_epilogue.
@@ -10,9 +5,18 @@ Fri Jan  8 10:51:13 1999  Andreas Schwab  <schwab@issan.cs.uni-dortmund.de>
 
 Fri Jan  8 01:43:53 1999  Jeffrey A Law  (law@cygnus.com)
 
+       * stmt.c (optimize_tail_recursion): New function, extracted from ...
+       (expand_return): Use optimize_tail_recursion.
+       * tree.h (optimize_tail_recursion): Declare.
+
        * toplev.c (compile_file): Move call to output_func_start_profiler
        to after the loop to emit deferred functions.
 
+Thu Jan  7 19:52:53 1999  Gerald Pfeifer  <pfeifer@dbai.tuwien.ac.at>
+
+       * system.h (abort): Supply more detailed information on how to
+       report an Internal Compiler Error.
+
 Thu Jan  7 11:26:17 1999  Mark Mitchell  <mark@markmitchell.com>
 
        * calls.c (store_unaligned_arguments_into_pseudos): Use xmalloc to
index 7a8a6571305f5e5b92572e05969767eac135ae14..4f2e911dfbcf909ef37a4bf662ca17503cf41a85 100644 (file)
@@ -1,5 +1,5 @@
 /* Expands front end tree to back end RTL for GNU C-Compiler
-   Copyright (C) 1987, 88, 89, 92-97, 1998 Free Software Foundation, Inc.
+   Copyright (C) 1987, 88, 89, 92-98, 1999 Free Software Foundation, Inc.
 
 This file is part of GNU CC.
 
@@ -2564,32 +2564,9 @@ expand_return (retval)
       return;
     }
 
-  /* For tail-recursive call to current function,
-     just jump back to the beginning.
-     It's unsafe if any auto variable in this function
-     has its address taken; for simplicity,
-     require stack frame to be empty.  */
-  if (optimize && retval_rhs != 0
-      && 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
-      /* Finish checking validity, and if valid emit code
-        to set the argument variables for the new call.  */
-      && tail_recursion_args (TREE_OPERAND (retval_rhs, 1),
-                             DECL_ARGUMENTS (current_function_decl)))
-    {
-      if (tail_recursion_label == 0)
-       {
-         tail_recursion_label = gen_label_rtx ();
-         emit_label_after (tail_recursion_label,
-                           tail_recursion_reentry);
-       }
-      emit_queue ();
-      expand_goto_internal (NULL_TREE, tail_recursion_label, last_insn);
-      emit_barrier ();
-      return;
-    }
+  /* Attempt to optimize the call if it is tail recursive.  */
+  optimize_tail_recursion (retval_rhs, last_insn);
+
 #ifdef HAVE_return
   /* This optimization is safe if there are local cleanups
      because expand_null_return takes care of them.
@@ -2794,6 +2771,45 @@ drop_through_at_end_p ()
   return insn && GET_CODE (insn) != BARRIER;
 }
 \f
+/* Test CALL_EXPR to determine if it is a potential tail recursion call
+   and emit code to optimize the tail recursion.  LAST_INSN indicates where
+   to place the jump to the tail recursion label.
+
+   This is only used by expand_return, but expand_call is expected to
+   use it soon.  */
+
+void
+optimize_tail_recursion (call_expr, last_insn)
+     tree call_expr;
+     rtx last_insn;
+{
+  /* For tail-recursive call to current function,
+     just jump back to the beginning.
+     It's unsafe if any auto variable in this function
+     has its address taken; for simplicity,
+     require stack frame to be empty.  */
+  if (optimize && call_expr != 0
+      && frame_offset == 0
+      && TREE_CODE (call_expr) == CALL_EXPR
+      && TREE_CODE (TREE_OPERAND (call_expr, 0)) == ADDR_EXPR
+      && TREE_OPERAND (TREE_OPERAND (call_expr, 0), 0) == current_function_decl
+      /* Finish checking validity, and if valid emit code
+        to set the argument variables for the new call.  */
+      && tail_recursion_args (TREE_OPERAND (call_expr, 1),
+                             DECL_ARGUMENTS (current_function_decl)))
+    {
+      if (tail_recursion_label == 0)
+       {
+         tail_recursion_label = gen_label_rtx ();
+         emit_label_after (tail_recursion_label,
+                           tail_recursion_reentry);
+       }
+      emit_queue ();
+      expand_goto_internal (NULL_TREE, tail_recursion_label, last_insn);
+      emit_barrier ();
+    }
+}
+
 /* Emit code to alter this function's formal parms for a tail-recursive call.
    ACTUALS is a list of actual parameter expressions (chain of TREE_LISTs).
    FORMALS is the chain of decls of formals.
index 895cf2a1b4a4ecfa7d1697bf186e7125f9ab9392..cf3ec9dc3682f4118e017386e2d781c1fe93f895 100644 (file)
@@ -1,5 +1,5 @@
 /* Front-end tree definitions for GNU compiler.
-   Copyright (C) 1989, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
+   Copyright (C) 1989, 93-98, 1999 Free Software Foundation, Inc.
 
 This file is part of GNU CC.
 
@@ -1930,6 +1930,7 @@ extern int expand_exit_something          PROTO((void));
 
 extern void expand_null_return                 PROTO((void));
 extern void expand_return                      PROTO((tree));
+extern void optimize_tail_recursion            PROTO((tree, struct rtx_def *));
 extern void expand_start_bindings              PROTO((int));
 extern void expand_end_bindings                        PROTO((tree, int, int));
 extern void start_cleanup_deferral             PROTO((void));