From 267301972659e347333a04ce393e1af15d42531d Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Fri, 19 Oct 2018 06:38:33 -0400 Subject: [PATCH 1/9] FIXME: eliminate usage of cfun in tree-tailcall.c --- gcc/tree-tailcall.c | 99 +++++++++++++++++++++++++++++------------------------ 1 file changed, 54 insertions(+), 45 deletions(-) diff --git a/gcc/tree-tailcall.c b/gcc/tree-tailcall.c index 8e9c2cb..7d1f1c3 100644 --- a/gcc/tree-tailcall.c +++ b/gcc/tree-tailcall.c @@ -42,6 +42,12 @@ along with GCC; see the file COPYING3. If not see #include "common/common-target.h" #include "ipa-utils.h" +#if (GCC_VERSION >= 3000) +#undef cfun +#pragma GCC poison cfun +// TODO: poison current_function_decl +#endif + /* The file implements the tail recursion elimination. It is also used to analyze the tail calls in general, passing the results to the rtl level where they are used for sibcall optimization. @@ -124,16 +130,16 @@ struct tailcall accumulator. */ static tree m_acc, a_acc; -static bool optimize_tail_call (struct tailcall *, bool); -static void eliminate_tail_call (struct tailcall *); +static bool optimize_tail_call (function *, struct tailcall *, bool); +static void eliminate_tail_call (function *, struct tailcall *); /* Returns false when the function is not suitable for tail call optimization from some reason (e.g. if it takes variable number of arguments). */ static bool -suitable_for_tail_opt_p (void) +suitable_for_tail_opt_p (function *fun) { - if (cfun->stdarg) + if (fun->stdarg) return false; return true; @@ -144,13 +150,13 @@ suitable_for_tail_opt_p (void) tail call discovery happen. */ static bool -suitable_for_tail_call_opt_p (void) +suitable_for_tail_call_opt_p (function *fun) { tree param; /* alloca (until we have stack slot life analysis) inhibits sibling call optimizations, but not tail recursion. */ - if (cfun->calls_alloca) + if (fun->calls_alloca) return false; /* If we are using sjlj exceptions, we may need to add a call to @@ -163,7 +169,7 @@ suitable_for_tail_call_opt_p (void) /* Any function that calls setjmp might have longjmp called from any called function. ??? We really should represent this properly in the CFG so that this needn't be special cased. */ - if (cfun->calls_setjmp) + if (fun->calls_setjmp) return false; /* ??? It is OK if the argument of a function is taken in some cases, @@ -395,7 +401,7 @@ propagate_through_phis (tree var, edge e) added to the start of RET. */ static void -find_tail_calls (basic_block bb, struct tailcall **ret) +find_tail_calls (function *fun, basic_block bb, struct tailcall **ret) { tree ass_var = NULL_TREE, ret_var, func, param; gimple *stmt; @@ -436,8 +442,8 @@ find_tail_calls (basic_block bb, struct tailcall **ret) /* Allow simple copies between local variables, even if they're aggregates. */ if (is_gimple_assign (stmt) - && auto_var_in_fn_p (gimple_assign_lhs (stmt), cfun->decl) - && auto_var_in_fn_p (gimple_assign_rhs1 (stmt), cfun->decl)) + && auto_var_in_fn_p (gimple_assign_lhs (stmt), fun->decl) + && auto_var_in_fn_p (gimple_assign_rhs1 (stmt), fun->decl)) continue; /* If the statement references memory or volatile operands, fail. */ @@ -451,7 +457,7 @@ find_tail_calls (basic_block bb, struct tailcall **ret) edge_iterator ei; /* Recurse to the predecessors. */ FOR_EACH_EDGE (e, ei, bb->preds) - find_tail_calls (e->src, ret); + find_tail_calls (fun, e->src, ret); return; } @@ -469,7 +475,7 @@ find_tail_calls (basic_block bb, struct tailcall **ret) we need to revisit this here, to allow that situation. */ if (ass_var && !is_gimple_reg (ass_var) - && !auto_var_in_fn_p (ass_var, cfun->decl)) + && !auto_var_in_fn_p (ass_var, fun->decl)) return; /* We found the call, check whether it is suitable. */ @@ -515,10 +521,10 @@ find_tail_calls (basic_block bb, struct tailcall **ret) /* Make sure the tail invocation of this function does not indirectly refer to local variables. (Passing variables directly by value is OK.) */ - FOR_EACH_LOCAL_DECL (cfun, idx, var) + FOR_EACH_LOCAL_DECL (fun, idx, var) { if (TREE_CODE (var) != PARM_DECL - && auto_var_in_fn_p (var, cfun->decl) + && auto_var_in_fn_p (var, fun->decl) && may_be_aliased (var) && (ref_maybe_used_by_stmt_p (call, var) || call_may_clobber_ref_p (call, var))) @@ -819,7 +825,7 @@ decrease_profile (basic_block bb, profile_count count) when the call is eliminated. */ static bool -arg_needs_copy_p (tree param) +arg_needs_copy_p (function *fun, tree param) { tree def; @@ -827,7 +833,7 @@ arg_needs_copy_p (tree param) return false; /* Parameters that are only defined but never used need not be copied. */ - def = ssa_default_def (cfun, param); + def = ssa_default_def (fun, param); if (!def) return false; @@ -838,7 +844,7 @@ arg_needs_copy_p (tree param) temporary variables used to copy the function arguments. */ static void -eliminate_tail_call (struct tailcall *t) +eliminate_tail_call (function *fun, struct tailcall *t) { tree param, rslt; gimple *stmt, *call; @@ -864,7 +870,7 @@ eliminate_tail_call (struct tailcall *t) gcc_assert (is_gimple_call (stmt)); - first = single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun)); + first = single_succ (ENTRY_BLOCK_PTR_FOR_FN (fun)); /* Remove the code after call_gsi that will become unreachable. The possibly unreachable code in other blocks is removed later in @@ -895,11 +901,11 @@ eliminate_tail_call (struct tailcall *t) /* When profile is inconsistent and the recursion edge is more frequent than number of executions of functions, scale it down, so we do not end up with 0 executions of entry block. */ - if (count >= ENTRY_BLOCK_PTR_FOR_FN (cfun)->count) - count = ENTRY_BLOCK_PTR_FOR_FN (cfun)->count.apply_scale (7, 8); - decrease_profile (EXIT_BLOCK_PTR_FOR_FN (cfun), count); - decrease_profile (ENTRY_BLOCK_PTR_FOR_FN (cfun), count); - if (e->dest != EXIT_BLOCK_PTR_FOR_FN (cfun)) + if (count >= ENTRY_BLOCK_PTR_FOR_FN (fun)->count) + count = ENTRY_BLOCK_PTR_FOR_FN (fun)->count.apply_scale (7, 8); + decrease_profile (EXIT_BLOCK_PTR_FOR_FN (fun), count); + decrease_profile (ENTRY_BLOCK_PTR_FOR_FN (fun), count); + if (e->dest != EXIT_BLOCK_PTR_FOR_FN (fun)) decrease_profile (e->dest, count); /* Replace the call by a jump to the start of function. */ @@ -915,7 +921,7 @@ eliminate_tail_call (struct tailcall *t) param; param = DECL_CHAIN (param), idx++) { - if (!arg_needs_copy_p (param)) + if (!arg_needs_copy_p (fun, param)) continue; arg = gimple_call_arg (stmt, idx); @@ -946,11 +952,11 @@ eliminate_tail_call (struct tailcall *t) mark the tailcalls for the sibcall optimization. */ static bool -optimize_tail_call (struct tailcall *t, bool opt_tailcalls) +optimize_tail_call (function *fun, struct tailcall *t, bool opt_tailcalls) { if (t->tail_recursion) { - eliminate_tail_call (t); + eliminate_tail_call (fun, t); return true; } @@ -959,7 +965,7 @@ optimize_tail_call (struct tailcall *t, bool opt_tailcalls) gcall *stmt = as_a (gsi_stmt (t->call_gsi)); gimple_call_set_tail (stmt, true); - cfun->tail_call_marked = true; + fun->tail_call_marked = true; if (dump_file && (dump_flags & TDF_DETAILS)) { fprintf (dump_file, "Found tail call "); @@ -998,23 +1004,23 @@ create_tailcall_accumulator (const char *label, basic_block bb, tree init) into iteration. */ static unsigned int -tree_optimize_tail_calls_1 (bool opt_tailcalls) +tree_optimize_tail_calls_1 (function *fun, bool opt_tailcalls) { edge e; bool phis_constructed = false; struct tailcall *tailcalls = NULL, *act, *next; bool changed = false; - basic_block first = single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun)); + basic_block first = single_succ (ENTRY_BLOCK_PTR_FOR_FN (fun)); tree param; gimple *stmt; edge_iterator ei; - if (!suitable_for_tail_opt_p ()) + if (!suitable_for_tail_opt_p (fun)) return 0; if (opt_tailcalls) - opt_tailcalls = suitable_for_tail_call_opt_p (); + opt_tailcalls = suitable_for_tail_call_opt_p (fun); - FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds) + FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (fun)->preds) { /* Only traverse the normal exits, i.e. those that end with return statement. */ @@ -1022,7 +1028,7 @@ tree_optimize_tail_calls_1 (bool opt_tailcalls) if (stmt && gimple_code (stmt) == GIMPLE_RETURN) - find_tail_calls (e->src, &tailcalls); + find_tail_calls (fun, e->src, &tailcalls); } /* Construct the phi nodes and accumulators if necessary. */ @@ -1039,19 +1045,19 @@ tree_optimize_tail_calls_1 (bool opt_tailcalls) if (!single_pred_p (first) || !gimple_seq_empty_p (phi_nodes (first))) first = - split_edge (single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun))); + split_edge (single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (fun))); /* Copy the args if needed. */ for (param = DECL_ARGUMENTS (current_function_decl); param; param = DECL_CHAIN (param)) - if (arg_needs_copy_p (param)) + if (arg_needs_copy_p (fun, param)) { - tree name = ssa_default_def (cfun, param); + tree name = ssa_default_def (fun, param); tree new_name = make_ssa_name (param, SSA_NAME_DEF_STMT (name)); gphi *phi; - set_ssa_default_def (cfun, param, new_name); + set_ssa_default_def (fun, param, new_name); phi = create_phi_node (name, first); add_phi_arg (phi, new_name, single_pred_edge (first), EXPR_LOCATION (param)); @@ -1079,14 +1085,14 @@ tree_optimize_tail_calls_1 (bool opt_tailcalls) for (; tailcalls; tailcalls = next) { next = tailcalls->next; - changed |= optimize_tail_call (tailcalls, opt_tailcalls); + changed |= optimize_tail_call (fun, tailcalls, opt_tailcalls); free (tailcalls); } if (a_acc || m_acc) { /* Modify the remaining return statements. */ - FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds) + FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (fun)->preds) { stmt = last_stmt (e->src); @@ -1107,7 +1113,7 @@ tree_optimize_tail_calls_1 (bool opt_tailcalls) header of the loop created by tail recursion elimination. Do so by triggering the SSA renamer. */ if (phis_constructed) - mark_virtual_operands_for_renaming (cfun); + mark_virtual_operands_for_renaming (fun); if (changed) return TODO_cleanup_cfg | TODO_update_ssa_only_virtuals; @@ -1121,9 +1127,9 @@ gate_tail_calls (void) } static unsigned int -execute_tail_calls (void) +execute_tail_calls (function *fun) { - return tree_optimize_tail_calls_1 (true); + return tree_optimize_tail_calls_1 (fun, true); } namespace { @@ -1151,9 +1157,9 @@ public: /* opt_pass methods: */ opt_pass * clone () { return new pass_tail_recursion (m_ctxt); } virtual bool gate (function *) { return gate_tail_calls (); } - virtual unsigned int execute (function *) + virtual unsigned int execute (function *fun) { - return tree_optimize_tail_calls_1 (false); + return tree_optimize_tail_calls_1 (fun, false); } }; // class pass_tail_recursion @@ -1190,7 +1196,10 @@ public: /* opt_pass methods: */ virtual bool gate (function *) { return gate_tail_calls (); } - virtual unsigned int execute (function *) { return execute_tail_calls (); } + virtual unsigned int execute (function *fun) + { + return execute_tail_calls (fun); + } }; // class pass_tail_calls -- 1.8.5.3