aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJan Hubicka <hubicka@ucw.cz>2025-03-13 20:11:02 +0100
committerJan Hubicka <hubicka@ucw.cz>2025-03-13 20:12:33 +0100
commit57dbbdd8e34b80926e06b352b6c442c555b303ed (patch)
tree1613be4c727ccf96aa86f5bf9fff819a24304e8a /gcc
parenta5d56278d145d439092adf6f65c865c85623f881 (diff)
downloadgcc-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.cc33
-rw-r--r--gcc/ipa-profile.cc7
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 ())
{