コード例 #1
0
ファイル: cgraphbuild.c プロジェクト: ArtemL/GCC
static bool
mark_load (gimple stmt, tree t, tree, void *data)
{
  t = get_base_address (t);
  if (t && TREE_CODE (t) == FUNCTION_DECL)
    {
      /* ??? This can happen on platforms with descriptors when these are
	 directly manipulated in the code.  Pretend that it's an address.  */
      struct cgraph_node *node = cgraph_get_create_node (t);
      cgraph_mark_address_taken_node (node);
      ipa_record_reference ((symtab_node *)data,
			    node,
			    IPA_REF_ADDR, stmt);
    }
  else if (t && TREE_CODE (t) == VAR_DECL
	   && (TREE_STATIC (t) || DECL_EXTERNAL (t)))
    {
      varpool_node *vnode = varpool_node_for_decl (t);

      ipa_record_reference ((symtab_node *)data,
			    vnode,
			    IPA_REF_LOAD, stmt);
    }
  return false;
}
コード例 #2
0
ファイル: cgraphbuild.c プロジェクト: ArtemL/GCC
static tree
record_reference (tree *tp, int *walk_subtrees, void *data)
{
  tree t = *tp;
  tree decl;
  struct record_reference_ctx *ctx = (struct record_reference_ctx *)data;

  t = canonicalize_constructor_val (t, NULL);
  if (!t)
    t = *tp;
  else if (t != *tp)
    *tp = t;

  switch (TREE_CODE (t))
    {
    case VAR_DECL:
    case FUNCTION_DECL:
      gcc_unreachable ();
      break;

    case FDESC_EXPR:
    case ADDR_EXPR:
      /* Record dereferences to the functions.  This makes the
	 functions reachable unconditionally.  */
      decl = get_base_var (*tp);
      if (TREE_CODE (decl) == FUNCTION_DECL)
	{
	  struct cgraph_node *node = cgraph_get_create_node (decl);
	  if (!ctx->only_vars)
	    cgraph_mark_address_taken_node (node);
	  ipa_record_reference (ctx->varpool_node,
				node,
			        IPA_REF_ADDR, NULL);
	}

      if (TREE_CODE (decl) == VAR_DECL)
	{
	  varpool_node *vnode = varpool_node_for_decl (decl);
	  ipa_record_reference (ctx->varpool_node,
				vnode,
				IPA_REF_ADDR, NULL);
	}
      *walk_subtrees = 0;
      break;

    default:
      /* Save some cycles by not walking types and declaration as we
	 won't find anything useful there anyway.  */
      if (IS_TYPE_OR_DECL_P (*tp))
	{
	  *walk_subtrees = 0;
	  break;
	}
      break;
    }

  return NULL_TREE;
}
コード例 #3
0
ファイル: varpool.c プロジェクト: Lao16/gcc
/* Add the variable DECL to the varpool.
   Unlike varpool_finalize_decl function is intended to be used
   by middle end and allows insertion of new variable at arbitrary point
   of compilation.  */
void
varpool_add_new_variable (tree decl)
{
  struct varpool_node *node;
  varpool_finalize_decl (decl);
  node = varpool_node_for_decl (decl);
  if (varpool_externally_visible_p (node, false))
    node->symbol.externally_visible = true;
}
コード例 #4
0
ファイル: varpool.c プロジェクト: palves/gcc
/* Add the variable DECL to the varpool.
   Unlike varpool_finalize_decl function is intended to be used
   by middle end and allows insertion of new variable at arbitrary point
   of compilation.  */
void
varpool_add_new_variable (tree decl)
{
  varpool_node *node;
  varpool_finalize_decl (decl);
  node = varpool_node_for_decl (decl);
  varpool_call_variable_insertion_hooks (node);
  if (varpool_externally_visible_p (node))
    node->externally_visible = true;
}
コード例 #5
0
ファイル: cgraphbuild.c プロジェクト: ArtemL/GCC
void
record_references_in_initializer (tree decl, bool only_vars)
{
  struct pointer_set_t *visited_nodes = pointer_set_create ();
  varpool_node *node = varpool_node_for_decl (decl);
  struct record_reference_ctx ctx = {false, NULL};

  ctx.varpool_node = node;
  ctx.only_vars = only_vars;
  walk_tree (&DECL_INITIAL (decl), record_reference,
             &ctx, visited_nodes);
  pointer_set_destroy (visited_nodes);
}
コード例 #6
0
ファイル: cgraphbuild.c プロジェクト: TinoSM/gcc
static bool
mark_store (gimple stmt, tree t, tree, void *data)
{
  t = get_base_address (t);
  if (t && TREE_CODE (t) == VAR_DECL
      && (TREE_STATIC (t) || DECL_EXTERNAL (t)))
    {
      varpool_node *vnode = varpool_node_for_decl (t);

      ((symtab_node *)data)->add_reference (vnode, IPA_REF_STORE, stmt);
     }
  return false;
}
コード例 #7
0
ファイル: varpool.c プロジェクト: palves/gcc
varpool_node *
varpool_create_variable_alias (tree alias, tree decl)
{
  varpool_node *alias_node;

  gcc_assert (TREE_CODE (decl) == VAR_DECL);
  gcc_assert (TREE_CODE (alias) == VAR_DECL);
  alias_node = varpool_node_for_decl (alias);
  alias_node->alias = true;
  alias_node->definition = true;
  alias_node->alias_target = decl;
  if (lookup_attribute ("weakref", DECL_ATTRIBUTES (alias)) != NULL)
    alias_node->weakref = true;
  return alias_node;
}
コード例 #8
0
ファイル: varpool.c プロジェクト: palves/gcc
/* Create a new global variable of type TYPE.  */
tree
add_new_static_var (tree type)
{
  tree new_decl;
  varpool_node *new_node;

  new_decl = create_tmp_var_raw (type, NULL);
  DECL_NAME (new_decl) = create_tmp_var_name (NULL);
  TREE_READONLY (new_decl) = 0;
  TREE_STATIC (new_decl) = 1;
  TREE_USED (new_decl) = 1;
  DECL_CONTEXT (new_decl) = NULL_TREE;
  DECL_ABSTRACT (new_decl) = 0;
  lang_hooks.dup_lang_specific_decl (new_decl);
  new_node = varpool_node_for_decl (new_decl);
  varpool_finalize_decl (new_decl);

  return new_node->decl;
}
コード例 #9
0
ファイル: varpool.c プロジェクト: Lao16/gcc
void
varpool_analyze_node (struct varpool_node *node)
{
  tree decl = node->symbol.decl;

  /* When reading back varpool at LTO time, we re-construct the queue in order
     to have "needed" list right by inserting all needed nodes into varpool.
     We however don't want to re-analyze already analyzed nodes.  */
  if (!node->analyzed)
    {
      gcc_assert (!in_lto_p || cgraph_function_flags_ready);
      /* Compute the alignment early so function body expanders are
	 already informed about increased alignment.  */
      align_variable (decl, 0);
    }
  if (node->alias && node->alias_of)
    {
      struct varpool_node *tgt = varpool_node_for_decl (node->alias_of);
      struct varpool_node *n;

      for (n = tgt; n && n->alias;
	   n = n->analyzed ? varpool_alias_aliased_node (n) : NULL)
	if (n == node)
	  {
	    error ("variable %q+D part of alias cycle", node->symbol.decl);
	    node->alias = false;
	    continue;
	  }
      if (!vec_safe_length (node->symbol.ref_list.references))
	ipa_record_reference ((symtab_node)node, (symtab_node)tgt, IPA_REF_ALIAS, NULL);
      if (node->extra_name_alias)
	{
	  DECL_WEAK (node->symbol.decl) = DECL_WEAK (node->alias_of);
	  DECL_EXTERNAL (node->symbol.decl) = DECL_EXTERNAL (node->alias_of);
	  DECL_VISIBILITY (node->symbol.decl) = DECL_VISIBILITY (node->alias_of);
	  fixup_same_cpp_alias_visibility ((symtab_node) node,
					   (symtab_node) tgt, node->alias_of);
	}
    }
  else if (DECL_INITIAL (decl))
    record_references_in_initializer (decl, node->analyzed);
  node->analyzed = true;
}
コード例 #10
0
ファイル: cgraphbuild.c プロジェクト: TinoSM/gcc
static bool
mark_address (gimple stmt, tree addr, tree, void *data)
{
  addr = get_base_address (addr);
  if (TREE_CODE (addr) == FUNCTION_DECL)
    {
      struct cgraph_node *node = cgraph_get_create_node (addr);
      cgraph_mark_address_taken_node (node);
      ((symtab_node *)data)->add_reference (node, IPA_REF_ADDR, stmt);
    }
  else if (addr && TREE_CODE (addr) == VAR_DECL
	   && (TREE_STATIC (addr) || DECL_EXTERNAL (addr)))
    {
      varpool_node *vnode = varpool_node_for_decl (addr);

      ((symtab_node *)data)->add_reference (vnode, IPA_REF_ADDR, stmt);
    }

  return false;
}
コード例 #11
0
ファイル: varpool.c プロジェクト: palves/gcc
varpool_node *
varpool_extra_name_alias (tree alias, tree decl)
{
  varpool_node *alias_node;

#ifndef ASM_OUTPUT_DEF
  /* If aliases aren't supported by the assembler, fail.  */
  return NULL;
#endif
  alias_node = varpool_create_variable_alias (alias, decl);
  alias_node->cpp_implicit_alias = true;

  /* Extra name alias mechanizm creates aliases really late
     via DECL_ASSEMBLER_NAME mechanizm.
     This is unfortunate because they are not going through the
     standard channels.  Ensure they get output.  */
  if (cpp_implicit_aliases_done)
    symtab_resolve_alias (alias_node,
			  varpool_node_for_decl (decl));
  return alias_node;
}
コード例 #12
0
ファイル: cgraphbuild.c プロジェクト: TinoSM/gcc
static void
record_type_list (struct cgraph_node *node, tree list)
{
  for (; list; list = TREE_CHAIN (list))
    {
      tree type = TREE_VALUE (list);
      
      if (TYPE_P (type))
	type = lookup_type_for_runtime (type);
      STRIP_NOPS (type);
      if (TREE_CODE (type) == ADDR_EXPR)
	{
	  type = TREE_OPERAND (type, 0);
	  if (TREE_CODE (type) == VAR_DECL)
	    {
	      varpool_node *vnode = varpool_node_for_decl (type);
	      node->add_reference (vnode, IPA_REF_ADDR);
	    }
	}
    }
}
コード例 #13
0
ファイル: varpool.c プロジェクト: Lao16/gcc
struct varpool_node *
varpool_create_variable_alias (tree alias, tree decl)
{
  struct varpool_node *alias_node;

  gcc_assert (TREE_CODE (decl) == VAR_DECL);
  gcc_assert (TREE_CODE (alias) == VAR_DECL);
  alias_node = varpool_node_for_decl (alias);
  alias_node->alias = 1;
  alias_node->finalized = 1;
  alias_node->alias_of = decl;

  /* Extra name alias mechanizm creates aliases really late
     via DECL_ASSEMBLER_NAME mechanizm.
     This is unfortunate because they are not going through the
     standard channels.  Ensure they get output.  */
  if (cgraph_state >= CGRAPH_STATE_IPA)
    {
      varpool_analyze_node (alias_node);
      if (TREE_PUBLIC (alias))
	alias_node->symbol.externally_visible = true;
    }
  return alias_node;
}