/* Optimization of function bodies might've rendered some variables as unnecessary so we want to avoid these from being compiled. This is done by pruning the queue and keeping only the variables that really appear needed (ie they are either externally visible or referenced by compiled function). Re-doing the reachability analysis on variables brings back the remaining variables referenced by these. */ void varpool_remove_unreferenced_decls (void) { struct varpool_node *next, *node = varpool_nodes_queue; varpool_reset_queue (); if (seen_error ()) return; while (node) { next = node->next_needed; node->needed = 0; if (node->analyzed && (!varpool_can_remove_if_no_refs (node) /* We just expanded all function bodies. See if any of them needed the variable. */ || DECL_RTL_SET_P (node->decl))) varpool_mark_needed_node (node); node = next; } /* Make sure we mark alias targets as used targets. */ finish_aliases_1 (); varpool_analyze_pending_decls (); }
static void varpool_remove_unreferenced_decls (void) { varpool_node *next, *node; varpool_node *first = (varpool_node *)(void *)1; int i; struct ipa_ref *ref; struct pointer_set_t *referenced = pointer_set_create (); if (seen_error ()) return; if (cgraph_dump_file) fprintf (cgraph_dump_file, "Trivially needed variables:"); FOR_EACH_DEFINED_VARIABLE (node) { if (node->analyzed && (!varpool_can_remove_if_no_refs (node) /* We just expanded all function bodies. See if any of them needed the variable. */ || DECL_RTL_SET_P (node->decl))) { enqueue_node (node, &first); if (cgraph_dump_file) fprintf (cgraph_dump_file, " %s", node->asm_name ()); } } while (first != (varpool_node *)(void *)1) { node = first; first = (varpool_node *)first->aux; if (node->same_comdat_group) { symtab_node *next; for (next = node->same_comdat_group; next != node; next = next->same_comdat_group) { varpool_node *vnext = dyn_cast <varpool_node *> (next); if (vnext && vnext->analyzed && !symtab_comdat_local_p (next)) enqueue_node (vnext, &first); } } for (i = 0; ipa_ref_list_reference_iterate (&node->ref_list, i, ref); i++) { varpool_node *vnode = dyn_cast <varpool_node *> (ref->referred); if (vnode && !vnode->in_other_partition && (!DECL_EXTERNAL (ref->referred->decl) || vnode->alias) && vnode->analyzed) enqueue_node (vnode, &first); else pointer_set_insert (referenced, node); } } if (cgraph_dump_file) fprintf (cgraph_dump_file, "\nRemoving variables:"); for (node = varpool_first_defined_variable (); node; node = next) { next = varpool_next_defined_variable (node); if (!node->aux) { if (cgraph_dump_file) fprintf (cgraph_dump_file, " %s", node->asm_name ()); if (pointer_set_contains (referenced, node)) varpool_remove_initializer (node); else varpool_remove_node (node); } } pointer_set_destroy (referenced); if (cgraph_dump_file) fprintf (cgraph_dump_file, "\n"); }
static void varpool_remove_unreferenced_decls (void) { struct varpool_node *next, *node; struct varpool_node *first = (struct varpool_node *)(void *)1; int i; struct ipa_ref *ref; if (seen_error ()) return; if (cgraph_dump_file) fprintf (cgraph_dump_file, "Trivially needed variables:"); FOR_EACH_DEFINED_VARIABLE (node) { if (node->analyzed && (!varpool_can_remove_if_no_refs (node) /* We just expanded all function bodies. See if any of them needed the variable. */ || (!DECL_EXTERNAL (node->symbol.decl) && DECL_RTL_SET_P (node->symbol.decl)))) { enqueue_node (node, &first); if (cgraph_dump_file) fprintf (cgraph_dump_file, " %s", varpool_node_asm_name (node)); } } while (first != (struct varpool_node *)(void *)1) { node = first; first = (struct varpool_node *)first->symbol.aux; if (node->symbol.same_comdat_group) { symtab_node next; for (next = node->symbol.same_comdat_group; next != (symtab_node)node; next = next->symbol.same_comdat_group) { varpool_node *vnext = dyn_cast <varpool_node> (next); if (vnext && vnext->analyzed) enqueue_node (vnext, &first); } } for (i = 0; ipa_ref_list_reference_iterate (&node->symbol.ref_list, i, ref); i++) { varpool_node *vnode = dyn_cast <varpool_node> (ref->referred); if (vnode && (!DECL_EXTERNAL (ref->referred->symbol.decl) || vnode->alias) && vnode->analyzed) enqueue_node (vnode, &first); } } if (cgraph_dump_file) fprintf (cgraph_dump_file, "\nRemoving variables:"); for (node = varpool_first_defined_variable (); node; node = next) { next = varpool_next_defined_variable (node); if (!node->symbol.aux) { if (cgraph_dump_file) fprintf (cgraph_dump_file, " %s", varpool_node_asm_name (node)); varpool_remove_node (node); } } if (cgraph_dump_file) fprintf (cgraph_dump_file, "\n"); }