+/* We removed or are going to remove the last call to NODE.
+ Return true if we can and want proactively remove the NODE now.
+ This is important to do, since we want inliner to know when offline
+ copy of function was removed. */
+
+static bool
+can_remove_node_now_p_1 (struct cgraph_node *node)
+{
+ /* FIXME: When address is taken of DECL_EXTERNAL function we still
+ can remove its offline copy, but we would need to keep unanalyzed node in
+ the callgraph so references can point to it. */
+ return (!node->address_taken
+ && !ipa_ref_has_aliases_p (&node->ref_list)
+ && cgraph_can_remove_if_no_direct_calls_p (node)
+ /* Inlining might enable more devirtualizing, so we want to remove
+ those only after all devirtualizable virtual calls are processed.
+ Lacking may edges in callgraph we just preserve them post
+ inlining. */
+ && !DECL_VIRTUAL_P (node->decl)
+ /* During early inlining some unanalyzed cgraph nodes might be in the
+ callgraph and they might reffer the function in question. */
+ && !cgraph_new_nodes);
+}
+
+/* We are going to eliminate last direct call to NODE (or alias of it) via edge E.
+ Verify that the NODE can be removed from unit and if it is contained in comdat
+ group that the whole comdat group is removable. */
+
+static bool
+can_remove_node_now_p (struct cgraph_node *node, struct cgraph_edge *e)
+{
+ struct cgraph_node *next;
+ if (!can_remove_node_now_p_1 (node))
+ return false;
+
+ /* When we see same comdat group, we need to be sure that all
+ items can be removed. */
+ if (!node->same_comdat_group)
+ return true;
+ for (next = node->same_comdat_group;
+ next != node; next = next->same_comdat_group)
+ if ((next->callers && next->callers != e)
+ || !can_remove_node_now_p_1 (next))
+ return false;
+ return true;
+}
+