Avoid trashing of polymorphic call cache during inlining
Jan Hubicka
hubicka@ucw.cz
Mon Nov 4 19:45:00 GMT 2019
Hi,
I am not really pround of this implementation (and will think of better
interface), but this patch saves about 10% of WPA time by avoiding
unnecesary invalidations of the polymorphic call target hash during
inlining.
ipa-devirt register node removal hook to invalidate cache when one of
functions in it gets removed. Now inliner often decides to inline into
a thunk. In order to get costs right it turns the thunk into a gimple
functions and re-inserts it into the summaries (so the summaries gets
computed for the actual thunk body).
Bootstrapped/regtested x86_64-linux, comitted.
* ipa-inline-transform.c: Include ipa-utils.h
(inline_call): Set thunk_expansion flag.
* ipa-utils.h (thunk_expansion): Declare.
* ipa-devirt.c (thunk_expansion): New global var.
(devirt_node_removal_hook): Do not invalidate cache while
doing thunk expansion.
Index: ipa-inline-transform.c
===================================================================
--- ipa-inline-transform.c (revision 277780)
+++ ipa-inline-transform.c (working copy)
@@ -47,6 +47,7 @@ along with GCC; see the file COPYING3.
#include "function.h"
#include "cfg.h"
#include "basic-block.h"
+#include "ipa-utils.h"
int ncalls_inlined;
int nfunctions_inlined;
@@ -352,6 +353,7 @@ inline_call (struct cgraph_edge *e, bool
if (to->thunk.thunk_p)
{
struct cgraph_node *target = to->callees->callee;
+ thunk_expansion = true;
symtab->call_cgraph_removal_hooks (to);
if (in_lto_p)
to->get_untransformed_body ();
@@ -360,6 +362,7 @@ inline_call (struct cgraph_edge *e, bool
for (e = to->callees; e && e->callee != target; e = e->next_callee)
;
symtab->call_cgraph_insertion_hooks (to);
+ thunk_expansion = false;
gcc_assert (e);
}
Index: ipa-utils.h
===================================================================
--- ipa-utils.h (revision 277780)
+++ ipa-utils.h (working copy)
@@ -47,6 +47,9 @@ void ipa_merge_profiles (struct cgraph_n
struct cgraph_node *src, bool preserve_body = false);
bool recursive_call_p (tree, tree);
+/* In ipa-prop.c */
+void ipa_remove_useless_jump_functions ();
+
/* In ipa-profile.c */
bool ipa_propagate_frequency (struct cgraph_node *node);
@@ -54,6 +57,7 @@ bool ipa_propagate_frequency (struct cgr
struct odr_type_d;
typedef odr_type_d *odr_type;
+extern bool thunk_expansion;
void build_type_inheritance_graph (void);
void rebuild_type_inheritance_graph (void);
void update_type_inheritance_graph (void);
Index: ipa-devirt.c
===================================================================
--- ipa-devirt.c (revision 277780)
+++ ipa-devirt.c (working copy)
@@ -172,6 +172,11 @@ struct default_hash_traits <type_pair>
}
};
+/* HACK alert: this is used to communicate with ipa-inline-transform that
+ thunk is being expanded and there is no need to clear the polymorphic
+ call target cache. */
+bool thunk_expansion;
+
static bool odr_types_equivalent_p (tree, tree, bool, bool *,
hash_set<type_pair> *,
location_t, location_t);
@@ -2747,6 +2752,7 @@ static void
devirt_node_removal_hook (struct cgraph_node *n, void *d ATTRIBUTE_UNUSED)
{
if (cached_polymorphic_call_targets
+ && !thunk_expansion
&& cached_polymorphic_call_targets->contains (n))
free_polymorphic_call_targets_hash ();
}
More information about the Gcc-patches
mailing list