summaryrefslogtreecommitdiffstats
path: root/gcc/tree-tailcall.c
diff options
context:
space:
mode:
authorsteven <steven@138bc75d-0d04-0410-961f-82ee72b054a4>2004-05-14 18:29:09 +0000
committersteven <steven@138bc75d-0d04-0410-961f-82ee72b054a4>2004-05-14 18:29:09 +0000
commitcefc957dd23a825ed66c3cb9f78f59d136485780 (patch)
treed4f040f6987fd06abab74375ab42f23b8c8798c0 /gcc/tree-tailcall.c
parent9fb994de761a002454e2b01e07db96579429bec7 (diff)
downloadppe42-gcc-cefc957dd23a825ed66c3cb9f78f59d136485780.tar.gz
ppe42-gcc-cefc957dd23a825ed66c3cb9f78f59d136485780.zip
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@81855 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-tailcall.c')
-rw-r--r--gcc/tree-tailcall.c21
1 files changed, 15 insertions, 6 deletions
diff --git a/gcc/tree-tailcall.c b/gcc/tree-tailcall.c
index 65657da250b..9321c93a541 100644
--- a/gcc/tree-tailcall.c
+++ b/gcc/tree-tailcall.c
@@ -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
- 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):
@@ -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);
-
- 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;
@@ -295,7 +301,7 @@ process_assignment (tree ass, tree stmt, block_stmt_iterator call, tree *m,
else
return false;
- switch (TREE_CODE (src))
+ switch (code)
{
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;
}
+ /* 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)
{
+ tree ret_op = TREE_OPERAND (ret_var, 1);
+ STRIP_NOPS (ret_op);
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))
OpenPOWER on IntegriCloud