> Yes, this looks OK. Inliner coul also take care to turn the master clone
> into unanalyzed node as remove_unreachable_nodes would, but I do not think
> it is worth the effort. Please put the loop later in the function so it
> does not slow things down unnecesarily (there are often many inline clones)
Here's what I have installed on the mainline after re-testing, this defers the
check as much as possible.
2014-10-17 Eric Botcazou <ebotca...@adacore.com>
* ipa-inline-transform.c (master_clone_with_noninline_clones_p): New.
(clone_inlined_nodes): Do not overwrite the clone if above predicate
returns true.
--
Eric Botcazou
Index: ipa-inline-transform.c
===================================================================
--- ipa-inline-transform.c (revision 216252)
+++ ipa-inline-transform.c (working copy)
@@ -122,6 +122,20 @@ can_remove_node_now_p (struct cgraph_nod
return true;
}
+/* Return true if NODE is a master clone with non-inline clones. */
+
+static bool
+master_clone_with_noninline_clones_p (struct cgraph_node *node)
+{
+ if (node->clone_of)
+ return false;
+
+ for (struct cgraph_node *n = node->clones; n; n = n->next_sibling_clone)
+ if (n->decl != node->decl)
+ return true;
+
+ return false;
+}
/* E is expected to be an edge being inlined. Clone destination node of
the edge and redirect it to the new clone.
@@ -155,7 +169,10 @@ clone_inlined_nodes (struct cgraph_edge
/* Recursive inlining never wants the master clone to
be overwritten. */
&& update_original
- && can_remove_node_now_p (e->callee, e))
+ && can_remove_node_now_p (e->callee, e)
+ /* We cannot overwrite a master clone with non-inline clones
+ until after these clones are materialized. */
+ && !master_clone_with_noninline_clones_p (e->callee))
{
/* TODO: When callee is in a comdat group, we could remove all of it,
including all inline clones inlined into it. That would however