diff options
author | Jan Hubicka <jh@suse.cz> | 2023-07-29 08:18:18 +0200 |
---|---|---|
committer | Jan Hubicka <jh@suse.cz> | 2023-07-29 08:18:18 +0200 |
commit | 7ed98195f3f5c23948fff7ecc720127485490397 (patch) | |
tree | af37bed7c0564fcfc6456a07d57b0b8cb735d47b /gcc/tree-vect-loop-manip.cc | |
parent | e0f91730aa7e31fb56c6ae4a888497c38e4d584c (diff) | |
download | gcc-7ed98195f3f5c23948fff7ecc720127485490397.zip gcc-7ed98195f3f5c23948fff7ecc720127485490397.tar.gz gcc-7ed98195f3f5c23948fff7ecc720127485490397.tar.bz2 |
Fix profile update after vectorize loop versioning
Vectorizer while loop versioning produces a versioned loop
guarded with two conditionals of the form
if (cond1)
goto scalar_loop
else
goto next_bb
next_bb:
if (cond2)
godo scalar_loop
else
goto vector_loop
It wants the combined test to be prob (whch is set to likely)
and uses profile_probability::split to determine probability
of cond1 and cond2.
However spliting is turning:
if (cond)
goto lab; // ORIG probability
into
if (cond1)
goto lab; // FIRST = ORIG * CPROB probability
if (cond2)
goto lab; // SECOND probability
Which is or instead of and. As a result we get pretty low probabiility
of entering vectorized loop.
The fixes this by introducing sqrt to profile probability (which is correct
way to split this) and also adding pow that is needed elsewhere.
While loop versioning I now produce code as if there was only one combined
conditional and then update probability of conditional produced (containig
cond1). Later edge is split and new conditional is added. At that time
it is necessary to update probability of the BB containing second conditional
so everything matches.
gcc/ChangeLog:
* profile-count.cc (profile_probability::sqrt): New member function.
(profile_probability::pow): Likewise.
* profile-count.h: (profile_probability::sqrt): Declare
(profile_probability::pow): Likewise.
* tree-vect-loop-manip.cc (vect_loop_versioning): Fix profile update.
Diffstat (limited to 'gcc/tree-vect-loop-manip.cc')
-rw-r--r-- | gcc/tree-vect-loop-manip.cc | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/gcc/tree-vect-loop-manip.cc b/gcc/tree-vect-loop-manip.cc index 30baac6..e53a99e 100644 --- a/gcc/tree-vect-loop-manip.cc +++ b/gcc/tree-vect-loop-manip.cc @@ -3784,7 +3784,7 @@ vect_loop_versioning (loop_vec_info loop_vinfo, } tree cost_name = NULL_TREE; - profile_probability prob2 = profile_probability::uninitialized (); + profile_probability prob2 = profile_probability::always (); if (cond_expr && EXPR_P (cond_expr) && (version_niter @@ -3797,7 +3797,7 @@ vect_loop_versioning (loop_vec_info loop_vinfo, is_gimple_val, NULL_TREE); /* Split prob () into two so that the overall probability of passing both the cost-model and versioning checks is the orig prob. */ - prob2 = prob.split (prob); + prob2 = prob = prob.sqrt (); } if (version_niter) @@ -3941,7 +3941,15 @@ vect_loop_versioning (loop_vec_info loop_vinfo, initialize_original_copy_tables (); nloop = loop_version (loop_to_version, cond_expr, &condition_bb, - prob, prob.invert (), prob, prob.invert (), true); + prob * prob2, (prob * prob2).invert (), + prob * prob2, (prob * prob2).invert (), + true); + /* We will later insert second conditional so overall outcome of + both is prob * prob2. */ + edge true_e, false_e; + extract_true_false_edges_from_block (condition_bb, &true_e, &false_e); + true_e->probability = prob; + false_e->probability = prob.invert (); gcc_assert (nloop); nloop = get_loop_copy (loop); @@ -4037,6 +4045,7 @@ vect_loop_versioning (loop_vec_info loop_vinfo, edge e2 = make_edge (e->src, false_e->dest, EDGE_FALSE_VALUE); e->probability = prob2; e2->probability = prob2.invert (); + e->dest->count = e->count (); set_immediate_dominator (CDI_DOMINATORS, false_e->dest, e->src); auto_vec<basic_block, 3> adj; for (basic_block son = first_dom_son (CDI_DOMINATORS, e->dest); |