static struct cgraph_node *
cgraph_empty_node_for_versioning (struct cgraph_node *old_version,
tree new_decl)
{
struct cgraph_node *new_version;
struct cgraph_edge *e, *new_e;
struct cgraph_edge *next_callee;
gcc_assert (old_version);
new_version = cgraph_node (new_decl);
new_version->analyzed = true;
new_version->local = old_version->local;
new_version->global = old_version->global;
new_version->rtl = new_version->rtl;
new_version->reachable = true;
new_version->count = old_version->count;
/* Clone the old node callees. Recursive calls are
also cloned. */
for (e = old_version->callees;e; e=e->next_callee)
{
new_e = cgraph_clone_edge (e, new_version, e->call_stmt, 0, e->frequency,
e->loop_nest, true);
new_e->count = e->count;
}
/* Fix recursive calls.
If OLD_VERSION has a recursive call after the
previous edge cloning, the new version will have an edge
pointing to the old version, which is wrong;
Redirect it to point to the new version. */
for (e = new_version->callees ; e; e = next_callee)
{
next_callee = e->next_callee;
if (e->callee == old_version)
cgraph_redirect_edge_callee (e, new_version);
if (!next_callee)
break;
}
return new_version;
}
...
tree old_decl = old_version_node->decl;
struct cgraph_node *new_version_node = NULL;
tree new_decl;
/* Make a new FUNCTION_DECL tree node for the
new version. */
new_decl = copy_node (old_decl);
new_version_node =
cgraph_empty_node_for_versioning (old_version_node, new_decl);
/* Copy the OLD_VERSION_NODE function tree to the new version. */
tree_function_versioning (old_decl, new_decl, tree_map, false);
...