diff options
author | Martin Jambor <mjambor@suse.cz> | 2019-08-30 10:08:42 +0200 |
---|---|---|
committer | Martin Jambor <jamborm@gcc.gnu.org> | 2019-08-30 10:08:42 +0200 |
commit | bb4d170d7b43be4b28ef20978ab2b453f6f2c55d (patch) | |
tree | 394953a5970e622f04c96ee0a7aec0a73949f6c8 /gcc/tree-tailcall.c | |
parent | ffb738a286543a47682c72a9410eae3f85872580 (diff) | |
download | gcc-bb4d170d7b43be4b28ef20978ab2b453f6f2c55d.zip gcc-bb4d170d7b43be4b28ef20978ab2b453f6f2c55d.tar.gz gcc-bb4d170d7b43be4b28ef20978ab2b453f6f2c55d.tar.bz2 |
[PR 91579] Avoid creating redundant PHI nodes in tail-call pass
2019-08-30 Martin Jambor <mjambor@suse.cz>
tree-optimization/91579
* tree-tailcall.c (tailr_arg_needs_copy): New variable.
(find_tail_calls): Allocate tailr_arg_needs_copy and set its bits as
appropriate.
(arg_needs_copy_p): Removed.
(eliminate_tail_call): Test tailr_arg_needs_copy instead of calling
arg_needs_copy_p.
(tree_optimize_tail_calls_1): Likewise. Free tailr_arg_needs_copy.
testsuite/
* gcc.dg/tree-ssa/pr91579.c: New test.
From-SVN: r275062
Diffstat (limited to 'gcc/tree-tailcall.c')
-rw-r--r-- | gcc/tree-tailcall.c | 48 |
1 files changed, 25 insertions, 23 deletions
diff --git a/gcc/tree-tailcall.c b/gcc/tree-tailcall.c index a4b563e..4824a5e 100644 --- a/gcc/tree-tailcall.c +++ b/gcc/tree-tailcall.c @@ -126,6 +126,11 @@ struct tailcall accumulator. */ static tree m_acc, a_acc; +/* Bitmap with a bit for each function parameter which is set to true if we + have to copy the parameter for conversion of tail-recursive calls. */ + +static bitmap tailr_arg_needs_copy; + static bool optimize_tail_call (struct tailcall *, bool); static void eliminate_tail_call (struct tailcall *); @@ -727,6 +732,18 @@ find_tail_calls (basic_block bb, struct tailcall **ret) gimple_stmt_iterator mgsi = gsi_for_stmt (stmt); gsi_move_before (&mgsi, &gsi); } + if (!tailr_arg_needs_copy) + tailr_arg_needs_copy = BITMAP_ALLOC (NULL); + for (param = DECL_ARGUMENTS (current_function_decl), idx = 0; + param; + param = DECL_CHAIN (param), idx++) + { + tree ddef, arg = gimple_call_arg (call, idx); + if (is_gimple_reg (param) + && (ddef = ssa_default_def (cfun, param)) + && (arg != ddef)) + bitmap_set_bit (tailr_arg_needs_copy, idx); + } } nw = XNEW (struct tailcall); @@ -905,25 +922,6 @@ decrease_profile (basic_block bb, profile_count count) } } -/* Returns true if argument PARAM of the tail recursive call needs to be copied - when the call is eliminated. */ - -static bool -arg_needs_copy_p (tree param) -{ - tree def; - - if (!is_gimple_reg (param)) - return false; - - /* Parameters that are only defined but never used need not be copied. */ - def = ssa_default_def (cfun, param); - if (!def) - return false; - - return true; -} - /* Eliminates tail call described by T. TMP_VARS is a list of temporary variables used to copy the function arguments. */ @@ -1005,7 +1003,7 @@ eliminate_tail_call (struct tailcall *t) param; param = DECL_CHAIN (param), idx++) { - if (!arg_needs_copy_p (param)) + if (!bitmap_bit_p (tailr_arg_needs_copy, idx)) continue; arg = gimple_call_arg (stmt, idx); @@ -1139,10 +1137,11 @@ tree_optimize_tail_calls_1 (bool opt_tailcalls) split_edge (single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun))); /* Copy the args if needed. */ - for (param = DECL_ARGUMENTS (current_function_decl); + unsigned idx; + for (param = DECL_ARGUMENTS (current_function_decl), idx = 0; param; - param = DECL_CHAIN (param)) - if (arg_needs_copy_p (param)) + param = DECL_CHAIN (param), idx++) + if (bitmap_bit_p (tailr_arg_needs_copy, idx)) { tree name = ssa_default_def (cfun, param); tree new_name = make_ssa_name (param, SSA_NAME_DEF_STMT (name)); @@ -1206,6 +1205,9 @@ tree_optimize_tail_calls_1 (bool opt_tailcalls) if (phis_constructed) mark_virtual_operands_for_renaming (cfun); + if (tailr_arg_needs_copy) + BITMAP_FREE (tailr_arg_needs_copy); + if (changed) return TODO_cleanup_cfg | TODO_update_ssa_only_virtuals; return 0; |