Exemplo n.º 1
0
/* Return true if list contains an alias.  */
bool
ipa_ref_has_aliases_p (struct ipa_ref_list *ref_list)
{
  struct ipa_ref *ref;
  int i;
  for (i = 0; ipa_ref_list_referring_iterate (ref_list, i, ref); i++)
    if (ref->use == IPA_REF_ALIAS)
      return true;
  return false;
}
Exemplo n.º 2
0
void
ipa_clone_referring (symtab_node dest_node,
		    struct ipa_ref_list *src)
{
  struct ipa_ref *ref;
  int i;
  for (i = 0; ipa_ref_list_referring_iterate (src, i, ref); i++)
    ipa_record_reference (ref->referring,
			  dest_node,
			  ref->use, ref->stmt);
}
Exemplo n.º 3
0
Arquivo: varpool.c Projeto: palves/gcc
static void
assemble_aliases (varpool_node *node)
{
  int i;
  struct ipa_ref *ref;
  for (i = 0; ipa_ref_list_referring_iterate (&node->ref_list, i, ref); i++)
    if (ref->use == IPA_REF_ALIAS)
      {
	varpool_node *alias = ipa_ref_referring_varpool_node (ref);
	do_assemble_alias (alias->decl,
			   DECL_ASSEMBLER_NAME (node->decl));
	assemble_aliases (alias);
      }
}
Exemplo n.º 4
0
void
ipa_dump_referring (FILE * file, struct ipa_ref_list *list)
{
  struct ipa_ref *ref;
  int i;
  for (i = 0; ipa_ref_list_referring_iterate (list, i, ref); i++)
    {
      fprintf (file, "%s/%i (%s)",
               symtab_node_asm_name (ref->referring),
               ref->referring->symbol.order,
	       ipa_ref_use_name [ref->use]);
    }
  fprintf (file, "\n");
}
Exemplo n.º 5
0
void
ipa_dump_referring (FILE * file, struct ipa_ref_list *list)
{
  struct ipa_ref *ref;
  int i;
  for (i = 0; ipa_ref_list_referring_iterate (list, i, ref); i++)
    {
      fprintf (file, "%s/%i (%s)",
               ref->referring->asm_name (),
               ref->referring->order,
	       ipa_ref_use_name [ref->use]);
      if (ref->speculative)
	fprintf (file, " (speculative)");
    }
  fprintf (file, "\n");
}
Exemplo n.º 6
0
void
ipa_clone_referring (symtab_node *dest_node,
		    struct ipa_ref_list *src)
{
  struct ipa_ref *ref, *ref2;
  int i;
  for (i = 0; ipa_ref_list_referring_iterate (src, i, ref); i++)
    {
      bool speculative = ref->speculative;
      unsigned int stmt_uid = ref->lto_stmt_uid;

      ref2 = ipa_record_reference (ref->referring,
				   dest_node,
				   ref->use, ref->stmt);
      ref2->speculative = speculative;
      ref2->lto_stmt_uid = stmt_uid;
    }
}
Exemplo n.º 7
0
Arquivo: varpool.c Projeto: palves/gcc
bool
varpool_for_node_and_aliases (varpool_node *node,
			      bool (*callback) (varpool_node *, void *),
			      void *data,
			      bool include_overwritable)
{
  int i;
  struct ipa_ref *ref;

  if (callback (node, data))
    return true;
  for (i = 0; ipa_ref_list_referring_iterate (&node->ref_list, i, ref); i++)
    if (ref->use == IPA_REF_ALIAS)
      {
	varpool_node *alias = ipa_ref_referring_varpool_node (ref);
	if (include_overwritable
	    || cgraph_variable_initializer_availability (alias) > AVAIL_OVERWRITABLE)
          if (varpool_for_node_and_aliases (alias, callback, data,
					   include_overwritable))
	    return true;
      }
  return false;
}
Exemplo n.º 8
0
Arquivo: symtab.c Projeto: Roffi/gcc
bool
symtab_for_node_and_aliases (symtab_node node,
			     bool (*callback) (symtab_node, void *),
			     void *data,
			     bool include_overwritable)
{
  int i;
  struct ipa_ref *ref;

  if (callback (node, data))
    return true;
  for (i = 0; ipa_ref_list_referring_iterate (&node->symbol.ref_list, i, ref); i++)
    if (ref->use == IPA_REF_ALIAS)
      {
	symtab_node alias = ref->referring;
	if (include_overwritable
	    || symtab_node_availability (alias) > AVAIL_OVERWRITABLE)
          if (symtab_for_node_and_aliases (alias, callback, data,
					   include_overwritable))
	    return true;
      }
  return false;
}
Exemplo n.º 9
0
DEBUG_FUNCTION bool
verify_symtab_base (symtab_node *node)
{
  bool error_found = false;
  symtab_node *hashed_node;

  if (is_a <cgraph_node> (node))
    {
      if (TREE_CODE (node->decl) != FUNCTION_DECL)
	{
          error ("function symbol is not function");
          error_found = true;
	}
    }
  else if (is_a <varpool_node> (node))
    {
      if (TREE_CODE (node->decl) != VAR_DECL)
	{
          error ("variable symbol is not variable");
          error_found = true;
	}
    }
  else
    {
      error ("node has unknown type");
      error_found = true;
    }
   
  if (cgraph_state != CGRAPH_LTO_STREAMING)
    {
      hashed_node = symtab_get_node (node->decl);
      if (!hashed_node)
	{
	  error ("node not found in symtab decl hashtable");
	  error_found = true;
	}
      if (hashed_node != node
	  && (!is_a <cgraph_node> (node)
	      || !dyn_cast <cgraph_node> (node)->clone_of
	      || dyn_cast <cgraph_node> (node)->clone_of->decl
		 != node->decl))
	{
	  error ("node differs from symtab decl hashtable");
	  error_found = true;
	}
    }
  if (assembler_name_hash)
    {
      hashed_node = symtab_node_for_asm (DECL_ASSEMBLER_NAME (node->decl));
      if (hashed_node && hashed_node->previous_sharing_asm_name)
	{
          error ("assembler name hash list corrupted");
          error_found = true;
	}
      while (hashed_node)
	{
	  if (hashed_node == node)
	    break;
	  hashed_node = hashed_node->next_sharing_asm_name;
	}
      if (!hashed_node
          && !(is_a <varpool_node> (node)
	       || DECL_HARD_REGISTER (node->decl)))
	{
          error ("node not found in symtab assembler name hash");
          error_found = true;
	}
    }
  if (node->previous_sharing_asm_name
      && node->previous_sharing_asm_name->next_sharing_asm_name != node)
    {
      error ("double linked list of assembler names corrupted");
      error_found = true;
    }
  if (node->analyzed && !node->definition)
    {
      error ("node is analyzed byt it is not a definition");
      error_found = true;
    }
  if (node->cpp_implicit_alias && !node->alias)
    {
      error ("node is alias but not implicit alias");
      error_found = true;
    }
  if (node->alias && !node->definition
      && !node->weakref)
    {
      error ("node is alias but not definition");
      error_found = true;
    }
  if (node->weakref && !node->alias)
    {
      error ("node is weakref but not an alias");
      error_found = true;
    }
  if (node->same_comdat_group)
    {
      symtab_node *n = node->same_comdat_group;

      if (!DECL_ONE_ONLY (n->decl))
	{
	  error ("non-DECL_ONE_ONLY node in a same_comdat_group list");
	  error_found = true;
	}
      if (n->type != node->type)
	{
	  error ("mixing different types of symbol in same comdat groups is not supported");
	  error_found = true;
	}
      if (n == node)
	{
	  error ("node is alone in a comdat group");
	  error_found = true;
	}
      do
	{
	  if (!n->same_comdat_group)
	    {
	      error ("same_comdat_group is not a circular list");
	      error_found = true;
	      break;
	    }
	  n = n->same_comdat_group;
	}
      while (n != node);
      if (symtab_comdat_local_p (node))
	{
	  struct ipa_ref_list *refs = &node->ref_list;
	  struct ipa_ref *ref;
	  for (int i = 0; ipa_ref_list_referring_iterate (refs, i, ref); ++i)
	    {
	      if (!symtab_in_same_comdat_p (ref->referring, node))
		{
		  error ("comdat-local symbol referred to by %s outside its "
			 "comdat",
			 identifier_to_locale (ref->referring->name()));
		  error_found = true;
		}
	    }
	}
    }
  return error_found;
}
Exemplo n.º 10
0
tree
propagate_comdat_group (struct symtab_node *symbol,
			tree newgroup, pointer_map <tree> &map)
{
  int i;
  struct ipa_ref *ref;

  /* Walk all references to SYMBOL, recursively dive into aliases.  */

  for (i = 0;
       ipa_ref_list_referring_iterate (&symbol->ref_list, i, ref)
       && newgroup != error_mark_node; i++)
    {
      struct symtab_node *symbol2 = ref->referring;

      if (ref->use == IPA_REF_ALIAS)
	{
	  newgroup = propagate_comdat_group (symbol2, newgroup, map);
	  continue;
	}

      /* One COMDAT group can not hold both variables and functions at
	 a same time.  For now we just go to BOTTOM, in future we may
	 invent special comdat groups for this case.  */

      if (symbol->type != symbol2->type)
	{
	  newgroup = error_mark_node;
	  break;
	}

      /* If we see inline clone, its comdat group actually
	 corresponds to the comdat group of the function it is inlined
	 to.  */

      if (cgraph_node * cn = dyn_cast <cgraph_node *> (symbol2))
	{
	  if (cn->global.inlined_to)
	    symbol2 = cn->global.inlined_to;
	}

      /* The actual merge operation.  */

      tree *val2 = map.contains (symbol2);

      if (val2 && *val2 != newgroup)
	{
	  if (!newgroup)
	    newgroup = *val2;
	  else
	    newgroup = error_mark_node;
	}
    }

  /* If we analyze function, walk also callers.  */

  cgraph_node *cnode = dyn_cast <cgraph_node *> (symbol);

  if (cnode)
    for (struct cgraph_edge * edge = cnode->callers;
	 edge && newgroup != error_mark_node; edge = edge->next_caller)
      {
	struct symtab_node *symbol2 = edge->caller;

	/* If we see inline clone, its comdat group actually
	   corresponds to the comdat group of the function it is inlined
	   to.  */

	if (cgraph_node * cn = dyn_cast <cgraph_node *> (symbol2))
	  {
	    if (cn->global.inlined_to)
	      symbol2 = cn->global.inlined_to;
	  }

        /* The actual merge operation.  */

	tree *val2 = map.contains (symbol2);

	if (val2 && *val2 != newgroup)
	  {
	    if (!newgroup)
	      newgroup = *val2;
	    else
	      newgroup = error_mark_node;
	  }
      }
  return newgroup;
}