diff options
author | Jan Hubicka <hubicka@ucw.cz> | 2017-02-11 17:11:57 +0100 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2017-02-11 16:11:57 +0000 |
commit | 31deea5e716be71a07d8f1ec4670e9a074b32127 (patch) | |
tree | e6a7756caa5c6eea66f27278605a6eb45ff0a73d /gcc | |
parent | 56a9ca70382a7077d864a65e018616a7f409359c (diff) | |
download | gcc-31deea5e716be71a07d8f1ec4670e9a074b32127.zip gcc-31deea5e716be71a07d8f1ec4670e9a074b32127.tar.gz gcc-31deea5e716be71a07d8f1ec4670e9a074b32127.tar.bz2 |
re PR tree-optimization/79224 (Large C-Ray slowdown)
PR ipa/79224
* ipa-inline-analysis.c (get_minimal_bb): New function.
(record_modified): Use it.
(remap_edge_change_prob): Handle also ancestor functions.
From-SVN: r245357
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/ipa-inline-analysis.c | 47 |
2 files changed, 43 insertions, 11 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8e7c2de..424fb4f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2017-02-11 Jan Hubicka <hubicka@ucw.cz> + + PR ipa/79224 + * ipa-inline-analysis.c (get_minimal_bb): New function. + (record_modified): Use it. + (remap_edge_change_prob): Handle also ancestor functions. + 2017-02-11 Gerald Pfeifer <gerald@pfeifer.com> * doc/contrib.texi (Contributors): Remove broken link into diff --git a/gcc/ipa-inline-analysis.c b/gcc/ipa-inline-analysis.c index 76ea850..611faab 100644 --- a/gcc/ipa-inline-analysis.c +++ b/gcc/ipa-inline-analysis.c @@ -2151,6 +2151,23 @@ struct record_modified_bb_info gimple *stmt; }; +/* Value is initialized in INIT_BB and used in USE_BB. We want to copute + probability how often it changes between USE_BB. + INIT_BB->frequency/USE_BB->frequency is an estimate, but if INIT_BB + is in different loop nest, we can do better. + This is all just estimate. In theory we look for minimal cut separating + INIT_BB and USE_BB, but we only want to anticipate loop invariant motion + anyway. */ + +static basic_block +get_minimal_bb (basic_block init_bb, basic_block use_bb) +{ + struct loop *l = find_common_loop (init_bb->loop_father, use_bb->loop_father); + if (l && l->header->frequency < init_bb->frequency) + return l->header; + return init_bb; +} + /* Callback of walk_aliased_vdefs. Records basic blocks where the value may be set except for info->stmt. */ @@ -2164,7 +2181,9 @@ record_modified (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef, void *data) bitmap_set_bit (info->bb_set, SSA_NAME_IS_DEFAULT_DEF (vdef) ? ENTRY_BLOCK_PTR_FOR_FN (cfun)->index - : gimple_bb (SSA_NAME_DEF_STMT (vdef))->index); + : get_minimal_bb + (gimple_bb (SSA_NAME_DEF_STMT (vdef)), + gimple_bb (info->stmt))->index); return false; } @@ -2206,7 +2225,9 @@ param_change_prob (gimple *stmt, int i) if (SSA_NAME_IS_DEFAULT_DEF (base)) init_freq = ENTRY_BLOCK_PTR_FOR_FN (cfun)->frequency; else - init_freq = gimple_bb (SSA_NAME_DEF_STMT (base))->frequency; + init_freq = get_minimal_bb + (gimple_bb (SSA_NAME_DEF_STMT (base)), + gimple_bb (stmt))->frequency; if (!init_freq) init_freq = 1; @@ -3521,18 +3542,22 @@ remap_edge_change_prob (struct cgraph_edge *inlined_edge, { struct ipa_jump_func *jfunc = ipa_get_ith_jump_func (args, i); if (jfunc->type == IPA_JF_PASS_THROUGH - && (ipa_get_jf_pass_through_formal_id (jfunc) - < (int) inlined_es->param.length ())) + || jfunc->type == IPA_JF_ANCESTOR) { - int jf_formal_id = ipa_get_jf_pass_through_formal_id (jfunc); - int prob1 = es->param[i].change_prob; - int prob2 = inlined_es->param[jf_formal_id].change_prob; - int prob = combine_probabilities (prob1, prob2); + int id = jfunc->type == IPA_JF_PASS_THROUGH + ? ipa_get_jf_pass_through_formal_id (jfunc) + : ipa_get_jf_ancestor_formal_id (jfunc); + if (id < (int) inlined_es->param.length ()) + { + int prob1 = es->param[i].change_prob; + int prob2 = inlined_es->param[id].change_prob; + int prob = combine_probabilities (prob1, prob2); - if (prob1 && prob2 && !prob) - prob = 1; + if (prob1 && prob2 && !prob) + prob = 1; - es->param[i].change_prob = prob; + es->param[i].change_prob = prob; + } } } } |