diff options
author | Jan Hubicka <hubicka@ucw.cz> | 2025-03-13 20:11:02 +0100 |
---|---|---|
committer | Jan Hubicka <hubicka@ucw.cz> | 2025-03-13 20:12:33 +0100 |
commit | 57dbbdd8e34b80926e06b352b6c442c555b303ed (patch) | |
tree | 1613be4c727ccf96aa86f5bf9fff819a24304e8a /gcc | |
parent | a5d56278d145d439092adf6f65c865c85623f881 (diff) | |
download | gcc-57dbbdd8e34b80926e06b352b6c442c555b303ed.zip gcc-57dbbdd8e34b80926e06b352b6c442c555b303ed.tar.gz gcc-57dbbdd8e34b80926e06b352b6c442c555b303ed.tar.bz2 |
Fix speculation_useful_p
This patch fixes issue with speculation and x264. With profile feedback
we first introduce speculative calls to mc_chroma which is called indirectly.
Then we propagate constants acorss these calls (which is useful transform) but
then speculation_useful_p decides that these speculations are not useful and
we end up calling unspecialized version.
This patch updates speculation_useful_p to consider edges redirected earlier
to clones as useful, since we can expect that ipa-cp knows what it is doing
(originally it only looked for inlined calls). I also noticed that we want
to keep edges even if they are not hot.
Finally I noticed a typo in computing target in code which intends to keep
devirtualized calls to functions where we propagated pureness/constness. Newly
we also track ipa-modref summaries as they also may be useful.
gcc/ChangeLog:
PR ipa/119147
* ipa-inline.cc: Include ipa-modref-tree.h and
ipa-modref.h.
(speculation_useful_p): If target is a clone, speculation is usef;
fix mixup of caller and callee; speculate also calls not considered
hot; consider modref summary also possibly useful for optimization.
* ipa-profile.cc (ipa_profile): Keep non-hot speculations.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ipa-inline.cc | 33 | ||||
-rw-r--r-- | gcc/ipa-profile.cc | 7 |
2 files changed, 24 insertions, 16 deletions
diff --git a/gcc/ipa-inline.cc b/gcc/ipa-inline.cc index 1631295..9e6e85d 100644 --- a/gcc/ipa-inline.cc +++ b/gcc/ipa-inline.cc @@ -121,6 +121,8 @@ along with GCC; see the file COPYING3. If not see #include "attribs.h" #include "asan.h" #include "ipa-strub.h" +#include "ipa-modref-tree.h" +#include "ipa-modref.h" /* Inliner uses greedy algorithm to inline calls in a priority order. Badness is used as the key in a Fibonacci heap which roughly corresponds @@ -1941,23 +1943,30 @@ heap_edge_removal_hook (struct cgraph_edge *e, void *data) bool speculation_useful_p (struct cgraph_edge *e, bool anticipate_inlining) { - /* If we have already decided to inline the edge, it seems useful. */ - if (!e->inline_failed) + /* If we have already decided to inline the edge, it seems useful. + Also if ipa-cp or other pass worked hard enough to produce a clone, + we already decided this is a good idea. */ + if (!e->inline_failed + || e->callee->clone_of) return true; enum availability avail; struct cgraph_node *target = e->callee->ultimate_alias_target (&avail, - e->caller); + e->callee); gcc_assert (e->speculative && !e->indirect_unknown_callee); - if (!e->maybe_hot_p ()) + /* Even if calll statement is not hot, we can still have useful speculation + in cases where a lot of time is spent is callee. + Do not check maybe_hot_p. */ + if (!e->count.nonzero_p ()) return false; /* See if IP optimizations found something potentially useful about the - function. For now we look only for CONST/PURE flags. Almost everything - else we propagate is useless. */ - if (avail >= AVAIL_AVAILABLE) + function. Do this only if the call seems hot since this is about + optimizing the code surrounding call site rahter than improving + callee. */ + if (avail >= AVAIL_AVAILABLE && e->maybe_hot_p ()) { int ecf_flags = flags_from_decl_or_type (target->decl); if (ecf_flags & ECF_CONST) @@ -1972,12 +1981,18 @@ speculation_useful_p (struct cgraph_edge *e, bool anticipate_inlining) ->ecf_flags & ECF_PURE)) return true; } + else if (get_modref_function_summary (target)) + return true; } /* If we did not managed to inline the function nor redirect to an ipa-cp clone (that are seen by having local flag set), it is probably pointless to inline it unless hardware is missing - indirect call predictor. */ - if (!anticipate_inlining && !target->local) + indirect call predictor. + + At this point we know we will not dispatch into faster version of + callee, so if call itself is not hot, we definitely can give up + speculating. */ + if (!anticipate_inlining && (!target->local || !e->maybe_hot_p ())) return false; /* For overwritable targets there is not much to do. */ if (!can_inline_edge_p (e, false) diff --git a/gcc/ipa-profile.cc b/gcc/ipa-profile.cc index 51616de..0863866 100644 --- a/gcc/ipa-profile.cc +++ b/gcc/ipa-profile.cc @@ -882,13 +882,6 @@ ipa_profile (void) "Not speculating: " "probability is too low.\n"); } - else if (!e->maybe_hot_p ()) - { - nuseless++; - if (dump_file) - fprintf (dump_file, - "Not speculating: call is cold.\n"); - } else if (n2->get_availability () <= AVAIL_INTERPOSABLE && n2->can_be_discarded_p ()) { |