From: hubicka Date: Mon, 17 Nov 2014 22:04:36 +0000 (+0000) Subject: * ipa-cp.c (ipa_get_indirect_edge_target_1): Handle speculation. X-Git-Tag: upstream/5.3.0~4041 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=f21a87d84ae19eb85b088169a3b499e978904df1;p=platform%2Fupstream%2Flinaro-gcc.git * ipa-cp.c (ipa_get_indirect_edge_target_1): Handle speculation. (ipa_get_indirect_edge_target): Add SPECULATIVE argument. (devirtualization_time_bonus): Use it. (ipcp_discover_new_direct_edges): Likewise. * ipa-inline-analysis.c (estimate_edge_devirt_benefit): Update. * ipa-prop.h (ipa_get_indirect_edge_target): Update prototype. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@217675 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5e2e1a1..366be84 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,14 @@ 2014-11-17 Jan Hubicka + * ipa-cp.c (ipa_get_indirect_edge_target_1): Handle speculation. + (ipa_get_indirect_edge_target): Add SPECULATIVE argument. + (devirtualization_time_bonus): Use it. + (ipcp_discover_new_direct_edges): Likewise. + * ipa-inline-analysis.c (estimate_edge_devirt_benefit): Update. + * ipa-prop.h (ipa_get_indirect_edge_target): Update prototype. + +2014-11-17 Jan Hubicka + * tree.c (free_lang_data_in_decl): Set DECL_FUNCTION_SPECIFIC_OPTIMIZATION to optimization_default_node. diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c index 375b49e..e598241 100644 --- a/gcc/ipa-cp.c +++ b/gcc/ipa-cp.c @@ -1730,13 +1730,16 @@ ipa_get_indirect_edge_target_1 (struct cgraph_edge *ie, vec known_csts, vec known_contexts, vec known_aggs, - struct ipa_agg_replacement_value *agg_reps) + struct ipa_agg_replacement_value *agg_reps, + bool *speculative) { int param_index = ie->indirect_info->param_index; HOST_WIDE_INT anc_offset; tree t; tree target = NULL; + *speculative = false; + if (param_index == -1 || known_csts.length () <= (unsigned int) param_index) return NULL_TREE; @@ -1792,8 +1795,7 @@ ipa_get_indirect_edge_target_1 (struct cgraph_edge *ie, t = NULL; /* Try to work out value of virtual table pointer value in replacemnets. */ - if (!t && agg_reps && !ie->indirect_info->by_ref - && !ie->indirect_info->vptr_changed) + if (!t && agg_reps && !ie->indirect_info->by_ref) { while (agg_reps) { @@ -1811,8 +1813,7 @@ ipa_get_indirect_edge_target_1 (struct cgraph_edge *ie, /* Try to work out value of virtual table pointer value in known aggregate values. */ if (!t && known_aggs.length () > (unsigned int) param_index - && !ie->indirect_info->by_ref - && !ie->indirect_info->vptr_changed) + && !ie->indirect_info->by_ref) { struct ipa_agg_jump_function *agg; agg = known_aggs[param_index]; @@ -1836,7 +1837,9 @@ ipa_get_indirect_edge_target_1 (struct cgraph_edge *ie, || !possible_polymorphic_call_target_p (ie, cgraph_node::get (target))) target = ipa_impossible_devirt_target (ie, target); - return target; + *speculative = ie->indirect_info->vptr_changed; + if (!*speculative) + return target; } } } @@ -1877,11 +1880,32 @@ ipa_get_indirect_edge_target_1 (struct cgraph_edge *ie, ie->indirect_info->otr_token, context, &final); if (!final || targets.length () > 1) - return NULL_TREE; - if (targets.length () == 1) - target = targets[0]->decl; + { + struct cgraph_node *node; + if (*speculative) + return target; + if (!flag_devirtualize_speculatively || ie->speculative + || !ie->maybe_hot_p ()) + return NULL; + node = try_speculative_devirtualization (ie->indirect_info->otr_type, + ie->indirect_info->otr_token, + context); + if (node) + { + *speculative = true; + target = node->decl; + } + else + return NULL; + } else - target = ipa_impossible_devirt_target (ie, NULL_TREE); + { + *speculative = false; + if (targets.length () == 1) + target = targets[0]->decl; + else + target = ipa_impossible_devirt_target (ie, NULL_TREE); + } if (target && !possible_polymorphic_call_target_p (ie, cgraph_node::get (target))) @@ -1899,10 +1923,11 @@ tree ipa_get_indirect_edge_target (struct cgraph_edge *ie, vec known_csts, vec known_contexts, - vec known_aggs) + vec known_aggs, + bool *speculative) { return ipa_get_indirect_edge_target_1 (ie, known_csts, known_contexts, - known_aggs, NULL); + known_aggs, NULL, speculative); } /* Calculate devirtualization time bonus for NODE, assuming we know KNOWN_CSTS @@ -1923,9 +1948,10 @@ devirtualization_time_bonus (struct cgraph_node *node, struct inline_summary *isummary; enum availability avail; tree target; + bool speculative; target = ipa_get_indirect_edge_target (ie, known_csts, known_contexts, - known_aggs); + known_aggs, &speculative); if (!target) continue; @@ -1944,12 +1970,12 @@ devirtualization_time_bonus (struct cgraph_node *node, /* FIXME: The values below need re-considering and perhaps also integrating into the cost metrics, at lest in some very basic way. */ if (isummary->size <= MAX_INLINE_INSNS_AUTO / 4) - res += 31; + res += 31 / ((int)speculative + 1); else if (isummary->size <= MAX_INLINE_INSNS_AUTO / 2) - res += 15; + res += 15 / ((int)speculative + 1); else if (isummary->size <= MAX_INLINE_INSNS_AUTO || DECL_DECLARED_INLINE_P (callee->decl)) - res += 7; + res += 7 / ((int)speculative + 1); } return res; @@ -2645,16 +2671,18 @@ ipcp_discover_new_direct_edges (struct cgraph_node *node, for (ie = node->indirect_calls; ie; ie = next_ie) { tree target; + bool speculative; next_ie = ie->next_callee; target = ipa_get_indirect_edge_target_1 (ie, known_csts, known_contexts, - vNULL, aggvals); + vNULL, aggvals, &speculative); if (target) { bool agg_contents = ie->indirect_info->agg_contents; bool polymorphic = ie->indirect_info->polymorphic; int param_index = ie->indirect_info->param_index; - struct cgraph_edge *cs = ipa_make_edge_direct_to_target (ie, target); + struct cgraph_edge *cs = ipa_make_edge_direct_to_target (ie, target, + speculative); found = true; if (cs && !agg_contents && !polymorphic) diff --git a/gcc/ipa-inline-analysis.c b/gcc/ipa-inline-analysis.c index 69e0612..dace2fc 100644 --- a/gcc/ipa-inline-analysis.c +++ b/gcc/ipa-inline-analysis.c @@ -2986,6 +2986,7 @@ estimate_edge_devirt_benefit (struct cgraph_edge *ie, struct cgraph_node *callee; struct inline_summary *isummary; enum availability avail; + bool speculative; if (!known_vals.exists () && !known_contexts.exists ()) return false; @@ -2993,8 +2994,8 @@ estimate_edge_devirt_benefit (struct cgraph_edge *ie, return false; target = ipa_get_indirect_edge_target (ie, known_vals, known_contexts, - known_aggs); - if (!target) + known_aggs, &speculative); + if (!target || speculative) return false; /* Account for difference in cost between indirect and direct calls. */ diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h index 9e0ce35..6adb8d4 100644 --- a/gcc/ipa-prop.h +++ b/gcc/ipa-prop.h @@ -529,7 +529,8 @@ bool ipa_propagate_indirect_call_infos (struct cgraph_edge *cs, tree ipa_get_indirect_edge_target (struct cgraph_edge *ie, vec , vec, - vec ); + vec, + bool *); struct cgraph_edge *ipa_make_edge_direct_to_target (struct cgraph_edge *, tree, bool speculative = false); tree ipa_impossible_devirt_target (struct cgraph_edge *, tree);