From a065d52eff29059a680ee8d44b11f03c0a544562 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Sun, 31 Aug 2008 18:45:05 +0200 Subject: [PATCH] ipa-cp.c (ipcp_need_original_clone_p): Remove. * ipa-cp.c (ipcp_need_original_clone_p): Remove. (ipcp_estimate_growth): New. (ipcp_insert_stage): Use ipcp_estimate_growth. * profile.c (branch_prob): When reading failed, do not consider profile as read. From-SVN: r139835 --- gcc/ChangeLog | 8 +++++++ gcc/ipa-cp.c | 72 ++++++++++++++++++++++++++++++++++++++++++----------------- gcc/profile.c | 2 +- 3 files changed, 61 insertions(+), 21 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e046003..bfbf234 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,13 @@ 2008-08-31 Jan Hubicka + * ipa-cp.c (ipcp_need_original_clone_p): Remove. + (ipcp_estimate_growth): New. + (ipcp_insert_stage): Use ipcp_estimate_growth. + * profile.c (branch_prob): When reading failed, do not consider + profile as read. + +2008-08-31 Jan Hubicka + * tree-ssa-loop-unswitch.c (tree_unswitch_single_loop): Check that loop is optimized for speed. diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c index 6c3572d..8f1c161 100644 --- a/gcc/ipa-cp.c +++ b/gcc/ipa-cp.c @@ -1042,22 +1042,58 @@ ipcp_update_profiling (void) } } -/* Return true if original clone needs to be preserved. */ -static bool -ipcp_need_original_clone_p (struct cgraph_node *node) +/* If NODE was cloned, how much would program grow? */ +static long +ipcp_estimate_growth (struct cgraph_node *node) { - struct cgraph_edge *e; + struct cgraph_edge *cs; + int redirectable_node_callers = 0; + int removable_args = 0; + bool need_original = node->needed; + struct ipa_node_params *info; + int i, count; + int growth; - if (node->needed) - return true; - for (e = node->callers; e; e = e->next_caller) - if (!bitmap_bit_p (dead_nodes, e->caller->uid) - && ipcp_need_redirect_p (e)) - return true; + for (cs = node->callers; cs != NULL; cs = cs->next_caller) + if (!ipcp_need_redirect_p (cs)) + redirectable_node_callers++; + else + need_original = true; + + /* If we will be able to fully replace orignal node, we never increase + program size. */ + if (!need_original) + return false; - return false; + info = IPA_NODE_REF (node); + count = ipa_get_param_count (info); + for (i = 0; i < count; i++) + { + struct ipcp_lattice *lat = ipcp_get_ith_lattice (info, i); + tree parm_tree = ipa_get_ith_param (info, i); + + /* We can proactively remove obviously unused arguments. */ + if (is_gimple_reg (parm_tree) + && !gimple_default_def (DECL_STRUCT_FUNCTION (node->decl), + parm_tree)) + removable_args++; + + if (lat->type == IPA_CONST_VALUE) + removable_args++; + } + + /* We make just very simple estimate of savings for removal of operand from + call site. Precise cost is dificult to get, as our size metric counts + constants and moves as free. Generally we are looking for cases that + small function is called very many times. */ + growth = node->local.inline_summary.self_insns + - removable_args * redirectable_node_callers; + if (growth < 0) + return 0; + return growth; } + /* Estimate cost of cloning NODE. */ static long ipcp_estimate_cloning_cost (struct cgraph_node *node) @@ -1067,12 +1103,12 @@ ipcp_estimate_cloning_cost (struct cgraph_node *node) struct cgraph_edge *e; int cost; - /* When we don't need original clone; we should always propagate. */ - if (!ipcp_need_original_clone_p (node)) + cost = ipcp_estimate_growth (node) * 1000; + if (!cost) { if (dump_file) - fprintf (dump_file, "Function %s can be fully propagated\n", - cgraph_node_name (node)); + fprintf (dump_file, "Versioning of %s will save code size\n", + cgraph_node_name (node)); return 0; } @@ -1084,7 +1120,6 @@ ipcp_estimate_cloning_cost (struct cgraph_node *node) freq_sum += e->frequency + 1; } - cost = node->local.inline_summary.self_insns * 1000; if (max_count) cost /= count_sum * 1000 / max_count + 1; else @@ -1185,10 +1220,7 @@ ipcp_insert_stage (void) fprintf (dump_file, "considering function %s\n", cgraph_node_name (node)); - if (ipcp_need_original_clone_p (node)) - growth = node->local.inline_summary.self_insns; - else - bitmap_set_bit (dead_nodes, node->uid); + growth = ipcp_estimate_growth (node); if (new_insns + growth > max_new_insns) break; diff --git a/gcc/profile.c b/gcc/profile.c index 6aca917..6f89645 100644 --- a/gcc/profile.c +++ b/gcc/profile.c @@ -1154,7 +1154,7 @@ branch_prob (void) VEC_free (histogram_value, heap, values); free_edge_list (el); - if (flag_branch_probabilities) + if (flag_branch_probabilities && profile_info) profile_status = PROFILE_READ; coverage_end_function (); } -- 2.7.4