diff options
Diffstat (limited to 'gcc/tree-tailcall.c')
-rw-r--r-- | gcc/tree-tailcall.c | 22 |
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. */ |