> Patch is still OK, but ipa-ICF will only identify the functions if
> static chain is unused. Perhaps just picking the winning candidate to be
> version without static chain and making ipa-inline to not ICE when calls
> with static chain lands to function with no static chain would help us
> to optimize better.
I see, thanks for the explanation. The attached patch appears to work.
PR ipa/113996
* ipa-icf.h (sem_function): Add static_chain_p member.
* ipa-icf.cc (sem_function::init): Initialize it.
(sem_item_optimizer::merge_classes): If the class is made of
functions, pick one without static chain as the target.
--
Eric Botcazou
diff --git a/gcc/ipa-icf.cc b/gcc/ipa-icf.cc
index 5d5a42f9c6c..4fc02831798 100644
--- a/gcc/ipa-icf.cc
+++ b/gcc/ipa-icf.cc
@@ -1368,6 +1368,8 @@ sem_function::init (ipa_icf_gimple::func_checker *checker)
/* iterating all function arguments. */
arg_count = count_formal_params (fndecl);
+ static_chain_p = func->static_chain_decl != NULL_TREE;
+
edge_count = n_edges_for_fn (func);
cgraph_node *cnode = dyn_cast <cgraph_node *> (node);
if (!cnode->thunk)
@@ -3399,11 +3401,22 @@ sem_item_optimizer::merge_classes (unsigned int prev_class_count,
sem_item *source = c->members[0];
- if (DECL_NAME (source->decl)
- && MAIN_NAME_P (DECL_NAME (source->decl)))
- /* If merge via wrappers, picking main as the target can be
- problematic. */
- source = c->members[1];
+ if (source->type == FUNC)
+ {
+ /* Pick a member without static chain, if any. */
+ for (unsigned int j = 0; j < c->members.length (); j++)
+ if (!static_cast<sem_function *> (c->members[j])->static_chain_p)
+ {
+ source = c->members[j];
+ break;
+ }
+
+ /* If merge via wrappers, picking main as the target can be
+ problematic. */
+ if (DECL_NAME (source->decl)
+ && MAIN_NAME_P (DECL_NAME (source->decl)))
+ source = c->members[source == c->members[0] ? 1 : 0];
+ }
for (unsigned int j = 0; j < c->members.length (); j++)
{
diff --git a/gcc/ipa-icf.h b/gcc/ipa-icf.h
index ef7e41bfa88..da20862c306 100644
--- a/gcc/ipa-icf.h
+++ b/gcc/ipa-icf.h
@@ -355,6 +355,9 @@ public:
parameters. */
bool compatible_parm_types_p (tree, tree);
+ /* Return true if parameter I may be used. */
+ bool param_used_p (unsigned int i);
+
/* Exception handling region tree. */
eh_region region_tree;
@@ -379,6 +382,9 @@ public:
/* Total number of SSA names used in the function. */
unsigned ssa_names_size;
+ /* Whether the special PARM_DECL for the static chain is present. */
+ bool static_chain_p;
+
/* Array of structures for all basic blocks. */
vec <ipa_icf_gimple::sem_bb *> bb_sorted;
@@ -386,9 +392,6 @@ public:
function. */
hashval_t m_alias_sets_hash;
- /* Return true if parameter I may be used. */
- bool param_used_p (unsigned int i);
-
private:
/* Calculates hash value based on a BASIC_BLOCK. */
hashval_t get_bb_hash (const ipa_icf_gimple::sem_bb *basic_block);