summaryrefslogtreecommitdiff
path: root/gcc/tree-tailcall.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/tree-tailcall.c')
-rw-r--r--gcc/tree-tailcall.c22
1 files changed, 9 insertions, 13 deletions
diff --git a/gcc/tree-tailcall.c b/gcc/tree-tailcall.c
index 061d6c95a4e..59a7694f095 100644
--- a/gcc/tree-tailcall.c
+++ b/gcc/tree-tailcall.c
@@ -136,15 +136,11 @@ suitable_for_tail_opt_p (void)
if (cfun->stdarg)
return false;
- /* No local variable nor structure field should be call-used. We
- ignore any kind of memory tag, as these are not real variables. */
-
+ /* No local variable nor structure field should be call-used. */
FOR_EACH_REFERENCED_VAR (var, rvi)
{
if (!is_global_var (var)
- && !MTAG_P (var)
- && (gimple_aliases_computed_p (cfun)? is_call_used (var)
- : TREE_ADDRESSABLE (var)))
+ && is_call_used (var))
return false;
}
@@ -410,11 +406,9 @@ find_tail_calls (basic_block bb, struct tailcall **ret)
break;
}
- /* If the statement has virtual or volatile operands, fail. */
- if (!ZERO_SSA_OPERANDS (stmt, (SSA_OP_VUSE | SSA_OP_VIRTUAL_DEFS))
- || gimple_has_volatile_ops (stmt)
- || (!gimple_aliases_computed_p (cfun)
- && gimple_references_memory_p (stmt)))
+ /* If the statement references memory or volatile operands, fail. */
+ if (gimple_references_memory_p (stmt)
+ || gimple_has_volatile_ops (stmt))
return;
}
@@ -914,8 +908,10 @@ tree_optimize_tail_calls_1 (bool opt_tailcalls)
if (!phis_constructed)
{
- /* Ensure that there is only one predecessor of the block. */
- if (!single_pred_p (first))
+ /* Ensure that there is only one predecessor of the block
+ or if there are existing degenerate PHI nodes. */
+ if (!single_pred_p (first)
+ || !gimple_seq_empty_p (phi_nodes (first)))
first = split_edge (single_succ_edge (ENTRY_BLOCK_PTR));
/* Copy the args if needed. */