Beispiel #1
0
/* 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 ();
}
Beispiel #2
0
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");
}
Beispiel #3
0
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");
}