aboutsummaryrefslogtreecommitdiff
path: root/gcc/ipa-cp.c
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2008-08-31 18:45:05 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2008-08-31 16:45:05 +0000
commita065d52eff29059a680ee8d44b11f03c0a544562 (patch)
tree422fb0a8faa00c7edd926c5753a32a442ce9540d /gcc/ipa-cp.c
parent079990a2bffd576c7f8a3f375e8f02be2bc00306 (diff)
downloadgcc-a065d52eff29059a680ee8d44b11f03c0a544562.zip
gcc-a065d52eff29059a680ee8d44b11f03c0a544562.tar.gz
gcc-a065d52eff29059a680ee8d44b11f03c0a544562.tar.bz2
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
Diffstat (limited to 'gcc/ipa-cp.c')
-rw-r--r--gcc/ipa-cp.c72
1 files changed, 52 insertions, 20 deletions
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;