diff options
author | steven <steven@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-05-14 18:29:09 +0000 |
---|---|---|
committer | steven <steven@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-05-14 18:29:09 +0000 |
commit | cefc957dd23a825ed66c3cb9f78f59d136485780 (patch) | |
tree | d4f040f6987fd06abab74375ab42f23b8c8798c0 /gcc/tree-tailcall.c | |
parent | 9fb994de761a002454e2b01e07db96579429bec7 (diff) | |
download | gcc-cefc957dd23a825ed66c3cb9f78f59d136485780.tar.gz |
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.c | 21 |
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)) |