OSDN Git Service

PR opt/14472
authorsteven <steven@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 14 May 2004 18:29:09 +0000 (18:29 +0000)
committersteven <steven@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 14 May 2004 18:29:09 +0000 (18:29 +0000)
* tree-tailcall.c (process_assignment): Use STRIP_NOPS to
ignore type conversions that do not inhibit tail calling.
(find_tail_calls): Likewise.

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

gcc/ChangeLog
gcc/tree-tailcall.c

index 844500d..f327a76 100644 (file)
@@ -1,3 +1,10 @@
+2004-05-14  Steven Bosscher  <stevenb@suse.de>
+
+       PR opt/14472
+       * tree-tailcall.c (process_assignment): Use STRIP_NOPS to
+       ignore type conversions that do not inhibit tail calling.
+       (find_tail_calls): Likewise.
+
 2004-05-14  Jeff Law  <law@redhat.com>
 
        * tree-ssa-dom.c (simplify_rhs_and_lookup_avail_expr): Reorganize
 2004-05-14  Jeff Law  <law@redhat.com>
 
        * tree-ssa-dom.c (simplify_rhs_and_lookup_avail_expr): Reorganize
index 65657da..9321c93 100644 (file)
@@ -72,7 +72,7 @@ Boston, MA 02111-1307, USA.  */
    omit the accumulator.
 
    There are three cases how the function may exit.  The first one is
    omit the accumulator.
 
    There are three cases how the function may exit.  The first one is
-   handled in adjust_return_value, the later two in adjust_accumulator_values
+   handled in adjust_return_value, the other two in adjust_accumulator_values
    (the second case is actually a special case of the third one and we
    present it separately just for clarity):
 
    (the second case is actually a special case of the third one and we
    present it separately just for clarity):
 
@@ -260,10 +260,16 @@ process_assignment (tree ass, tree stmt, block_stmt_iterator call, tree *m,
   tree dest = TREE_OPERAND (ass, 0);
   tree src = TREE_OPERAND (ass, 1);
   enum tree_code code = TREE_CODE (src);
   tree dest = TREE_OPERAND (ass, 0);
   tree src = TREE_OPERAND (ass, 1);
   enum tree_code code = TREE_CODE (src);
-
-  if (code == SSA_NAME)
+  tree src_var = src;
+
+  /* See if this is a simple copy operation of an SSA name to the function
+     result.  In that case we may have a simple tail call.  Ignore type
+     conversions that can never produce extra code between the function
+     call and the function return.  */
+  STRIP_NOPS (src_var);
+  if (TREE_CODE (src_var) == SSA_NAME)
     {
     {
-      if (src != *ass_var)
+      if (src_var != *ass_var)
        return false;
 
       *ass_var = dest;
        return false;
 
       *ass_var = dest;
@@ -295,7 +301,7 @@ process_assignment (tree ass, tree stmt, block_stmt_iterator call, tree *m,
   else
     return false;
 
   else
     return false;
 
-  switch (TREE_CODE (src))
+  switch (code)
     {
     case PLUS_EXPR:
       /* There should be no previous addition.  TODO -- it should be fairly
     {
     case PLUS_EXPR:
       /* There should be no previous addition.  TODO -- it should be fairly
@@ -463,12 +469,15 @@ find_tail_calls (basic_block bb, struct tailcall **ret)
        return;
     }
 
        return;
     }
 
+  /* See if this is a tail call we can handle.  */
   ret_var = TREE_OPERAND (stmt, 0);
   if (ret_var
       && TREE_CODE (ret_var) == MODIFY_EXPR)
     {
   ret_var = TREE_OPERAND (stmt, 0);
   if (ret_var
       && TREE_CODE (ret_var) == MODIFY_EXPR)
     {
+      tree ret_op = TREE_OPERAND (ret_var, 1);
+      STRIP_NOPS (ret_op);
       if (!tail_recursion
       if (!tail_recursion
-         && TREE_CODE (TREE_OPERAND (ret_var, 1)) != SSA_NAME)
+         && TREE_CODE (ret_op) != SSA_NAME)
        return;
 
       if (!process_assignment (ret_var, stmt, bsi, &m, &a, &ass_var))
        return;
 
       if (!process_assignment (ret_var, stmt, bsi, &m, &a, &ass_var))